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 }