(root)/
util-linux-2.39/
misc-utils/
lsfd-sock-xinfo.c
       1  /*
       2   * lsfd-sock-xinfo.c - read various information from files under /proc/net/
       3   *
       4   * Copyright (C) 2022 Red Hat, Inc. All rights reserved.
       5   * Written by Masatake YAMATO <yamato@redhat.com>
       6   *
       7   * This program is free software; you can redistribute it and/or modify
       8   * it under the terms of the GNU General Public License as published by
       9   * the Free Software Foundation; either version 2 of the License, or
      10   * (at your option) any later version.
      11   *
      12   * This program is distributed in the hope that it would be useful,
      13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15   * GNU General Public License for more details.
      16   *
      17   * You should have received a copy of the GNU General Public License
      18   * along with this program; if not, write to the Free Software Foundation,
      19   * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      20   */
      21  #include <arpa/inet.h>		/* inet_ntop */
      22  #include <netinet/in.h>		/* in6_addr */
      23  #include <fcntl.h>		/* open(2) */
      24  #include <ifaddrs.h>		/* getifaddrs */
      25  #include <inttypes.h>		/* SCNu16 */
      26  #include <net/if.h>		/* if_nametoindex */
      27  #include <linux/if_ether.h>	/* ETH_P_* */
      28  #include <linux/net.h>		/* SS_* */
      29  #include <linux/netlink.h>	/* NETLINK_* */
      30  #include <linux/un.h>		/* UNIX_PATH_MAX */
      31  #include <sched.h>		/* for setns(2) */
      32  #include <search.h>
      33  #include <stdint.h>
      34  #include <string.h>
      35  #include <sys/socket.h>		/* SOCK_* */
      36  
      37  #include "xalloc.h"
      38  #include "nls.h"
      39  #include "libsmartcols.h"
      40  #include "sysfs.h"
      41  #include "bitops.h"
      42  
      43  #include "lsfd.h"
      44  #include "lsfd-sock.h"
      45  
      46  static void load_xinfo_from_proc_icmp(ino_t netns_inode);
      47  static void load_xinfo_from_proc_icmp6(ino_t netns_inode);
      48  static void load_xinfo_from_proc_unix(ino_t netns_inode);
      49  static void load_xinfo_from_proc_raw(ino_t netns_inode);
      50  static void load_xinfo_from_proc_tcp(ino_t netns_inode);
      51  static void load_xinfo_from_proc_udp(ino_t netns_inode);
      52  static void load_xinfo_from_proc_udplite(ino_t netns_inode);
      53  static void load_xinfo_from_proc_tcp6(ino_t netns_inode);
      54  static void load_xinfo_from_proc_udp6(ino_t netns_inode);
      55  static void load_xinfo_from_proc_udplite6(ino_t netns_inode);
      56  static void load_xinfo_from_proc_raw6(ino_t netns_inode);
      57  static void load_xinfo_from_proc_netlink(ino_t netns_inode);
      58  static void load_xinfo_from_proc_packet(ino_t netns_inode);
      59  
      60  static int self_netns_fd = -1;
      61  static struct stat self_netns_sb;
      62  
      63  static void *xinfo_tree;	/* for tsearch/tfind */
      64  static void *netns_tree;
      65  
      66  struct iface {
      67  	unsigned int index;
      68  	char name[IF_NAMESIZE];
      69  };
      70  
      71  static const char *get_iface_name(ino_t netns, unsigned int iface_index);
      72  
      73  struct netns {
      74  	ino_t inode;
      75  	struct iface *ifaces;
      76  };
      77  
      78  static int netns_compare(const void *a, const void *b)
      79  {
      80  	const struct netns *netns_a = a;
      81  	const struct netns *netns_b = b;
      82  
      83  	return netns_a->inode - netns_b->inode;
      84  }
      85  
      86  static void netns_free(void *netns)
      87  {
      88  	struct netns *nsobj = netns;
      89  
      90  	free(nsobj->ifaces);
      91  	free(netns);
      92  }
      93  
      94  /*
      95   * iface index -> iface name mappings
      96   */
      97  static void load_ifaces_from_getifaddrs(struct netns *nsobj)
      98  {
      99  	struct ifaddrs *ifa_list;
     100  	struct ifaddrs *ifa;
     101  	size_t i, count = 0;
     102  
     103  	if (getifaddrs(&ifa_list) < 0)
     104  		return;
     105  
     106  	for (ifa = ifa_list; ifa != NULL; ifa = ifa->ifa_next)
     107  		count++;
     108  
     109  	nsobj->ifaces = xcalloc(count + 1, sizeof(*nsobj->ifaces));
     110  
     111  	for (ifa = ifa_list, i = 0; ifa != NULL; ifa = ifa->ifa_next, i++) {
     112  		unsigned int if_index = if_nametoindex(ifa->ifa_name);
     113  
     114  		nsobj->ifaces[i].index = if_index;
     115  		strncpy(nsobj->ifaces[i].name, ifa->ifa_name, IF_NAMESIZE - 1);
     116  		/* The slot for the last byte is already filled by calloc. */
     117  	}
     118  	/* nsobj->ifaces[count] is the sentinel value. */
     119  
     120  	freeifaddrs(ifa_list);
     121  
     122  	return;
     123  }
     124  
     125  static const char *get_iface_name(ino_t netns, unsigned int iface_index)
     126  {
     127  	struct netns **nsobj = tfind(&netns, &netns_tree, netns_compare);
     128  	if (!nsobj)
     129  		return NULL;
     130  
     131  	for (size_t i = 0; (*nsobj)->ifaces[i].index; i++) {
     132  		if ((*nsobj)->ifaces[i].index == iface_index)
     133  			return (*nsobj)->ifaces[i].name;
     134  	}
     135  
     136  	return NULL;
     137  }
     138  
     139  static bool is_sock_xinfo_loaded(ino_t netns)
     140  {
     141  	return tfind(&netns, &netns_tree, netns_compare)? true: false;
     142  }
     143  
     144  static struct netns *mark_sock_xinfo_loaded(ino_t ino)
     145  {
     146  	struct netns *netns = xcalloc(1, sizeof(*netns));
     147  	ino_t **tmp;
     148  
     149  	netns->inode = ino;
     150  	tmp = tsearch(netns, &netns_tree, netns_compare);
     151  	if (tmp == NULL)
     152  		errx(EXIT_FAILURE, _("failed to allocate memory"));
     153  	return *(struct netns **)tmp;
     154  }
     155  
     156  static void load_sock_xinfo_no_nsswitch(struct netns *nsobj)
     157  {
     158  	ino_t netns = nsobj? nsobj->inode: 0;
     159  
     160  	load_xinfo_from_proc_unix(netns);
     161  	load_xinfo_from_proc_tcp(netns);
     162  	load_xinfo_from_proc_udp(netns);
     163  	load_xinfo_from_proc_udplite(netns);
     164  	load_xinfo_from_proc_raw(netns);
     165  	load_xinfo_from_proc_tcp6(netns);
     166  	load_xinfo_from_proc_udp6(netns);
     167  	load_xinfo_from_proc_udplite6(netns);
     168  	load_xinfo_from_proc_raw6(netns);
     169  	load_xinfo_from_proc_icmp(netns);
     170  	load_xinfo_from_proc_icmp6(netns);
     171  	load_xinfo_from_proc_netlink(netns);
     172  	load_xinfo_from_proc_packet(netns);
     173  
     174  	if (nsobj)
     175  		load_ifaces_from_getifaddrs(nsobj);
     176  }
     177  
     178  static void load_sock_xinfo_with_fd(int fd, struct netns *nsobj)
     179  {
     180  	if (setns(fd, CLONE_NEWNET) == 0) {
     181  		load_sock_xinfo_no_nsswitch(nsobj);
     182  		setns(self_netns_fd, CLONE_NEWNET);
     183  	}
     184  }
     185  
     186  void load_sock_xinfo(struct path_cxt *pc, const char *name, ino_t netns)
     187  {
     188  	if (self_netns_fd == -1)
     189  		return;
     190  
     191  	if (!is_sock_xinfo_loaded(netns)) {
     192  		int fd;
     193  		struct netns *nsobj = mark_sock_xinfo_loaded(netns);
     194  		fd = ul_path_open(pc, O_RDONLY, name);
     195  		if (fd < 0)
     196  			return;
     197  
     198  		load_sock_xinfo_with_fd(fd, nsobj);
     199  		close(fd);
     200  	}
     201  }
     202  
     203  void initialize_sock_xinfos(void)
     204  {
     205  	struct path_cxt *pc;
     206  	DIR *dir;
     207  	struct dirent *d;
     208  
     209  	self_netns_fd = open("/proc/self/ns/net", O_RDONLY);
     210  
     211  	if (self_netns_fd < 0)
     212  		load_sock_xinfo_no_nsswitch(NULL);
     213  	else {
     214  		if (fstat(self_netns_fd, &self_netns_sb) == 0) {
     215  			struct netns *nsobj = mark_sock_xinfo_loaded(self_netns_sb.st_ino);
     216  			load_sock_xinfo_no_nsswitch(nsobj);
     217  		}
     218  	}
     219  
     220  	/* Load /proc/net/{unix,...} of the network namespace
     221  	 * specified with netns files under /var/run/netns/.
     222  	 *
     223  	 * `ip netns' command pins a network namespace on
     224  	 * /var/run/netns.
     225  	 */
     226  	pc = ul_new_path("/var/run/netns");
     227  	if (!pc)
     228  		err(EXIT_FAILURE, _("failed to alloc path context for /var/run/netns"));
     229  	dir = ul_path_opendir(pc, NULL);
     230  	if (dir == NULL) {
     231  		ul_unref_path(pc);
     232  		return;
     233  	}
     234  	while ((d = readdir(dir))) {
     235  		struct stat sb;
     236  		int fd;
     237  		struct netns *nsobj;
     238  		if (ul_path_stat(pc, &sb, 0, d->d_name) < 0)
     239  			continue;
     240  		if (is_sock_xinfo_loaded(sb.st_ino))
     241  			continue;
     242  		nsobj = mark_sock_xinfo_loaded(sb.st_ino);
     243  		fd = ul_path_open(pc, O_RDONLY, d->d_name);
     244  		if (fd < 0)
     245  			continue;
     246  		load_sock_xinfo_with_fd(fd, nsobj);
     247  		close(fd);
     248  	}
     249  	closedir(dir);
     250  	ul_unref_path(pc);
     251  }
     252  
     253  static void free_sock_xinfo(void *node)
     254  {
     255  	struct sock_xinfo *xinfo = node;
     256  	if (xinfo->class->free)
     257  		xinfo->class->free(xinfo);
     258  	free(node);
     259  }
     260  
     261  void finalize_sock_xinfos(void)
     262  {
     263  	if (self_netns_fd != -1)
     264  		close(self_netns_fd);
     265  	tdestroy(netns_tree, netns_free);
     266  	tdestroy(xinfo_tree, free_sock_xinfo);
     267  }
     268  
     269  static int xinfo_compare(const void *a, const void *b)
     270  {
     271  	return ((struct sock_xinfo *)a)->inode - ((struct sock_xinfo *)b)->inode;
     272  }
     273  
     274  static void add_sock_info(struct sock_xinfo *xinfo)
     275  {
     276  	struct sock_xinfo **tmp = tsearch(xinfo, &xinfo_tree, xinfo_compare);
     277  
     278  	if (tmp == NULL)
     279  		errx(EXIT_FAILURE, _("failed to allocate memory"));
     280  }
     281  
     282  struct sock_xinfo *get_sock_xinfo(ino_t netns_inode)
     283  {
     284  	struct sock_xinfo **xinfo = tfind(&netns_inode, &xinfo_tree, xinfo_compare);
     285  
     286  	if (xinfo)
     287  		return *xinfo;
     288  	return NULL;
     289  }
     290  
     291  bool is_nsfs_dev(dev_t dev)
     292  {
     293  	return dev == self_netns_sb.st_dev;
     294  }
     295  
     296  static const char *sock_decode_type(uint16_t type)
     297  {
     298  	switch (type) {
     299  	case SOCK_STREAM:
     300  		return "stream";
     301  	case SOCK_DGRAM:
     302  		return "dgram";
     303  	case SOCK_RAW:
     304  		return "raw";
     305  	case SOCK_RDM:
     306  		return "rdm";
     307  	case SOCK_SEQPACKET:
     308  		return "seqpacket";
     309  	case SOCK_DCCP:
     310  		return "dccp";
     311  	case SOCK_PACKET:
     312  		return "packet";
     313  	default:
     314  		return "unknown";
     315  	}
     316  }
     317  
     318  /*
     319   * Protocol specific code
     320   */
     321  
     322  /*
     323   * UNIX
     324   */
     325  struct unix_xinfo {
     326  	struct sock_xinfo sock;
     327  	int acceptcon;	/* flags */
     328  	uint16_t type;
     329  	uint8_t  st;
     330  	char path[
     331  		  UNIX_PATH_MAX
     332  		  + 1		/* for @ */
     333  		  + 1		/* \0? */
     334  		  ];
     335  };
     336  
     337  static const char *unix_decode_state(uint8_t st)
     338  {
     339  	switch (st) {
     340  	case SS_FREE:
     341  		return "free";
     342  	case SS_UNCONNECTED:
     343  		return "unconnected";
     344  	case SS_CONNECTING:
     345  		return "connecting";
     346  	case SS_CONNECTED:
     347  		return "connected";
     348  	case SS_DISCONNECTING:
     349  		return "disconnecting";
     350  	default:
     351  		return "unknown";
     352  	}
     353  }
     354  
     355  static char *unix_get_name(struct sock_xinfo *sock_xinfo,
     356  			   struct sock *sock)
     357  {
     358  	struct unix_xinfo *ux = (struct unix_xinfo *)sock_xinfo;
     359  	const char *state = unix_decode_state(ux->st);
     360  	char *str = NULL;
     361  
     362  	if (sock->protoname && (strcmp(sock->protoname, "UNIX-STREAM") == 0))
     363  		xasprintf(&str, "state=%s%s%s",
     364  			  (ux->acceptcon)? "listen": state,
     365  			  *(ux->path)? " path=": "",
     366  			  *(ux->path)? ux->path: "");
     367  	else
     368  		xasprintf(&str, "state=%s%s%s type=%s",
     369  			  (ux->acceptcon)? "listen": state,
     370  			  *(ux->path)? " path=": "",
     371  			  *(ux->path)? ux->path: "",
     372  			  sock_decode_type(ux->type));
     373  	return str;
     374  }
     375  
     376  static char *unix_get_type(struct sock_xinfo *sock_xinfo,
     377  			   struct sock *sock __attribute__((__unused__)))
     378  {
     379  	const char *str;
     380  	struct unix_xinfo *ux = (struct unix_xinfo *)sock_xinfo;
     381  
     382  	str = sock_decode_type(ux->type);
     383  	return xstrdup(str);
     384  }
     385  
     386  static char *unix_get_state(struct sock_xinfo *sock_xinfo,
     387  			    struct sock *sock __attribute__((__unused__)))
     388  {
     389  	const char *str;
     390  	struct unix_xinfo *ux = (struct unix_xinfo *)sock_xinfo;
     391  
     392  	if (ux->acceptcon)
     393  		return xstrdup("listen");
     394  
     395  	str = unix_decode_state(ux->st);
     396  	return xstrdup(str);
     397  }
     398  
     399  static bool unix_get_listening(struct sock_xinfo *sock_xinfo,
     400  			       struct sock *sock __attribute__((__unused__)))
     401  {
     402  	struct unix_xinfo *ux = (struct unix_xinfo *)sock_xinfo;
     403  
     404  	return ux->acceptcon;
     405  }
     406  
     407  static bool unix_fill_column(struct proc *proc __attribute__((__unused__)),
     408  			     struct sock_xinfo *sock_xinfo,
     409  			     struct sock *sock __attribute__((__unused__)),
     410  			     struct libscols_line *ln __attribute__((__unused__)),
     411  			     int column_id,
     412  			     size_t column_index __attribute__((__unused__)),
     413  			     char **str)
     414  {
     415  	struct unix_xinfo *ux = (struct unix_xinfo *)sock_xinfo;
     416  
     417  	switch (column_id) {
     418  	case COL_UNIX_PATH:
     419  		if (*ux->path) {
     420  			*str = xstrdup(ux->path);
     421  			return true;
     422  		}
     423  		break;
     424  	}
     425  
     426  	return false;
     427  }
     428  
     429  static const struct sock_xinfo_class unix_xinfo_class = {
     430  	.get_name = unix_get_name,
     431  	.get_type = unix_get_type,
     432  	.get_state = unix_get_state,
     433  	.get_listening = unix_get_listening,
     434  	.fill_column = unix_fill_column,
     435  	.free = NULL,
     436  };
     437  
     438  /* UNIX_LINE_LEN need at least 54 + 21 + UNIX_PATH_MAX + 1.
     439   *
     440   * An actual number must be used in this definition
     441   * since UNIX_LINE_LEN is specified as an argument for
     442   * stringify_value().
     443   */
     444  #define UNIX_LINE_LEN 256
     445  static void load_xinfo_from_proc_unix(ino_t netns_inode)
     446  {
     447  	char line[UNIX_LINE_LEN];
     448  	FILE *unix_fp;
     449  
     450  	unix_fp = fopen("/proc/net/unix", "r");
     451  	if (!unix_fp)
     452  		return;
     453  
     454  	if (fgets(line, sizeof(line), unix_fp) == NULL)
     455  		goto out;
     456  	if (!(line[0] == 'N' && line[1] == 'u' && line[2] == 'm'))
     457  		/* Unexpected line */
     458  		goto out;
     459  
     460  	while (fgets(line, sizeof(line), unix_fp)) {
     461  		uint64_t flags;
     462  		uint32_t type;
     463  		unsigned int st;
     464  		unsigned long inode;
     465  		struct unix_xinfo *ux;
     466  		char path[UNIX_LINE_LEN + 1] = { 0 };
     467  
     468  
     469  		if (sscanf(line, "%*x: %*x %*x %" SCNx64 " %x %x %lu %"
     470  			   stringify_value(UNIX_LINE_LEN) "[^\n]",
     471  			   &flags, &type, &st, &inode, path) < 4)
     472  			continue;
     473  
     474  		if (inode == 0)
     475  			continue;
     476  
     477  		ux = xcalloc(1, sizeof(*ux));
     478  		ux->sock.class = &unix_xinfo_class;
     479  		ux->sock.inode = (ino_t)inode;
     480  		ux->sock.netns_inode = netns_inode;
     481  
     482  		ux->acceptcon = !!flags;
     483  		ux->type = type;
     484  		ux->st = st;
     485  		xstrncpy(ux->path, path, sizeof(ux->path));
     486  
     487  		add_sock_info(&ux->sock);
     488  	}
     489  
     490   out:
     491  	fclose(unix_fp);
     492  }
     493  
     494  /*
     495   * AF_INET
     496   */
     497  struct inet_xinfo {
     498  	struct sock_xinfo sock;
     499  	struct in_addr local_addr;
     500  	struct in_addr remote_addr;
     501  };
     502  
     503  static uint32_t kernel32_to_cpu(enum sysfs_byteorder byteorder, uint32_t v)
     504  {
     505  	if (byteorder == SYSFS_BYTEORDER_LITTLE)
     506  		return le32_to_cpu(v);
     507  	else
     508  		return be32_to_cpu(v);
     509  }
     510  
     511  /*
     512   * AF_INET6
     513   */
     514  struct inet6_xinfo {
     515  	struct sock_xinfo sock;
     516  	struct in6_addr local_addr;
     517  	struct in6_addr remote_addr;
     518  };
     519  
     520  /*
     521   * L4 abstract-layer for protocols stacked on IP and IP6.
     522   */
     523  enum l4_state {
     524  	/*
     525  	 * Taken from linux/include/net/tcp_states.h.
     526  	 * (GPL-2.0-or-later)
     527  	 *
     528  	 * UDP and RAW sockets also uses the contents in Linux.
     529  	 */
     530  	TCP_ESTABLISHED = 1,
     531  	TCP_SYN_SENT,
     532  	TCP_SYN_RECV,
     533  	TCP_FIN_WAIT1,
     534  	TCP_FIN_WAIT2,
     535  	TCP_TIME_WAIT,
     536  	TCP_CLOSE,
     537  	TCP_CLOSE_WAIT,
     538  	TCP_LAST_ACK,
     539  	TCP_LISTEN,
     540  	TCP_CLOSING,
     541  	TCP_NEW_SYN_RECV,
     542  
     543  	TCP_MAX_STATES	/* Leave at the end! */
     544  };
     545  
     546  static const char *l4_decode_state(enum l4_state st)
     547  {
     548  	const char * table [] = {
     549  		[TCP_ESTABLISHED] = "established",
     550  		[TCP_SYN_SENT] = "syn-sent",
     551  		[TCP_SYN_RECV] = "syn-recv",
     552  		[TCP_FIN_WAIT1] = "fin-wait1",
     553  		[TCP_FIN_WAIT2] = "fin-wait2",
     554  		[TCP_TIME_WAIT] = "time-wait",
     555  		[TCP_CLOSE] = "close",
     556  		[TCP_CLOSE_WAIT] = "close-wait",
     557  		[TCP_LAST_ACK] = "last-ack",
     558  		[TCP_LISTEN] = "listen",
     559  		[TCP_CLOSING] = "closing",
     560  		[TCP_NEW_SYN_RECV] = "new-syn-recv",
     561  	};
     562  
     563  	if (st < TCP_MAX_STATES)
     564  		return table[st];
     565  	return "unknown";
     566  }
     567  
     568  struct l4_xinfo {
     569  	union {
     570  		struct inet_xinfo inet;
     571  		struct inet6_xinfo inet6;
     572  	};
     573  	enum l4_state st;
     574  };
     575  
     576  enum l4_side { L4_LOCAL, L4_REMOTE };
     577  enum l3_decorator { L3_DECO_START, L3_DECO_END };
     578  
     579  struct l4_xinfo_class {
     580  	struct sock_xinfo_class sock;
     581  	struct sock_xinfo *(*scan_line)(const struct sock_xinfo_class *,
     582  					char *,
     583  					ino_t,
     584  					enum sysfs_byteorder);
     585  	void * (*get_addr)(struct l4_xinfo *, enum l4_side);
     586  	bool (*is_any_addr)(void *);
     587  	int family;
     588  	const char *l3_decorator[2];
     589  };
     590  
     591  #define l3_fill_column_handler(L3, SOCK_XINFO, COLUMN_ID, STR)	__extension__ \
     592  	({								\
     593  		struct l4_xinfo_class *class = (struct l4_xinfo_class *)SOCK_XINFO->class; \
     594  		struct l4_xinfo *l4 = (struct l4_xinfo *)SOCK_XINFO;	\
     595  		void *n = NULL;						\
     596  		char s[BUFSIZ];						\
     597  		bool r = false;						\
     598  									\
     599  		switch (COLUMN_ID) {					\
     600  		case COL_##L3##_LADDR:					\
     601  			n = class->get_addr(l4, L4_LOCAL);		\
     602  			break;						\
     603  		case COL_##L3##_RADDR:					\
     604  			n = class->get_addr(l4, L4_REMOTE);		\
     605  			break;						\
     606  		default:						\
     607  			break;						\
     608  		}							\
     609  									\
     610  		if (n && inet_ntop(class->family, n, s, sizeof(s))) {	\
     611  			*STR = xstrdup(s);				\
     612  			r = true;					\
     613  		}							\
     614  		r;							\
     615  	})
     616  
     617  /*
     618   * TCP
     619   */
     620  struct tcp_xinfo {
     621  	struct l4_xinfo l4;
     622  	uint16_t local_port;
     623  	uint16_t remote_port;
     624  };
     625  
     626  static char *tcp_get_name(struct sock_xinfo *sock_xinfo,
     627  			  struct sock *sock  __attribute__((__unused__)))
     628  {
     629  	char *str = NULL;
     630  	struct tcp_xinfo *tcp = ((struct tcp_xinfo *)sock_xinfo);
     631  	struct l4_xinfo *l4 = &tcp->l4;
     632  	const char *st_str = l4_decode_state(l4->st);
     633  	struct l4_xinfo_class *class = (struct l4_xinfo_class *)sock_xinfo->class;
     634  	void *laddr = class->get_addr(l4, L4_LOCAL);
     635  	void *raddr = class->get_addr(l4, L4_REMOTE);
     636  	char local_s[BUFSIZ];
     637  	char remote_s[BUFSIZ];
     638  	const char *start = class->l3_decorator[L3_DECO_START];
     639  	const char *end = class->l3_decorator[L3_DECO_END];
     640  
     641  	if (!inet_ntop(class->family, laddr, local_s, sizeof(local_s)))
     642  		xasprintf(&str, "state=%s", st_str);
     643  	else if (l4->st == TCP_LISTEN
     644  		 || !inet_ntop(class->family, raddr, remote_s, sizeof(remote_s)))
     645  		xasprintf(&str, "state=%s laddr=%s%s%s:%"PRIu16,
     646  			  st_str,
     647  			  start, local_s, end, tcp->local_port);
     648  	else
     649  		xasprintf(&str, "state=%s laddr=%s%s%s:%"PRIu16" raddr=%s%s%s:%"PRIu16,
     650  			  st_str,
     651  			  start, local_s, end, tcp->local_port,
     652  			  start, remote_s, end, tcp->remote_port);
     653  	return str;
     654  }
     655  
     656  static char *tcp_get_type(struct sock_xinfo *sock_xinfo __attribute__((__unused__)),
     657  			   struct sock *sock __attribute__((__unused__)))
     658  {
     659  	return xstrdup("stream");
     660  }
     661  
     662  static char *tcp_get_state(struct sock_xinfo *sock_xinfo,
     663  			   struct sock *sock __attribute__((__unused__)))
     664  {
     665  	return xstrdup(l4_decode_state(((struct l4_xinfo *)sock_xinfo)->st));
     666  }
     667  
     668  static bool tcp_get_listening(struct sock_xinfo *sock_xinfo,
     669  			      struct sock *sock __attribute__((__unused__)))
     670  {
     671  	return ((struct l4_xinfo *)sock_xinfo)->st == TCP_LISTEN;
     672  }
     673  
     674  #define l4_fill_column_handler(L4, SOCK_XINFO, COLUMN_ID, STR)	__extension__ \
     675  	({								\
     676  		struct l4_xinfo_class *class = (struct l4_xinfo_class *)SOCK_XINFO->class; \
     677  		struct tcp_xinfo *tcp = (struct tcp_xinfo *)SOCK_XINFO; \
     678  		struct l4_xinfo *l4 = &tcp->l4;				\
     679  		void *n = NULL;						\
     680  		bool has_laddr = false;					\
     681  		unsigned short p;					\
     682  		bool has_lport = false;					\
     683  		char s[BUFSIZ];						\
     684  		bool r = true;						\
     685  									\
     686  		switch (COLUMN_ID) {					\
     687  		case COL_##L4##_LADDR:					\
     688  			n = class->get_addr(l4, L4_LOCAL);		\
     689  			has_laddr = true;				\
     690  			p = tcp->local_port;				\
     691  			/* FALL THROUGH */				\
     692  		case COL_##L4##_RADDR:					\
     693  			if (!has_laddr) {				\
     694  				n = class->get_addr(l4, L4_REMOTE);	\
     695  				p = tcp->remote_port;			\
     696  			}						\
     697  			if (n && inet_ntop(class->family, n, s, sizeof(s))) \
     698  				xasprintf(STR, "%s%s%s:%"PRIu16, \
     699  					  class->l3_decorator[L3_DECO_START], \
     700  					  s,				\
     701  					  class->l3_decorator[L3_DECO_END], \
     702  					  p);				\
     703  			break;						\
     704  		case COL_##L4##_LPORT:					\
     705  			p = tcp->local_port;				\
     706  			has_lport = true;				\
     707  			/* FALL THROUGH */				\
     708  		case COL_##L4##_RPORT:					\
     709  			if (!has_lport)					\
     710  				p = tcp->remote_port;			\
     711  			xasprintf(STR, "%"PRIu16, p);			\
     712  			break;						\
     713  		default:						\
     714  			r = false;					\
     715  			break;						\
     716  		}							\
     717  		r;							\
     718  	})
     719  
     720  static struct sock_xinfo *tcp_xinfo_scan_line(const struct sock_xinfo_class *class,
     721  					      char * line,
     722  					      ino_t netns_inode,
     723  					      enum sysfs_byteorder byteorder)
     724  {
     725  	unsigned long local_addr;
     726  	unsigned long local_port;
     727  	unsigned long remote_addr;
     728  	unsigned long remote_port;
     729  	unsigned long st;
     730  	unsigned long long inode;
     731  	struct tcp_xinfo *tcp;
     732  	struct inet_xinfo *inet;
     733  	struct sock_xinfo *sock;
     734  
     735  	if (sscanf(line, "%*d: %lx:%lx %lx:%lx %lx %*x:%*x %*x:%*x %*x %*u %*u %lld",
     736  		   &local_addr, &local_port, &remote_addr, &remote_port,
     737  		   &st, &inode) != 6)
     738  		return NULL;
     739  
     740  	if (inode == 0)
     741  		return NULL;
     742  
     743  	tcp = xcalloc(1, sizeof(*tcp));
     744  	inet = &tcp->l4.inet;
     745  	sock = &inet->sock;
     746  	sock->class = class;
     747  	sock->inode = (ino_t)inode;
     748  	sock->netns_inode = netns_inode;
     749  	inet->local_addr.s_addr = kernel32_to_cpu(byteorder, local_addr);
     750  	tcp->local_port = local_port;
     751  	inet->remote_addr.s_addr = kernel32_to_cpu(byteorder, remote_addr);
     752  	tcp->remote_port = remote_port;
     753  	tcp->l4.st = st;
     754  
     755  	return sock;
     756  }
     757  
     758  static void *tcp_xinfo_get_addr(struct l4_xinfo *l4, enum l4_side side)
     759  {
     760  	return (side == L4_LOCAL)
     761  		? &l4->inet.local_addr
     762  		: &l4->inet.remote_addr;
     763  }
     764  
     765  static bool tcp_xinfo_is_any_addr(void *addr)
     766  {
     767  	return ((struct in_addr *)addr)->s_addr == INADDR_ANY;
     768  }
     769  
     770  static bool tcp_fill_column(struct proc *proc __attribute__((__unused__)),
     771  			    struct sock_xinfo *sock_xinfo,
     772  			    struct sock *sock __attribute__((__unused__)),
     773  			    struct libscols_line *ln __attribute__((__unused__)),
     774  			    int column_id,
     775  			    size_t column_index __attribute__((__unused__)),
     776  			    char **str)
     777  {
     778  	return l3_fill_column_handler(INET, sock_xinfo, column_id, str)
     779  		|| l4_fill_column_handler(TCP, sock_xinfo, column_id, str);
     780  }
     781  
     782  static const struct l4_xinfo_class tcp_xinfo_class = {
     783  	.sock = {
     784  		.get_name = tcp_get_name,
     785  		.get_type = tcp_get_type,
     786  		.get_state = tcp_get_state,
     787  		.get_listening = tcp_get_listening,
     788  		.fill_column = tcp_fill_column,
     789  		.free = NULL,
     790  	},
     791  	.scan_line = tcp_xinfo_scan_line,
     792  	.get_addr = tcp_xinfo_get_addr,
     793  	.is_any_addr = tcp_xinfo_is_any_addr,
     794  	.family = AF_INET,
     795  	.l3_decorator = {"", ""},
     796  };
     797  
     798  static bool L4_verify_initial_line(const char *line)
     799  {
     800  	/* At least we expect two white spaces. */
     801  	if (strncmp(line, "  ", 2) != 0)
     802  		return false;
     803  	line += 2;
     804  
     805  	/* Skip white spaces. */
     806  	line = skip_space(line);
     807  
     808  	return strncmp(line, "sl", 2) == 0;
     809  }
     810  
     811  #define TCP_LINE_LEN 256
     812  static void load_xinfo_from_proc_inet_L4(ino_t netns_inode, const char *proc_file,
     813  					 const struct l4_xinfo_class *class)
     814  {
     815  	char line[TCP_LINE_LEN];
     816  	FILE *tcp_fp;
     817  
     818  	tcp_fp = fopen(proc_file, "r");
     819  	if (!tcp_fp)
     820  		return;
     821  
     822  	if (fgets(line, sizeof(line), tcp_fp) == NULL)
     823  		goto out;
     824  	if (!L4_verify_initial_line(line))
     825  		/* Unexpected line */
     826  		goto out;
     827  
     828  	enum sysfs_byteorder byteorder = sysfs_get_byteorder(NULL);
     829  
     830  	while (fgets(line, sizeof(line), tcp_fp)) {
     831  		struct sock_xinfo *sock = class->scan_line(&class->sock, line, netns_inode, byteorder);
     832  		if (sock)
     833  			add_sock_info(sock);
     834  	}
     835  
     836   out:
     837  	fclose(tcp_fp);
     838  }
     839  
     840  static void load_xinfo_from_proc_tcp(ino_t netns_inode)
     841  {
     842  	load_xinfo_from_proc_inet_L4(netns_inode,
     843  				     "/proc/net/tcp",
     844  				     &tcp_xinfo_class);
     845  }
     846  
     847  /*
     848   * UDP
     849   */
     850  static char *udp_get_name(struct sock_xinfo *sock_xinfo,
     851  			  struct sock *sock  __attribute__((__unused__)))
     852  {
     853  	char *str = NULL;
     854  	struct tcp_xinfo *tcp = ((struct tcp_xinfo *)sock_xinfo);
     855  	struct l4_xinfo *l4 = &tcp->l4;
     856  	unsigned int st = l4->st;
     857  	const char *st_str = l4_decode_state(st);
     858  	struct l4_xinfo_class *class = (struct l4_xinfo_class *)sock_xinfo->class;
     859  	void *laddr = class->get_addr(l4, L4_LOCAL);
     860  	void *raddr = class->get_addr(l4, L4_REMOTE);
     861  	char local_s[BUFSIZ];
     862  	char remote_s[BUFSIZ];
     863  	const char *start = class->l3_decorator[L3_DECO_START];
     864  	const char *end = class->l3_decorator[L3_DECO_END];
     865  
     866  	if (!inet_ntop(class->family, laddr, local_s, sizeof(local_s)))
     867  		xasprintf(&str, "state=%s", st_str);
     868  	else if ((class->is_any_addr(raddr) && tcp->remote_port == 0)
     869  		 || !inet_ntop(class->family, raddr, remote_s, sizeof(remote_s)))
     870  		xasprintf(&str, "state=%s laddr=%s%s%s:%"PRIu16,
     871  			  st_str,
     872  			  start, local_s, end, tcp->local_port);
     873  	else
     874  		xasprintf(&str, "state=%s laddr=%s%s%s:%"PRIu16" raddr=%s%s%s:%"PRIu16,
     875  			  st_str,
     876  			  start, local_s, end, tcp->local_port,
     877  			  start, remote_s, end, tcp->remote_port);
     878  	return str;
     879  }
     880  
     881  static char *udp_get_type(struct sock_xinfo *sock_xinfo __attribute__((__unused__)),
     882  			  struct sock *sock __attribute__((__unused__)))
     883  {
     884  	return xstrdup("dgram");
     885  }
     886  
     887  static bool udp_fill_column(struct proc *proc __attribute__((__unused__)),
     888  			    struct sock_xinfo *sock_xinfo,
     889  			    struct sock *sock __attribute__((__unused__)),
     890  			    struct libscols_line *ln __attribute__((__unused__)),
     891  			    int column_id,
     892  			    size_t column_index __attribute__((__unused__)),
     893  			    char **str)
     894  {
     895  	return l3_fill_column_handler(INET, sock_xinfo, column_id, str)
     896  		|| l4_fill_column_handler(UDP, sock_xinfo, column_id, str);
     897  }
     898  
     899  static const struct l4_xinfo_class udp_xinfo_class = {
     900  	.sock = {
     901  		.get_name = udp_get_name,
     902  		.get_type = udp_get_type,
     903  		.get_state = tcp_get_state,
     904  		.get_listening = NULL,
     905  		.fill_column = udp_fill_column,
     906  		.free = NULL,
     907  	},
     908  	.scan_line = tcp_xinfo_scan_line,
     909  	.get_addr = tcp_xinfo_get_addr,
     910  	.is_any_addr = tcp_xinfo_is_any_addr,
     911  	.family = AF_INET,
     912  	.l3_decorator = {"", ""},
     913  };
     914  
     915  static void load_xinfo_from_proc_udp(ino_t netns_inode)
     916  {
     917  	load_xinfo_from_proc_inet_L4(netns_inode,
     918  				     "/proc/net/udp",
     919  				     &udp_xinfo_class);
     920  }
     921  
     922  /*
     923   * UDP-Lite
     924   */
     925  static bool udplite_fill_column(struct proc *proc __attribute__((__unused__)),
     926  				struct sock_xinfo *sock_xinfo,
     927  				struct sock *sock __attribute__((__unused__)),
     928  				struct libscols_line *ln __attribute__((__unused__)),
     929  				int column_id,
     930  				size_t column_index __attribute__((__unused__)),
     931  				char **str)
     932  {
     933  	return l3_fill_column_handler(INET, sock_xinfo, column_id, str)
     934  		|| l4_fill_column_handler(UDPLITE, sock_xinfo, column_id, str);
     935  }
     936  
     937  static const struct l4_xinfo_class udplite_xinfo_class = {
     938  	.sock = {
     939  		.get_name = udp_get_name,
     940  		.get_type = udp_get_type,
     941  		.get_state = tcp_get_state,
     942  		.get_listening = NULL,
     943  		.fill_column = udplite_fill_column,
     944  		.free = NULL,
     945  	},
     946  	.scan_line = tcp_xinfo_scan_line,
     947  	.get_addr = tcp_xinfo_get_addr,
     948  	.is_any_addr = tcp_xinfo_is_any_addr,
     949  	.family = AF_INET,
     950  	.l3_decorator = {"", ""},
     951  };
     952  
     953  static void load_xinfo_from_proc_udplite(ino_t netns_inode)
     954  {
     955  	load_xinfo_from_proc_inet_L4(netns_inode,
     956  				     "/proc/net/udplite",
     957  				     &udplite_xinfo_class);
     958  }
     959  
     960  /*
     961   * RAW
     962   */
     963  struct raw_xinfo {
     964  	struct l4_xinfo l4;
     965  	uint16_t protocol;
     966  };
     967  
     968  static char *raw_get_name_common(struct sock_xinfo *sock_xinfo,
     969  				 struct sock *sock  __attribute__((__unused__)),
     970  				 const char *port_label)
     971  {
     972  	char *str = NULL;
     973  	struct l4_xinfo_class *class = (struct l4_xinfo_class *)sock_xinfo->class;
     974  	struct raw_xinfo *raw = ((struct raw_xinfo *)sock_xinfo);
     975  	struct l4_xinfo *l4 = &raw->l4;
     976  	const char *st_str = l4_decode_state(l4->st);
     977  	void *laddr = class->get_addr(l4, L4_LOCAL);
     978  	void *raddr = class->get_addr(l4, L4_REMOTE);
     979  	char local_s[BUFSIZ];
     980  	char remote_s[BUFSIZ];
     981  
     982  	if (!inet_ntop(class->family, laddr, local_s, sizeof(local_s)))
     983  		xasprintf(&str, "state=%s", st_str);
     984  	else if (class->is_any_addr(raddr)
     985  		 || !inet_ntop(class->family, raddr, remote_s, sizeof(remote_s)))
     986  		xasprintf(&str, "state=%s %s=%"PRIu16" laddr=%s",
     987  			  st_str,
     988  			  port_label,
     989  			  raw->protocol, local_s);
     990  	else
     991  		xasprintf(&str, "state=%s %s=%"PRIu16" laddr=%s raddr=%s",
     992  			  st_str,
     993  			  port_label,
     994  			  raw->protocol, local_s, remote_s);
     995  	return str;
     996  }
     997  
     998  static char *raw_get_name(struct sock_xinfo *sock_xinfo,
     999  			  struct sock *sock  __attribute__((__unused__)))
    1000  {
    1001  	return raw_get_name_common(sock_xinfo, sock, "protocol");
    1002  }
    1003  
    1004  static char *raw_get_type(struct sock_xinfo *sock_xinfo __attribute__((__unused__)),
    1005  			  struct sock *sock __attribute__((__unused__)))
    1006  {
    1007  	return xstrdup("raw");
    1008  }
    1009  
    1010  static bool raw_fill_column(struct proc *proc __attribute__((__unused__)),
    1011  			    struct sock_xinfo *sock_xinfo,
    1012  			    struct sock *sock __attribute__((__unused__)),
    1013  			    struct libscols_line *ln __attribute__((__unused__)),
    1014  			    int column_id,
    1015  			    size_t column_index __attribute__((__unused__)),
    1016  			    char **str)
    1017  {
    1018  	if (l3_fill_column_handler(INET, sock_xinfo, column_id, str))
    1019  		return true;
    1020  
    1021  	if (column_id == COL_RAW_PROTOCOL) {
    1022  		xasprintf(str, "%"PRIu16,
    1023  			  ((struct raw_xinfo *)sock_xinfo)->protocol);
    1024  		return true;
    1025  	}
    1026  
    1027  	return false;
    1028  }
    1029  
    1030  static struct sock_xinfo *raw_xinfo_scan_line(const struct sock_xinfo_class *class,
    1031  					      char * line,
    1032  					      ino_t netns_inode,
    1033  					      enum sysfs_byteorder byteorder)
    1034  {
    1035  	unsigned long local_addr;
    1036  	unsigned long protocol;
    1037  	unsigned long remote_addr;
    1038  	unsigned long st;
    1039  	unsigned long long inode;
    1040  	struct raw_xinfo *raw;
    1041  	struct inet_xinfo *inet;
    1042  	struct sock_xinfo *sock;
    1043  
    1044  	if (sscanf(line, "%*d: %lx:%lx %lx:%*x %lx %*x:%*x %*x:%*x %*x %*u %*u %lld",
    1045  		   &local_addr, &protocol, &remote_addr,
    1046  		   &st, &inode) != 5)
    1047  		return NULL;
    1048  
    1049  	if (inode == 0)
    1050  		return NULL;
    1051  
    1052  	raw = xcalloc(1, sizeof(*raw));
    1053  	inet = &raw->l4.inet;
    1054  	sock = &inet->sock;
    1055  	sock->class = class;
    1056  	sock->inode = (ino_t)inode;
    1057  	sock->netns_inode = netns_inode;
    1058  	inet->local_addr.s_addr = kernel32_to_cpu(byteorder, local_addr);
    1059  	inet->remote_addr.s_addr = kernel32_to_cpu(byteorder, remote_addr);
    1060  	raw->protocol = protocol;
    1061  	raw->l4.st = st;
    1062  
    1063  	return sock;
    1064  }
    1065  
    1066  static const struct l4_xinfo_class raw_xinfo_class = {
    1067  	.sock = {
    1068  		.get_name = raw_get_name,
    1069  		.get_type = raw_get_type,
    1070  		.get_state = tcp_get_state,
    1071  		.get_listening = NULL,
    1072  		.fill_column = raw_fill_column,
    1073  		.free = NULL,
    1074  	},
    1075  	.scan_line = raw_xinfo_scan_line,
    1076  	.get_addr = tcp_xinfo_get_addr,
    1077  	.is_any_addr = tcp_xinfo_is_any_addr,
    1078  	.family = AF_INET,
    1079  	.l3_decorator = {"", ""},
    1080  };
    1081  
    1082  static void load_xinfo_from_proc_raw(ino_t netns_inode)
    1083  {
    1084  	load_xinfo_from_proc_inet_L4(netns_inode,
    1085  				     "/proc/net/raw",
    1086  				     &raw_xinfo_class);
    1087  }
    1088  
    1089  /*
    1090   * PING
    1091   */
    1092  static char *ping_get_name(struct sock_xinfo *sock_xinfo,
    1093  			  struct sock *sock  __attribute__((__unused__)))
    1094  {
    1095  	return raw_get_name_common(sock_xinfo, sock, "id");
    1096  }
    1097  
    1098  static char *ping_get_type(struct sock_xinfo *sock_xinfo __attribute__((__unused__)),
    1099  			   struct sock *sock __attribute__((__unused__)))
    1100  {
    1101  	return xstrdup("dgram");
    1102  }
    1103  
    1104  static bool ping_fill_column(struct proc *proc __attribute__((__unused__)),
    1105  			     struct sock_xinfo *sock_xinfo,
    1106  			     struct sock *sock __attribute__((__unused__)),
    1107  			     struct libscols_line *ln __attribute__((__unused__)),
    1108  			     int column_id,
    1109  			     size_t column_index __attribute__((__unused__)),
    1110  			     char **str)
    1111  {
    1112  	if (l3_fill_column_handler(INET, sock_xinfo, column_id, str))
    1113  		return true;
    1114  
    1115  	if (column_id == COL_PING_ID) {
    1116  		xasprintf(str, "%"PRIu16,
    1117  			  ((struct raw_xinfo *)sock_xinfo)->protocol);
    1118  		return true;
    1119  	}
    1120  
    1121  	return false;
    1122  }
    1123  
    1124  static const struct l4_xinfo_class ping_xinfo_class = {
    1125  	.sock = {
    1126  		.get_name = ping_get_name,
    1127  		.get_type = ping_get_type,
    1128  		.get_state = tcp_get_state,
    1129  		.get_listening = NULL,
    1130  		.fill_column = ping_fill_column,
    1131  		.free = NULL,
    1132  	},
    1133  	.scan_line = raw_xinfo_scan_line,
    1134  	.get_addr = tcp_xinfo_get_addr,
    1135  	.is_any_addr = tcp_xinfo_is_any_addr,
    1136  	.family = AF_INET,
    1137  	.l3_decorator = {"", ""},
    1138  };
    1139  
    1140  static void load_xinfo_from_proc_icmp(ino_t netns_inode)
    1141  {
    1142  	load_xinfo_from_proc_inet_L4(netns_inode,
    1143  				     "/proc/net/icmp",
    1144  				     &ping_xinfo_class);
    1145  }
    1146  
    1147  /*
    1148   * TCP6
    1149   */
    1150  static struct sock_xinfo *tcp6_xinfo_scan_line(const struct sock_xinfo_class *class,
    1151  					       char * line,
    1152  					       ino_t netns_inode,
    1153  					       enum sysfs_byteorder byteorder)
    1154  {
    1155  	uint32_t local_addr[4];
    1156  	unsigned int local_port;
    1157  	uint32_t remote_addr[4];
    1158  	unsigned int remote_port;
    1159  	unsigned int st;
    1160  	unsigned long inode;
    1161  	struct tcp_xinfo *tcp;
    1162  	struct inet6_xinfo *inet6;
    1163  	struct sock_xinfo *sock;
    1164  
    1165  	if (sscanf(line,
    1166  		   "%*d: "
    1167  		   "%08x%08x%08x%08x:%04x "
    1168  		   "%08x%08x%08x%08x:%04x "
    1169  		   "%x %*x:%*x %*x:%*x %*x %*u %*d %lu ",
    1170  		   local_addr+0, local_addr+1, local_addr+2, local_addr+3, &local_port,
    1171  		   remote_addr+0, remote_addr+1, remote_addr+2, remote_addr+3, &remote_port,
    1172  		   &st, &inode) != 12)
    1173  		return NULL;
    1174  
    1175  	if (inode == 0)
    1176  		return NULL;
    1177  
    1178  	tcp = xmalloc(sizeof(*tcp));
    1179  	inet6 = &tcp->l4.inet6;
    1180  	sock = &inet6->sock;
    1181  	sock->class = class;
    1182  	sock->inode = (ino_t)inode;
    1183  	sock->netns_inode = netns_inode;
    1184  	tcp->local_port = local_port;
    1185  	for (int i = 0; i < 4; i++) {
    1186  		inet6->local_addr.s6_addr32[i] = kernel32_to_cpu(byteorder, local_addr[i]);
    1187  		inet6->remote_addr.s6_addr32[i] = kernel32_to_cpu(byteorder, remote_addr[i]);
    1188  	}
    1189  	tcp->remote_port = remote_port;
    1190  	tcp->l4.st = st;
    1191  
    1192  	return sock;
    1193  }
    1194  
    1195  static bool tcp6_fill_column(struct proc *proc  __attribute__((__unused__)),
    1196  			     struct sock_xinfo *sock_xinfo,
    1197  			     struct sock *sock  __attribute__((__unused__)),
    1198  			     struct libscols_line *ln  __attribute__((__unused__)),
    1199  			     int column_id,
    1200  			     size_t column_index  __attribute__((__unused__)),
    1201  			     char **str)
    1202  {
    1203  	return l3_fill_column_handler(INET6, sock_xinfo, column_id, str)
    1204  		|| l4_fill_column_handler(TCP, sock_xinfo, column_id, str);
    1205  }
    1206  
    1207  static void *tcp6_xinfo_get_addr(struct l4_xinfo * l4, enum l4_side side)
    1208  {
    1209  	return (side == L4_LOCAL)
    1210  		? &l4->inet6.local_addr
    1211  		: &l4->inet6.remote_addr;
    1212  }
    1213  
    1214  static bool tcp6_xinfo_is_any_addr(void *addr)
    1215  {
    1216  	return IN6_ARE_ADDR_EQUAL(addr, &(struct in6_addr)IN6ADDR_ANY_INIT);
    1217  }
    1218  
    1219  static const struct l4_xinfo_class tcp6_xinfo_class = {
    1220  	.sock = {
    1221  		.get_name = tcp_get_name,
    1222  		.get_type = tcp_get_type,
    1223  		.get_state = tcp_get_state,
    1224  		.get_listening = tcp_get_listening,
    1225  		.fill_column = tcp6_fill_column,
    1226  		.free = NULL,
    1227  	},
    1228  	.scan_line = tcp6_xinfo_scan_line,
    1229  	.get_addr = tcp6_xinfo_get_addr,
    1230  	.is_any_addr = tcp6_xinfo_is_any_addr,
    1231  	.family = AF_INET6,
    1232  	.l3_decorator = {"[", "]"},
    1233  };
    1234  
    1235  static void load_xinfo_from_proc_tcp6(ino_t netns_inode)
    1236  {
    1237  	load_xinfo_from_proc_inet_L4(netns_inode,
    1238  				     "/proc/net/tcp6",
    1239  				     &tcp6_xinfo_class);
    1240  }
    1241  
    1242  /*
    1243   * UDP6
    1244   */
    1245  static bool udp6_fill_column(struct proc *proc  __attribute__((__unused__)),
    1246  			     struct sock_xinfo *sock_xinfo,
    1247  			     struct sock *sock  __attribute__((__unused__)),
    1248  			     struct libscols_line *ln  __attribute__((__unused__)),
    1249  			     int column_id,
    1250  			     size_t column_index  __attribute__((__unused__)),
    1251  			     char **str)
    1252  {
    1253  	return l3_fill_column_handler(INET6, sock_xinfo, column_id, str)
    1254  		|| l4_fill_column_handler(UDP, sock_xinfo, column_id, str);
    1255  }
    1256  
    1257  static const struct l4_xinfo_class udp6_xinfo_class = {
    1258  	.sock = {
    1259  		.get_name = udp_get_name,
    1260  		.get_type = udp_get_type,
    1261  		.get_state = tcp_get_state,
    1262  		.get_listening = NULL,
    1263  		.fill_column = udp6_fill_column,
    1264  		.free = NULL,
    1265  	},
    1266  	.scan_line = tcp6_xinfo_scan_line,
    1267  	.get_addr = tcp6_xinfo_get_addr,
    1268  	.is_any_addr = tcp6_xinfo_is_any_addr,
    1269  	.family = AF_INET6,
    1270  	.l3_decorator = {"[", "]"},
    1271  };
    1272  
    1273  static void load_xinfo_from_proc_udp6(ino_t netns_inode)
    1274  {
    1275  	load_xinfo_from_proc_inet_L4(netns_inode,
    1276  				     "/proc/net/udp6",
    1277  				     &udp6_xinfo_class);
    1278  }
    1279  
    1280  /*
    1281   * UDPLITEv6
    1282   */
    1283  static bool udplite6_fill_column(struct proc *proc __attribute__((__unused__)),
    1284  				 struct sock_xinfo *sock_xinfo,
    1285  				 struct sock *sock __attribute__((__unused__)),
    1286  				 struct libscols_line *ln __attribute__((__unused__)),
    1287  				 int column_id,
    1288  				 size_t column_index __attribute__((__unused__)),
    1289  				 char **str)
    1290  {
    1291  	return l3_fill_column_handler(INET6, sock_xinfo, column_id, str)
    1292  		|| l4_fill_column_handler(UDPLITE, sock_xinfo, column_id, str);
    1293  }
    1294  
    1295  static const struct l4_xinfo_class udplite6_xinfo_class = {
    1296  	.sock = {
    1297  		.get_name = udp_get_name,
    1298  		.get_type = udp_get_type,
    1299  		.get_state = tcp_get_state,
    1300  		.get_listening = NULL,
    1301  		.fill_column = udplite6_fill_column,
    1302  		.free = NULL,
    1303  	},
    1304  	.scan_line = tcp6_xinfo_scan_line,
    1305  	.get_addr = tcp6_xinfo_get_addr,
    1306  	.is_any_addr = tcp6_xinfo_is_any_addr,
    1307  	.family = AF_INET6,
    1308  	.l3_decorator = {"[", "]"},
    1309  };
    1310  
    1311  static void load_xinfo_from_proc_udplite6(ino_t netns_inode)
    1312  {
    1313  	load_xinfo_from_proc_inet_L4(netns_inode,
    1314  				     "/proc/net/udplite6",
    1315  				     &udplite6_xinfo_class);
    1316  }
    1317  
    1318  /*
    1319   * RAW6
    1320   */
    1321  static struct sock_xinfo *raw6_xinfo_scan_line(const struct sock_xinfo_class *class,
    1322  					       char * line,
    1323  					       ino_t netns_inode,
    1324  					       enum sysfs_byteorder byteorder)
    1325  {
    1326  	uint32_t local_addr[4];
    1327  	unsigned int protocol;
    1328  	uint32_t remote_addr[4];
    1329  	unsigned int st;
    1330  	unsigned long inode;
    1331  	struct raw_xinfo *raw;
    1332  	struct inet6_xinfo *inet6;
    1333  	struct sock_xinfo *sock;
    1334  
    1335  	if (sscanf(line,
    1336  		   "%*d: "
    1337  		   "%08x%08x%08x%08x:%04x "
    1338  		   "%08x%08x%08x%08x:0000 "
    1339  		   "%x %*x:%*x %*x:%*x %*x %*u %*d %lu ",
    1340  		   local_addr+0, local_addr+1, local_addr+2, local_addr+3, &protocol,
    1341  		   remote_addr+0, remote_addr+1, remote_addr+2, remote_addr+3,
    1342  		   &st, &inode) != 11)
    1343  		return NULL;
    1344  
    1345  	if (inode == 0)
    1346  		return NULL;
    1347  
    1348  	raw = xmalloc(sizeof(*raw));
    1349  	inet6 = &raw->l4.inet6;
    1350  	sock = &inet6->sock;
    1351  	sock->class = class;
    1352  	sock->inode = (ino_t)inode;
    1353  	sock->netns_inode = netns_inode;
    1354  	for (int i = 0; i < 4; i++) {
    1355  		inet6->local_addr.s6_addr32[i] = kernel32_to_cpu(byteorder, local_addr[i]);
    1356  		inet6->remote_addr.s6_addr32[i] = kernel32_to_cpu(byteorder, remote_addr[i]);
    1357  	}
    1358  	raw->protocol = protocol;
    1359  	raw->l4.st = st;
    1360  
    1361  	return sock;
    1362  }
    1363  
    1364  static bool raw6_fill_column(struct proc *proc  __attribute__((__unused__)),
    1365  			     struct sock_xinfo *sock_xinfo,
    1366  			     struct sock *sock  __attribute__((__unused__)),
    1367  			     struct libscols_line *ln  __attribute__((__unused__)),
    1368  			     int column_id,
    1369  			     size_t column_index  __attribute__((__unused__)),
    1370  			     char **str)
    1371  {
    1372  	struct raw_xinfo *raw;
    1373  
    1374  	if (l3_fill_column_handler(INET6, sock_xinfo, column_id, str))
    1375  		return true;
    1376  
    1377  	raw = (struct raw_xinfo *)sock_xinfo;
    1378  	if (column_id == COL_RAW_PROTOCOL) {
    1379  		xasprintf(str, "%"PRIu16, raw->protocol);
    1380  		return true;
    1381  	}
    1382  
    1383  	return false;
    1384  }
    1385  
    1386  static const struct l4_xinfo_class raw6_xinfo_class = {
    1387  	.sock = {
    1388  		.get_name = raw_get_name,
    1389  		.get_type = raw_get_type,
    1390  		.get_state = tcp_get_state,
    1391  		.get_listening = NULL,
    1392  		.fill_column = raw6_fill_column,
    1393  		.free = NULL,
    1394  	},
    1395  	.scan_line = raw6_xinfo_scan_line,
    1396  	.get_addr = tcp6_xinfo_get_addr,
    1397  	.is_any_addr = tcp6_xinfo_is_any_addr,
    1398  	.family = AF_INET6,
    1399  	.l3_decorator = {"[", "]"},
    1400  };
    1401  
    1402  static void load_xinfo_from_proc_raw6(ino_t netns_inode)
    1403  {
    1404  	load_xinfo_from_proc_inet_L4(netns_inode,
    1405  				     "/proc/net/raw6",
    1406  				     &raw6_xinfo_class);
    1407  }
    1408  
    1409  /*
    1410   * PINGv6
    1411   */
    1412  static bool ping6_fill_column(struct proc *proc __attribute__((__unused__)),
    1413  			     struct sock_xinfo *sock_xinfo,
    1414  			     struct sock *sock __attribute__((__unused__)),
    1415  			     struct libscols_line *ln __attribute__((__unused__)),
    1416  			     int column_id,
    1417  			     size_t column_index __attribute__((__unused__)),
    1418  			     char **str)
    1419  {
    1420  	if (l3_fill_column_handler(INET6, sock_xinfo, column_id, str))
    1421  		return true;
    1422  
    1423  	if (column_id == COL_PING_ID) {
    1424  		xasprintf(str, "%"PRIu16,
    1425  			  ((struct raw_xinfo *)sock_xinfo)->protocol);
    1426  		return true;
    1427  	}
    1428  
    1429  	return false;
    1430  }
    1431  
    1432  static const struct l4_xinfo_class ping6_xinfo_class = {
    1433  	.sock = {
    1434  		.get_name = ping_get_name,
    1435  		.get_type = ping_get_type,
    1436  		.get_state = tcp_get_state,
    1437  		.get_listening = NULL,
    1438  		.fill_column = ping6_fill_column,
    1439  		.free = NULL,
    1440  	},
    1441  	.scan_line = raw6_xinfo_scan_line,
    1442  	.get_addr = tcp6_xinfo_get_addr,
    1443  	.is_any_addr = tcp6_xinfo_is_any_addr,
    1444  	.family = AF_INET6,
    1445  	.l3_decorator = {"[", "]"},
    1446  };
    1447  
    1448  static void load_xinfo_from_proc_icmp6(ino_t netns_inode)
    1449  {
    1450  	load_xinfo_from_proc_inet_L4(netns_inode,
    1451  				     "/proc/net/icmp6",
    1452  				     &ping6_xinfo_class);
    1453  }
    1454  
    1455  /*
    1456   * NETLINK
    1457   */
    1458  struct netlink_xinfo {
    1459  	struct sock_xinfo sock;
    1460  	uint16_t protocol;
    1461  	uint32_t lportid;	/* netlink_diag may provide rportid.  */
    1462  	uint32_t groups;
    1463  };
    1464  
    1465  static const char *netlink_decode_protocol(uint16_t protocol)
    1466  {
    1467  	switch (protocol) {
    1468  	case NETLINK_ROUTE:
    1469  		return "route";
    1470  	case NETLINK_UNUSED:
    1471  		return "unused";
    1472  	case NETLINK_USERSOCK:
    1473  		return "usersock";
    1474  	case NETLINK_FIREWALL:
    1475  		return "firewall";
    1476  	case NETLINK_SOCK_DIAG:
    1477  		return "sock_diag";
    1478  	case NETLINK_NFLOG:
    1479  		return "nflog";
    1480  	case NETLINK_XFRM:
    1481  		return "xfrm";
    1482  	case NETLINK_SELINUX:
    1483  		return "selinux";
    1484  	case NETLINK_ISCSI:
    1485  		return "iscsi";
    1486  	case NETLINK_AUDIT:
    1487  		return "audit";
    1488  	case NETLINK_FIB_LOOKUP:
    1489  		return "fib_lookup";
    1490  	case NETLINK_CONNECTOR:
    1491  		return "connector";
    1492  	case NETLINK_NETFILTER:
    1493  		return "netfilter";
    1494  	case NETLINK_IP6_FW:
    1495  		return "ip6_fw";
    1496  	case NETLINK_DNRTMSG:
    1497  		return "dnrtmsg";
    1498  	case NETLINK_KOBJECT_UEVENT:
    1499  		return "kobject_uevent";
    1500  	case NETLINK_GENERIC:
    1501  		return "generic";
    1502  	case NETLINK_SCSITRANSPORT:
    1503  		return "scsitransport";
    1504  	case NETLINK_ECRYPTFS:
    1505  		return "ecryptfs";
    1506  	case NETLINK_RDMA:
    1507  		return "rdma";
    1508  	case NETLINK_CRYPTO:
    1509  		return "crypto";
    1510  #ifdef NETLINK_SMC
    1511  	case NETLINK_SMC:
    1512  		return "smc";
    1513  #endif
    1514  	default:
    1515  		return "unknown";
    1516  	}
    1517  }
    1518  
    1519  static char *netlink_get_name(struct sock_xinfo *sock_xinfo,
    1520  			      struct sock *sock __attribute__((__unused__)))
    1521  {
    1522  	struct netlink_xinfo *nl = (struct netlink_xinfo *)sock_xinfo;
    1523  	char *str = NULL;
    1524  	const char *protocol = netlink_decode_protocol(nl->protocol);
    1525  
    1526  	if (nl->groups)
    1527  		xasprintf(&str, "protocol=%s lport=%"PRIu16 " groups=%"PRIu32,
    1528  			  protocol,
    1529  			  nl->lportid, nl->groups);
    1530  	else
    1531  		xasprintf(&str, "protocol=%s lport=%"PRIu16,
    1532  			  protocol,
    1533  			  nl->lportid);
    1534  	return str;
    1535  }
    1536  
    1537  static char *netlink_get_type(struct sock_xinfo *sock_xinfo __attribute__((__unused__)),
    1538  			      struct sock *sock __attribute__((__unused__)))
    1539  {
    1540  	return xstrdup("raw");
    1541  }
    1542  
    1543  static bool netlink_fill_column(struct proc *proc __attribute__((__unused__)),
    1544  				struct sock_xinfo *sock_xinfo,
    1545  				struct sock *sock __attribute__((__unused__)),
    1546  				struct libscols_line *ln __attribute__((__unused__)),
    1547  				int column_id,
    1548  				size_t column_index __attribute__((__unused__)),
    1549  				char **str)
    1550  {
    1551  	struct netlink_xinfo *nl = (struct netlink_xinfo *)sock_xinfo;
    1552  
    1553  	switch (column_id) {
    1554  	case COL_NETLINK_GROUPS:
    1555  		xasprintf(str, "%"PRIu32, nl->groups);
    1556  		return true;
    1557  	case COL_NETLINK_LPORT:
    1558  		xasprintf(str, "%"PRIu32, nl->lportid);
    1559  		return true;
    1560  	case COL_NETLINK_PROTOCOL:
    1561  		*str = xstrdup(netlink_decode_protocol(nl->protocol));
    1562  		return true;
    1563  	}
    1564  
    1565  	return false;
    1566  }
    1567  
    1568  static const struct sock_xinfo_class netlink_xinfo_class = {
    1569  	.get_name = netlink_get_name,
    1570  	.get_type = netlink_get_type,
    1571  	.get_state = NULL,
    1572  	.get_listening = NULL,
    1573  	.fill_column = netlink_fill_column,
    1574  	.free = NULL,
    1575  };
    1576  
    1577  static void load_xinfo_from_proc_netlink(ino_t netns_inode)
    1578  {
    1579  	char line[BUFSIZ];
    1580  	FILE *netlink_fp;
    1581  
    1582  	netlink_fp = fopen("/proc/net/netlink", "r");
    1583  	if (!netlink_fp)
    1584  		return;
    1585  
    1586  	if (fgets(line, sizeof(line), netlink_fp) == NULL)
    1587  		goto out;
    1588  	if (!(line[0] == 's' && line[1] == 'k'))
    1589  		/* Unexpected line */
    1590  		goto out;
    1591  
    1592  	while (fgets(line, sizeof(line), netlink_fp)) {
    1593  		uint16_t protocol;
    1594  		uint32_t lportid;
    1595  		uint32_t groups;
    1596  		unsigned long inode;
    1597  		struct netlink_xinfo *nl;
    1598  
    1599  		if (sscanf(line, "%*x %" SCNu16 " %" SCNu32 " %" SCNx32 " %*d %*d %*d %*d %*u %lu",
    1600  			   &protocol, &lportid, &groups, &inode) < 4)
    1601  			continue;
    1602  
    1603  		if (inode == 0)
    1604  			continue;
    1605  
    1606  		nl = xcalloc(1, sizeof(*nl));
    1607  		nl->sock.class = &netlink_xinfo_class;
    1608  		nl->sock.inode = (ino_t)inode;
    1609  		nl->sock.netns_inode = netns_inode;
    1610  
    1611  		nl->protocol = protocol;
    1612  		nl->lportid = lportid;
    1613  		nl->groups = groups;
    1614  
    1615  		add_sock_info(&nl->sock);
    1616  	}
    1617  
    1618   out:
    1619  	fclose(netlink_fp);
    1620  }
    1621  
    1622  /*
    1623   * PACKET
    1624   */
    1625  struct packet_xinfo {
    1626  	struct sock_xinfo sock;
    1627  	uint16_t type;
    1628  	uint16_t protocol;
    1629  	unsigned int iface;
    1630  };
    1631  
    1632  static const char *packet_decode_protocol(uint16_t proto)
    1633  {
    1634  	switch (proto) {
    1635  	case 0:
    1636  		return NULL;
    1637  	case ETH_P_802_3:
    1638  		return "802_3";
    1639  	case ETH_P_AX25:
    1640  		return "ax25";
    1641  	case ETH_P_ALL:
    1642  		return "all";
    1643  	case ETH_P_802_2:
    1644  		return "802_2";
    1645  	case ETH_P_SNAP:
    1646  		return "snap";
    1647  	case ETH_P_DDCMP:
    1648  		return "ddcmp";
    1649  	case ETH_P_WAN_PPP:
    1650  		return "wan_ppp";
    1651  	case ETH_P_PPP_MP:
    1652  		return "ppp_mp";
    1653  	case ETH_P_LOCALTALK:
    1654  		return "localtalk";
    1655  	case ETH_P_CAN:
    1656  		return "can";
    1657  	case ETH_P_CANFD:
    1658  		return "canfd";
    1659  #ifdef ETH_P_CANXL
    1660  	case ETH_P_CANXL:
    1661  		return "canxl";
    1662  #endif
    1663  	case ETH_P_PPPTALK:
    1664  		return "ppptalk";
    1665  	case ETH_P_TR_802_2:
    1666  		return "tr_802_2";
    1667  	case ETH_P_MOBITEX:
    1668  		return "mobitex";
    1669  	case ETH_P_CONTROL:
    1670  		return "control";
    1671  	case ETH_P_IRDA:
    1672  		return "irda";
    1673  	case ETH_P_ECONET:
    1674  		return "econet";
    1675  	case ETH_P_HDLC:
    1676  		return "hdlc";
    1677  	case ETH_P_ARCNET:
    1678  		return "arcnet";
    1679  	case ETH_P_DSA:
    1680  		return "dsa";
    1681  	case ETH_P_TRAILER:
    1682  		return "trailer";
    1683  	case ETH_P_PHONET:
    1684  		return "phonet";
    1685  	case ETH_P_IEEE802154:
    1686  		return "ieee802154";
    1687  	case ETH_P_CAIF:
    1688  		return "caif";
    1689  #ifdef ETH_P_XDSA
    1690  	case ETH_P_XDSA:
    1691  		return "xdsa";
    1692  #endif
    1693  #ifdef ETH_P_MAP
    1694  	case ETH_P_MAP:
    1695  		return "map";
    1696  #endif
    1697  #ifdef ETH_P_MCTP
    1698  	case ETH_P_MCTP:
    1699  		return "mctp";
    1700  #endif
    1701  	case ETH_P_LOOP:
    1702  		return "loop";
    1703  	case ETH_P_PUP:
    1704  		return "pup";
    1705  	case ETH_P_PUPAT:
    1706  		return "pupat";
    1707  #ifdef ETH_P_TSN
    1708  	case ETH_P_TSN:
    1709  		return "tsn";
    1710  #endif
    1711  #ifdef ETH_P_ERSPAN2
    1712  	case ETH_P_ERSPAN2:
    1713  		return "erspan2";
    1714  #endif
    1715  	case ETH_P_IP:
    1716  		return "ip";
    1717  	case ETH_P_X25:
    1718  		return "x25";
    1719  	case ETH_P_ARP:
    1720  		return "arp";
    1721  	case ETH_P_BPQ:
    1722  		return "bpq";
    1723  	case ETH_P_IEEEPUP:
    1724  		return "ieeepup";
    1725  	case ETH_P_IEEEPUPAT:
    1726  		return "ieeepupat";
    1727  	case ETH_P_BATMAN:
    1728  		return "batman";
    1729  	case ETH_P_DEC:
    1730  		return "dec";
    1731  	case ETH_P_DNA_DL:
    1732  		return "dna_dl";
    1733  	case ETH_P_DNA_RC:
    1734  		return "dna_rc";
    1735  	case ETH_P_DNA_RT:
    1736  		return "dna_rt";
    1737  	case ETH_P_LAT:
    1738  		return "lat";
    1739  	case ETH_P_DIAG:
    1740  		return "diag";
    1741  	case ETH_P_CUST:
    1742  		return "cust";
    1743  	case ETH_P_SCA:
    1744  		return "sca";
    1745  	case ETH_P_TEB:
    1746  		return "teb";
    1747  	case ETH_P_RARP:
    1748  		return "rarp";
    1749  	case ETH_P_ATALK:
    1750  		return "atalk";
    1751  	case ETH_P_AARP:
    1752  		return "aarp";
    1753  	case ETH_P_8021Q:
    1754  		return "8021q";
    1755  #ifdef ETH_P_ERSPAN
    1756  	case ETH_P_ERSPAN:
    1757  		return "erspan";
    1758  #endif
    1759  	case ETH_P_IPX:
    1760  		return "ipx";
    1761  	case ETH_P_IPV6:
    1762  		return "ipv6";
    1763  	case ETH_P_PAUSE:
    1764  		return "pause";
    1765  	case ETH_P_SLOW:
    1766  		return "slow";
    1767  	case ETH_P_WCCP:
    1768  		return "wccp";
    1769  	case ETH_P_MPLS_UC:
    1770  		return "mpls_uc";
    1771  	case ETH_P_MPLS_MC:
    1772  		return "mpls_mc";
    1773  	case ETH_P_ATMMPOA:
    1774  		return "atmmpoa";
    1775  #ifdef ETH_P_PPP_DISC
    1776  	case ETH_P_PPP_DISC:
    1777  		return "ppp_disc";
    1778  #endif
    1779  #ifdef ETH_P_PPP_SES
    1780  	case ETH_P_PPP_SES:
    1781  		return "ppp_ses";
    1782  #endif
    1783  	case ETH_P_LINK_CTL:
    1784  		return "link_ctl";
    1785  	case ETH_P_ATMFATE:
    1786  		return "atmfate";
    1787  	case ETH_P_PAE:
    1788  		return "pae";
    1789  #ifdef ETH_P_PROFINET
    1790  	case ETH_P_PROFINET:
    1791  		return "profinet";
    1792  #endif
    1793  #ifdef ETH_P_REALTEK
    1794  	case ETH_P_REALTEK:
    1795  		return "realtek";
    1796  #endif
    1797  	case ETH_P_AOE:
    1798  		return "aoe";
    1799  #ifdef ETH_P_ETHERCAT
    1800  	case ETH_P_ETHERCAT:
    1801  		return "ethercat";
    1802  #endif
    1803  	case ETH_P_8021AD:
    1804  		return "8021ad";
    1805  	case ETH_P_802_EX1:
    1806  		return "802_ex1";
    1807  #ifdef ETH_P_PREAUTH
    1808  	case ETH_P_PREAUTH:
    1809  		return "preauth";
    1810  #endif
    1811  	case ETH_P_TIPC:
    1812  		return "tipc";
    1813  #ifdef ETH_P_LLDP
    1814  	case ETH_P_LLDP:
    1815  		return "lldp";
    1816  #endif
    1817  #ifdef ETH_P_MRP
    1818  	case ETH_P_MRP:
    1819  		return "mrp";
    1820  #endif
    1821  #ifdef ETH_P_MACSEC
    1822  	case ETH_P_MACSEC:
    1823  		return "macsec";
    1824  #endif
    1825  	case ETH_P_8021AH:
    1826  		return "8021ah";
    1827  #ifdef ETH_P_MVRP
    1828  	case ETH_P_MVRP:
    1829  		return "mvrp";
    1830  #endif
    1831  	case ETH_P_1588:
    1832  		return "1588";
    1833  #ifdef ETH_P_NCSI
    1834  	case ETH_P_NCSI:
    1835  		return "ncsi";
    1836  #endif
    1837  #ifdef ETH_P_PRP
    1838  	case ETH_P_PRP:
    1839  		return "prp";
    1840  #endif
    1841  #ifdef ETH_P_CFM
    1842  	case ETH_P_CFM:
    1843  		return "cfm";
    1844  #endif
    1845  	case ETH_P_FCOE:
    1846  		return "fcoe";
    1847  #ifdef ETH_P_IBOE
    1848  	case ETH_P_IBOE:
    1849  		return "iboe";
    1850  #endif
    1851  	case ETH_P_TDLS:
    1852  		return "tdls";
    1853  	case ETH_P_FIP:
    1854  		return "fip";
    1855  #ifdef ETH_P_80221
    1856  	case ETH_P_80221:
    1857  		return "80221";
    1858  #endif
    1859  #ifdef ETH_P_HSR
    1860  	case ETH_P_HSR:
    1861  		return "hsr";
    1862  #endif
    1863  #ifdef ETH_P_NSH
    1864  	case ETH_P_NSH:
    1865  		return "nsh";
    1866  #endif
    1867  #ifdef ETH_P_LOOPBACK
    1868  	case ETH_P_LOOPBACK:
    1869  		return "loopback";
    1870  #endif
    1871  	case ETH_P_QINQ1:
    1872  		return "qinq1";
    1873  	case ETH_P_QINQ2:
    1874  		return "qinq2";
    1875  	case ETH_P_QINQ3:
    1876  		return "qinq3";
    1877  	case ETH_P_EDSA:
    1878  		return "edsa";
    1879  #ifdef ETH_P_DSA_8021Q
    1880  	case ETH_P_DSA_8021Q:
    1881  		return "dsa_8021q";
    1882  #endif
    1883  #ifdef ETH_P_DSA_A5PSW
    1884  	case ETH_P_DSA_A5PSW:
    1885  		return "dsa_a5psw";
    1886  #endif
    1887  #ifdef ETH_P_IFE
    1888  	case ETH_P_IFE:
    1889  		return "ife";
    1890  #endif
    1891  	case ETH_P_AF_IUCV:
    1892  		return "af_iucv";
    1893  #ifdef ETH_P_802_3_MIN
    1894  	case ETH_P_802_3_MIN:
    1895  		return "802_3_min";
    1896  #endif
    1897  	default:
    1898  		return "unknown";
    1899  	}
    1900  }
    1901  
    1902  static char *packet_get_name(struct sock_xinfo *sock_xinfo,
    1903  			     struct sock *sock __attribute__((__unused__)))
    1904  {
    1905  	struct packet_xinfo *pkt = (struct packet_xinfo *)sock_xinfo;
    1906  	char *str = NULL;
    1907  	const char *type = sock_decode_type(pkt->type);
    1908  	const char *proto = packet_decode_protocol(pkt->protocol);
    1909  	const char *iface = get_iface_name(sock_xinfo->netns_inode,
    1910  					   pkt->iface);
    1911  
    1912  	if (iface && proto)
    1913  		xasprintf(&str, "type=%s protocol=%s iface=%s",
    1914  			  type, proto, iface);
    1915  	else if (proto)
    1916  		xasprintf(&str, "type=%s protocol=%s",
    1917  			  type, proto);
    1918  	else if (iface)
    1919  		xasprintf(&str, "type=%s iface=%s",
    1920  			  type, iface);
    1921  	else
    1922  		xasprintf(&str, "type=%s", type);
    1923  
    1924  	return str;
    1925  }
    1926  
    1927  static char *packet_get_type(struct sock_xinfo *sock_xinfo __attribute__((__unused__)),
    1928  			     struct sock *sock __attribute__((__unused__)))
    1929  {
    1930  	const char *str;
    1931  	struct packet_xinfo *pkt = (struct packet_xinfo *)sock_xinfo;
    1932  
    1933  	str = sock_decode_type(pkt->type);
    1934  	return xstrdup(str);
    1935  }
    1936  
    1937  static bool packet_fill_column(struct proc *proc __attribute__((__unused__)),
    1938  			       struct sock_xinfo *sock_xinfo,
    1939  			       struct sock *sock __attribute__((__unused__)),
    1940  			       struct libscols_line *ln __attribute__((__unused__)),
    1941  			       int column_id,
    1942  			       size_t column_index __attribute__((__unused__)),
    1943  			       char **str)
    1944  {
    1945  	struct packet_xinfo *pkt = (struct packet_xinfo *)sock_xinfo;
    1946  
    1947  	switch (column_id) {
    1948  	case COL_PACKET_IFACE: {
    1949  		const char *iface;
    1950  		iface = get_iface_name(sock_xinfo->netns_inode,
    1951  				       pkt->iface);
    1952  		if (iface) {
    1953  			*str = xstrdup(iface);
    1954  			return true;
    1955  		}
    1956  		break;
    1957  	}
    1958  	case COL_PACKET_PROTOCOL: {
    1959  		const char *proto;
    1960  		proto = packet_decode_protocol(pkt->protocol);
    1961  		if (proto) {
    1962  			*str = xstrdup(proto);
    1963  			return true;
    1964  		}
    1965  		break;
    1966  	}
    1967  	default:
    1968  		break;
    1969  	}
    1970  	return false;
    1971  }
    1972  
    1973  static const struct sock_xinfo_class packet_xinfo_class = {
    1974  	.get_name = packet_get_name,
    1975  	.get_type = packet_get_type,
    1976  	.get_state = NULL,
    1977  	.get_listening = NULL,
    1978  	.fill_column = packet_fill_column,
    1979  	.free = NULL,
    1980  };
    1981  
    1982  static void load_xinfo_from_proc_packet(ino_t netns_inode)
    1983  {
    1984  	char line[BUFSIZ];
    1985  	FILE *packet_fp;
    1986  
    1987  	packet_fp = fopen("/proc/net/packet", "r");
    1988  	if (!packet_fp)
    1989  		return;
    1990  
    1991  	if (fgets(line, sizeof(line), packet_fp) == NULL)
    1992  		goto out;
    1993  	if (!(line[0] == 's' && line[1] == 'k'))
    1994  		/* Unexpected line */
    1995  		goto out;
    1996  
    1997  	while (fgets(line, sizeof(line), packet_fp)) {
    1998  		uint16_t type;
    1999  		uint16_t protocol;
    2000  		unsigned int iface;
    2001  		unsigned long inode;
    2002  		struct packet_xinfo *pkt;
    2003  
    2004  		if (sscanf(line, "%*x %*d %" SCNu16 " %" SCNu16 " %u %*d %*d %*d %lu",
    2005  			   &type, &protocol, &iface, &inode) < 4)
    2006  			continue;
    2007  
    2008  		pkt = xcalloc(1, sizeof(*pkt));
    2009  		pkt->sock.class = &packet_xinfo_class;
    2010  		pkt->sock.inode = (ino_t)inode;
    2011  		pkt->sock.netns_inode = netns_inode;
    2012  
    2013  		pkt->type = type;
    2014  		pkt->protocol = protocol;
    2015  		pkt->iface = iface;
    2016  
    2017  		add_sock_info(&pkt->sock);
    2018  	}
    2019  
    2020   out:
    2021  	fclose(packet_fp);
    2022  }