X-Git-Url: http://gitweb.fperrin.net/?p=iftop.git;a=blobdiff_plain;f=options.c;h=b438d4c91bd4a9064afdd9509a2ffd6f3fd85324;hp=02e091ad99d9085410d8c66dff865b0fbabd72f1;hb=HEAD;hpb=cd1db5a0a5c698b647e554a003c7e48b5db695f5 diff --git a/options.c b/options.c index 02e091a..b438d4c 100644 --- a/options.c +++ b/options.c @@ -30,7 +30,7 @@ options_t options; -char optstr[] = "+i:f:nNF:G:lhpbBPm:c:"; +char optstr[] = "+i:f:nNF:G:lhpbBPm:c:s:tL:o:"; /* Global options. */ @@ -46,7 +46,8 @@ static char *bad_interface_names[] = { "gif", /* psuedo-device generic tunnel interface */ "dummy", "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[] = { @@ -54,7 +55,7 @@ config_enumeration_type sort_enumeration[] = { { "10s", OPTION_SORT_DIV2 }, { "40s", OPTION_SORT_DIV3 }, { "source", OPTION_SORT_SRC }, - { "destination", OPTION_SORT_SRC }, + { "destination", OPTION_SORT_DEST }, { NULL, -1 } }; @@ -86,8 +87,10 @@ static int is_bad_interface_name(char *i) { * interface or one of the interface types listed in bad_interface_names. */ static char *get_first_interface(void) { struct if_nameindex * nameindex; + struct ifreq ifr; char *i = NULL; int j = 0; + int s; /* Use if_nameindex(3) instead? */ nameindex = if_nameindex(); @@ -95,10 +98,15 @@ static char *get_first_interface(void) { return NULL; } + s = socket(AF_INET, SOCK_DGRAM, 0); /* any sort of IP socket will do */ + while(nameindex[j].if_index != 0) { if (strcmp(nameindex[j].if_name, "lo") != 0 && !is_bad_interface_name(nameindex[j].if_name)) { - i = xstrdup(nameindex[j].if_name); - break; + strncpy(ifr.ifr_name, nameindex[j].if_name, sizeof(ifr.ifr_name)); + if ((s == -1) || (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) || (ifr.ifr_flags & IFF_UP)) { + i = xstrdup(nameindex[j].if_name); + break; + } } j++; } @@ -147,6 +155,9 @@ void options_set_defaults() { options.max_bandwidth = 0; /* auto */ options.log_scale = 0; options.bar_interval = 1; + options.timed_output = 0; + options.no_curses = 0; + options.num_lines = 10; /* Figure out the name for the config file */ s = getenv("HOME"); @@ -162,86 +173,13 @@ 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: * Print usage information. */ static void usage(FILE *fp) { fprintf(fp, "iftop: display bandwidth usage on an interface by host\n" "\n" -"Synopsis: iftop -h | [-npblBP] [-i interface] [-f filter code]\n" +"Synopsis: iftop -h | [-npblNBP] [-i interface] [-f filter code]\n" " [-F net/mask] [-G net6/mask6]\n" "\n" " -h display this message\n" @@ -260,8 +198,20 @@ static void usage(FILE *fp) { " -P show ports as well as hosts\n" " -m limit sets the upper limit for the bandwidth scale\n" " -c config file specifies an alternative configuration file\n" +" -t use text interface without ncurses\n" +"\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 " IFTOP_VERSION "\n" +"iftop, version " PACKAGE_VERSION "\n" "copyright (c) 2002 Paul Warren and contributors\n" ); } @@ -324,6 +274,22 @@ void options_read_args(int argc, char **argv) { config_set_string("use-bytes", "true"); 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': xfree(options.config_file); options.config_file = xstrdup(optarg); @@ -538,18 +504,19 @@ int options_config_get_net_filter6() { } else { int bl, rem; - const uint32_t mm = 0xffffffff; - uint32_t part = mm; + const uint8_t mm = 0xff; + uint8_t part = mm; - bl = n / 32; - rem = n % 32; - part <<= 32 - rem; + bl = n / 8; + rem = n % 8; + part <<= 8 - rem; for (j=0; j < bl; ++j) - options.netfilter6mask.s6_addr32[j] = htonl(mm); + options.netfilter6mask.s6_addr[j] = mm; + if (rem > 0) - options.netfilter6mask.s6_addr32[bl] = htonl(part); + options.netfilter6mask.s6_addr[bl] = part; options.netfilter6 = 1; - } + } } else { if (inet_pton(AF_INET6, mask, &options.netfilter6mask) != 0) @@ -560,8 +527,8 @@ int options_config_get_net_filter6() { } } /* Prepare any comparison by masking the provided filtered net. */ - for (j=0; j < 4; ++j) - options.netfilter6net.s6_addr32[j] &= options.netfilter6mask.s6_addr32[j]; + for (j=0; j < 16; ++j) + options.netfilter6net.s6_addr[j] &= options.netfilter6mask.s6_addr[j]; return 1; } @@ -586,6 +553,9 @@ void options_make() { options_config_get_enum("port-display", showports_enumeration, (int*)&options.showports); 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_filter6(); };