|
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(); |
| }; |
}; |