From: Teemu Toivola Date: Sun, 16 Jun 2019 19:23:12 +0000 (+0300) Subject: filter out local and invalid interfaces from interface lists X-Git-Tag: v2.3~12 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=76713a32b60f75ded9c13db1ad95b656e6bfb496;p=vnstat filter out local and invalid interfaces from interface lists --- diff --git a/src/daemon.c b/src/daemon.c index 949c8b7..92c371f 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -123,7 +123,7 @@ unsigned int addinterfaces(DSTATE *s) timeused_debug(__func__, 1); /* get list of currently visible interfaces */ - if (getiflist(&ifl, 0) == 0) { + if (getiflist(&ifl, 0, 1) == 0) { iflistfree(&ifl); return 0; } @@ -147,14 +147,6 @@ unsigned int addinterfaces(DSTATE *s) if (debug) printf("Processing: \"%s\"\n", ifl_iterator->interface); - /* skip local interfaces */ - if ((strcmp(ifl_iterator->interface, "lo") == 0) || (strcmp(ifl_iterator->interface, "lo0") == 0) || (strcmp(ifl_iterator->interface, "sit0") == 0)) { - if (debug) - printf("skip\n"); - ifl_iterator = ifl_iterator->next; - continue; - } - /* skip already known interfaces */ if (db_getinterfacecountbyname(ifl_iterator->interface)) { if (debug) diff --git a/src/ifinfo.c b/src/ifinfo.c index 11d51e3..355e2a4 100644 --- a/src/ifinfo.c +++ b/src/ifinfo.c @@ -72,7 +72,7 @@ int getifliststring(char **ifacelist, int showspeed) } *ifacelist[0] = '\0'; - if (getiflist(&ifl, showspeed) > 0) { + if (getiflist(&ifl, showspeed, 1) > 0) { ifl_iterator = ifl; @@ -109,17 +109,17 @@ int getifliststring(char **ifacelist, int showspeed) return 0; } -int getiflist(iflist **ifl, const int getspeed) +int getiflist(iflist **ifl, const int getspeed, const int validate) { #if defined(__linux__) || defined(CHECK_VNSTAT) - return getiflist_linux(ifl, getspeed); + return getiflist_linux(ifl, getspeed, validate); #elif defined(BSD_VNSTAT) - return getiflist_bsd(ifl, getspeed); + return getiflist_bsd(ifl, getspeed, validate); #endif } #if defined(__linux__) || defined(CHECK_VNSTAT) -int getiflist_linux(iflist **ifl, const int getspeed) +int getiflist_linux(iflist **ifl, const int getspeed, const int validate) { char temp[64]; char interface[32]; @@ -135,6 +135,9 @@ int getiflist_linux(iflist **ifl, const int getspeed) sscanf(procline, "%63s", temp); if (strlen(temp) > 0 && (isdigit(temp[(strlen(temp) - 1)]) || temp[(strlen(temp) - 1)] == ':')) { sscanf(temp, "%31[^':']s", interface); + if (validate && !isifvalid(interface)) { + continue; + } if (getspeed) { iflistadd(ifl, interface, getifspeed(interface)); } else { @@ -155,6 +158,9 @@ int getiflist_linux(iflist **ifl, const int getspeed) if (di->d_name[0] == '.' || strlen(di->d_name) > 31) { continue; } + if (validate && !isifvalid(di->d_name)) { + continue; + } if (getspeed) { iflistadd(ifl, di->d_name, getifspeed(di->d_name)); } else { @@ -170,7 +176,7 @@ int getiflist_linux(iflist **ifl, const int getspeed) return 0; } #elif defined(BSD_VNSTAT) -int getiflist_bsd(iflist **ifl, const int getspeed) +int getiflist_bsd(iflist **ifl, const int getspeed, const int validate) { struct ifaddrs *ifap, *ifa; @@ -181,6 +187,9 @@ int getiflist_bsd(iflist **ifl, const int getspeed) if (ifa->ifa_addr->sa_family != AF_LINK || strlen(ifa->ifa_name) > 31) { continue; } + if (validate && !isifvalid(ifa->ifa_name)) { + continue; + } if (getspeed) { iflistadd(ifl, ifa->ifa_name, getifspeed(ifa->ifa_name)); } else { @@ -450,3 +459,17 @@ int isifavailable(const char *iface) return ret; } + +int isifvalid(const char *iface) +{ + if (strstr(iface, ":") != NULL) { + return 0; + } else if (strcmp(iface, "lo") == 0) { + return 0; + } else if (strcmp(iface, "lo0") == 0) { + return 0; + } else if (strcmp(iface, "sit0") == 0) { + return 0; + } + return 1; +} diff --git a/src/ifinfo.h b/src/ifinfo.h index 572a013..1ebf9bf 100644 --- a/src/ifinfo.h +++ b/src/ifinfo.h @@ -9,11 +9,11 @@ int getifinfo(const char *iface); int getifliststring(char **ifacelist, int showspeed); -int getiflist(iflist **ifl, int getspeed); +int getiflist(iflist **ifl, const int getspeed, const int validate); #if defined(__linux__) || defined(CHECK_VNSTAT) -int getiflist_linux(iflist **ifl, const int getspeed); +int getiflist_linux(iflist **ifl, const int getspeed, const int validate); #elif defined(BSD_VNSTAT) -int getiflist_bsd(iflist **ifl, const int getspeed); +int getiflist_bsd(iflist **ifl, const int getspeed, const int validate); #endif int readproc(const char *iface); int readsysclassnet(const char *iface); @@ -23,5 +23,6 @@ int readifaddrs(const char *iface); #endif uint32_t getifspeed(const char *iface); int isifavailable(const char *iface); +int isifvalid(const char *iface); #endif diff --git a/src/vnstat.c b/src/vnstat.c index 6ea1cb8..6c2d6ff 100644 --- a/src/vnstat.c +++ b/src/vnstat.c @@ -390,7 +390,11 @@ int main(int argc, char *argv[]) } } else if (strcmp(argv[currentarg], "--iflist") == 0) { getifliststring(&p.ifacelist, 1); - printf("Available interfaces: %s\n", p.ifacelist); + if (strlen(p.ifacelist)) { + printf("Available interfaces: %s\n", p.ifacelist); + } else { + printf("No usable interfaces found.\n"); + } free(p.ifacelist); return 0; } else if ((strcmp(argv[currentarg], "-v") == 0) || (strcmp(argv[currentarg], "--version") == 0)) { @@ -842,7 +846,7 @@ void handleifselection(PARAMS *p) } if (p->traffic || p->livetraffic) { - ifcount = getiflist(&ifl, 0); + ifcount = getiflist(&ifl, 0, 1); /* try to open database for extra information */ if (db == NULL) { diff --git a/tests/ifinfo_tests.c b/tests/ifinfo_tests.c index bd99507..183493a 100644 --- a/tests/ifinfo_tests.c +++ b/tests/ifinfo_tests.c @@ -31,7 +31,7 @@ START_TEST(getifliststring_proc_one_interface) fake_proc_net_dev("w", "ethunusual", 0, 0, 0, 0); ck_assert_int_eq(getifliststring(&ifacelist, 1), 1); - ck_assert_str_eq(ifacelist, "lo ethunusual "); + ck_assert_str_eq(ifacelist, "ethunusual "); free(ifacelist); } @@ -48,7 +48,7 @@ START_TEST(getifliststring_proc_one_interface_with_speed) fake_sys_class_net("ethunusual", 0, 0, 0, 0, 10); ck_assert_int_eq(getifliststring(&ifacelist, 1), 1); - ck_assert_str_eq(ifacelist, "lo ethunusual (10 Mbit) "); + ck_assert_str_eq(ifacelist, "ethunusual (10 Mbit) "); free(ifacelist); } @@ -68,7 +68,30 @@ START_TEST(getifliststring_proc_multiple_interfaces) fake_proc_net_dev("a", "i", 0, 0, 0, 0); ck_assert_int_eq(getifliststring(&ifacelist, 0), 1); - ck_assert_str_eq(ifacelist, "lo random interfaces having fun i "); + ck_assert_str_eq(ifacelist, "random interfaces having fun i "); + + free(ifacelist); +} +END_TEST + +START_TEST(getifliststring_proc_multiple_interfaces_validating) +{ + char *ifacelist; + + linuxonly; + + ck_assert_int_eq(remove_directory(TESTDIR), 1); + fake_proc_net_dev("w", "random", 0, 0, 0, 0); + fake_proc_net_dev("a", "interfaces", 0, 0, 0, 0); + fake_proc_net_dev("a", "having", 0, 0, 0, 0); + fake_proc_net_dev("a", "sit0", 0, 0, 0, 0); + fake_proc_net_dev("a", "fun", 0, 0, 0, 0); + fake_proc_net_dev("a", "lo0", 0, 0, 0, 0); + fake_proc_net_dev("a", "eth0:0", 0, 0, 0, 0); + fake_proc_net_dev("a", "i", 0, 0, 0, 0); + + ck_assert_int_eq(getifliststring(&ifacelist, 0), 1); + ck_assert_str_eq(ifacelist, "random interfaces having fun eth0 i "); free(ifacelist); } @@ -90,7 +113,7 @@ START_TEST(getifliststring_proc_long_interface_names) fake_proc_net_dev("a", "a", 0, 0, 0, 0); ck_assert_int_eq(getifliststring(&ifacelist, 0), 1); - ck_assert_str_eq(ifacelist, "lo random interfaces having toomuchfun longinterfaceislong a "); + ck_assert_str_eq(ifacelist, "random interfaces having toomuchfun longinterfaceislong a "); free(ifacelist); } @@ -148,6 +171,30 @@ START_TEST(getifliststring_sysclassnet_multiple_interfaces) } END_TEST +START_TEST(getifliststring_sysclassnet_multiple_interfaces_validating) +{ + char *ifacelist; + + linuxonly; + + ck_assert_int_eq(remove_directory(TESTDIR), 1); + fake_sys_class_net("lo", 0, 0, 0, 0, 0); + fake_sys_class_net("random", 0, 0, 0, 0, 0); + fake_sys_class_net("lo0", 0, 0, 0, 0, 0); + fake_sys_class_net("interfaces", 0, 0, 0, 0, 0); + fake_sys_class_net("having", 0, 0, 0, 0, 0); + fake_sys_class_net("fun", 0, 0, 0, 0, 0); + fake_sys_class_net("sit0", 0, 0, 0, 0, 0); + fake_sys_class_net("eth0:0", 0, 0, 0, 0, 0); + fake_sys_class_net("i", 0, 0, 0, 0, 0); + + ck_assert_int_eq(getifliststring(&ifacelist, 0), 1); + ck_assert_int_eq(strlen(ifacelist), 31); + + free(ifacelist); +} +END_TEST + START_TEST(getifliststring_sysclassnet_long_interface_names) { char *ifacelist; @@ -292,10 +339,12 @@ void add_ifinfo_tests(Suite *s) tcase_add_test(tc_ifinfo, getifliststring_proc_one_interface); tcase_add_test(tc_ifinfo, getifliststring_proc_one_interface_with_speed); tcase_add_test(tc_ifinfo, getifliststring_proc_multiple_interfaces); + tcase_add_test(tc_ifinfo, getifliststring_proc_multiple_interfaces_validating); tcase_add_test(tc_ifinfo, getifliststring_proc_long_interface_names); tcase_add_test(tc_ifinfo, getifliststring_sysclassnet_one_interface); tcase_add_test(tc_ifinfo, getifliststring_sysclassnet_one_interface_with_speed); tcase_add_test(tc_ifinfo, getifliststring_sysclassnet_multiple_interfaces); + tcase_add_test(tc_ifinfo, getifliststring_sysclassnet_multiple_interfaces_validating); tcase_add_test(tc_ifinfo, getifliststring_sysclassnet_long_interface_names); tcase_add_test(tc_ifinfo, readproc_no_file); tcase_add_test(tc_ifinfo, readproc_not_found);