2010-01-04 17:06:14 +00:00
|
|
|
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
|
|
|
|
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
|
2009-10-17 14:43:12 +00:00
|
|
|
*
|
|
|
|
* Conky, a system monitor, based on torsmo
|
|
|
|
*
|
|
|
|
* Any original torsmo code is licensed under the BSD license
|
|
|
|
*
|
|
|
|
* All code written since the fork of torsmo is licensed under the GPL
|
|
|
|
*
|
|
|
|
* Please see COPYING for details
|
|
|
|
*
|
|
|
|
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
|
2012-05-03 23:34:44 +00:00
|
|
|
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
|
2009-10-17 14:43:12 +00:00
|
|
|
* (see AUTHORS)
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
2009-10-24 23:59:07 +00:00
|
|
|
#include "conky.h"
|
2009-10-17 14:43:12 +00:00
|
|
|
#include "logging.h"
|
|
|
|
#include "specials.h"
|
|
|
|
#include "net/if.h"
|
|
|
|
#include "text_object.h"
|
|
|
|
#include "net_stat.h"
|
2009-11-14 03:19:51 +00:00
|
|
|
#include <netinet/in.h>
|
2009-10-17 14:43:12 +00:00
|
|
|
#include <errno.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/ioctl.h>
|
2009-11-07 11:21:48 +00:00
|
|
|
#include <unistd.h>
|
2018-01-19 14:00:42 +00:00
|
|
|
#if defined(__sun)
|
|
|
|
#include <sys/sockio.h>
|
|
|
|
#endif
|
2018-01-19 16:36:40 +00:00
|
|
|
#if defined(__HAIKU__)
|
|
|
|
#include <sys/sockio.h>
|
|
|
|
#define IFF_RUNNING IFF_LINK
|
|
|
|
#endif
|
2009-10-17 14:43:12 +00:00
|
|
|
|
|
|
|
/* network interface stuff */
|
|
|
|
|
2010-08-25 17:40:24 +00:00
|
|
|
enum if_up_strictness_ {
|
|
|
|
IFUP_UP,
|
|
|
|
IFUP_LINK,
|
|
|
|
IFUP_ADDR
|
|
|
|
};
|
|
|
|
|
|
|
|
template<>
|
|
|
|
conky::lua_traits<if_up_strictness_>::Map conky::lua_traits<if_up_strictness_>::map = {
|
|
|
|
{ "up", IFUP_UP },
|
|
|
|
{ "link", IFUP_LINK },
|
|
|
|
{ "address", IFUP_ADDR }
|
|
|
|
};
|
|
|
|
|
|
|
|
static conky::simple_config_setting<if_up_strictness_> if_up_strictness("if_up_strictness",
|
|
|
|
IFUP_UP, true);
|
2015-12-10 20:13:29 +00:00
|
|
|
/**
|
|
|
|
* global array of structs containing network statistics for each interface
|
|
|
|
**/
|
2009-11-07 22:46:46 +00:00
|
|
|
struct net_stat netstats[MAX_NET_INTERFACES];
|
2018-04-26 11:27:21 +00:00
|
|
|
struct net_stat foo_netstats;
|
2009-10-17 14:43:12 +00:00
|
|
|
|
2015-12-10 20:13:29 +00:00
|
|
|
/**
|
|
|
|
* Returns pointer to specified interface in netstats array.
|
|
|
|
* If not found then add the specified interface to the array.
|
|
|
|
* The added interface will have all its members initialized to 0,
|
|
|
|
* because clear_net_stats() is called from main() in conky.cc!
|
|
|
|
*
|
|
|
|
* @param[in] dev device / interface name. Silently ignores char * == NULL
|
|
|
|
**/
|
2009-10-17 14:43:12 +00:00
|
|
|
struct net_stat *get_net_stat(const char *dev, void *free_at_crash1, void *free_at_crash2)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
if (!dev) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* find interface stat */
|
2009-11-07 22:46:46 +00:00
|
|
|
for (i = 0; i < MAX_NET_INTERFACES; i++) {
|
2009-10-17 14:43:12 +00:00
|
|
|
if (netstats[i].dev && strcmp(netstats[i].dev, dev) == 0) {
|
|
|
|
return &netstats[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* wasn't found? add it */
|
2009-11-07 22:46:46 +00:00
|
|
|
for (i = 0; i < MAX_NET_INTERFACES; i++) {
|
2009-10-17 14:43:12 +00:00
|
|
|
if (netstats[i].dev == 0) {
|
2010-08-29 21:50:32 +00:00
|
|
|
netstats[i].dev = strndup(dev, text_buffer_size.get(*state));
|
2015-12-10 20:13:29 +00:00
|
|
|
/* initialize last_read_recv and last_read_trans to -1 denoting
|
|
|
|
* that they were never read before */
|
|
|
|
netstats[i].last_read_recv = -1;
|
|
|
|
netstats[i].last_read_trans = -1;
|
2009-10-17 14:43:12 +00:00
|
|
|
return &netstats[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-26 11:27:21 +00:00
|
|
|
clear_net_stats(&foo_netstats);
|
|
|
|
foo_netstats.dev = strndup(dev, text_buffer_size.get(*state));
|
|
|
|
/* initialize last_read_recv and last_read_trans to -1 denoting
|
|
|
|
* that they were never read before */
|
|
|
|
foo_netstats.last_read_recv = -1;
|
|
|
|
foo_netstats.last_read_trans = -1;
|
|
|
|
return &foo_netstats;
|
2009-10-17 14:43:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void parse_net_stat_arg(struct text_object *obj, const char *arg, void *free_at_crash)
|
|
|
|
{
|
2011-02-10 22:27:14 +00:00
|
|
|
bool shownetmask = false;
|
2011-02-11 12:05:00 +00:00
|
|
|
bool showscope = false;
|
2011-02-11 14:43:01 +00:00
|
|
|
char nextarg[21]; //longest arg possible is a devname (max 20 chars)
|
2011-02-10 22:27:14 +00:00
|
|
|
int i=0;
|
2011-02-11 14:43:01 +00:00
|
|
|
struct net_stat *netstat = NULL;
|
2011-02-10 22:27:14 +00:00
|
|
|
|
2009-10-17 14:43:12 +00:00
|
|
|
if (!arg)
|
|
|
|
arg = DEFAULTNETDEV;
|
|
|
|
|
2011-02-11 14:43:01 +00:00
|
|
|
while(sscanf(arg+i, " %20s", nextarg) == 1) {
|
|
|
|
if(strcmp(nextarg, "-n") == 0 || strcmp(nextarg, "--netmask") == 0) shownetmask = true;
|
|
|
|
else if(strcmp(nextarg, "-s") == 0 || strcmp(nextarg, "--scope") == 0) showscope = true;
|
|
|
|
else if(nextarg[0]=='-') { //multiple flags in 1 arg
|
|
|
|
for(int j=1; nextarg[j] != 0; j++) {
|
|
|
|
if(nextarg[j]=='n') shownetmask = true;
|
|
|
|
if(nextarg[j]=='s') showscope = true;
|
|
|
|
}
|
2011-02-10 22:27:14 +00:00
|
|
|
}
|
2011-02-11 14:43:01 +00:00
|
|
|
else netstat = get_net_stat(nextarg, obj, free_at_crash);
|
|
|
|
i+=strlen(nextarg); //skip this arg
|
|
|
|
while( ! (isspace(arg[i]) || arg[i] == 0)) i++; //and skip the spaces in front of it
|
2011-02-10 22:27:14 +00:00
|
|
|
}
|
2011-02-11 14:43:01 +00:00
|
|
|
if(netstat == NULL) netstat = get_net_stat(DEFAULTNETDEV, obj, free_at_crash);
|
2011-02-10 22:27:14 +00:00
|
|
|
|
2011-02-10 23:27:12 +00:00
|
|
|
#ifdef BUILD_IPV6
|
2011-02-10 22:27:14 +00:00
|
|
|
netstat->v6show_nm = shownetmask;
|
2011-02-11 12:05:00 +00:00
|
|
|
netstat->v6show_sc = showscope;
|
2011-02-10 23:27:12 +00:00
|
|
|
#endif /* BUILD_IPV6 */
|
2011-02-10 22:27:14 +00:00
|
|
|
obj->data.opaque = netstat;
|
2009-10-17 14:43:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void parse_net_stat_bar_arg(struct text_object *obj, const char *arg, void *free_at_crash)
|
|
|
|
{
|
|
|
|
if (arg) {
|
2009-12-04 00:13:36 +00:00
|
|
|
arg = scan_bar(obj, arg, 1);
|
2009-10-09 01:16:17 +00:00
|
|
|
obj->data.opaque = get_net_stat(arg, obj, free_at_crash);
|
2009-10-17 14:43:12 +00:00
|
|
|
} else {
|
|
|
|
// default to DEFAULTNETDEV
|
2010-08-29 21:50:32 +00:00
|
|
|
char *buf = strndup(DEFAULTNETDEV, text_buffer_size.get(*state));
|
2009-10-09 01:16:17 +00:00
|
|
|
obj->data.opaque = get_net_stat(buf, obj, free_at_crash);
|
2009-10-17 14:43:12 +00:00
|
|
|
free(buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void print_downspeed(struct text_object *obj, char *p, int p_max_size)
|
|
|
|
{
|
2010-01-04 17:06:14 +00:00
|
|
|
struct net_stat *ns = (struct net_stat *)obj->data.opaque;
|
2009-10-09 01:16:17 +00:00
|
|
|
|
|
|
|
if (!ns)
|
2009-10-17 14:43:12 +00:00
|
|
|
return;
|
|
|
|
|
2009-10-09 01:16:17 +00:00
|
|
|
human_readable(ns->recv_speed, p, p_max_size);
|
2009-10-17 14:43:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void print_downspeedf(struct text_object *obj, char *p, int p_max_size)
|
|
|
|
{
|
2010-01-04 17:06:14 +00:00
|
|
|
struct net_stat *ns = (struct net_stat *)obj->data.opaque;
|
2009-10-09 01:16:17 +00:00
|
|
|
|
|
|
|
if (!ns)
|
2009-10-17 14:43:12 +00:00
|
|
|
return;
|
|
|
|
|
2009-10-09 01:16:17 +00:00
|
|
|
spaced_print(p, p_max_size, "%.1f", 8, ns->recv_speed / 1024.0);
|
2009-10-17 14:43:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void print_upspeed(struct text_object *obj, char *p, int p_max_size)
|
|
|
|
{
|
2010-01-04 17:06:14 +00:00
|
|
|
struct net_stat *ns = (struct net_stat *)obj->data.opaque;
|
2009-10-09 01:16:17 +00:00
|
|
|
|
|
|
|
if (!ns)
|
2009-10-17 14:43:12 +00:00
|
|
|
return;
|
|
|
|
|
2009-10-09 01:16:17 +00:00
|
|
|
human_readable(ns->trans_speed, p, p_max_size);
|
2009-10-17 14:43:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void print_upspeedf(struct text_object *obj, char *p, int p_max_size)
|
|
|
|
{
|
2010-01-04 17:06:14 +00:00
|
|
|
struct net_stat *ns = (struct net_stat *)obj->data.opaque;
|
2009-10-09 01:16:17 +00:00
|
|
|
|
|
|
|
if (!ns)
|
2009-10-17 14:43:12 +00:00
|
|
|
return;
|
|
|
|
|
2009-10-09 01:16:17 +00:00
|
|
|
spaced_print(p, p_max_size, "%.1f", 8, ns->trans_speed / 1024.0);
|
2009-10-17 14:43:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void print_totaldown(struct text_object *obj, char *p, int p_max_size)
|
|
|
|
{
|
2010-01-04 17:06:14 +00:00
|
|
|
struct net_stat *ns = (struct net_stat *)obj->data.opaque;
|
2009-10-09 01:16:17 +00:00
|
|
|
|
|
|
|
if (!ns)
|
2009-10-17 14:43:12 +00:00
|
|
|
return;
|
|
|
|
|
2009-10-09 01:16:17 +00:00
|
|
|
human_readable(ns->recv, p, p_max_size);
|
2009-10-17 14:43:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void print_totalup(struct text_object *obj, char *p, int p_max_size)
|
|
|
|
{
|
2010-01-04 17:06:14 +00:00
|
|
|
struct net_stat *ns = (struct net_stat *)obj->data.opaque;
|
2009-10-09 01:16:17 +00:00
|
|
|
|
|
|
|
if (!ns)
|
2009-10-17 14:43:12 +00:00
|
|
|
return;
|
|
|
|
|
2009-10-09 01:16:17 +00:00
|
|
|
human_readable(ns->trans, p, p_max_size);
|
2009-10-17 14:43:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void print_addr(struct text_object *obj, char *p, int p_max_size)
|
|
|
|
{
|
2010-01-04 17:06:14 +00:00
|
|
|
struct net_stat *ns = (struct net_stat *)obj->data.opaque;
|
2009-10-09 01:16:17 +00:00
|
|
|
|
|
|
|
if (!ns)
|
2009-10-17 14:43:12 +00:00
|
|
|
return;
|
|
|
|
|
2009-10-09 01:16:17 +00:00
|
|
|
if ((ns->addr.sa_data[2] & 255) == 0 &&
|
|
|
|
(ns->addr.sa_data[3] & 255) == 0 &&
|
|
|
|
(ns->addr.sa_data[4] & 255) == 0 &&
|
|
|
|
(ns->addr.sa_data[5] & 255) == 0) {
|
2009-10-17 14:43:12 +00:00
|
|
|
snprintf(p, p_max_size, "No Address");
|
|
|
|
} else {
|
|
|
|
snprintf(p, p_max_size, "%u.%u.%u.%u",
|
2009-10-09 01:16:17 +00:00
|
|
|
ns->addr.sa_data[2] & 255,
|
|
|
|
ns->addr.sa_data[3] & 255,
|
|
|
|
ns->addr.sa_data[4] & 255,
|
|
|
|
ns->addr.sa_data[5] & 255);
|
2009-10-17 14:43:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef __linux__
|
|
|
|
void print_addrs(struct text_object *obj, char *p, int p_max_size)
|
|
|
|
{
|
2010-01-04 17:06:14 +00:00
|
|
|
struct net_stat *ns = (struct net_stat *)obj->data.opaque;
|
2009-10-09 01:16:17 +00:00
|
|
|
|
|
|
|
if (!ns)
|
2009-10-17 14:43:12 +00:00
|
|
|
return;
|
|
|
|
|
2009-10-09 01:16:17 +00:00
|
|
|
if (NULL != ns->addrs && strlen(ns->addrs) > 2) {
|
|
|
|
ns->addrs[strlen(ns->addrs) - 2] = 0; /* remove ", " from end of string */
|
|
|
|
strncpy(p, ns->addrs, p_max_size);
|
2009-10-17 14:43:12 +00:00
|
|
|
} else {
|
|
|
|
strncpy(p, "0.0.0.0", p_max_size);
|
|
|
|
}
|
|
|
|
}
|
2011-02-09 17:49:52 +00:00
|
|
|
|
|
|
|
#ifdef BUILD_IPV6
|
|
|
|
void print_v6addrs(struct text_object *obj, char *p, int p_max_size)
|
|
|
|
{
|
|
|
|
struct net_stat *ns = (struct net_stat *)obj->data.opaque;
|
2011-02-12 16:18:33 +00:00
|
|
|
char tempaddress[INET6_ADDRSTRLEN];
|
2011-02-09 17:49:52 +00:00
|
|
|
struct v6addr *current_v6 = ns->v6addrs;
|
|
|
|
|
|
|
|
if (!ns)
|
|
|
|
return;
|
|
|
|
|
2011-02-12 23:10:20 +00:00
|
|
|
if(p_max_size == 0) return;
|
2011-02-09 17:49:52 +00:00
|
|
|
if( ! ns->v6addrs) {
|
2012-01-09 10:20:53 +00:00
|
|
|
snprintf(p, p_max_size, "No Address");
|
2011-02-09 17:49:52 +00:00
|
|
|
return;
|
|
|
|
}
|
2011-02-12 23:10:20 +00:00
|
|
|
*p=0;
|
2011-02-09 17:49:52 +00:00
|
|
|
while(current_v6) {
|
2011-02-12 16:18:33 +00:00
|
|
|
inet_ntop(AF_INET6, &(current_v6->addr), tempaddress, INET6_ADDRSTRLEN);
|
2011-02-12 23:10:20 +00:00
|
|
|
strncat(p, tempaddress, p_max_size);
|
2011-02-10 22:27:14 +00:00
|
|
|
//netmask
|
|
|
|
if(ns->v6show_nm) {
|
|
|
|
char netmaskstr[5]; //max 5 chars (/128 + null-terminator)
|
|
|
|
sprintf(netmaskstr, "/%u", current_v6->netmask);
|
2011-02-12 23:10:20 +00:00
|
|
|
strncat(p, netmaskstr, p_max_size);
|
2011-02-10 22:27:14 +00:00
|
|
|
}
|
2011-02-11 12:05:00 +00:00
|
|
|
//scope
|
|
|
|
if(ns->v6show_sc) {
|
2011-02-12 23:10:20 +00:00
|
|
|
char scopestr[3];
|
|
|
|
sprintf(scopestr, "(%c)", current_v6->scope);
|
|
|
|
strncat(p, scopestr, p_max_size);
|
2011-02-11 12:05:00 +00:00
|
|
|
}
|
2011-02-10 22:27:14 +00:00
|
|
|
//next (or last) address
|
2011-02-09 17:49:52 +00:00
|
|
|
current_v6 = current_v6->next;
|
2011-02-12 23:10:20 +00:00
|
|
|
if(current_v6) strncat(p, ", ", p_max_size);
|
2011-02-09 17:49:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* BUILD_IPV6 */
|
|
|
|
|
2009-10-17 14:43:12 +00:00
|
|
|
#endif /* __linux__ */
|
|
|
|
|
2010-01-07 02:38:12 +00:00
|
|
|
#ifdef BUILD_X11
|
2015-12-11 00:39:59 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* This function is called periodically to update the download and upload graphs
|
|
|
|
*
|
|
|
|
* - evaluates argument strings like 'eth0 50,120 #FFFFFF #FF0000 0 -l'
|
|
|
|
* - sets the obj->data.opaque pointer to the interface specified
|
|
|
|
*
|
|
|
|
* @param[out] obj struct which will hold evaluated arguments
|
|
|
|
* @param[in] arg argument string to evaluate
|
|
|
|
**/
|
2009-10-17 14:43:12 +00:00
|
|
|
void parse_net_stat_graph_arg(struct text_object *obj, const char *arg, void *free_at_crash)
|
|
|
|
{
|
2015-12-11 00:39:59 +00:00
|
|
|
/* scan arguments and get interface name back */
|
2009-10-17 14:43:12 +00:00
|
|
|
char *buf = 0;
|
2009-11-05 23:05:08 +00:00
|
|
|
buf = scan_graph(obj, arg, 0);
|
2009-10-17 14:43:12 +00:00
|
|
|
|
|
|
|
// default to DEFAULTNETDEV
|
|
|
|
if (buf) {
|
2009-10-09 01:16:17 +00:00
|
|
|
obj->data.opaque = get_net_stat(buf, obj, free_at_crash);
|
2009-10-17 14:43:12 +00:00
|
|
|
free(buf);
|
|
|
|
return;
|
|
|
|
}
|
2009-10-09 01:16:17 +00:00
|
|
|
obj->data.opaque = get_net_stat(DEFAULTNETDEV, obj, free_at_crash);
|
2009-10-17 14:43:12 +00:00
|
|
|
}
|
|
|
|
|
2015-12-11 00:39:59 +00:00
|
|
|
/**
|
|
|
|
* returns the download speed in kiB/s for the interface referenced by obj
|
|
|
|
*
|
|
|
|
* @param[in] obj struct containting a member data, which is a struct
|
|
|
|
* containing a void * to a net_stat struct
|
|
|
|
**/
|
2009-12-04 00:53:53 +00:00
|
|
|
double downspeedgraphval(struct text_object *obj)
|
2009-10-17 14:43:12 +00:00
|
|
|
{
|
2010-01-04 17:06:14 +00:00
|
|
|
struct net_stat *ns = (struct net_stat *)obj->data.opaque;
|
2009-10-09 01:16:17 +00:00
|
|
|
|
2009-12-04 00:53:53 +00:00
|
|
|
return (ns ? (ns->recv_speed / 1024.0) : 0);
|
2009-10-17 14:43:12 +00:00
|
|
|
}
|
|
|
|
|
2009-12-04 00:53:53 +00:00
|
|
|
double upspeedgraphval(struct text_object *obj)
|
2009-10-17 14:43:12 +00:00
|
|
|
{
|
2010-01-04 17:06:14 +00:00
|
|
|
struct net_stat *ns = (struct net_stat *)obj->data.opaque;
|
2009-10-09 01:16:17 +00:00
|
|
|
|
2009-12-04 00:53:53 +00:00
|
|
|
return (ns ? (ns->trans_speed / 1024.0) : 0);
|
2009-10-17 14:43:12 +00:00
|
|
|
}
|
2010-01-07 02:38:12 +00:00
|
|
|
#endif /* BUILD_X11 */
|
2009-10-17 14:43:12 +00:00
|
|
|
|
2010-01-11 00:13:42 +00:00
|
|
|
#ifdef BUILD_WLAN
|
2009-10-17 14:43:12 +00:00
|
|
|
void print_wireless_essid(struct text_object *obj, char *p, int p_max_size)
|
|
|
|
{
|
2010-01-04 17:06:14 +00:00
|
|
|
struct net_stat *ns = (struct net_stat *)obj->data.opaque;
|
2009-10-09 01:16:17 +00:00
|
|
|
|
2010-02-21 14:12:38 +00:00
|
|
|
if (!ns) {
|
|
|
|
for(unsigned int i = 0; *(netstats[i].dev) != 0; i++) {
|
|
|
|
if(*(netstats[i].essid) != 0) {
|
|
|
|
snprintf(p, p_max_size, "%s", netstats[i].essid);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2009-10-17 14:43:12 +00:00
|
|
|
return;
|
2010-02-21 14:12:38 +00:00
|
|
|
}
|
2009-10-17 14:43:12 +00:00
|
|
|
|
2009-10-09 01:16:17 +00:00
|
|
|
snprintf(p, p_max_size, "%s", ns->essid);
|
2009-10-17 14:43:12 +00:00
|
|
|
}
|
|
|
|
void print_wireless_mode(struct text_object *obj, char *p, int p_max_size)
|
|
|
|
{
|
2010-01-04 17:06:14 +00:00
|
|
|
struct net_stat *ns = (struct net_stat *)obj->data.opaque;
|
2009-10-09 01:16:17 +00:00
|
|
|
|
|
|
|
if (!ns)
|
2009-10-17 14:43:12 +00:00
|
|
|
return;
|
|
|
|
|
2009-10-09 01:16:17 +00:00
|
|
|
snprintf(p, p_max_size, "%s", ns->mode);
|
2009-10-17 14:43:12 +00:00
|
|
|
}
|
2010-06-07 07:54:25 +00:00
|
|
|
void print_wireless_channel(struct text_object *obj, char *p, int p_max_size)
|
|
|
|
{
|
|
|
|
struct net_stat *ns = (struct net_stat *)obj->data.opaque;
|
|
|
|
|
|
|
|
if (!ns)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if(ns->channel != 0) {
|
|
|
|
snprintf(p, p_max_size, "%i", ns->channel);
|
|
|
|
} else {
|
|
|
|
snprintf(p, p_max_size, "/");
|
|
|
|
}
|
|
|
|
}
|
2010-06-07 08:50:02 +00:00
|
|
|
void print_wireless_frequency(struct text_object *obj, char *p, int p_max_size)
|
|
|
|
{
|
|
|
|
struct net_stat *ns = (struct net_stat *)obj->data.opaque;
|
|
|
|
|
|
|
|
if (!ns)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if(ns->freq[0] != 0) {
|
|
|
|
snprintf(p, p_max_size, "%s", ns->freq);
|
|
|
|
} else {
|
|
|
|
snprintf(p, p_max_size, "/");
|
|
|
|
}
|
|
|
|
}
|
2009-10-17 14:43:12 +00:00
|
|
|
void print_wireless_bitrate(struct text_object *obj, char *p, int p_max_size)
|
|
|
|
{
|
2010-01-04 17:06:14 +00:00
|
|
|
struct net_stat *ns = (struct net_stat *)obj->data.opaque;
|
2009-10-09 01:16:17 +00:00
|
|
|
|
|
|
|
if (!ns)
|
2009-10-17 14:43:12 +00:00
|
|
|
return;
|
|
|
|
|
2009-10-09 01:16:17 +00:00
|
|
|
snprintf(p, p_max_size, "%s", ns->bitrate);
|
2009-10-17 14:43:12 +00:00
|
|
|
}
|
|
|
|
void print_wireless_ap(struct text_object *obj, char *p, int p_max_size)
|
|
|
|
{
|
2010-01-04 17:06:14 +00:00
|
|
|
struct net_stat *ns = (struct net_stat *)obj->data.opaque;
|
2009-10-09 01:16:17 +00:00
|
|
|
|
|
|
|
if (!ns)
|
2009-10-17 14:43:12 +00:00
|
|
|
return;
|
|
|
|
|
2009-10-09 01:16:17 +00:00
|
|
|
snprintf(p, p_max_size, "%s", ns->ap);
|
2009-10-17 14:43:12 +00:00
|
|
|
}
|
|
|
|
void print_wireless_link_qual(struct text_object *obj, char *p, int p_max_size)
|
|
|
|
{
|
2010-01-04 17:06:14 +00:00
|
|
|
struct net_stat *ns = (struct net_stat *)obj->data.opaque;
|
2009-10-09 01:16:17 +00:00
|
|
|
|
|
|
|
if (!ns)
|
2009-10-17 14:43:12 +00:00
|
|
|
return;
|
|
|
|
|
2009-10-09 01:16:17 +00:00
|
|
|
spaced_print(p, p_max_size, "%d", 4, ns->link_qual);
|
2009-10-17 14:43:12 +00:00
|
|
|
}
|
|
|
|
void print_wireless_link_qual_max(struct text_object *obj, char *p, int p_max_size)
|
|
|
|
{
|
2010-01-04 17:06:14 +00:00
|
|
|
struct net_stat *ns = (struct net_stat *)obj->data.opaque;
|
2009-10-09 01:16:17 +00:00
|
|
|
|
|
|
|
if (!ns)
|
2009-10-17 14:43:12 +00:00
|
|
|
return;
|
|
|
|
|
2009-10-09 01:16:17 +00:00
|
|
|
spaced_print(p, p_max_size, "%d", 4, ns->link_qual_max);
|
2009-10-17 14:43:12 +00:00
|
|
|
}
|
|
|
|
void print_wireless_link_qual_perc(struct text_object *obj, char *p, int p_max_size)
|
|
|
|
{
|
2010-01-04 17:06:14 +00:00
|
|
|
struct net_stat *ns = (struct net_stat *)obj->data.opaque;
|
2009-10-09 01:16:17 +00:00
|
|
|
|
|
|
|
if (!ns)
|
2009-10-17 14:43:12 +00:00
|
|
|
return;
|
|
|
|
|
2009-10-09 01:16:17 +00:00
|
|
|
if (ns->link_qual_max > 0) {
|
2009-10-17 14:43:12 +00:00
|
|
|
spaced_print(p, p_max_size, "%.0f", 5,
|
2009-10-09 01:16:17 +00:00
|
|
|
(double) ns->link_qual /
|
|
|
|
ns->link_qual_max * 100);
|
2009-10-17 14:43:12 +00:00
|
|
|
} else {
|
|
|
|
spaced_print(p, p_max_size, "unk", 5);
|
|
|
|
}
|
|
|
|
}
|
2009-12-04 00:13:36 +00:00
|
|
|
double wireless_link_barval(struct text_object *obj)
|
2009-10-17 14:43:12 +00:00
|
|
|
{
|
2010-01-04 17:06:14 +00:00
|
|
|
struct net_stat *ns = (struct net_stat *)obj->data.opaque;
|
2009-10-09 01:16:17 +00:00
|
|
|
|
|
|
|
if (!ns)
|
2009-11-22 17:15:36 +00:00
|
|
|
return 0;
|
2009-10-17 14:43:12 +00:00
|
|
|
|
2009-12-04 00:13:36 +00:00
|
|
|
return (double)ns->link_qual / ns->link_qual_max;
|
2009-10-17 14:43:12 +00:00
|
|
|
}
|
2010-01-11 00:13:42 +00:00
|
|
|
#endif /* BUILD_WLAN */
|
2009-10-17 14:43:12 +00:00
|
|
|
|
2015-12-10 20:13:29 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Clears the global array of net_stat structs which contains networks
|
|
|
|
* statistics for every interface.
|
|
|
|
**/
|
2009-10-17 14:43:12 +00:00
|
|
|
void clear_net_stats(void)
|
|
|
|
{
|
2011-02-09 17:49:52 +00:00
|
|
|
#ifdef BUILD_IPV6
|
|
|
|
struct v6addr *nextv6;
|
|
|
|
#endif /* BUILD_IPV6 */
|
2009-10-17 14:43:12 +00:00
|
|
|
int i;
|
2009-11-07 22:46:46 +00:00
|
|
|
for (i = 0; i < MAX_NET_INTERFACES; i++) {
|
2010-02-24 01:14:20 +00:00
|
|
|
free_and_zero(netstats[i].dev);
|
2011-02-09 17:49:52 +00:00
|
|
|
#ifdef BUILD_IPV6
|
|
|
|
while(netstats[i].v6addrs) {
|
|
|
|
nextv6 = netstats[i].v6addrs;
|
|
|
|
netstats[i].v6addrs = netstats[i].v6addrs->next;
|
|
|
|
free_and_zero(nextv6);
|
|
|
|
}
|
|
|
|
#endif /* BUILD_IPV6 */
|
2009-10-17 14:43:12 +00:00
|
|
|
}
|
|
|
|
memset(netstats, 0, sizeof(netstats));
|
|
|
|
}
|
|
|
|
|
2018-04-26 11:27:21 +00:00
|
|
|
void clear_net_stats(net_stat *in) {
|
|
|
|
#ifdef BUILD_IPV6
|
|
|
|
struct v6addr *nextv6;
|
|
|
|
#endif /* BUILD_IPV6 */
|
|
|
|
free_and_zero(in->dev);
|
|
|
|
#ifdef BUILD_IPV6
|
|
|
|
while (in->v6addrs) {
|
|
|
|
nextv6 = in->v6addrs;
|
|
|
|
in->v6addrs = in->v6addrs->next;
|
|
|
|
free_and_zero(nextv6);
|
|
|
|
}
|
|
|
|
#endif /* BUILD_IPV6 */
|
|
|
|
}
|
|
|
|
|
2009-10-09 02:30:02 +00:00
|
|
|
void parse_if_up_arg(struct text_object *obj, const char *arg)
|
|
|
|
{
|
2010-08-29 21:50:32 +00:00
|
|
|
obj->data.opaque = strndup(arg, text_buffer_size.get(*state));
|
2009-10-09 02:30:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void free_if_up(struct text_object *obj)
|
|
|
|
{
|
2010-02-24 01:14:20 +00:00
|
|
|
free_and_zero(obj->data.opaque);
|
2009-10-09 02:30:02 +00:00
|
|
|
}
|
|
|
|
|
2009-10-17 14:43:12 +00:00
|
|
|
/* We should check if this is ok with OpenBSD and NetBSD as well. */
|
2009-10-09 02:30:02 +00:00
|
|
|
int interface_up(struct text_object *obj)
|
2009-10-17 14:43:12 +00:00
|
|
|
{
|
|
|
|
int fd;
|
|
|
|
struct ifreq ifr;
|
2010-01-04 17:06:14 +00:00
|
|
|
char *dev = (char*)obj->data.opaque;
|
2009-10-09 02:30:02 +00:00
|
|
|
|
|
|
|
if (!dev)
|
|
|
|
return 0;
|
2009-10-17 14:43:12 +00:00
|
|
|
|
|
|
|
if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
|
|
|
|
CRIT_ERR(NULL, NULL, "could not create sockfd");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
strncpy(ifr.ifr_name, dev, IFNAMSIZ);
|
|
|
|
if (ioctl(fd, SIOCGIFFLAGS, &ifr)) {
|
|
|
|
/* if device does not exist, treat like not up */
|
|
|
|
if (errno != ENODEV && errno != ENXIO)
|
|
|
|
perror("SIOCGIFFLAGS");
|
|
|
|
goto END_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(ifr.ifr_flags & IFF_UP)) /* iface is not up */
|
|
|
|
goto END_FALSE;
|
2010-08-25 17:40:24 +00:00
|
|
|
if (if_up_strictness.get(*state) == IFUP_UP)
|
2009-10-17 14:43:12 +00:00
|
|
|
goto END_TRUE;
|
|
|
|
|
2018-01-19 16:36:40 +00:00
|
|
|
#ifdef IFF_RUNNING
|
2009-10-17 14:43:12 +00:00
|
|
|
if (!(ifr.ifr_flags & IFF_RUNNING))
|
|
|
|
goto END_FALSE;
|
2018-01-19 16:36:40 +00:00
|
|
|
#endif
|
2010-08-25 17:40:24 +00:00
|
|
|
if (if_up_strictness.get(*state) == IFUP_LINK)
|
2009-10-17 14:43:12 +00:00
|
|
|
goto END_TRUE;
|
|
|
|
|
|
|
|
if (ioctl(fd, SIOCGIFADDR, &ifr)) {
|
|
|
|
perror("SIOCGIFADDR");
|
|
|
|
goto END_FALSE;
|
|
|
|
}
|
2018-01-19 16:36:40 +00:00
|
|
|
if (((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr.s_addr)
|
2009-10-17 14:43:12 +00:00
|
|
|
goto END_TRUE;
|
|
|
|
|
|
|
|
END_FALSE:
|
|
|
|
close(fd);
|
|
|
|
return 0;
|
|
|
|
END_TRUE:
|
|
|
|
close(fd);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2010-01-04 17:06:14 +00:00
|
|
|
struct _dns_data {
|
|
|
|
_dns_data() : nscount(0), ns_list(0) {}
|
|
|
|
int nscount;
|
|
|
|
char **ns_list;
|
2009-10-17 14:43:12 +00:00
|
|
|
};
|
|
|
|
|
2010-01-04 17:06:14 +00:00
|
|
|
static _dns_data dns_data;
|
|
|
|
|
2009-11-29 19:55:42 +00:00
|
|
|
void free_dns_data(struct text_object *obj)
|
2009-10-17 14:43:12 +00:00
|
|
|
{
|
|
|
|
int i;
|
2009-11-29 19:55:42 +00:00
|
|
|
|
|
|
|
(void)obj;
|
|
|
|
|
2009-10-17 14:43:12 +00:00
|
|
|
for (i = 0; i < dns_data.nscount; i++)
|
|
|
|
free(dns_data.ns_list[i]);
|
2012-12-26 22:22:34 +00:00
|
|
|
free(dns_data.ns_list);
|
2009-10-17 14:43:12 +00:00
|
|
|
memset(&dns_data, 0, sizeof(dns_data));
|
|
|
|
}
|
|
|
|
|
2010-05-05 16:46:04 +00:00
|
|
|
int update_dns_data(void)
|
2009-10-17 14:43:12 +00:00
|
|
|
{
|
|
|
|
FILE *fp;
|
|
|
|
char line[256];
|
|
|
|
//static double last_dns_update = 0.0;
|
|
|
|
|
|
|
|
/* maybe updating too often causes higher load because of /etc lying on a real FS
|
|
|
|
if (current_update_time - last_dns_update < 10.0)
|
2010-05-05 16:46:04 +00:00
|
|
|
return 0;
|
2009-10-17 14:43:12 +00:00
|
|
|
|
|
|
|
last_dns_update = current_update_time;
|
|
|
|
*/
|
|
|
|
|
2009-11-29 19:55:42 +00:00
|
|
|
free_dns_data(NULL);
|
2009-10-17 14:43:12 +00:00
|
|
|
|
|
|
|
if ((fp = fopen("/etc/resolv.conf", "r")) == NULL)
|
2010-05-05 16:46:04 +00:00
|
|
|
return 0;
|
2009-10-17 14:43:12 +00:00
|
|
|
while(!feof(fp)) {
|
|
|
|
if (fgets(line, 255, fp) == NULL) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!strncmp(line, "nameserver ", 11)) {
|
|
|
|
line[strlen(line) - 1] = '\0'; // remove trailing newline
|
|
|
|
dns_data.nscount++;
|
2010-01-04 17:06:14 +00:00
|
|
|
dns_data.ns_list = (char**)realloc(dns_data.ns_list, dns_data.nscount * sizeof(char *));
|
2010-08-29 21:50:32 +00:00
|
|
|
dns_data.ns_list[dns_data.nscount - 1] = strndup(line + 11, text_buffer_size.get(*state));
|
2009-10-17 14:43:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
fclose(fp);
|
2010-05-05 16:46:04 +00:00
|
|
|
return 0;
|
2009-10-17 14:43:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void parse_nameserver_arg(struct text_object *obj, const char *arg)
|
|
|
|
{
|
|
|
|
obj->data.l = arg ? atoi(arg) : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void print_nameserver(struct text_object *obj, char *p, int p_max_size)
|
|
|
|
{
|
|
|
|
if (dns_data.nscount > obj->data.l)
|
|
|
|
snprintf(p, p_max_size, "%s", dns_data.ns_list[obj->data.l]);
|
|
|
|
}
|