]> granicus.if.org Git - vnstat/commitdiff
filter out local and invalid interfaces from interface lists
authorTeemu Toivola <git@humdi.net>
Sun, 16 Jun 2019 19:23:12 +0000 (22:23 +0300)
committerTeemu Toivola <git@humdi.net>
Sun, 16 Jun 2019 19:23:12 +0000 (22:23 +0300)
src/daemon.c
src/ifinfo.c
src/ifinfo.h
src/vnstat.c
tests/ifinfo_tests.c

index 949c8b770ba544676dad9180f6797d201acc0a91..92c371f05ebcdbf89d20d54fce52f9e593fa2fc9 100644 (file)
@@ -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)
index 11d51e3f0a4e28dfd2b543afbdb97d30a365ec59..355e2a489980d86cfbf49bc07983e8a801116abd 100644 (file)
@@ -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;
+}
index 572a013eb1a89cfd7839d331ddadce02e4913635..1ebf9bf1daae88e762cafa6bc5ff146ea22fc012 100644 (file)
@@ -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
index 6ea1cb8edcd460553c6677b847a859caa41fc7b6..6c2d6ff9cc017dc01dfb2c5dd058c745f7a3f7a2 100644 (file)
@@ -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) {
index bd995072214f342cbbe872168f3ed19e1573055e..183493a428dff6aefe8ae49fd140ff5e0070ec25 100644 (file)
@@ -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);