]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lsfd: add a helper function decoding interface indexes
authorMasatake YAMATO <yamato@redhat.com>
Wed, 1 Mar 2023 14:34:09 +0000 (23:34 +0900)
committerMasatake YAMATO <yamato@redhat.com>
Sun, 5 Mar 2023 18:17:30 +0000 (03:17 +0900)
Thomas Weißschuh <thomas@t-8ch.de> suggested using arrays instead
of tree.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
misc-utils/lsfd-sock-xinfo.c

index fe814480855bfaca57033076cff3c81ccc3fa7fc..a305de6b518785caecf9001e17f49b460e394b48 100644 (file)
@@ -21,7 +21,9 @@
 #include <arpa/inet.h>         /* inet_ntop */
 #include <netinet/in.h>                /* in6_addr */
 #include <fcntl.h>             /* open(2) */
+#include <ifaddrs.h>           /* getifaddrs */
 #include <inttypes.h>          /* SCNu16 */
+#include <net/if.h>            /* if_nametoindex */
 #include <linux/net.h>         /* SS_* */
 #include <linux/netlink.h>     /* NETLINK_* */
 #include <linux/un.h>          /* UNIX_PATH_MAX */
@@ -59,8 +61,16 @@ static struct stat self_netns_sb;
 static void *xinfo_tree;       /* for tsearch/tfind */
 static void *netns_tree;
 
+struct iface {
+       unsigned int index;
+       char name[IF_NAMESIZE];
+};
+
+static const char *get_iface_name(ino_t netns, unsigned int iface_index);
+
 struct netns {
        ino_t inode;
+       struct iface *ifaces;
 };
 
 static int netns_compare(const void *a, const void *b)
@@ -73,9 +83,57 @@ static int netns_compare(const void *a, const void *b)
 
 static void netns_free(void *netns)
 {
+       struct netns *nsobj = netns;
+
+       free(nsobj->ifaces);
        free(netns);
 }
 
+/*
+ * iface index -> iface name mappings
+ */
+static void load_ifaces_from_getifaddrs(struct netns *nsobj)
+{
+       struct ifaddrs *ifa_list;
+       struct ifaddrs *ifa;
+       size_t i, count = 0;
+
+       if (getifaddrs(&ifa_list) < 0)
+               return;
+
+       for (ifa = ifa_list; ifa != NULL; ifa = ifa->ifa_next)
+               count++;
+
+       nsobj->ifaces = xcalloc(count + 1, sizeof(*nsobj->ifaces));
+
+       for (ifa = ifa_list, i = 0; ifa != NULL; ifa = ifa->ifa_next, i++) {
+               unsigned int if_index = if_nametoindex(ifa->ifa_name);
+
+               nsobj->ifaces[i].index = if_index;
+               strncpy(nsobj->ifaces[i].name, ifa->ifa_name, IF_NAMESIZE - 1);
+               /* The slot for the last byte is already filled by calloc. */
+       }
+       /* nsobj->ifaces[count] is the sentinel value. */
+
+       freeifaddrs(ifa_list);
+
+       return;
+}
+
+static const char *get_iface_name(ino_t netns, unsigned int iface_index)
+{
+       struct netns **nsobj = tfind(&netns, &netns_tree, netns_compare);
+       if (!nsobj)
+               return NULL;
+
+       for (size_t i = 0; (*nsobj)->ifaces[i].index; i++) {
+               if ((*nsobj)->ifaces[i].index == iface_index)
+                       return (*nsobj)->ifaces[i].name;
+       }
+
+       return NULL;
+}
+
 static bool is_sock_xinfo_loaded(ino_t netns)
 {
        return tfind(&netns, &netns_tree, netns_compare)? true: false;
@@ -83,7 +141,7 @@ static bool is_sock_xinfo_loaded(ino_t netns)
 
 static struct netns *mark_sock_xinfo_loaded(ino_t ino)
 {
-       struct netns *netns = xmalloc(sizeof(*netns));
+       struct netns *netns = xcalloc(1, sizeof(*netns));
        ino_t **tmp;
 
        netns->inode = ino;
@@ -109,6 +167,9 @@ static void load_sock_xinfo_no_nsswitch(struct netns *nsobj)
        load_xinfo_from_proc_icmp(netns);
        load_xinfo_from_proc_icmp6(netns);
        load_xinfo_from_proc_netlink(netns);
+
+       if (nsobj)
+               load_ifaces_from_getifaddrs(nsobj);
 }
 
 static void load_sock_xinfo_with_fd(int fd, struct netns *nsobj)