version 1.1.1.1, 2012/02/21 16:57:34
|
version 1.1.1.2, 2016/10/18 14:04:50
|
Line 30
|
Line 30
|
|
|
options_t options; |
options_t options; |
|
|
char optstr[] = "+i:f:nNF:hpbBPm:c:"; | char optstr[] = "+i:f:nNF:G:lhpbBPm:c:s:tL:o:"; |
|
|
/* Global options. */ |
/* Global options. */ |
|
|
Line 46 static char *bad_interface_names[] = {
|
Line 46 static char *bad_interface_names[] = {
|
"gif", /* psuedo-device generic tunnel interface */ |
"gif", /* psuedo-device generic tunnel interface */ |
"dummy", |
"dummy", |
"vmnet", |
"vmnet", |
NULL /* last entry must be NULL */ | "wmaster", /* wmaster0 is an internal-use interface for mac80211, a Linux WiFi API. */ |
| NULL /* last entry must be NULL */ |
}; |
}; |
|
|
config_enumeration_type sort_enumeration[] = { |
config_enumeration_type sort_enumeration[] = { |
Line 54 config_enumeration_type sort_enumeration[] = {
|
Line 55 config_enumeration_type sort_enumeration[] = {
|
{ "10s", OPTION_SORT_DIV2 }, |
{ "10s", OPTION_SORT_DIV2 }, |
{ "40s", OPTION_SORT_DIV3 }, |
{ "40s", OPTION_SORT_DIV3 }, |
{ "source", OPTION_SORT_SRC }, |
{ "source", OPTION_SORT_SRC }, |
{ "destination", OPTION_SORT_SRC }, | { "destination", OPTION_SORT_DEST }, |
{ NULL, -1 } |
{ NULL, -1 } |
}; |
}; |
|
|
Line 86 static int is_bad_interface_name(char *i) {
|
Line 87 static int is_bad_interface_name(char *i) {
|
* interface or one of the interface types listed in bad_interface_names. */ |
* interface or one of the interface types listed in bad_interface_names. */ |
static char *get_first_interface(void) { |
static char *get_first_interface(void) { |
struct if_nameindex * nameindex; |
struct if_nameindex * nameindex; |
|
struct ifreq ifr; |
char *i = NULL; |
char *i = NULL; |
int j = 0; |
int j = 0; |
|
int s; |
/* Use if_nameindex(3) instead? */ |
/* Use if_nameindex(3) instead? */ |
|
|
nameindex = if_nameindex(); |
nameindex = if_nameindex(); |
Line 95 static char *get_first_interface(void) {
|
Line 98 static char *get_first_interface(void) {
|
return NULL; |
return NULL; |
} |
} |
|
|
|
s = socket(AF_INET, SOCK_DGRAM, 0); /* any sort of IP socket will do */ |
|
|
while(nameindex[j].if_index != 0) { |
while(nameindex[j].if_index != 0) { |
if (strcmp(nameindex[j].if_name, "lo") != 0 && !is_bad_interface_name(nameindex[j].if_name)) { |
if (strcmp(nameindex[j].if_name, "lo") != 0 && !is_bad_interface_name(nameindex[j].if_name)) { |
i = xstrdup(nameindex[j].if_name); | strncpy(ifr.ifr_name, nameindex[j].if_name, sizeof(ifr.ifr_name)); |
break; | if ((s == -1) || (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) || (ifr.ifr_flags & IFF_UP)) { |
| i = xstrdup(nameindex[j].if_name); |
| break; |
| } |
} |
} |
j++; |
j++; |
} |
} |
Line 118 void options_set_defaults() {
|
Line 126 void options_set_defaults() {
|
options.netfilter = 0; |
options.netfilter = 0; |
inet_aton("10.0.1.0", &options.netfilternet); |
inet_aton("10.0.1.0", &options.netfilternet); |
inet_aton("255.255.255.0", &options.netfiltermask); |
inet_aton("255.255.255.0", &options.netfiltermask); |
|
options.netfilter6 = 0; |
|
inet_pton(AF_INET6, "fe80::", &options.netfilter6net); /* Link-local */ |
|
inet_pton(AF_INET6, "ffff::", &options.netfilter6mask); |
|
options.link_local = 0; |
options.dnsresolution = 1; |
options.dnsresolution = 1; |
options.portresolution = 1; |
options.portresolution = 1; |
#ifdef NEED_PROMISCUOUS_FOR_OUTGOING |
#ifdef NEED_PROMISCUOUS_FOR_OUTGOING |
Line 143 void options_set_defaults() {
|
Line 155 void options_set_defaults() {
|
options.max_bandwidth = 0; /* auto */ |
options.max_bandwidth = 0; /* auto */ |
options.log_scale = 0; |
options.log_scale = 0; |
options.bar_interval = 1; |
options.bar_interval = 1; |
|
options.timed_output = 0; |
|
options.no_curses = 0; |
|
options.num_lines = 10; |
|
|
/* Figure out the name for the config file */ |
/* Figure out the name for the config file */ |
s = getenv("HOME"); |
s = getenv("HOME"); |
Line 158 void options_set_defaults() {
|
Line 173 void options_set_defaults() {
|
|
|
} |
} |
|
|
static void die(char *msg) { |
|
fprintf(stderr, msg); |
|
exit(1); |
|
} |
|
|
|
static void set_max_bandwidth(char* arg) { |
|
char* units; |
|
long long mult = 1; |
|
long long value; |
|
units = arg + strspn(arg, "0123456789"); |
|
if(strlen(units) > 1) { |
|
die("Invalid units\n"); |
|
} |
|
if(strlen(units) == 1) { |
|
if(*units == 'k' || *units == 'K') { |
|
mult = 1024; |
|
} |
|
else if(*units == 'm' || *units == 'M') { |
|
mult = 1024 * 1024; |
|
} |
|
else if(*units == 'g' || *units == 'G') { |
|
mult = 1024 * 1024 * 1024; |
|
} |
|
} |
|
*units = '\0'; |
|
if(sscanf(arg, "%lld", &value) != 1) { |
|
die("Error reading max bandwidth\n"); |
|
} |
|
options.max_bandwidth = value * mult; |
|
} |
|
|
|
static void set_net_filter(char* arg) { |
|
char* mask; |
|
|
|
mask = strchr(arg, '/'); |
|
if (mask == NULL) { |
|
die("Could not parse net/mask\n"); |
|
} |
|
*mask = '\0'; |
|
mask++; |
|
if (inet_aton(arg, &options.netfilternet) == 0) |
|
die("Invalid network address\n"); |
|
/* Accept a netmask like /24 or /255.255.255.0. */ |
|
if (mask[strspn(mask, "0123456789")] == '\0') { |
|
/* Whole string is numeric */ |
|
int n; |
|
n = atoi(mask); |
|
if (n > 32) { |
|
die("Invalid netmask"); |
|
} |
|
else { |
|
if(n == 32) { |
|
/* This needs to be special cased, although I don't fully |
|
* understand why -pdw |
|
*/ |
|
options.netfiltermask.s_addr = htonl(0xffffffffl); |
|
} |
|
else { |
|
u_int32_t mm = 0xffffffffl; |
|
mm >>= n; |
|
options.netfiltermask.s_addr = htonl(~mm); |
|
} |
|
} |
|
} |
|
else if (inet_aton(mask, &options.netfiltermask) == 0) { |
|
die("Invalid netmask\n"); |
|
} |
|
options.netfilternet.s_addr = options.netfilternet.s_addr & options.netfiltermask.s_addr; |
|
|
|
options.netfilter = 1; |
|
|
|
} |
|
|
|
/* usage: |
/* usage: |
* Print usage information. */ |
* Print usage information. */ |
static void usage(FILE *fp) { |
static void usage(FILE *fp) { |
fprintf(fp, |
fprintf(fp, |
"iftop: display bandwidth usage on an interface by host\n" |
"iftop: display bandwidth usage on an interface by host\n" |
"\n" |
"\n" |
"Synopsis: iftop -h | [-npbBP] [-i interface] [-f filter code] [-N net/mask]\n" | "Synopsis: iftop -h | [-npblNBP] [-i interface] [-f filter code]\n" |
| " [-F net/mask] [-G net6/mask6]\n" |
"\n" |
"\n" |
" -h display this message\n" |
" -h display this message\n" |
" -n don't do hostname lookups\n" |
" -n don't do hostname lookups\n" |
Line 249 static void usage(FILE *fp) {
|
Line 192 static void usage(FILE *fp) {
|
" -i interface listen on named interface\n" |
" -i interface listen on named interface\n" |
" -f filter code use filter code to select packets to count\n" |
" -f filter code use filter code to select packets to count\n" |
" (default: none, but only IP packets are counted)\n" |
" (default: none, but only IP packets are counted)\n" |
" -F net/mask show traffic flows in/out of network\n" | " -F net/mask show traffic flows in/out of IPv4 network\n" |
| " -G net6/mask6 show traffic flows in/out of IPv6 network\n" |
| " -l display and count link-local IPv6 traffic (default: off)\n" |
" -P show ports as well as hosts\n" |
" -P show ports as well as hosts\n" |
" -m limit sets the upper limit for the bandwidth scale\n" |
" -m limit sets the upper limit for the bandwidth scale\n" |
" -c config file specifies an alternative configuration file\n" |
" -c config file specifies an alternative configuration file\n" |
|
" -t use text interface without ncurses\n" |
"\n" |
"\n" |
"iftop, version " IFTOP_VERSION "\n" | " Sorting orders:\n" |
| " -o 2s Sort by first column (2s traffic average)\n" |
| " -o 10s Sort by second column (10s traffic average) [default]\n" |
| " -o 40s Sort by third column (40s traffic average)\n" |
| " -o source Sort by source address\n" |
| " -o destination Sort by destination address\n" |
| "\n" |
| " The following options are only available in combination with -t\n" |
| " -s num print one single text output afer num seconds, then quit\n" |
| " -L num number of lines to print\n" |
| "\n" |
| "iftop, version " PACKAGE_VERSION "\n" |
"copyright (c) 2002 Paul Warren <pdw@ex-parrot.com> and contributors\n" |
"copyright (c) 2002 Paul Warren <pdw@ex-parrot.com> and contributors\n" |
); |
); |
} |
} |
Line 285 void options_read_args(int argc, char **argv) {
|
Line 242 void options_read_args(int argc, char **argv) {
|
config_set_string("filter-code", optarg); |
config_set_string("filter-code", optarg); |
break; |
break; |
|
|
|
case 'l': |
|
config_set_string("link-local", "true"); |
|
break; |
|
|
case 'p': |
case 'p': |
config_set_string("promiscuous", "true"); |
config_set_string("promiscuous", "true"); |
break; |
break; |
Line 297 void options_read_args(int argc, char **argv) {
|
Line 258 void options_read_args(int argc, char **argv) {
|
config_set_string("net-filter", optarg); |
config_set_string("net-filter", optarg); |
break; |
break; |
|
|
|
case 'G': |
|
config_set_string("net-filter6", optarg); |
|
break; |
|
|
case 'm': |
case 'm': |
config_set_string("max-bandwidth", optarg); |
config_set_string("max-bandwidth", optarg); |
break; |
break; |
|
|
case 'b': |
case 'b': |
config_set_string("show-bars", "true"); | config_set_string("show-bars", "false"); |
break; |
break; |
|
|
case 'B': |
case 'B': |
config_set_string("use-bytes", "true"); |
config_set_string("use-bytes", "true"); |
break; |
break; |
|
|
|
case 's': |
|
config_set_string("timed-output", optarg); |
|
break; |
|
|
|
case 't': |
|
config_set_string("no-curses", "true"); |
|
break; |
|
|
|
case 'L': |
|
config_set_string("num-lines", optarg); |
|
break; |
|
|
|
case 'o': |
|
config_set_string("sort", optarg); |
|
break; |
|
|
case 'c': |
case 'c': |
xfree(options.config_file); |
xfree(options.config_file); |
options.config_file = xstrdup(optarg); |
options.config_file = xstrdup(optarg); |
Line 327 void options_read_args(int argc, char **argv) {
|
Line 308 void options_read_args(int argc, char **argv) {
|
} |
} |
} |
} |
|
|
|
|
if (optind != argc) { |
if (optind != argc) { |
fprintf(stderr, "iftop: found arguments following options\n"); |
fprintf(stderr, "iftop: found arguments following options\n"); |
fprintf(stderr, "*** some options have changed names since v0.9 ***\n"); |
fprintf(stderr, "*** some options have changed names since v0.9 ***\n"); |
Line 437 int options_config_get_net_filter() {
|
Line 419 int options_config_get_net_filter() {
|
if(s) { |
if(s) { |
char* mask; |
char* mask; |
|
|
|
options.netfilter = 0; |
|
|
mask = strchr(s, '/'); |
mask = strchr(s, '/'); |
if (mask == NULL) { |
if (mask == NULL) { |
fprintf(stderr, "Could not parse net/mask: %s\n", s); |
fprintf(stderr, "Could not parse net/mask: %s\n", s); |
Line 454 int options_config_get_net_filter() {
|
Line 438 int options_config_get_net_filter() {
|
int n; |
int n; |
n = atoi(mask); |
n = atoi(mask); |
if (n > 32) { |
if (n > 32) { |
fprintf(stderr, "Invalid netmask: %s\n", s); | fprintf(stderr, "Invalid netmask length: %s\n", mask); |
} |
} |
else { |
else { |
if(n == 32) { |
if(n == 32) { |
Line 469 int options_config_get_net_filter() {
|
Line 453 int options_config_get_net_filter() {
|
options.netfiltermask.s_addr = htonl(~mm); |
options.netfiltermask.s_addr = htonl(~mm); |
} |
} |
} |
} |
|
options.netfilter = 1; |
} |
} |
else if (inet_aton(mask, &options.netfiltermask) == 0) { | else { |
fprintf(stderr, "Invalid netmask: %s\n", s); | if (inet_aton(mask, &options.netfiltermask) != 0) |
| options.netfilter = 1; |
| else { |
| fprintf(stderr, "Invalid netmask: %s\n", s); |
| return 0; |
| } |
} |
} |
options.netfilternet.s_addr = options.netfilternet.s_addr & options.netfiltermask.s_addr; |
options.netfilternet.s_addr = options.netfilternet.s_addr & options.netfiltermask.s_addr; |
options.netfilter = 1; |
|
return 1; |
return 1; |
} |
} |
return 0; |
return 0; |
} |
} |
|
|
|
/* |
|
* Read the net filter IPv6 option. |
|
*/ |
|
int options_config_get_net_filter6() { |
|
char* s; |
|
int j; |
|
|
|
s = config_get_string("net-filter6"); |
|
if(s) { |
|
char* mask; |
|
|
|
options.netfilter6 = 0; |
|
|
|
mask = strchr(s, '/'); |
|
if (mask == NULL) { |
|
fprintf(stderr, "Could not parse IPv6 net/prefix: %s\n", s); |
|
return 0; |
|
} |
|
*mask = '\0'; |
|
mask++; |
|
if (inet_pton(AF_INET6, s, &options.netfilter6net) == 0) { |
|
fprintf(stderr, "Invalid IPv6 network address: %s\n", s); |
|
return 0; |
|
} |
|
/* Accept prefix lengths and address expressions. */ |
|
if (mask[strspn(mask, "0123456789")] == '\0') { |
|
/* Whole string is numeric */ |
|
unsigned int n; |
|
|
|
n = atoi(mask); |
|
if (n > 128 || n < 1) { |
|
fprintf(stderr, "Invalid IPv6 prefix length: %s\n", mask); |
|
} |
|
else { |
|
int bl, rem; |
|
const uint8_t mm = 0xff; |
|
uint8_t part = mm; |
|
|
|
bl = n / 8; |
|
rem = n % 8; |
|
part <<= 8 - rem; |
|
for (j=0; j < bl; ++j) |
|
options.netfilter6mask.s6_addr[j] = mm; |
|
|
|
if (rem > 0) |
|
options.netfilter6mask.s6_addr[bl] = part; |
|
options.netfilter6 = 1; |
|
} |
|
} |
|
else { |
|
if (inet_pton(AF_INET6, mask, &options.netfilter6mask) != 0) |
|
options.netfilter6 = 1; |
|
else { |
|
fprintf(stderr, "Invalid IPv6 netmask: %s\n", s); |
|
return 0; |
|
} |
|
} |
|
/* Prepare any comparison by masking the provided filtered net. */ |
|
for (j=0; j < 16; ++j) |
|
options.netfilter6net.s6_addr[j] &= options.netfilter6mask.s6_addr[j]; |
|
|
|
return 1; |
|
} |
|
return 0; |
|
} |
|
|
void options_make() { |
void options_make() { |
options_config_get_string("interface", &options.interface); |
options_config_get_string("interface", &options.interface); |
options_config_get_bool("dns-resolution", &options.dnsresolution); |
options_config_get_bool("dns-resolution", &options.dnsresolution); |
Line 498 void options_make() {
|
Line 552 void options_make() {
|
options_config_get_bw_rate("max-bandwidth", &options.max_bandwidth); |
options_config_get_bw_rate("max-bandwidth", &options.max_bandwidth); |
options_config_get_enum("port-display", showports_enumeration, (int*)&options.showports); |
options_config_get_enum("port-display", showports_enumeration, (int*)&options.showports); |
options_config_get_string("screen-filter", &options.screenfilter); |
options_config_get_string("screen-filter", &options.screenfilter); |
|
options_config_get_bool("link-local", &options.link_local); |
|
options_config_get_int("timed-output", &options.timed_output); |
|
options_config_get_bool("no-curses", &options.no_curses); |
|
options_config_get_int("num-lines", &options.num_lines); |
options_config_get_net_filter(); |
options_config_get_net_filter(); |
|
options_config_get_net_filter6(); |
}; |
}; |