1
2
3
4
5
6
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <unistd.h>
11#include <fcntl.h>
12#include <sys/ioctl.h>
13#include <sys/socket.h>
14#include <sys/uio.h>
15#include <sys/sysmacros.h>
16#include <netinet/in.h>
17#include <string.h>
18#include <errno.h>
19#include <netdb.h>
20#include <arpa/inet.h>
21#include <dirent.h>
22#include <fnmatch.h>
23#include <getopt.h>
24#include <stdbool.h>
25#include <limits.h>
26#include <stdarg.h>
27#include <ctype.h>
28
29#include "ss_util.h"
30#include "utils.h"
31#include "ll_map.h"
32#include "libnetlink.h"
33#include "namespace.h"
34#include "version.h"
35#include "rt_names.h"
36#include "cg_map.h"
37#include "selinux.h"
38
39#include <linux/tcp.h>
40#include <linux/unix_diag.h>
41#include <linux/netdevice.h>
42#include <linux/filter.h>
43#include <linux/xdp_diag.h>
44#include <linux/packet_diag.h>
45#include <linux/netlink_diag.h>
46#include <linux/sctp.h>
47#include <linux/vm_sockets_diag.h>
48#include <linux/net.h>
49#include <linux/tipc.h>
50#include <linux/tipc_netlink.h>
51#include <linux/tipc_sockets_diag.h>
52#include <linux/tls.h>
53#include <linux/mptcp.h>
54
55#ifdef HAVE_LIBBPF
56
57
58
59
60
61
62#define ENABLE_BPF_SKSTORAGE_SUPPORT
63
64#include <bpf/bpf.h>
65#include <bpf/btf.h>
66#include <bpf/libbpf.h>
67#include <linux/btf.h>
68
69#if ((LIBBPF_MAJOR_VERSION == 0) && (LIBBPF_MINOR_VERSION < 6))
70#warning "libbpf version 0.6 or later is required, disabling BPF socket-local storage support"
71#undef ENABLE_BPF_SKSTORAGE_SUPPORT
72#endif
73#endif
74
75#if HAVE_RPC
76#include <rpc/rpc.h>
77#include <rpc/xdr.h>
78#endif
79
80
81#ifndef PF_VSOCK
82#define PF_VSOCK 40
83#endif
84#ifndef AF_VSOCK
85#define AF_VSOCK PF_VSOCK
86#endif
87
88#ifndef IPPROTO_MPTCP
89#define IPPROTO_MPTCP 262
90#endif
91
92#define BUF_CHUNK (1024 * 1024)
93#define BUF_CHUNKS_MAX 5
94#define LEN_ALIGN(x) (((x) + 1) & ~1)
95
96int preferred_family = AF_UNSPEC;
97static int show_options;
98int show_details;
99static int show_queues = 1;
100static int show_processes;
101static int show_threads;
102static int show_mem;
103static int show_tcpinfo;
104static int show_bpf;
105static int show_proc_ctx;
106static int show_sock_ctx;
107static int show_header = 1;
108static int follow_events;
109static int sctp_ino;
110static int show_tipcinfo;
111static int show_tos;
112static int show_cgroup;
113static int show_inet_sockopt;
114int oneline;
115
116enum col_id {
117 COL_NETID,
118 COL_STATE,
119 COL_RECVQ,
120 COL_SENDQ,
121 COL_ADDR,
122 COL_SERV,
123 COL_RADDR,
124 COL_RSERV,
125 COL_PROC,
126 COL_EXT,
127 COL_MAX
128};
129
130enum col_align {
131 ALIGN_LEFT,
132 ALIGN_CENTER,
133 ALIGN_RIGHT
134};
135
136struct column {
137 const enum col_align align;
138 const char *header;
139 const char *ldelim;
140 int disabled;
141 int width;
142 int max_len;
143};
144
145static struct column columns[] = {
146 { ALIGN_LEFT, "Netid", "", 0, 0, 0 },
147 { ALIGN_LEFT, "State", " ", 0, 0, 0 },
148 { ALIGN_LEFT, "Recv-Q", " ", 0, 0, 0 },
149 { ALIGN_LEFT, "Send-Q", " ", 0, 0, 0 },
150 { ALIGN_RIGHT, "Local Address:", " ", 0, 0, 0 },
151 { ALIGN_LEFT, "Port", "", 0, 0, 0 },
152 { ALIGN_RIGHT, "Peer Address:", " ", 0, 0, 0 },
153 { ALIGN_LEFT, "Port", "", 0, 0, 0 },
154 { ALIGN_LEFT, "Process", "", 0, 0, 0 },
155 { ALIGN_LEFT, "", "", 0, 0, 0 },
156};
157
158static struct column *current_field = columns;
159
160
161
162
163
164
165
166
167struct buf_chunk {
168 struct buf_chunk *next;
169 char *end;
170 char data[0];
171};
172
173struct buf_token {
174 uint16_t len;
175 char data[0];
176};
177
178static struct {
179 struct buf_token *cur;
180 struct buf_chunk *head;
181 struct buf_chunk *tail;
182 int chunks;
183} buffer;
184
185static const char *TCP_PROTO = "tcp";
186static const char *UDP_PROTO = "udp";
187#ifdef HAVE_RPC
188static const char *TCP6_PROTO = "tcp6";
189static const char *UDP6_PROTO = "udp6";
190static const char *SCTP_PROTO = "sctp";
191#endif
192static const char *RAW_PROTO = "raw";
193static const char *dg_proto;
194
195enum {
196 TCP_DB,
197 MPTCP_DB,
198 DCCP_DB,
199 UDP_DB,
200 RAW_DB,
201 UNIX_DG_DB,
202 UNIX_ST_DB,
203 UNIX_SQ_DB,
204 PACKET_DG_DB,
205 PACKET_R_DB,
206 NETLINK_DB,
207 SCTP_DB,
208 VSOCK_ST_DB,
209 VSOCK_DG_DB,
210 TIPC_DB,
211 XDP_DB,
212 MAX_DB
213};
214
215#define PACKET_DBM ((1<<PACKET_DG_DB)|(1<<PACKET_R_DB))
216#define UNIX_DBM ((1<<UNIX_DG_DB)|(1<<UNIX_ST_DB)|(1<<UNIX_SQ_DB))
217#define ALL_DB ((1<<MAX_DB)-1)
218#define INET_L4_DBM ((1<<TCP_DB)|(1<<MPTCP_DB)|(1<<UDP_DB)|(1<<DCCP_DB)|(1<<SCTP_DB))
219#define INET_DBM (INET_L4_DBM | (1<<RAW_DB))
220#define VSOCK_DBM ((1<<VSOCK_ST_DB)|(1<<VSOCK_DG_DB))
221
222enum {
223 SS_UNKNOWN,
224 SS_ESTABLISHED,
225 SS_SYN_SENT,
226 SS_SYN_RECV,
227 SS_FIN_WAIT1,
228 SS_FIN_WAIT2,
229 SS_TIME_WAIT,
230 SS_CLOSE,
231 SS_CLOSE_WAIT,
232 SS_LAST_ACK,
233 SS_LISTEN,
234 SS_CLOSING,
235 SS_NEW_SYN_RECV,
236 SS_BOUND_INACTIVE,
237 SS_MAX
238};
239
240enum {
241 SCTP_STATE_CLOSED = 0,
242 SCTP_STATE_COOKIE_WAIT = 1,
243 SCTP_STATE_COOKIE_ECHOED = 2,
244 SCTP_STATE_ESTABLISHED = 3,
245 SCTP_STATE_SHUTDOWN_PENDING = 4,
246 SCTP_STATE_SHUTDOWN_SENT = 5,
247 SCTP_STATE_SHUTDOWN_RECEIVED = 6,
248 SCTP_STATE_SHUTDOWN_ACK_SENT = 7,
249};
250
251#define SS_ALL ((1 << SS_MAX) - 1)
252#define SS_CONN (SS_ALL & ~((1<<SS_LISTEN)|(1<<SS_CLOSE)|(1<<SS_TIME_WAIT)|(1<<SS_SYN_RECV)))
253#define TIPC_SS_CONN ((1<<SS_ESTABLISHED)|(1<<SS_LISTEN)|(1<<SS_CLOSE))
254
255#include "ssfilter.h"
256
257struct filter {
258 int dbs;
259 int states;
260 uint64_t families;
261 struct ssfilter *f;
262 bool kill;
263 struct rtnl_handle *rth_for_killing;
264};
265
266#define FAMILY_MASK(family) ((uint64_t)1 << (family))
267
268static const struct filter default_dbs[MAX_DB] = {
269 [TCP_DB] = {
270 .states = SS_CONN,
271 .families = FAMILY_MASK(AF_INET) | FAMILY_MASK(AF_INET6),
272 },
273 [MPTCP_DB] = {
274 .states = SS_CONN,
275 .families = FAMILY_MASK(AF_INET) | FAMILY_MASK(AF_INET6),
276 },
277 [DCCP_DB] = {
278 .states = SS_CONN,
279 .families = FAMILY_MASK(AF_INET) | FAMILY_MASK(AF_INET6),
280 },
281 [UDP_DB] = {
282 .states = (1 << SS_ESTABLISHED),
283 .families = FAMILY_MASK(AF_INET) | FAMILY_MASK(AF_INET6),
284 },
285 [RAW_DB] = {
286 .states = (1 << SS_ESTABLISHED),
287 .families = FAMILY_MASK(AF_INET) | FAMILY_MASK(AF_INET6),
288 },
289 [UNIX_DG_DB] = {
290 .states = (1 << SS_CLOSE),
291 .families = FAMILY_MASK(AF_UNIX),
292 },
293 [UNIX_ST_DB] = {
294 .states = SS_CONN,
295 .families = FAMILY_MASK(AF_UNIX),
296 },
297 [UNIX_SQ_DB] = {
298 .states = SS_CONN,
299 .families = FAMILY_MASK(AF_UNIX),
300 },
301 [PACKET_DG_DB] = {
302 .states = (1 << SS_CLOSE),
303 .families = FAMILY_MASK(AF_PACKET),
304 },
305 [PACKET_R_DB] = {
306 .states = (1 << SS_CLOSE),
307 .families = FAMILY_MASK(AF_PACKET),
308 },
309 [NETLINK_DB] = {
310 .states = (1 << SS_CLOSE),
311 .families = FAMILY_MASK(AF_NETLINK),
312 },
313 [SCTP_DB] = {
314 .states = SS_CONN,
315 .families = FAMILY_MASK(AF_INET) | FAMILY_MASK(AF_INET6),
316 },
317 [VSOCK_ST_DB] = {
318 .states = SS_CONN,
319 .families = FAMILY_MASK(AF_VSOCK),
320 },
321 [VSOCK_DG_DB] = {
322 .states = SS_CONN,
323 .families = FAMILY_MASK(AF_VSOCK),
324 },
325 [TIPC_DB] = {
326 .states = TIPC_SS_CONN,
327 .families = FAMILY_MASK(AF_TIPC),
328 },
329 [XDP_DB] = {
330 .states = (1 << SS_CLOSE),
331 .families = FAMILY_MASK(AF_XDP),
332 },
333};
334
335static const struct filter default_afs[AF_MAX] = {
336 [AF_INET] = {
337 .dbs = INET_DBM,
338 .states = SS_CONN,
339 },
340 [AF_INET6] = {
341 .dbs = INET_DBM,
342 .states = SS_CONN,
343 },
344 [AF_UNIX] = {
345 .dbs = UNIX_DBM,
346 .states = SS_CONN,
347 },
348 [AF_PACKET] = {
349 .dbs = PACKET_DBM,
350 .states = (1 << SS_CLOSE),
351 },
352 [AF_NETLINK] = {
353 .dbs = (1 << NETLINK_DB),
354 .states = (1 << SS_CLOSE),
355 },
356 [AF_VSOCK] = {
357 .dbs = VSOCK_DBM,
358 .states = SS_CONN,
359 },
360 [AF_TIPC] = {
361 .dbs = (1 << TIPC_DB),
362 .states = TIPC_SS_CONN,
363 },
364 [AF_XDP] = {
365 .dbs = (1 << XDP_DB),
366 .states = (1 << SS_CLOSE),
367 },
368};
369
370static int do_default = 1;
371static struct filter current_filter;
372
373static void filter_db_set(struct filter *f, int db, bool enable)
374{
375 if (enable) {
376 f->states |= default_dbs[db].states;
377 f->dbs |= 1 << db;
378 } else {
379 f->dbs &= ~(1 << db);
380 }
381 do_default = 0;
382}
383
384static int filter_db_parse(struct filter *f, const char *s)
385{
386 const struct {
387 const char *name;
388 int dbs[MAX_DB + 1];
389 } db_name_tbl[] = {
390#define ENTRY(name, ...) { #name, { __VA_ARGS__, MAX_DB } }
391 ENTRY(all, UDP_DB, DCCP_DB, TCP_DB, MPTCP_DB, RAW_DB,
392 UNIX_ST_DB, UNIX_DG_DB, UNIX_SQ_DB,
393 PACKET_R_DB, PACKET_DG_DB, NETLINK_DB,
394 SCTP_DB, VSOCK_ST_DB, VSOCK_DG_DB, XDP_DB),
395 ENTRY(inet, UDP_DB, DCCP_DB, TCP_DB, MPTCP_DB, SCTP_DB, RAW_DB),
396 ENTRY(udp, UDP_DB),
397 ENTRY(dccp, DCCP_DB),
398 ENTRY(tcp, TCP_DB),
399 ENTRY(mptcp, MPTCP_DB),
400 ENTRY(sctp, SCTP_DB),
401 ENTRY(raw, RAW_DB),
402 ENTRY(unix, UNIX_ST_DB, UNIX_DG_DB, UNIX_SQ_DB),
403 ENTRY(unix_stream, UNIX_ST_DB),
404 ENTRY(u_str, UNIX_ST_DB),
405 ENTRY(unix_dgram, UNIX_DG_DB),
406 ENTRY(u_dgr, UNIX_DG_DB),
407 ENTRY(unix_seqpacket, UNIX_SQ_DB),
408 ENTRY(u_seq, UNIX_SQ_DB),
409 ENTRY(packet, PACKET_R_DB, PACKET_DG_DB),
410 ENTRY(packet_raw, PACKET_R_DB),
411 ENTRY(p_raw, PACKET_R_DB),
412 ENTRY(packet_dgram, PACKET_DG_DB),
413 ENTRY(p_dgr, PACKET_DG_DB),
414 ENTRY(netlink, NETLINK_DB),
415 ENTRY(tipc, TIPC_DB),
416 ENTRY(vsock, VSOCK_ST_DB, VSOCK_DG_DB),
417 ENTRY(vsock_stream, VSOCK_ST_DB),
418 ENTRY(v_str, VSOCK_ST_DB),
419 ENTRY(vsock_dgram, VSOCK_DG_DB),
420 ENTRY(v_dgr, VSOCK_DG_DB),
421 ENTRY(xdp, XDP_DB),
422#undef ENTRY
423 };
424 bool enable = true;
425 unsigned int i;
426 const int *dbp;
427
428 if (s[0] == '!') {
429 enable = false;
430 s++;
431 }
432 for (i = 0; i < ARRAY_SIZE(db_name_tbl); i++) {
433 if (strcmp(s, db_name_tbl[i].name))
434 continue;
435 for (dbp = db_name_tbl[i].dbs; *dbp != MAX_DB; dbp++)
436 filter_db_set(f, *dbp, enable);
437 return 0;
438 }
439 return -1;
440}
441
442static void filter_af_set(struct filter *f, int af)
443{
444 f->states |= default_afs[af].states;
445 f->families |= FAMILY_MASK(af);
446 do_default = 0;
447 preferred_family = af;
448}
449
450static int filter_af_get(struct filter *f, int af)
451{
452 return !!(f->families & FAMILY_MASK(af));
453}
454
455static void filter_states_set(struct filter *f, int states)
456{
457 if (states)
458 f->states = states;
459}
460
461static void filter_merge_defaults(struct filter *f)
462{
463 int db;
464 int af;
465
466 for (db = 0; db < MAX_DB; db++) {
467 if (!(f->dbs & (1 << db)))
468 continue;
469
470 if (!(default_dbs[db].families & f->families))
471 f->families |= default_dbs[db].families;
472 }
473 for (af = 0; af < AF_MAX; af++) {
474 if (!(f->families & FAMILY_MASK(af)))
475 continue;
476
477 if (!(default_afs[af].dbs & f->dbs))
478 f->dbs |= default_afs[af].dbs;
479 }
480}
481
482#define net_tcp_open() generic_proc_open("PROC_NET_TCP", "net/tcp")
483#define net_tcp6_open() generic_proc_open("PROC_NET_TCP6", "net/tcp6")
484#define net_udp_open() generic_proc_open("PROC_NET_UDP", "net/udp")
485#define net_udp6_open() generic_proc_open("PROC_NET_UDP6", "net/udp6")
486#define net_raw_open() generic_proc_open("PROC_NET_RAW", "net/raw")
487#define net_raw6_open() generic_proc_open("PROC_NET_RAW6", "net/raw6")
488#define net_unix_open() generic_proc_open("PROC_NET_UNIX", "net/unix")
489#define net_packet_open() generic_proc_open("PROC_NET_PACKET", \
490 "net/packet")
491#define net_netlink_open() generic_proc_open("PROC_NET_NETLINK", \
492 "net/netlink")
493#define net_sockstat_open() generic_proc_open("PROC_NET_SOCKSTAT", \
494 "net/sockstat")
495#define net_sockstat6_open() generic_proc_open("PROC_NET_SOCKSTAT6", \
496 "net/sockstat6")
497#define net_snmp_open() generic_proc_open("PROC_NET_SNMP", "net/snmp")
498#define ephemeral_ports_open() generic_proc_open("PROC_IP_LOCAL_PORT_RANGE", \
499 "sys/net/ipv4/ip_local_port_range")
500
501struct user_ent {
502 struct user_ent *next;
503 unsigned int ino;
504 int pid;
505 int tid;
506 int fd;
507 char *task;
508 char *task_ctx;
509 char *socket_ctx;
510};
511
512#define USER_ENT_HASH_SIZE 256
513static struct user_ent *user_ent_hash[USER_ENT_HASH_SIZE];
514
515static int user_ent_hashfn(unsigned int ino)
516{
517 int val = (ino >> 24) ^ (ino >> 16) ^ (ino >> 8) ^ ino;
518
519 return val & (USER_ENT_HASH_SIZE - 1);
520}
521
522static void user_ent_add(unsigned int ino, char *task,
523 int pid, int tid, int fd,
524 char *task_ctx,
525 char *sock_ctx)
526{
527 struct user_ent *p, **pp;
528
529 p = malloc(sizeof(struct user_ent));
530 if (!p) {
531 fprintf(stderr, "ss: failed to malloc buffer\n");
532 abort();
533 }
534 p->next = NULL;
535 p->ino = ino;
536 p->pid = pid;
537 p->tid = tid;
538 p->fd = fd;
539 p->task = strdup(task);
540 p->task_ctx = strdup(task_ctx);
541 p->socket_ctx = strdup(sock_ctx);
542
543 pp = &user_ent_hash[user_ent_hashfn(ino)];
544 p->next = *pp;
545 *pp = p;
546}
547
548#define MAX_PATH_LEN 1024
549
550static void user_ent_hash_build_task(char *path, int pid, int tid)
551{
552 const char *no_ctx = "unavailable";
553 char task[16] = {'\0', };
554 char stat[MAX_PATH_LEN];
555 int pos_id, pos_fd;
556 char *task_context;
557 struct dirent *d;
558 DIR *dir;
559
560 if (getpidcon(tid, &task_context) != 0)
561 task_context = strdup(no_ctx);
562
563 pos_id = strlen(path);
564
565 snprintf(path + pos_id, MAX_PATH_LEN - pos_id, "fd/");
566 dir = opendir(path);
567 if (!dir) {
568 freecon(task_context);
569 return;
570 }
571
572 pos_fd = strlen(path);
573
574 while ((d = readdir(dir)) != NULL) {
575 const char *pattern = "socket:[";
576 char *sock_context;
577 unsigned int ino;
578 ssize_t link_len;
579 char lnk[64];
580 int fd;
581
582 if (sscanf(d->d_name, "%d%*c", &fd) != 1)
583 continue;
584
585 snprintf(path + pos_fd, MAX_PATH_LEN - pos_fd, "%d", fd);
586
587 link_len = readlink(path, lnk, sizeof(lnk) - 1);
588 if (link_len == -1)
589 continue;
590 lnk[link_len] = '\0';
591
592 if (strncmp(lnk, pattern, strlen(pattern)))
593 continue;
594
595 if (sscanf(lnk, "socket:[%u]", &ino) != 1)
596 continue;
597
598 if (getfilecon(path, &sock_context) <= 0)
599 sock_context = strdup(no_ctx);
600
601 if (task[0] == '\0') {
602 FILE *fp;
603
604 strlcpy(stat, path, pos_id + 1);
605 snprintf(stat + pos_id, sizeof(stat) - pos_id, "stat");
606
607 fp = fopen(stat, "r");
608 if (fp) {
609 if (fscanf(fp, "%*d (%[^)])", task) < 1) {
610 ;
611 }
612 fclose(fp);
613 }
614 }
615
616 user_ent_add(ino, task, pid, tid, fd, task_context, sock_context);
617 freecon(sock_context);
618 }
619
620 freecon(task_context);
621 closedir(dir);
622}
623
624static void user_ent_destroy(void)
625{
626 struct user_ent *p, *p_next;
627 int cnt = 0;
628
629 while (cnt != USER_ENT_HASH_SIZE) {
630 p = user_ent_hash[cnt];
631 while (p) {
632 free(p->task);
633 free(p->task_ctx);
634 free(p->socket_ctx);
635 p_next = p->next;
636 free(p);
637 p = p_next;
638 }
639 cnt++;
640 }
641}
642
643static void user_ent_hash_build(void)
644{
645 const char *root = getenv("PROC_ROOT") ? : "/proc/";
646 char name[MAX_PATH_LEN];
647 struct dirent *d;
648 int nameoff;
649 DIR *dir;
650
651 strlcpy(name, root, sizeof(name));
652
653 if (strlen(name) == 0 || name[strlen(name) - 1] != '/')
654 strcat(name, "/");
655
656 nameoff = strlen(name);
657
658 dir = opendir(name);
659 if (!dir)
660 return;
661
662 while ((d = readdir(dir)) != NULL) {
663 int pid;
664
665 if (sscanf(d->d_name, "%d%*c", &pid) != 1)
666 continue;
667
668 snprintf(name + nameoff, sizeof(name) - nameoff, "%d/", pid);
669 user_ent_hash_build_task(name, pid, pid);
670
671 if (show_threads) {
672 struct dirent *task_d;
673 DIR *task_dir;
674
675 snprintf(name + nameoff, sizeof(name) - nameoff, "%d/task/", pid);
676
677 task_dir = opendir(name);
678 if (!task_dir)
679 continue;
680
681 while ((task_d = readdir(task_dir)) != NULL) {
682 int tid;
683
684 if (sscanf(task_d->d_name, "%d%*c", &tid) != 1)
685 continue;
686 if (tid == pid)
687 continue;
688
689 snprintf(name + nameoff, sizeof(name) - nameoff, "%d/", tid);
690 user_ent_hash_build_task(name, pid, tid);
691 }
692 closedir(task_dir);
693 }
694 }
695 closedir(dir);
696}
697
698enum entry_types {
699 USERS,
700 PROC_CTX,
701 PROC_SOCK_CTX
702};
703
704#define ENTRY_BUF_SIZE 512
705static int find_entry(unsigned int ino, char **buf, int type)
706{
707 struct user_ent *p;
708 int cnt = 0;
709 char *ptr;
710 char thread_info[16] = {'\0', };
711 char *new_buf;
712 int len, new_buf_len;
713 int buf_used = 0;
714 int buf_len = 0;
715
716 if (!ino)
717 return 0;
718
719 p = user_ent_hash[user_ent_hashfn(ino)];
720 ptr = *buf = NULL;
721 while (p) {
722 if (p->ino != ino)
723 goto next;
724
725 while (1) {
726 ptr = *buf + buf_used;
727
728 if (show_threads)
729 snprintf(thread_info, sizeof(thread_info), "tid=%d,", p->tid);
730
731 switch (type) {
732 case USERS:
733 len = snprintf(ptr, buf_len - buf_used,
734 "(\"%s\",pid=%d,%sfd=%d),",
735 p->task, p->pid, thread_info, p->fd);
736 break;
737 case PROC_CTX:
738 len = snprintf(ptr, buf_len - buf_used,
739 "(\"%s\",pid=%d,%sproc_ctx=%s,fd=%d),",
740 p->task, p->pid, thread_info,
741 p->task_ctx, p->fd);
742 break;
743 case PROC_SOCK_CTX:
744 len = snprintf(ptr, buf_len - buf_used,
745 "(\"%s\",pid=%d,%sproc_ctx=%s,fd=%d,sock_ctx=%s),",
746 p->task, p->pid, thread_info,
747 p->task_ctx, p->fd,
748 p->socket_ctx);
749 break;
750 default:
751 fprintf(stderr, "ss: invalid type: %d\n", type);
752 abort();
753 }
754
755 if (len < 0 || len >= buf_len - buf_used) {
756 new_buf_len = buf_len + ENTRY_BUF_SIZE;
757 new_buf = realloc(*buf, new_buf_len);
758 if (!new_buf) {
759 fprintf(stderr, "ss: failed to malloc buffer\n");
760 abort();
761 }
762 *buf = new_buf;
763 buf_len = new_buf_len;
764 continue;
765 } else {
766 buf_used += len;
767 break;
768 }
769 }
770 cnt++;
771next:
772 p = p->next;
773 }
774 if (buf_used) {
775 ptr = *buf + buf_used;
776 ptr[-1] = '\0';
777 }
778 return cnt;
779}
780
781static unsigned long long cookie_sk_get(const uint32_t *cookie)
782{
783 return (((unsigned long long)cookie[1] << 31) << 1) | cookie[0];
784}
785
786static const char *sctp_sstate_name[] = {
787 [SCTP_STATE_CLOSED] = "CLOSED",
788 [SCTP_STATE_COOKIE_WAIT] = "COOKIE_WAIT",
789 [SCTP_STATE_COOKIE_ECHOED] = "COOKIE_ECHOED",
790 [SCTP_STATE_ESTABLISHED] = "ESTAB",
791 [SCTP_STATE_SHUTDOWN_PENDING] = "SHUTDOWN_PENDING",
792 [SCTP_STATE_SHUTDOWN_SENT] = "SHUTDOWN_SENT",
793 [SCTP_STATE_SHUTDOWN_RECEIVED] = "SHUTDOWN_RECEIVED",
794 [SCTP_STATE_SHUTDOWN_ACK_SENT] = "ACK_SENT",
795};
796
797static const char * const stype_nameg[] = {
798 "UNKNOWN",
799 [SOCK_STREAM] = "STREAM",
800 [SOCK_DGRAM] = "DGRAM",
801 [SOCK_RDM] = "RDM",
802 [SOCK_SEQPACKET] = "SEQPACKET",
803};
804
805struct sockstat {
806 struct sockstat *next;
807 unsigned int type;
808 uint16_t prot;
809 uint16_t raw_prot;
810 inet_prefix local;
811 inet_prefix remote;
812 int lport;
813 int rport;
814 int state;
815 int rq, wq;
816 unsigned int ino;
817 unsigned int uid;
818 int refcnt;
819 unsigned int iface;
820 unsigned long long sk;
821 char *name;
822 char *peer_name;
823 __u32 mark;
824 __u64 cgroup_id;
825};
826
827struct dctcpstat {
828 unsigned int ce_state;
829 unsigned int alpha;
830 unsigned int ab_ecn;
831 unsigned int ab_tot;
832 bool enabled;
833};
834
835struct tcpstat {
836 struct sockstat ss;
837 unsigned int timer;
838 unsigned int timeout;
839 int probes;
840 char cong_alg[16];
841 double rto, ato, rtt, rttvar;
842 int qack, ssthresh, backoff;
843 double send_bps;
844 int snd_wscale;
845 int rcv_wscale;
846 int mss;
847 int rcv_mss;
848 int advmss;
849 unsigned int pmtu;
850 unsigned int cwnd;
851 unsigned int lastsnd;
852 unsigned int lastrcv;
853 unsigned int lastack;
854 double pacing_rate;
855 double pacing_rate_max;
856 double delivery_rate;
857 unsigned long long bytes_acked;
858 unsigned long long bytes_received;
859 unsigned int segs_out;
860 unsigned int segs_in;
861 unsigned int data_segs_out;
862 unsigned int data_segs_in;
863 unsigned int unacked;
864 unsigned int retrans;
865 unsigned int retrans_total;
866 unsigned int lost;
867 unsigned int sacked;
868 unsigned int fackets;
869 unsigned int reordering;
870 unsigned int not_sent;
871 unsigned int delivered;
872 unsigned int delivered_ce;
873 unsigned int dsack_dups;
874 unsigned int reord_seen;
875 double rcv_rtt;
876 double min_rtt;
877 unsigned int rcv_ooopack;
878 unsigned int snd_wnd;
879 unsigned int rcv_wnd;
880 unsigned int rehash;
881 int rcv_space;
882 unsigned int rcv_ssthresh;
883 unsigned long long busy_time;
884 unsigned long long rwnd_limited;
885 unsigned long long sndbuf_limited;
886 unsigned long long bytes_sent;
887 unsigned long long bytes_retrans;
888 bool has_ts_opt;
889 bool has_usec_ts_opt;
890 bool has_sack_opt;
891 bool has_ecn_opt;
892 bool has_ecnseen_opt;
893 bool has_fastopen_opt;
894 bool has_wscale_opt;
895 bool app_limited;
896 struct dctcpstat *dctcp;
897 struct tcp_bbr_info *bbr_info;
898};
899
900
901
902
903static bool is_sctp_assoc(struct sockstat *s, const char *sock_name)
904{
905 if (strcmp(sock_name, "sctp"))
906 return false;
907 if (!sctp_ino || sctp_ino != s->ino)
908 return false;
909 return true;
910}
911
912static const char *unix_netid_name(int type)
913{
914 switch (type) {
915 case SOCK_STREAM:
916 return "u_str";
917 case SOCK_SEQPACKET:
918 return "u_seq";
919 case SOCK_DGRAM:
920 default:
921 return "u_dgr";
922 }
923}
924
925static const char *proto_name(int protocol)
926{
927 switch (protocol) {
928 case 0:
929 return "raw";
930 case IPPROTO_UDP:
931 return "udp";
932 case IPPROTO_TCP:
933 return "tcp";
934 case IPPROTO_MPTCP:
935 return "mptcp";
936 case IPPROTO_SCTP:
937 return "sctp";
938 case IPPROTO_DCCP:
939 return "dccp";
940 case IPPROTO_ICMPV6:
941 return "icmp6";
942 }
943
944 return "???";
945}
946
947static const char *vsock_netid_name(int type)
948{
949 switch (type) {
950 case SOCK_STREAM:
951 return "v_str";
952 case SOCK_DGRAM:
953 return "v_dgr";
954 default:
955 return "???";
956 }
957}
958
959static const char *tipc_netid_name(int type)
960{
961 switch (type) {
962 case SOCK_STREAM:
963 return "ti_st";
964 case SOCK_DGRAM:
965 return "ti_dg";
966 case SOCK_RDM:
967 return "ti_rd";
968 case SOCK_SEQPACKET:
969 return "ti_sq";
970 default:
971 return "???";
972 }
973}
974
975
976static struct buf_chunk *buf_chunk_new(void)
977{
978 struct buf_chunk *new = malloc(BUF_CHUNK);
979
980 if (!new)
981 abort();
982
983 new->next = NULL;
984
985
986 buffer.tail = new;
987
988
989
990
991 buffer.cur = (struct buf_token *)new->data;
992 buffer.cur->len = 0;
993
994 new->end = buffer.cur->data;
995
996 buffer.chunks++;
997
998 return new;
999}
1000
1001
1002static int buf_chunk_avail(struct buf_chunk *chunk)
1003{
1004 return BUF_CHUNK - offsetof(struct buf_chunk, data) -
1005 (chunk->end - chunk->data);
1006}
1007
1008
1009
1010
1011static int buf_update(int len)
1012{
1013 struct buf_chunk *chunk = buffer.tail;
1014 struct buf_token *t = buffer.cur;
1015
1016
1017
1018
1019
1020 if ((len < buf_chunk_avail(chunk) && len != -1 ) ||
1021 t == (struct buf_token *)chunk->data) {
1022 len = min(len, buf_chunk_avail(chunk));
1023
1024
1025 len = min(len, USHRT_MAX - t->len);
1026
1027 chunk->end += len;
1028 t->len += len;
1029 return 0;
1030 }
1031
1032
1033 chunk->next = buf_chunk_new();
1034
1035
1036 memcpy(chunk->next->data, t, sizeof(t->len) + t->len);
1037 chunk->next->end += t->len;
1038
1039
1040 chunk->end -= t->len + sizeof(t->len);
1041
1042 return -EAGAIN;
1043}
1044
1045
1046__attribute__((format(printf, 1, 0)))
1047static void vout(const char *fmt, va_list args)
1048{
1049 struct column *f = current_field;
1050 va_list _args;
1051 char *pos;
1052 int len;
1053
1054 if (f->disabled)
1055 return;
1056
1057 if (!buffer.head)
1058 buffer.head = buf_chunk_new();
1059
1060again:
1061 va_copy(_args, args);
1062
1063 pos = buffer.cur->data + buffer.cur->len;
1064
1065
1066 len = vsnprintf(pos, buf_chunk_avail(buffer.tail), fmt, _args);
1067
1068 if (buf_update(len))
1069 goto again;
1070}
1071
1072__attribute__((format(printf, 1, 2)))
1073static void out(const char *fmt, ...)
1074{
1075 va_list args;
1076
1077 va_start(args, fmt);
1078 vout(fmt, args);
1079 va_end(args);
1080}
1081
1082static int print_left_spacing(struct column *f, int stored, int printed)
1083{
1084 int s;
1085
1086 if (!f->width || f->align == ALIGN_LEFT)
1087 return 0;
1088
1089 s = f->width - stored - printed;
1090 if (f->align == ALIGN_CENTER)
1091
1092 s = (s + 1) / 2;
1093
1094 if (s > 0)
1095 return printf("%*c", s, ' ');
1096
1097 return 0;
1098}
1099
1100static void print_right_spacing(struct column *f, int printed)
1101{
1102 int s;
1103
1104 if (!f->width || f->align == ALIGN_RIGHT)
1105 return;
1106
1107 s = f->width - printed;
1108 if (f->align == ALIGN_CENTER)
1109 s /= 2;
1110
1111 if (s > 0)
1112 printf("%*c", s, ' ');
1113}
1114
1115
1116static void field_flush(struct column *f)
1117{
1118 struct buf_chunk *chunk;
1119 unsigned int pad;
1120
1121 if (f->disabled)
1122 return;
1123
1124 chunk = buffer.tail;
1125 pad = buffer.cur->len % 2;
1126
1127 if (buffer.cur->len > f->max_len)
1128 f->max_len = buffer.cur->len;
1129
1130
1131
1132
1133
1134 if (buf_chunk_avail(chunk) - pad < sizeof(buffer.cur->len)) {
1135 chunk->end += pad;
1136 chunk->next = buf_chunk_new();
1137 return;
1138 }
1139
1140 buffer.cur = (struct buf_token *)(buffer.cur->data +
1141 LEN_ALIGN(buffer.cur->len));
1142 buffer.cur->len = 0;
1143 buffer.tail->end = buffer.cur->data;
1144}
1145
1146static int field_is_last(struct column *f)
1147{
1148 return f - columns == COL_MAX - 1;
1149}
1150
1151
1152static struct buf_token *buf_token_next(struct buf_token *cur)
1153{
1154 struct buf_chunk *chunk = buffer.tail;
1155
1156
1157 if (cur->data + LEN_ALIGN(cur->len) == chunk->end) {
1158 buffer.tail = chunk = chunk->next;
1159 return chunk ? (struct buf_token *)chunk->data : NULL;
1160 }
1161
1162 return (struct buf_token *)(cur->data + LEN_ALIGN(cur->len));
1163}
1164
1165
1166static void buf_free_all(void)
1167{
1168 struct buf_chunk *tmp;
1169
1170 for (buffer.tail = buffer.head; buffer.tail; ) {
1171 tmp = buffer.tail;
1172 buffer.tail = buffer.tail->next;
1173 free(tmp);
1174 }
1175 buffer.head = NULL;
1176 buffer.chunks = 0;
1177}
1178
1179
1180
1181
1182static int render_screen_width(void)
1183{
1184 int width = -1;
1185
1186 if (isatty(STDOUT_FILENO)) {
1187 struct winsize w;
1188
1189 if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) != -1) {
1190 if (w.ws_col > 0)
1191 width = w.ws_col;
1192 }
1193 }
1194
1195 if (width == -1) {
1196 const char *p = getenv("COLUMNS");
1197 int c;
1198
1199 if (p) {
1200 c = atoi(p);
1201 if (c > 0)
1202 width = c;
1203 }
1204 }
1205
1206 return width;
1207}
1208
1209
1210
1211
1212
1213
1214static void render_calc_width(void)
1215{
1216 int screen_width, first, len = 0, linecols = 0;
1217 struct column *c, *eol = columns - 1;
1218 bool compact_output = false;
1219
1220 screen_width = render_screen_width();
1221 if (screen_width == -1) {
1222 screen_width = INT_MAX;
1223 compact_output = true;
1224 }
1225
1226
1227 for (first = 1, c = columns; c - columns < COL_MAX; c++) {
1228 if (c->disabled)
1229 continue;
1230
1231 if (!first && c->max_len)
1232 c->width = c->max_len + strlen(c->ldelim);
1233 else
1234 c->width = c->max_len;
1235
1236
1237
1238
1239
1240 c->width = min(c->width, screen_width);
1241
1242 if (c->width)
1243 first = 0;
1244 }
1245
1246 if (compact_output) {
1247
1248 return;
1249 }
1250
1251
1252 for (c = columns; c - columns < COL_MAX; c++) {
1253 int pad, spacing, rem, last;
1254 struct column *tmp;
1255
1256 if (!c->width)
1257 continue;
1258
1259 linecols++;
1260 len += c->width;
1261
1262 for (last = 1, tmp = c + 1; tmp - columns < COL_MAX; tmp++) {
1263 if (tmp->width) {
1264 last = 0;
1265 break;
1266 }
1267 }
1268
1269 if (!last && len < screen_width) {
1270
1271 continue;
1272 }
1273
1274 if (len == screen_width) {
1275
1276 goto newline;
1277 }
1278
1279 if (len > screen_width) {
1280
1281 len -= c->width;
1282 c--;
1283 linecols--;
1284 }
1285
1286
1287 pad = screen_width - len;
1288 spacing = pad / linecols;
1289 rem = pad % linecols;
1290 for (tmp = c; tmp > eol; tmp--) {
1291 if (!tmp->width)
1292 continue;
1293
1294 tmp->width += spacing;
1295 if (rem) {
1296 tmp->width++;
1297 rem--;
1298 }
1299 }
1300
1301newline:
1302
1303 eol = c;
1304 len = 0;
1305 linecols = 0;
1306 }
1307}
1308
1309
1310static void render(void)
1311{
1312 struct buf_token *token;
1313 int printed, line_started = 0;
1314 struct column *f;
1315
1316 if (!buffer.head)
1317 return;
1318
1319 token = (struct buf_token *)buffer.head->data;
1320
1321
1322 buffer.tail->end += buffer.cur->len % 2;
1323
1324 render_calc_width();
1325
1326
1327 buffer.tail = buffer.head;
1328
1329 f = columns;
1330 while (!f->width)
1331 f++;
1332
1333 while (token) {
1334
1335 if (line_started++)
1336 printed = printf("%s", f->ldelim);
1337 else
1338 printed = 0;
1339
1340
1341 printed += print_left_spacing(f, token->len, printed);
1342 printed += fwrite(token->data, 1, token->len, stdout);
1343 print_right_spacing(f, printed);
1344
1345
1346 do {
1347 if (field_is_last(f)) {
1348 printf("\n");
1349 f = columns;
1350 line_started = 0;
1351 } else {
1352 f++;
1353 }
1354 } while (f->disabled);
1355
1356 token = buf_token_next(token);
1357 }
1358
1359
1360
1361 if (line_started)
1362 printf("\n");
1363
1364 buf_free_all();
1365 current_field = columns;
1366}
1367
1368
1369
1370
1371static void field_next(void)
1372{
1373 if (field_is_last(current_field) && buffer.chunks >= BUF_CHUNKS_MAX) {
1374 render();
1375 return;
1376 }
1377
1378 field_flush(current_field);
1379 if (field_is_last(current_field))
1380 current_field = columns;
1381 else
1382 current_field++;
1383}
1384
1385
1386static void field_set(enum col_id id)
1387{
1388 while (id != current_field - columns)
1389 field_next();
1390}
1391
1392
1393static void print_header(void)
1394{
1395 while (!field_is_last(current_field)) {
1396 if (!current_field->disabled)
1397 out("%s", current_field->header);
1398 field_next();
1399 }
1400}
1401
1402static void sock_state_print(struct sockstat *s)
1403{
1404 const char *sock_name;
1405 static const char * const sstate_name[] = {
1406 "UNKNOWN",
1407 [SS_ESTABLISHED] = "ESTAB",
1408 [SS_SYN_SENT] = "SYN-SENT",
1409 [SS_SYN_RECV] = "SYN-RECV",
1410 [SS_FIN_WAIT1] = "FIN-WAIT-1",
1411 [SS_FIN_WAIT2] = "FIN-WAIT-2",
1412 [SS_TIME_WAIT] = "TIME-WAIT",
1413 [SS_CLOSE] = "UNCONN",
1414 [SS_CLOSE_WAIT] = "CLOSE-WAIT",
1415 [SS_LAST_ACK] = "LAST-ACK",
1416 [SS_LISTEN] = "LISTEN",
1417 [SS_CLOSING] = "CLOSING",
1418 [SS_NEW_SYN_RECV] = "UNDEF",
1419 [SS_BOUND_INACTIVE] = "UNDEF",
1420 };
1421
1422 switch (s->local.family) {
1423 case AF_UNIX:
1424 sock_name = unix_netid_name(s->type);
1425 break;
1426 case AF_INET:
1427 case AF_INET6:
1428 sock_name = proto_name(s->type);
1429 break;
1430 case AF_PACKET:
1431 sock_name = s->type == SOCK_RAW ? "p_raw" : "p_dgr";
1432 break;
1433 case AF_NETLINK:
1434 sock_name = "nl";
1435 break;
1436 case AF_TIPC:
1437 sock_name = tipc_netid_name(s->type);
1438 break;
1439 case AF_VSOCK:
1440 sock_name = vsock_netid_name(s->type);
1441 break;
1442 case AF_XDP:
1443 sock_name = "xdp";
1444 break;
1445 default:
1446 sock_name = "unknown";
1447 }
1448
1449 if (is_sctp_assoc(s, sock_name)) {
1450 field_set(COL_STATE);
1451 out("`- %s", sctp_sstate_name[s->state]);
1452 } else {
1453 field_set(COL_NETID);
1454 out("%s", sock_name);
1455 field_set(COL_STATE);
1456 out("%s", sstate_name[s->state]);
1457 }
1458
1459 if (show_queues) {
1460 field_set(COL_RECVQ);
1461 out("%-6d", s->rq);
1462 field_set(COL_SENDQ);
1463 out("%-6d", s->wq);
1464 }
1465
1466 field_set(COL_ADDR);
1467}
1468
1469static void sock_details_print(struct sockstat *s)
1470{
1471 if (s->uid)
1472 out(" uid:%u", s->uid);
1473
1474 out(" ino:%u", s->ino);
1475 out(" sk:%llx", s->sk);
1476
1477 if (s->mark)
1478 out(" fwmark:0x%x", s->mark);
1479
1480 if (s->cgroup_id)
1481 out(" cgroup:%s", cg_id_to_path(s->cgroup_id));
1482}
1483
1484static void sock_addr_print(const char *addr, char *delim, const char *port,
1485 const char *ifname)
1486{
1487 if (ifname)
1488 out("%s" "%%" "%s%s", addr, ifname, delim);
1489 else
1490 out("%s%s", addr, delim);
1491
1492 field_next();
1493 out("%s", port);
1494 field_next();
1495}
1496
1497static const char *print_ms_timer(unsigned int timeout)
1498{
1499 static char buf[64];
1500 int secs, msecs, minutes;
1501
1502 secs = timeout/1000;
1503 minutes = secs/60;
1504 secs = secs%60;
1505 msecs = timeout%1000;
1506 buf[0] = 0;
1507 if (minutes) {
1508 msecs = 0;
1509 snprintf(buf, sizeof(buf)-16, "%dmin", minutes);
1510 if (minutes > 9)
1511 secs = 0;
1512 }
1513 if (secs) {
1514 if (secs > 9)
1515 msecs = 0;
1516 sprintf(buf+strlen(buf), "%d%s", secs, msecs ? "." : "sec");
1517 }
1518 if (msecs)
1519 sprintf(buf+strlen(buf), "%03d%s", msecs, secs ? "sec" : "ms");
1520 return buf;
1521}
1522
1523struct scache {
1524 struct scache *next;
1525 int port;
1526 char *name;
1527 const char *proto;
1528};
1529
1530static struct scache *rlist;
1531
1532#ifdef HAVE_RPC
1533static CLIENT *rpc_client_create(rpcprog_t prog, rpcvers_t vers)
1534{
1535 struct netbuf nbuf;
1536 struct sockaddr_un saddr;
1537 int sock;
1538
1539 memset(&saddr, 0, sizeof(saddr));
1540 sock = socket(AF_LOCAL, SOCK_STREAM, 0);
1541 if (sock < 0)
1542 return NULL;
1543
1544 saddr.sun_family = AF_LOCAL;
1545 strcpy(saddr.sun_path, _PATH_RPCBINDSOCK);
1546 nbuf.len = SUN_LEN(&saddr);
1547 nbuf.maxlen = sizeof(struct sockaddr_un);
1548 nbuf.buf = &saddr;
1549
1550 return clnt_vc_create(sock, &nbuf, prog, vers, 0, 0);
1551}
1552
1553static void init_service_resolver(void)
1554{
1555 struct rpcblist *rhead = NULL;
1556 struct timeval timeout;
1557 struct rpcent *rpc;
1558 enum clnt_stat res;
1559 CLIENT *client;
1560
1561 timeout.tv_sec = 5;
1562 timeout.tv_usec = 0;
1563
1564 client = rpc_client_create(PMAPPROG, RPCBVERS4);
1565 if (!client)
1566 return;
1567
1568 res = clnt_call(client, RPCBPROC_DUMP, (xdrproc_t)xdr_void, NULL,
1569 (xdrproc_t)xdr_rpcblist_ptr, (char *)&rhead,
1570 timeout);
1571 if (res != RPC_SUCCESS)
1572 return;
1573
1574 for (; rhead; rhead = rhead->rpcb_next) {
1575 char prog[128] = "rpc.";
1576 struct scache *c;
1577 int hport, lport, ok;
1578
1579 c = malloc(sizeof(*c));
1580 if (!c)
1581 continue;
1582
1583 ok = sscanf(rhead->rpcb_map.r_addr, "::.%d.%d", &hport, &lport);
1584 if (!ok)
1585 ok = sscanf(rhead->rpcb_map.r_addr, "0.0.0.0.%d.%d",
1586 &hport, &lport);
1587 if (!ok)
1588 continue;
1589 c->port = hport << 8 | lport;
1590
1591 if (strcmp(rhead->rpcb_map.r_netid, TCP_PROTO) == 0 ||
1592 strcmp(rhead->rpcb_map.r_netid, TCP6_PROTO) == 0)
1593 c->proto = TCP_PROTO;
1594 else if (strcmp(rhead->rpcb_map.r_netid, UDP_PROTO) == 0 ||
1595 strcmp(rhead->rpcb_map.r_netid, UDP6_PROTO) == 0)
1596 c->proto = UDP_PROTO;
1597 else if (strcmp(rhead->rpcb_map.r_netid, SCTP_PROTO) == 0)
1598 c->proto = SCTP_PROTO;
1599 else
1600 continue;
1601
1602 rpc = getrpcbynumber(rhead->rpcb_map.r_prog);
1603 if (rpc) {
1604 strncat(prog, rpc->r_name, 128 - strlen(prog));
1605 c->name = strdup(prog);
1606 }
1607
1608 c->next = rlist;
1609 rlist = c;
1610 }
1611}
1612#endif
1613
1614
1615
1616
1617
1618
1619
1620static int is_ephemeral(int port)
1621{
1622 static int min = 0, max;
1623
1624 if (!min) {
1625 FILE *f = ephemeral_ports_open();
1626
1627 if (!f || fscanf(f, "%d %d", &min, &max) < 2) {
1628 min = 1024;
1629 max = 4999;
1630 }
1631 if (f)
1632 fclose(f);
1633 }
1634 return port >= min && port <= max;
1635}
1636
1637
1638static const char *__resolve_service(int port)
1639{
1640 struct scache *c;
1641
1642 for (c = rlist; c; c = c->next) {
1643 if (c->port == port && c->proto == dg_proto)
1644 return c->name;
1645 }
1646
1647 if (!is_ephemeral(port)) {
1648 static int notfirst;
1649 struct servent *se;
1650
1651 if (!notfirst) {
1652 setservent(1);
1653 notfirst = 1;
1654 }
1655 se = getservbyport(htons(port), dg_proto);
1656 if (se)
1657 return se->s_name;
1658 }
1659
1660 return NULL;
1661}
1662
1663#define SCACHE_BUCKETS 1024
1664static struct scache *cache_htab[SCACHE_BUCKETS];
1665
1666static const char *resolve_service(int port)
1667{
1668 static char buf[128];
1669 struct scache *c;
1670 const char *res;
1671 int hash;
1672
1673 if (port == 0) {
1674 buf[0] = '*';
1675 buf[1] = 0;
1676 return buf;
1677 }
1678
1679 if (numeric)
1680 goto do_numeric;
1681
1682 if (dg_proto == RAW_PROTO)
1683 return inet_proto_n2a(port, buf, sizeof(buf));
1684
1685
1686 hash = (port^(((unsigned long)dg_proto)>>2)) % SCACHE_BUCKETS;
1687
1688 for (c = cache_htab[hash]; c; c = c->next) {
1689 if (c->port == port && c->proto == dg_proto)
1690 goto do_cache;
1691 }
1692
1693 c = malloc(sizeof(*c));
1694 if (!c)
1695 goto do_numeric;
1696 res = __resolve_service(port);
1697 c->port = port;
1698 c->name = res ? strdup(res) : NULL;
1699 c->proto = dg_proto;
1700 c->next = cache_htab[hash];
1701 cache_htab[hash] = c;
1702
1703do_cache:
1704 if (c->name)
1705 return c->name;
1706
1707do_numeric:
1708 sprintf(buf, "%u", port);
1709 return buf;
1710}
1711
1712static void inet_addr_print(const inet_prefix *a, int port,
1713 unsigned int ifindex, bool v6only)
1714{
1715 char buf[1024];
1716 const char *ap = buf;
1717 const char *ifname = NULL;
1718
1719 if (a->family == AF_INET) {
1720 ap = format_host(AF_INET, 4, a->data);
1721 } else {
1722 if (!v6only &&
1723 !memcmp(a->data, &in6addr_any, sizeof(in6addr_any))) {
1724 buf[0] = '*';
1725 buf[1] = 0;
1726 } else {
1727 ap = format_host(a->family, 16, a->data);
1728
1729
1730 if (strchr(ap, ':')) {
1731 snprintf(buf, sizeof(buf),
1732 "[%s]", ap);
1733 ap = buf;
1734 }
1735 }
1736 }
1737
1738 if (ifindex)
1739 ifname = ll_index_to_name(ifindex);
1740
1741 sock_addr_print(ap, ":", resolve_service(port), ifname);
1742}
1743
1744struct aafilter {
1745 inet_prefix addr;
1746 long port;
1747 unsigned int iface;
1748 __u32 mark;
1749 __u32 mask;
1750 __u64 cgroup_id;
1751 struct aafilter *next;
1752};
1753
1754static int inet2_addr_match(const inet_prefix *a, const inet_prefix *p,
1755 int plen)
1756{
1757 if (!inet_addr_match(a, p, plen))
1758 return 0;
1759
1760
1761
1762
1763 if (p->family == AF_INET && a->family == AF_INET6) {
1764 if (a->data[0] == 0 && a->data[1] == 0 &&
1765 a->data[2] == htonl(0xffff)) {
1766 inet_prefix tmp = *a;
1767
1768 tmp.data[0] = a->data[3];
1769 return inet_addr_match(&tmp, p, plen);
1770 }
1771 }
1772 return 1;
1773}
1774
1775static int unix_match(const inet_prefix *a, const inet_prefix *p)
1776{
1777 char *addr, *pattern;
1778
1779 memcpy(&addr, a->data, sizeof(addr));
1780 memcpy(&pattern, p->data, sizeof(pattern));
1781 if (pattern == NULL)
1782 return 1;
1783 if (addr == NULL)
1784 addr = "";
1785 return !fnmatch(pattern, addr, FNM_CASEFOLD);
1786}
1787
1788static int run_ssfilter(struct ssfilter *f, struct sockstat *s)
1789{
1790 switch (f->type) {
1791 case SSF_S_AUTO:
1792 {
1793 if (s->local.family == AF_UNIX) {
1794 char *p;
1795
1796 memcpy(&p, s->local.data, sizeof(p));
1797 return p == NULL || (p[0] == '@' && strlen(p) == 6 &&
1798 strspn(p+1, "0123456789abcdef") == 5);
1799 }
1800 if (s->local.family == AF_PACKET)
1801 return s->lport == 0 && s->local.data[0] == 0;
1802 if (s->local.family == AF_NETLINK)
1803 return s->lport < 0;
1804 if (s->local.family == AF_VSOCK)
1805 return s->lport > 1023;
1806
1807 return is_ephemeral(s->lport);
1808 }
1809 case SSF_DCOND:
1810 {
1811 struct aafilter *a = (void *)f->pred;
1812
1813 if (a->addr.family == AF_UNIX)
1814 return unix_match(&s->remote, &a->addr);
1815 if (a->port != -1 && a->port != s->rport)
1816 return 0;
1817 if (a->addr.bitlen) {
1818 do {
1819 if (!inet2_addr_match(&s->remote, &a->addr, a->addr.bitlen))
1820 return 1;
1821 } while ((a = a->next) != NULL);
1822 return 0;
1823 }
1824 return 1;
1825 }
1826 case SSF_SCOND:
1827 {
1828 struct aafilter *a = (void *)f->pred;
1829
1830 if (a->addr.family == AF_UNIX)
1831 return unix_match(&s->local, &a->addr);
1832 if (a->port != -1 && a->port != s->lport)
1833 return 0;
1834 if (a->addr.bitlen) {
1835 do {
1836 if (!inet2_addr_match(&s->local, &a->addr, a->addr.bitlen))
1837 return 1;
1838 } while ((a = a->next) != NULL);
1839 return 0;
1840 }
1841 return 1;
1842 }
1843 case SSF_D_GE:
1844 {
1845 struct aafilter *a = (void *)f->pred;
1846
1847 return s->rport >= a->port;
1848 }
1849 case SSF_D_LE:
1850 {
1851 struct aafilter *a = (void *)f->pred;
1852
1853 return s->rport <= a->port;
1854 }
1855 case SSF_S_GE:
1856 {
1857 struct aafilter *a = (void *)f->pred;
1858
1859 return s->lport >= a->port;
1860 }
1861 case SSF_S_LE:
1862 {
1863 struct aafilter *a = (void *)f->pred;
1864
1865 return s->lport <= a->port;
1866 }
1867 case SSF_DEVCOND:
1868 {
1869 struct aafilter *a = (void *)f->pred;
1870
1871 return s->iface == a->iface;
1872 }
1873 case SSF_MARKMASK:
1874 {
1875 struct aafilter *a = (void *)f->pred;
1876
1877 return (s->mark & a->mask) == a->mark;
1878 }
1879 case SSF_CGROUPCOND:
1880 {
1881 struct aafilter *a = (void *)f->pred;
1882
1883 return s->cgroup_id == a->cgroup_id;
1884 }
1885
1886 case SSF_AND:
1887 return run_ssfilter(f->pred, s) && run_ssfilter(f->post, s);
1888 case SSF_OR:
1889 return run_ssfilter(f->pred, s) || run_ssfilter(f->post, s);
1890 case SSF_NOT:
1891 return !run_ssfilter(f->pred, s);
1892 default:
1893 abort();
1894 }
1895}
1896
1897
1898static void ssfilter_patch(char *a, int len, int reloc)
1899{
1900 while (len > 0) {
1901 struct inet_diag_bc_op *op = (struct inet_diag_bc_op *)a;
1902
1903 if (op->no == len+4)
1904 op->no += reloc;
1905 len -= op->yes;
1906 a += op->yes;
1907 }
1908 if (len < 0)
1909 abort();
1910}
1911
1912static int ssfilter_bytecompile(struct ssfilter *f, char **bytecode)
1913{
1914 switch (f->type) {
1915 case SSF_S_AUTO:
1916 {
1917 if (!(*bytecode = malloc(4))) abort();
1918 ((struct inet_diag_bc_op *)*bytecode)[0] = (struct inet_diag_bc_op){ INET_DIAG_BC_AUTO, 4, 8 };
1919 return 4;
1920 }
1921 case SSF_DCOND:
1922 case SSF_SCOND:
1923 {
1924 struct aafilter *a = (void *)f->pred;
1925 struct aafilter *b;
1926 char *ptr;
1927 int code = (f->type == SSF_DCOND ? INET_DIAG_BC_D_COND : INET_DIAG_BC_S_COND);
1928 int len = 0;
1929
1930 for (b = a; b; b = b->next) {
1931 len += 4 + sizeof(struct inet_diag_hostcond);
1932 if (a->addr.family == AF_INET6)
1933 len += 16;
1934 else
1935 len += 4;
1936 if (b->next)
1937 len += 4;
1938 }
1939 if (!(ptr = malloc(len))) abort();
1940 *bytecode = ptr;
1941 for (b = a; b; b = b->next) {
1942 struct inet_diag_bc_op *op = (struct inet_diag_bc_op *)ptr;
1943 int alen = (a->addr.family == AF_INET6 ? 16 : 4);
1944 int oplen = alen + 4 + sizeof(struct inet_diag_hostcond);
1945 struct inet_diag_hostcond *cond = (struct inet_diag_hostcond *)(ptr+4);
1946
1947 *op = (struct inet_diag_bc_op){ code, oplen, oplen+4 };
1948 cond->family = a->addr.family;
1949 cond->port = a->port;
1950 cond->prefix_len = a->addr.bitlen;
1951 memcpy(cond->addr, a->addr.data, alen);
1952 ptr += oplen;
1953 if (b->next) {
1954 op = (struct inet_diag_bc_op *)ptr;
1955 *op = (struct inet_diag_bc_op){ INET_DIAG_BC_JMP, 4, len - (ptr-*bytecode)};
1956 ptr += 4;
1957 }
1958 }
1959 return ptr - *bytecode;
1960 }
1961 case SSF_D_GE:
1962 {
1963 struct aafilter *x = (void *)f->pred;
1964
1965 if (!(*bytecode = malloc(8))) abort();
1966 ((struct inet_diag_bc_op *)*bytecode)[0] = (struct inet_diag_bc_op){ INET_DIAG_BC_D_GE, 8, 12 };
1967 ((struct inet_diag_bc_op *)*bytecode)[1] = (struct inet_diag_bc_op){ 0, 0, x->port };
1968 return 8;
1969 }
1970 case SSF_D_LE:
1971 {
1972 struct aafilter *x = (void *)f->pred;
1973
1974 if (!(*bytecode = malloc(8))) abort();
1975 ((struct inet_diag_bc_op *)*bytecode)[0] = (struct inet_diag_bc_op){ INET_DIAG_BC_D_LE, 8, 12 };
1976 ((struct inet_diag_bc_op *)*bytecode)[1] = (struct inet_diag_bc_op){ 0, 0, x->port };
1977 return 8;
1978 }
1979 case SSF_S_GE:
1980 {
1981 struct aafilter *x = (void *)f->pred;
1982
1983 if (!(*bytecode = malloc(8))) abort();
1984 ((struct inet_diag_bc_op *)*bytecode)[0] = (struct inet_diag_bc_op){ INET_DIAG_BC_S_GE, 8, 12 };
1985 ((struct inet_diag_bc_op *)*bytecode)[1] = (struct inet_diag_bc_op){ 0, 0, x->port };
1986 return 8;
1987 }
1988 case SSF_S_LE:
1989 {
1990 struct aafilter *x = (void *)f->pred;
1991
1992 if (!(*bytecode = malloc(8))) abort();
1993 ((struct inet_diag_bc_op *)*bytecode)[0] = (struct inet_diag_bc_op){ INET_DIAG_BC_S_LE, 8, 12 };
1994 ((struct inet_diag_bc_op *)*bytecode)[1] = (struct inet_diag_bc_op){ 0, 0, x->port };
1995 return 8;
1996 }
1997
1998 case SSF_AND:
1999 {
2000 char *a1 = NULL, *a2 = NULL, *a;
2001 int l1, l2;
2002
2003 l1 = ssfilter_bytecompile(f->pred, &a1);
2004 l2 = ssfilter_bytecompile(f->post, &a2);
2005 if (!l1 || !l2) {
2006 free(a1);
2007 free(a2);
2008 return 0;
2009 }
2010 if (!(a = malloc(l1+l2))) abort();
2011 memcpy(a, a1, l1);
2012 memcpy(a+l1, a2, l2);
2013 free(a1); free(a2);
2014 ssfilter_patch(a, l1, l2);
2015 *bytecode = a;
2016 return l1+l2;
2017 }
2018 case SSF_OR:
2019 {
2020 char *a1 = NULL, *a2 = NULL, *a;
2021 int l1, l2;
2022
2023 l1 = ssfilter_bytecompile(f->pred, &a1);
2024 l2 = ssfilter_bytecompile(f->post, &a2);
2025 if (!l1 || !l2) {
2026 free(a1);
2027 free(a2);
2028 return 0;
2029 }
2030 if (!(a = malloc(l1+l2+4))) abort();
2031 memcpy(a, a1, l1);
2032 memcpy(a+l1+4, a2, l2);
2033 free(a1); free(a2);
2034 *(struct inet_diag_bc_op *)(a+l1) = (struct inet_diag_bc_op){ INET_DIAG_BC_JMP, 4, l2+4 };
2035 *bytecode = a;
2036 return l1+l2+4;
2037 }
2038 case SSF_NOT:
2039 {
2040 char *a1 = NULL, *a;
2041 int l1;
2042
2043 l1 = ssfilter_bytecompile(f->pred, &a1);
2044 if (!l1) {
2045 free(a1);
2046 return 0;
2047 }
2048 if (!(a = malloc(l1+4))) abort();
2049 memcpy(a, a1, l1);
2050 free(a1);
2051 *(struct inet_diag_bc_op *)(a+l1) = (struct inet_diag_bc_op){ INET_DIAG_BC_JMP, 4, 8 };
2052 *bytecode = a;
2053 return l1+4;
2054 }
2055 case SSF_DEVCOND:
2056 {
2057
2058 return 0;
2059 }
2060 case SSF_MARKMASK:
2061 {
2062 struct aafilter *a = (void *)f->pred;
2063 struct instr {
2064 struct inet_diag_bc_op op;
2065 struct inet_diag_markcond cond;
2066 };
2067 int inslen = sizeof(struct instr);
2068
2069 if (!(*bytecode = malloc(inslen))) abort();
2070 ((struct instr *)*bytecode)[0] = (struct instr) {
2071 { INET_DIAG_BC_MARK_COND, inslen, inslen + 4 },
2072 { a->mark, a->mask},
2073 };
2074
2075 return inslen;
2076 }
2077 case SSF_CGROUPCOND:
2078 {
2079 struct aafilter *a = (void *)f->pred;
2080 struct instr {
2081 struct inet_diag_bc_op op;
2082 __u64 cgroup_id;
2083 } __attribute__((packed));
2084 int inslen = sizeof(struct instr);
2085
2086 if (!(*bytecode = malloc(inslen))) abort();
2087 ((struct instr *)*bytecode)[0] = (struct instr) {
2088 { INET_DIAG_BC_CGROUP_COND, inslen, inslen + 4 },
2089 a->cgroup_id,
2090 };
2091
2092 return inslen;
2093 }
2094 default:
2095 abort();
2096 }
2097}
2098
2099static int remember_he(struct aafilter *a, struct hostent *he)
2100{
2101 char **ptr = he->h_addr_list;
2102 int cnt = 0;
2103 int len;
2104
2105 if (he->h_addrtype == AF_INET)
2106 len = 4;
2107 else if (he->h_addrtype == AF_INET6)
2108 len = 16;
2109 else
2110 return 0;
2111
2112 while (*ptr) {
2113 struct aafilter *b = a;
2114
2115 if (a->addr.bitlen) {
2116 if ((b = malloc(sizeof(*b))) == NULL)
2117 return cnt;
2118 *b = *a;
2119 a->next = b;
2120 }
2121 memcpy(b->addr.data, *ptr, len);
2122 b->addr.bytelen = len;
2123 b->addr.bitlen = len*8;
2124 b->addr.family = he->h_addrtype;
2125 ptr++;
2126 cnt++;
2127 }
2128 return cnt;
2129}
2130
2131static int get_dns_host(struct aafilter *a, const char *addr, int fam)
2132{
2133 static int notfirst;
2134 int cnt = 0;
2135 struct hostent *he;
2136
2137 a->addr.bitlen = 0;
2138 if (!notfirst) {
2139 sethostent(1);
2140 notfirst = 1;
2141 }
2142 he = gethostbyname2(addr, fam == AF_UNSPEC ? AF_INET : fam);
2143 if (he)
2144 cnt = remember_he(a, he);
2145 if (fam == AF_UNSPEC) {
2146 he = gethostbyname2(addr, AF_INET6);
2147 if (he)
2148 cnt += remember_he(a, he);
2149 }
2150 return !cnt;
2151}
2152
2153static int xll_initted;
2154
2155static void xll_init(void)
2156{
2157 struct rtnl_handle rth;
2158
2159 if (rtnl_open(&rth, 0) < 0)
2160 exit(1);
2161
2162 ll_init_map(&rth);
2163 rtnl_close(&rth);
2164 xll_initted = 1;
2165}
2166
2167static const char *xll_index_to_name(int index)
2168{
2169 if (!xll_initted)
2170 xll_init();
2171 return ll_index_to_name(index);
2172}
2173
2174static int xll_name_to_index(const char *dev)
2175{
2176 if (!xll_initted)
2177 xll_init();
2178 return ll_name_to_index(dev);
2179}
2180
2181void *parse_devcond(char *name)
2182{
2183 struct aafilter a = { .iface = 0 };
2184 struct aafilter *res;
2185
2186 a.iface = xll_name_to_index(name);
2187 if (a.iface == 0) {
2188 char *end;
2189 unsigned long n;
2190
2191 n = strtoul(name, &end, 0);
2192 if (!end || end == name || *end || n > UINT_MAX)
2193 return NULL;
2194
2195 a.iface = n;
2196 }
2197
2198 res = malloc(sizeof(*res));
2199 *res = a;
2200
2201 return res;
2202}
2203
2204static void vsock_set_inet_prefix(inet_prefix *a, __u32 cid)
2205{
2206 *a = (inet_prefix){
2207 .bytelen = sizeof(cid),
2208 .family = AF_VSOCK,
2209 };
2210 memcpy(a->data, &cid, sizeof(cid));
2211}
2212
2213static char* find_port(char *addr, bool is_port)
2214{
2215 char *port = NULL;
2216 if (is_port)
2217 port = addr;
2218 else
2219 port = strchr(addr, ':');
2220 if (port && *port == ':')
2221 *port++ = '\0';
2222 return port;
2223}
2224
2225void *parse_hostcond(char *addr, bool is_port)
2226{
2227 char *port = NULL;
2228 struct aafilter a = { .port = -1 };
2229 struct aafilter *res;
2230 int fam = preferred_family;
2231 struct filter *f = ¤t_filter;
2232
2233 if (strncmp(addr, "unix:", 5) == 0) {
2234 fam = AF_UNIX;
2235 addr += 5;
2236 } else if (strncmp(addr, "link:", 5) == 0) {
2237 fam = AF_PACKET;
2238 addr += 5;
2239 } else if (strncmp(addr, "netlink:", 8) == 0) {
2240 fam = AF_NETLINK;
2241 addr += 8;
2242 } else if (strncmp(addr, "vsock:", 6) == 0) {
2243 fam = AF_VSOCK;
2244 addr += 6;
2245 } else if (strncmp(addr, "inet:", 5) == 0) {
2246 fam = AF_INET;
2247 addr += 5;
2248 } else if (strncmp(addr, "inet6:", 6) == 0) {
2249 fam = AF_INET6;
2250 addr += 6;
2251 }
2252
2253 if (fam == AF_UNIX) {
2254 char *p;
2255
2256 a.addr.family = AF_UNIX;
2257 p = strdup(addr);
2258 a.addr.bitlen = 8*strlen(p);
2259 memcpy(a.addr.data, &p, sizeof(p));
2260 goto out;
2261 }
2262
2263 if (fam == AF_PACKET) {
2264 a.addr.family = AF_PACKET;
2265 a.addr.bitlen = 0;
2266 port = find_port(addr, is_port);
2267 if (port) {
2268 if (*port && strcmp(port, "*")) {
2269 if (get_long(&a.port, port, 0)) {
2270 if ((a.port = xll_name_to_index(port)) <= 0)
2271 return NULL;
2272 }
2273 }
2274 }
2275 if (!is_port && addr[0] && strcmp(addr, "*")) {
2276 unsigned short tmp;
2277
2278 a.addr.bitlen = 32;
2279 if (ll_proto_a2n(&tmp, addr))
2280 return NULL;
2281 a.addr.data[0] = ntohs(tmp);
2282 }
2283 goto out;
2284 }
2285
2286 if (fam == AF_NETLINK) {
2287 a.addr.family = AF_NETLINK;
2288 a.addr.bitlen = 0;
2289 port = find_port(addr, is_port);
2290 if (port) {
2291 if (*port && strcmp(port, "*")) {
2292 if (get_long(&a.port, port, 0)) {
2293 if (strcmp(port, "kernel") == 0)
2294 a.port = 0;
2295 else
2296 return NULL;
2297 }
2298 }
2299 }
2300 if (!is_port && addr[0] && strcmp(addr, "*")) {
2301 a.addr.bitlen = 32;
2302 if (nl_proto_a2n(&a.addr.data[0], addr) == -1)
2303 return NULL;
2304 }
2305 goto out;
2306 }
2307
2308 if (fam == AF_VSOCK) {
2309 __u32 cid = ~(__u32)0;
2310
2311 a.addr.family = AF_VSOCK;
2312
2313 port = find_port(addr, is_port);
2314
2315 if (port && strcmp(port, "*") &&
2316 get_u32((__u32 *)&a.port, port, 0))
2317 return NULL;
2318
2319 if (!is_port && addr[0] && strcmp(addr, "*")) {
2320 a.addr.bitlen = 32;
2321 if (get_u32(&cid, addr, 0))
2322 return NULL;
2323 }
2324 vsock_set_inet_prefix(&a.addr, cid);
2325 goto out;
2326 }
2327
2328
2329 if (addr[0] == '[') {
2330 addr++;
2331 if ((port = strchr(addr, ']')) == NULL)
2332 return NULL;
2333 *port++ = 0;
2334 } else if (addr[0] == '*') {
2335 port = addr+1;
2336 } else {
2337 port = strrchr(strchr(addr, '/') ? : addr, ':');
2338 }
2339
2340 if (is_port)
2341 port = addr;
2342
2343 if (port && *port) {
2344 if (*port == ':')
2345 *port++ = 0;
2346
2347 if (*port && *port != '*') {
2348 if (get_long(&a.port, port, 0)) {
2349 struct servent *se1 = NULL;
2350 struct servent *se2 = NULL;
2351
2352 if (current_filter.dbs&(1<<UDP_DB))
2353 se1 = getservbyname(port, UDP_PROTO);
2354 if (current_filter.dbs&(1<<TCP_DB))
2355 se2 = getservbyname(port, TCP_PROTO);
2356 if (se1 && se2 && se1->s_port != se2->s_port) {
2357 fprintf(stderr, "Error: ambiguous port \"%s\".\n", port);
2358 return NULL;
2359 }
2360 if (!se1)
2361 se1 = se2;
2362 if (se1) {
2363 a.port = ntohs(se1->s_port);
2364 } else {
2365 struct scache *s;
2366
2367 for (s = rlist; s; s = s->next) {
2368 if ((s->proto == UDP_PROTO &&
2369 (current_filter.dbs&(1<<UDP_DB))) ||
2370 (s->proto == TCP_PROTO &&
2371 (current_filter.dbs&(1<<TCP_DB)))) {
2372 if (s->name && strcmp(s->name, port) == 0) {
2373 if (a.port > 0 && a.port != s->port) {
2374 fprintf(stderr, "Error: ambiguous port \"%s\".\n", port);
2375 return NULL;
2376 }
2377 a.port = s->port;
2378 }
2379 }
2380 }
2381 if (a.port <= 0) {
2382 fprintf(stderr, "Error: \"%s\" does not look like a port.\n", port);
2383 return NULL;
2384 }
2385 }
2386 }
2387 }
2388 }
2389 if (!is_port && *addr && *addr != '*') {
2390 if (get_prefix_1(&a.addr, addr, fam)) {
2391 if (get_dns_host(&a, addr, fam)) {
2392 fprintf(stderr, "Error: an inet prefix is expected rather than \"%s\".\n", addr);
2393 return NULL;
2394 }
2395 }
2396 }
2397
2398out:
2399 if (fam != AF_UNSPEC) {
2400 int states = f->states;
2401 f->families = 0;
2402 filter_af_set(f, fam);
2403 filter_states_set(f, states);
2404 }
2405
2406 res = malloc(sizeof(*res));
2407 if (res)
2408 memcpy(res, &a, sizeof(a));
2409 return res;
2410}
2411
2412void *parse_markmask(const char *markmask)
2413{
2414 struct aafilter a, *res;
2415
2416 if (strchr(markmask, '/')) {
2417 if (sscanf(markmask, "%i/%i", &a.mark, &a.mask) != 2)
2418 return NULL;
2419 } else {
2420 a.mask = 0xffffffff;
2421 if (sscanf(markmask, "%i", &a.mark) != 1)
2422 return NULL;
2423 }
2424
2425 res = malloc(sizeof(*res));
2426 if (res)
2427 memcpy(res, &a, sizeof(a));
2428 return res;
2429}
2430
2431void *parse_cgroupcond(const char *path)
2432{
2433 struct aafilter *res;
2434 __u64 id;
2435
2436 id = get_cgroup2_id(path);
2437 if (!id)
2438 return NULL;
2439
2440 res = malloc(sizeof(*res));
2441 if (res)
2442 res->cgroup_id = id;
2443
2444 return res;
2445}
2446
2447static void proc_ctx_print(struct sockstat *s)
2448{
2449 char *buf;
2450
2451 if (show_proc_ctx || show_sock_ctx) {
2452 if (find_entry(s->ino, &buf,
2453 (show_proc_ctx & show_sock_ctx) ?
2454 PROC_SOCK_CTX : PROC_CTX) > 0) {
2455 out(" users:(%s)", buf);
2456 free(buf);
2457 }
2458 } else if (show_processes || show_threads) {
2459 if (find_entry(s->ino, &buf, USERS) > 0) {
2460 out(" users:(%s)", buf);
2461 free(buf);
2462 }
2463 }
2464
2465 field_next();
2466}
2467
2468static void inet_stats_print(struct sockstat *s, bool v6only)
2469{
2470 sock_state_print(s);
2471
2472 inet_addr_print(&s->local, s->lport, s->iface, v6only);
2473 inet_addr_print(&s->remote, s->rport, 0, v6only);
2474
2475 proc_ctx_print(s);
2476}
2477
2478static int proc_parse_inet_addr(char *loc, char *rem, int family, struct
2479 sockstat * s)
2480{
2481 s->local.family = s->remote.family = family;
2482 if (family == AF_INET) {
2483 sscanf(loc, "%x:%x", s->local.data, (unsigned *)&s->lport);
2484 sscanf(rem, "%x:%x", s->remote.data, (unsigned *)&s->rport);
2485 s->local.bytelen = s->remote.bytelen = 4;
2486 return 0;
2487 } else {
2488 sscanf(loc, "%08x%08x%08x%08x:%x",
2489 s->local.data,
2490 s->local.data + 1,
2491 s->local.data + 2,
2492 s->local.data + 3,
2493 &s->lport);
2494 sscanf(rem, "%08x%08x%08x%08x:%x",
2495 s->remote.data,
2496 s->remote.data + 1,
2497 s->remote.data + 2,
2498 s->remote.data + 3,
2499 &s->rport);
2500 s->local.bytelen = s->remote.bytelen = 16;
2501 return 0;
2502 }
2503 return -1;
2504}
2505
2506static int proc_inet_split_line(char *line, char **loc, char **rem, char **data)
2507{
2508 char *p;
2509
2510 if ((p = strchr(line, ':')) == NULL)
2511 return -1;
2512
2513 *loc = p+2;
2514 if ((p = strchr(*loc, ':')) == NULL)
2515 return -1;
2516
2517 p[5] = 0;
2518 *rem = p+6;
2519 if ((p = strchr(*rem, ':')) == NULL)
2520 return -1;
2521
2522 p[5] = 0;
2523 *data = p+6;
2524 return 0;
2525}
2526
2527
2528
2529
2530
2531
2532static char *sprint_bw(char *buf, double bw)
2533{
2534 if (numeric)
2535 sprintf(buf, "%.0f", bw);
2536 else if (bw >= 1e12)
2537 sprintf(buf, "%.3gT", bw / 1e12);
2538 else if (bw >= 1e9)
2539 sprintf(buf, "%.3gG", bw / 1e9);
2540 else if (bw >= 1e6)
2541 sprintf(buf, "%.3gM", bw / 1e6);
2542 else if (bw >= 1e3)
2543 sprintf(buf, "%.3gk", bw / 1e3);
2544 else
2545 sprintf(buf, "%g", bw);
2546
2547 return buf;
2548}
2549
2550static void sctp_stats_print(struct sctp_info *s)
2551{
2552 if (s->sctpi_tag)
2553 out(" tag:%x", s->sctpi_tag);
2554 if (s->sctpi_state)
2555 out(" state:%s", sctp_sstate_name[s->sctpi_state]);
2556 if (s->sctpi_rwnd)
2557 out(" rwnd:%d", s->sctpi_rwnd);
2558 if (s->sctpi_unackdata)
2559 out(" unackdata:%d", s->sctpi_unackdata);
2560 if (s->sctpi_penddata)
2561 out(" penddata:%d", s->sctpi_penddata);
2562 if (s->sctpi_instrms)
2563 out(" instrms:%d", s->sctpi_instrms);
2564 if (s->sctpi_outstrms)
2565 out(" outstrms:%d", s->sctpi_outstrms);
2566 if (s->sctpi_inqueue)
2567 out(" inqueue:%d", s->sctpi_inqueue);
2568 if (s->sctpi_outqueue)
2569 out(" outqueue:%d", s->sctpi_outqueue);
2570 if (s->sctpi_overall_error)
2571 out(" overerr:%d", s->sctpi_overall_error);
2572 if (s->sctpi_max_burst)
2573 out(" maxburst:%d", s->sctpi_max_burst);
2574 if (s->sctpi_maxseg)
2575 out(" maxseg:%d", s->sctpi_maxseg);
2576 if (s->sctpi_peer_rwnd)
2577 out(" prwnd:%d", s->sctpi_peer_rwnd);
2578 if (s->sctpi_peer_tag)
2579 out(" ptag:%x", s->sctpi_peer_tag);
2580 if (s->sctpi_peer_capable)
2581 out(" pcapable:%d", s->sctpi_peer_capable);
2582 if (s->sctpi_peer_sack)
2583 out(" psack:%d", s->sctpi_peer_sack);
2584 if (s->sctpi_s_autoclose)
2585 out(" autoclose:%d", s->sctpi_s_autoclose);
2586 if (s->sctpi_s_adaptation_ind)
2587 out(" adapind:%d", s->sctpi_s_adaptation_ind);
2588 if (s->sctpi_s_pd_point)
2589 out(" pdpoint:%d", s->sctpi_s_pd_point);
2590 if (s->sctpi_s_nodelay)
2591 out(" nodelay:%d", s->sctpi_s_nodelay);
2592 if (s->sctpi_s_disable_fragments)
2593 out(" nofrag:%d", s->sctpi_s_disable_fragments);
2594 if (s->sctpi_s_v4mapped)
2595 out(" v4mapped:%d", s->sctpi_s_v4mapped);
2596 if (s->sctpi_s_frag_interleave)
2597 out(" fraginl:%d", s->sctpi_s_frag_interleave);
2598}
2599
2600static void tcp_stats_print(struct tcpstat *s)
2601{
2602 char b1[64];
2603
2604 if (s->has_ts_opt)
2605 out(" ts");
2606 if (s->has_usec_ts_opt)
2607 out(" usec_ts");
2608 if (s->has_sack_opt)
2609 out(" sack");
2610 if (s->has_ecn_opt)
2611 out(" ecn");
2612 if (s->has_ecnseen_opt)
2613 out(" ecnseen");
2614 if (s->has_fastopen_opt)
2615 out(" fastopen");
2616 if (s->cong_alg[0])
2617 out(" %s", s->cong_alg);
2618 if (s->has_wscale_opt)
2619 out(" wscale:%d,%d", s->snd_wscale, s->rcv_wscale);
2620 if (s->rto)
2621 out(" rto:%g", s->rto);
2622 if (s->backoff)
2623 out(" backoff:%u", s->backoff);
2624 if (s->rtt)
2625 out(" rtt:%g/%g", s->rtt, s->rttvar);
2626 if (s->ato)
2627 out(" ato:%g", s->ato);
2628
2629 if (s->qack)
2630 out(" qack:%d", s->qack);
2631 if (s->qack & 1)
2632 out(" bidir");
2633
2634 if (s->mss)
2635 out(" mss:%d", s->mss);
2636 if (s->pmtu)
2637 out(" pmtu:%u", s->pmtu);
2638 if (s->rcv_mss)
2639 out(" rcvmss:%d", s->rcv_mss);
2640 if (s->advmss)
2641 out(" advmss:%d", s->advmss);
2642 if (s->cwnd)
2643 out(" cwnd:%u", s->cwnd);
2644 if (s->ssthresh)
2645 out(" ssthresh:%d", s->ssthresh);
2646
2647 if (s->bytes_sent)
2648 out(" bytes_sent:%llu", s->bytes_sent);
2649 if (s->bytes_retrans)
2650 out(" bytes_retrans:%llu", s->bytes_retrans);
2651 if (s->bytes_acked)
2652 out(" bytes_acked:%llu", s->bytes_acked);
2653 if (s->bytes_received)
2654 out(" bytes_received:%llu", s->bytes_received);
2655 if (s->segs_out)
2656 out(" segs_out:%u", s->segs_out);
2657 if (s->segs_in)
2658 out(" segs_in:%u", s->segs_in);
2659 if (s->data_segs_out)
2660 out(" data_segs_out:%u", s->data_segs_out);
2661 if (s->data_segs_in)
2662 out(" data_segs_in:%u", s->data_segs_in);
2663
2664 if (s->dctcp && s->dctcp->enabled) {
2665 struct dctcpstat *dctcp = s->dctcp;
2666
2667 out(" dctcp:(ce_state:%u,alpha:%u,ab_ecn:%u,ab_tot:%u)",
2668 dctcp->ce_state, dctcp->alpha, dctcp->ab_ecn,
2669 dctcp->ab_tot);
2670 } else if (s->dctcp) {
2671 out(" dctcp:fallback_mode");
2672 }
2673
2674 if (s->bbr_info) {
2675 __u64 bw;
2676
2677 bw = s->bbr_info->bbr_bw_hi;
2678 bw <<= 32;
2679 bw |= s->bbr_info->bbr_bw_lo;
2680
2681 out(" bbr:(bw:%sbps,mrtt:%g",
2682 sprint_bw(b1, bw * 8.0),
2683 (double)s->bbr_info->bbr_min_rtt / 1000.0);
2684 if (s->bbr_info->bbr_pacing_gain)
2685 out(",pacing_gain:%g",
2686 (double)s->bbr_info->bbr_pacing_gain / 256.0);
2687 if (s->bbr_info->bbr_cwnd_gain)
2688 out(",cwnd_gain:%g",
2689 (double)s->bbr_info->bbr_cwnd_gain / 256.0);
2690 out(")");
2691 }
2692
2693 if (s->send_bps)
2694 out(" send %sbps", sprint_bw(b1, s->send_bps));
2695 if (s->lastsnd)
2696 out(" lastsnd:%u", s->lastsnd);
2697 if (s->lastrcv)
2698 out(" lastrcv:%u", s->lastrcv);
2699 if (s->lastack)
2700 out(" lastack:%u", s->lastack);
2701
2702 if (s->pacing_rate) {
2703 out(" pacing_rate %sbps", sprint_bw(b1, s->pacing_rate));
2704 if (s->pacing_rate_max)
2705 out("/%sbps", sprint_bw(b1, s->pacing_rate_max));
2706 }
2707
2708 if (s->delivery_rate)
2709 out(" delivery_rate %sbps", sprint_bw(b1, s->delivery_rate));
2710 if (s->delivered)
2711 out(" delivered:%u", s->delivered);
2712 if (s->delivered_ce)
2713 out(" delivered_ce:%u", s->delivered_ce);
2714 if (s->app_limited)
2715 out(" app_limited");
2716
2717 if (s->busy_time) {
2718 out(" busy:%llums", s->busy_time / 1000);
2719 if (s->rwnd_limited)
2720 out(" rwnd_limited:%llums(%.1f%%)",
2721 s->rwnd_limited / 1000,
2722 100.0 * s->rwnd_limited / s->busy_time);
2723 if (s->sndbuf_limited)
2724 out(" sndbuf_limited:%llums(%.1f%%)",
2725 s->sndbuf_limited / 1000,
2726 100.0 * s->sndbuf_limited / s->busy_time);
2727 }
2728
2729 if (s->unacked)
2730 out(" unacked:%u", s->unacked);
2731 if (s->retrans || s->retrans_total)
2732 out(" retrans:%u/%u", s->retrans, s->retrans_total);
2733 if (s->lost)
2734 out(" lost:%u", s->lost);
2735 if (s->sacked && s->ss.state != SS_LISTEN)
2736 out(" sacked:%u", s->sacked);
2737 if (s->dsack_dups)
2738 out(" dsack_dups:%u", s->dsack_dups);
2739 if (s->fackets)
2740 out(" fackets:%u", s->fackets);
2741 if (s->reordering != 3)
2742 out(" reordering:%d", s->reordering);
2743 if (s->reord_seen)
2744 out(" reord_seen:%d", s->reord_seen);
2745 if (s->rcv_rtt)
2746 out(" rcv_rtt:%g", s->rcv_rtt);
2747 if (s->rcv_space)
2748 out(" rcv_space:%d", s->rcv_space);
2749 if (s->rcv_ssthresh)
2750 out(" rcv_ssthresh:%u", s->rcv_ssthresh);
2751 if (s->not_sent)
2752 out(" notsent:%u", s->not_sent);
2753 if (s->min_rtt)
2754 out(" minrtt:%g", s->min_rtt);
2755 if (s->rcv_ooopack)
2756 out(" rcv_ooopack:%u", s->rcv_ooopack);
2757 if (s->snd_wnd)
2758 out(" snd_wnd:%u", s->snd_wnd);
2759 if (s->rcv_wnd)
2760 out(" rcv_wnd:%u", s->rcv_wnd);
2761 if (s->rehash)
2762 out(" rehash:%u", s->rehash);
2763}
2764
2765static void tcp_timer_print(struct tcpstat *s)
2766{
2767 static const char * const tmr_name[] = {
2768 "off",
2769 "on",
2770 "keepalive",
2771 "timewait",
2772 "persist",
2773 "unknown"
2774 };
2775
2776 if (s->timer) {
2777 if (s->timer > 4)
2778 s->timer = 5;
2779 out(" timer:(%s,%s,%d)",
2780 tmr_name[s->timer],
2781 print_ms_timer(s->timeout),
2782 s->retrans);
2783 }
2784}
2785
2786static void sctp_timer_print(struct tcpstat *s)
2787{
2788 if (s->timer)
2789 out(" timer:(T3_RTX,%s,%d)",
2790 print_ms_timer(s->timeout), s->retrans);
2791}
2792
2793static int tcp_show_line(char *line, const struct filter *f, int family)
2794{
2795 int rto = 0, ato = 0;
2796 struct tcpstat s = {};
2797 char *loc, *rem, *data;
2798 char opt[256];
2799 int n;
2800 int hz = get_user_hz();
2801
2802 if (proc_inet_split_line(line, &loc, &rem, &data))
2803 return -1;
2804
2805 int state = (data[1] >= 'A') ? (data[1] - 'A' + 10) : (data[1] - '0');
2806
2807 if (!(f->states & (1 << state)))
2808 return 0;
2809
2810 proc_parse_inet_addr(loc, rem, family, &s.ss);
2811
2812 if (f->f && run_ssfilter(f->f, &s.ss) == 0)
2813 return 0;
2814
2815 opt[0] = 0;
2816 n = sscanf(data, "%x %x:%x %x:%x %x %d %d %u %d %llx %d %d %d %u %d %[^\n]\n",
2817 &s.ss.state, &s.ss.wq, &s.ss.rq,
2818 &s.timer, &s.timeout, &s.retrans, &s.ss.uid, &s.probes,
2819 &s.ss.ino, &s.ss.refcnt, &s.ss.sk, &rto, &ato, &s.qack, &s.cwnd,
2820 &s.ssthresh, opt);
2821
2822 if (n < 17)
2823 opt[0] = 0;
2824
2825 if (n < 12) {
2826 rto = 0;
2827 s.cwnd = 2;
2828 s.ssthresh = -1;
2829 ato = s.qack = 0;
2830 }
2831
2832 s.retrans = s.timer != 1 ? s.probes : s.retrans;
2833 s.timeout = (s.timeout * 1000 + hz - 1) / hz;
2834 s.ato = (double)ato / hz;
2835 s.qack /= 2;
2836 s.rto = (double)rto;
2837 s.ssthresh = s.ssthresh == -1 ? 0 : s.ssthresh;
2838 s.rto = s.rto != 3 * hz ? s.rto / hz : 0;
2839 s.ss.type = IPPROTO_TCP;
2840
2841 inet_stats_print(&s.ss, false);
2842
2843 if (show_options)
2844 tcp_timer_print(&s);
2845
2846 if (show_details) {
2847 sock_details_print(&s.ss);
2848 if (opt[0])
2849 out(" opt:\"%s\"", opt);
2850 }
2851
2852 if (show_tcpinfo)
2853 tcp_stats_print(&s);
2854
2855 return 0;
2856}
2857
2858static int generic_record_read(FILE *fp,
2859 int (*worker)(char*, const struct filter *, int),
2860 const struct filter *f, int fam)
2861{
2862 char line[256];
2863
2864
2865 if (fgets(line, sizeof(line), fp) == NULL)
2866 goto outerr;
2867
2868 while (fgets(line, sizeof(line), fp) != NULL) {
2869 int n = strlen(line);
2870
2871 if (n == 0 || line[n-1] != '\n') {
2872 errno = -EINVAL;
2873 return -1;
2874 }
2875 line[n-1] = 0;
2876
2877 if (worker(line, f, fam) < 0)
2878 return 0;
2879 }
2880outerr:
2881
2882 return ferror(fp) ? -1 : 0;
2883}
2884
2885static void print_skmeminfo(struct rtattr *tb[], int attrtype)
2886{
2887 const __u32 *skmeminfo;
2888
2889 if (!tb[attrtype]) {
2890 if (attrtype == INET_DIAG_SKMEMINFO) {
2891 if (!tb[INET_DIAG_MEMINFO])
2892 return;
2893
2894 const struct inet_diag_meminfo *minfo =
2895 RTA_DATA(tb[INET_DIAG_MEMINFO]);
2896
2897 out(" mem:(r%u,w%u,f%u,t%u)",
2898 minfo->idiag_rmem,
2899 minfo->idiag_wmem,
2900 minfo->idiag_fmem,
2901 minfo->idiag_tmem);
2902 }
2903 return;
2904 }
2905
2906 skmeminfo = RTA_DATA(tb[attrtype]);
2907
2908 out(" skmem:(r%u,rb%u,t%u,tb%u,f%u,w%u,o%u",
2909 skmeminfo[SK_MEMINFO_RMEM_ALLOC],
2910 skmeminfo[SK_MEMINFO_RCVBUF],
2911 skmeminfo[SK_MEMINFO_WMEM_ALLOC],
2912 skmeminfo[SK_MEMINFO_SNDBUF],
2913 skmeminfo[SK_MEMINFO_FWD_ALLOC],
2914 skmeminfo[SK_MEMINFO_WMEM_QUEUED],
2915 skmeminfo[SK_MEMINFO_OPTMEM]);
2916
2917 if (RTA_PAYLOAD(tb[attrtype]) >=
2918 (SK_MEMINFO_BACKLOG + 1) * sizeof(__u32))
2919 out(",bl%u", skmeminfo[SK_MEMINFO_BACKLOG]);
2920
2921 if (RTA_PAYLOAD(tb[attrtype]) >=
2922 (SK_MEMINFO_DROPS + 1) * sizeof(__u32))
2923 out(",d%u", skmeminfo[SK_MEMINFO_DROPS]);
2924
2925 out(")");
2926}
2927
2928
2929static void out_escape_buf(const __u8 *buf, size_t len, const char *escape)
2930{
2931 size_t i;
2932
2933 for (i = 0; i < len; ++i) {
2934 if (isprint(buf[i]) && buf[i] != '\\' &&
2935 !strchr(escape, buf[i]))
2936 out("%c", buf[i]);
2937 else
2938 out("\\%03o", buf[i]);
2939 }
2940}
2941
2942static void print_md5sig(struct tcp_diag_md5sig *sig)
2943{
2944 out("%s/%d=",
2945 format_host(sig->tcpm_family,
2946 sig->tcpm_family == AF_INET6 ? 16 : 4,
2947 &sig->tcpm_addr),
2948 sig->tcpm_prefixlen);
2949 out_escape_buf(sig->tcpm_key, sig->tcpm_keylen, " ,");
2950}
2951
2952static void tcp_tls_version(struct rtattr *attr)
2953{
2954 u_int16_t val;
2955
2956 if (!attr)
2957 return;
2958 val = rta_getattr_u16(attr);
2959
2960 switch (val) {
2961 case TLS_1_2_VERSION:
2962 out(" version: 1.2");
2963 break;
2964 case TLS_1_3_VERSION:
2965 out(" version: 1.3");
2966 break;
2967 default:
2968 out(" version: unknown(%hu)", val);
2969 break;
2970 }
2971}
2972
2973static void tcp_tls_cipher(struct rtattr *attr)
2974{
2975 u_int16_t val;
2976
2977 if (!attr)
2978 return;
2979 val = rta_getattr_u16(attr);
2980
2981 switch (val) {
2982 case TLS_CIPHER_AES_GCM_128:
2983 out(" cipher: aes-gcm-128");
2984 break;
2985 case TLS_CIPHER_AES_GCM_256:
2986 out(" cipher: aes-gcm-256");
2987 break;
2988 }
2989}
2990
2991static void tcp_tls_conf(const char *name, struct rtattr *attr)
2992{
2993 u_int16_t val;
2994
2995 if (!attr)
2996 return;
2997 val = rta_getattr_u16(attr);
2998
2999 switch (val) {
3000 case TLS_CONF_BASE:
3001 out(" %s: none", name);
3002 break;
3003 case TLS_CONF_SW:
3004 out(" %s: sw", name);
3005 break;
3006 case TLS_CONF_HW:
3007 out(" %s: hw", name);
3008 break;
3009 case TLS_CONF_HW_RECORD:
3010 out(" %s: hw-record", name);
3011 break;
3012 default:
3013 out(" %s: unknown(%hu)", name, val);
3014 break;
3015 }
3016}
3017
3018static void mptcp_subflow_info(struct rtattr *tb[])
3019{
3020 u_int32_t flags = 0;
3021
3022 if (tb[MPTCP_SUBFLOW_ATTR_FLAGS]) {
3023 char caps[32 + 1] = { 0 }, *cap = &caps[0];
3024
3025 flags = rta_getattr_u32(tb[MPTCP_SUBFLOW_ATTR_FLAGS]);
3026
3027 if (flags & MPTCP_SUBFLOW_FLAG_MCAP_REM)
3028 *cap++ = 'M';
3029 if (flags & MPTCP_SUBFLOW_FLAG_MCAP_LOC)
3030 *cap++ = 'm';
3031 if (flags & MPTCP_SUBFLOW_FLAG_JOIN_REM)
3032 *cap++ = 'J';
3033 if (flags & MPTCP_SUBFLOW_FLAG_JOIN_LOC)
3034 *cap++ = 'j';
3035 if (flags & MPTCP_SUBFLOW_FLAG_BKUP_REM)
3036 *cap++ = 'B';
3037 if (flags & MPTCP_SUBFLOW_FLAG_BKUP_LOC)
3038 *cap++ = 'b';
3039 if (flags & MPTCP_SUBFLOW_FLAG_FULLY_ESTABLISHED)
3040 *cap++ = 'e';
3041 if (flags & MPTCP_SUBFLOW_FLAG_CONNECTED)
3042 *cap++ = 'c';
3043 if (flags & MPTCP_SUBFLOW_FLAG_MAPVALID)
3044 *cap++ = 'v';
3045 if (flags)
3046 out(" flags:%s", caps);
3047 }
3048 if (tb[MPTCP_SUBFLOW_ATTR_TOKEN_REM] &&
3049 tb[MPTCP_SUBFLOW_ATTR_TOKEN_LOC] &&
3050 tb[MPTCP_SUBFLOW_ATTR_ID_REM] &&
3051 tb[MPTCP_SUBFLOW_ATTR_ID_LOC])
3052 out(" token:%04x(id:%hhu)/%04x(id:%hhu)",
3053 rta_getattr_u32(tb[MPTCP_SUBFLOW_ATTR_TOKEN_REM]),
3054 rta_getattr_u8(tb[MPTCP_SUBFLOW_ATTR_ID_REM]),
3055 rta_getattr_u32(tb[MPTCP_SUBFLOW_ATTR_TOKEN_LOC]),
3056 rta_getattr_u8(tb[MPTCP_SUBFLOW_ATTR_ID_LOC]));
3057 if (tb[MPTCP_SUBFLOW_ATTR_MAP_SEQ])
3058 out(" seq:%llu",
3059 rta_getattr_u64(tb[MPTCP_SUBFLOW_ATTR_MAP_SEQ]));
3060 if (tb[MPTCP_SUBFLOW_ATTR_MAP_SFSEQ])
3061 out(" sfseq:%u",
3062 rta_getattr_u32(tb[MPTCP_SUBFLOW_ATTR_MAP_SFSEQ]));
3063 if (tb[MPTCP_SUBFLOW_ATTR_SSN_OFFSET])
3064 out(" ssnoff:%u",
3065 rta_getattr_u32(tb[MPTCP_SUBFLOW_ATTR_SSN_OFFSET]));
3066 if (tb[MPTCP_SUBFLOW_ATTR_MAP_DATALEN])
3067 out(" maplen:%u",
3068 rta_getattr_u32(tb[MPTCP_SUBFLOW_ATTR_MAP_DATALEN]));
3069}
3070
3071#define TCPI_HAS_OPT(info, opt) !!(info->tcpi_options & (opt))
3072
3073static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r,
3074 struct rtattr *tb[])
3075{
3076 double rtt = 0;
3077 struct tcpstat s = {};
3078
3079 s.ss.state = r->idiag_state;
3080
3081 print_skmeminfo(tb, INET_DIAG_SKMEMINFO);
3082
3083 if (tb[INET_DIAG_INFO]) {
3084 struct tcp_info *info;
3085 int len = RTA_PAYLOAD(tb[INET_DIAG_INFO]);
3086
3087
3088 if (len < sizeof(*info)) {
3089 info = alloca(sizeof(*info));
3090 memcpy(info, RTA_DATA(tb[INET_DIAG_INFO]), len);
3091 memset((char *)info + len, 0, sizeof(*info) - len);
3092 } else
3093 info = RTA_DATA(tb[INET_DIAG_INFO]);
3094
3095 if (show_options) {
3096 s.has_ts_opt = TCPI_HAS_OPT(info, TCPI_OPT_TIMESTAMPS);
3097 s.has_usec_ts_opt = TCPI_HAS_OPT(info, TCPI_OPT_USEC_TS);
3098 s.has_sack_opt = TCPI_HAS_OPT(info, TCPI_OPT_SACK);
3099 s.has_ecn_opt = TCPI_HAS_OPT(info, TCPI_OPT_ECN);
3100 s.has_ecnseen_opt = TCPI_HAS_OPT(info, TCPI_OPT_ECN_SEEN);
3101 s.has_fastopen_opt = TCPI_HAS_OPT(info, TCPI_OPT_SYN_DATA);
3102 }
3103
3104 if (tb[INET_DIAG_CONG])
3105 strncpy(s.cong_alg,
3106 rta_getattr_str(tb[INET_DIAG_CONG]),
3107 sizeof(s.cong_alg) - 1);
3108
3109 if (TCPI_HAS_OPT(info, TCPI_OPT_WSCALE)) {
3110 s.has_wscale_opt = true;
3111 s.snd_wscale = info->tcpi_snd_wscale;
3112 s.rcv_wscale = info->tcpi_rcv_wscale;
3113 }
3114
3115 if (info->tcpi_rto && info->tcpi_rto != 3000000)
3116 s.rto = (double)info->tcpi_rto / 1000;
3117
3118 s.backoff = info->tcpi_backoff;
3119 s.rtt = (double)info->tcpi_rtt / 1000;
3120 s.rttvar = (double)info->tcpi_rttvar / 1000;
3121 s.ato = (double)info->tcpi_ato / 1000;
3122 s.mss = info->tcpi_snd_mss;
3123 s.rcv_mss = info->tcpi_rcv_mss;
3124 s.advmss = info->tcpi_advmss;
3125 s.rcv_space = info->tcpi_rcv_space;
3126 s.rcv_rtt = (double)info->tcpi_rcv_rtt / 1000;
3127 s.lastsnd = info->tcpi_last_data_sent;
3128 s.lastrcv = info->tcpi_last_data_recv;
3129 s.lastack = info->tcpi_last_ack_recv;
3130 s.unacked = info->tcpi_unacked;
3131 s.retrans = info->tcpi_retrans;
3132 s.retrans_total = info->tcpi_total_retrans;
3133 s.lost = info->tcpi_lost;
3134 s.sacked = info->tcpi_sacked;
3135 s.fackets = info->tcpi_fackets;
3136 s.reordering = info->tcpi_reordering;
3137 s.rcv_ssthresh = info->tcpi_rcv_ssthresh;
3138 s.cwnd = info->tcpi_snd_cwnd;
3139 s.pmtu = info->tcpi_pmtu;
3140
3141 if (info->tcpi_snd_ssthresh < 0xFFFF)
3142 s.ssthresh = info->tcpi_snd_ssthresh;
3143
3144 rtt = (double) info->tcpi_rtt;
3145 if (tb[INET_DIAG_VEGASINFO]) {
3146 const struct tcpvegas_info *vinfo
3147 = RTA_DATA(tb[INET_DIAG_VEGASINFO]);
3148
3149 if (vinfo->tcpv_enabled &&
3150 vinfo->tcpv_rtt && vinfo->tcpv_rtt != 0x7fffffff)
3151 rtt = vinfo->tcpv_rtt;
3152 }
3153
3154 if (tb[INET_DIAG_DCTCPINFO]) {
3155 struct dctcpstat *dctcp = malloc(sizeof(struct
3156 dctcpstat));
3157
3158 const struct tcp_dctcp_info *dinfo
3159 = RTA_DATA(tb[INET_DIAG_DCTCPINFO]);
3160
3161 dctcp->enabled = !!dinfo->dctcp_enabled;
3162 dctcp->ce_state = dinfo->dctcp_ce_state;
3163 dctcp->alpha = dinfo->dctcp_alpha;
3164 dctcp->ab_ecn = dinfo->dctcp_ab_ecn;
3165 dctcp->ab_tot = dinfo->dctcp_ab_tot;
3166 s.dctcp = dctcp;
3167 }
3168
3169 if (tb[INET_DIAG_BBRINFO]) {
3170 const void *bbr_info = RTA_DATA(tb[INET_DIAG_BBRINFO]);
3171 int len = min(RTA_PAYLOAD(tb[INET_DIAG_BBRINFO]),
3172 sizeof(*s.bbr_info));
3173
3174 s.bbr_info = calloc(1, sizeof(*s.bbr_info));
3175 if (s.bbr_info && bbr_info)
3176 memcpy(s.bbr_info, bbr_info, len);
3177 }
3178
3179 if (rtt > 0 && info->tcpi_snd_mss && info->tcpi_snd_cwnd) {
3180 s.send_bps = (double) info->tcpi_snd_cwnd *
3181 (double)info->tcpi_snd_mss * 8000000. / rtt;
3182 }
3183
3184 if (info->tcpi_pacing_rate &&
3185 info->tcpi_pacing_rate != ~0ULL) {
3186 s.pacing_rate = info->tcpi_pacing_rate * 8.;
3187
3188 if (info->tcpi_max_pacing_rate &&
3189 info->tcpi_max_pacing_rate != ~0ULL)
3190 s.pacing_rate_max = info->tcpi_max_pacing_rate * 8.;
3191 }
3192 s.bytes_acked = info->tcpi_bytes_acked;
3193 s.bytes_received = info->tcpi_bytes_received;
3194 s.segs_out = info->tcpi_segs_out;
3195 s.segs_in = info->tcpi_segs_in;
3196 s.data_segs_out = info->tcpi_data_segs_out;
3197 s.data_segs_in = info->tcpi_data_segs_in;
3198 s.not_sent = info->tcpi_notsent_bytes;
3199 if (info->tcpi_min_rtt && info->tcpi_min_rtt != ~0U)
3200 s.min_rtt = (double) info->tcpi_min_rtt / 1000;
3201 s.delivery_rate = info->tcpi_delivery_rate * 8.;
3202 s.app_limited = info->tcpi_delivery_rate_app_limited;
3203 s.busy_time = info->tcpi_busy_time;
3204 s.rwnd_limited = info->tcpi_rwnd_limited;
3205 s.sndbuf_limited = info->tcpi_sndbuf_limited;
3206 s.delivered = info->tcpi_delivered;
3207 s.delivered_ce = info->tcpi_delivered_ce;
3208 s.dsack_dups = info->tcpi_dsack_dups;
3209 s.reord_seen = info->tcpi_reord_seen;
3210 s.bytes_sent = info->tcpi_bytes_sent;
3211 s.bytes_retrans = info->tcpi_bytes_retrans;
3212 s.rcv_ooopack = info->tcpi_rcv_ooopack;
3213 s.snd_wnd = info->tcpi_snd_wnd;
3214 s.rcv_wnd = info->tcpi_rcv_wnd;
3215 s.rehash = info->tcpi_rehash;
3216 tcp_stats_print(&s);
3217 free(s.dctcp);
3218 free(s.bbr_info);
3219 }
3220 if (tb[INET_DIAG_MD5SIG]) {
3221 struct tcp_diag_md5sig *sig = RTA_DATA(tb[INET_DIAG_MD5SIG]);
3222 int len = RTA_PAYLOAD(tb[INET_DIAG_MD5SIG]);
3223
3224 out(" md5keys:");
3225 print_md5sig(sig++);
3226 for (len -= sizeof(*sig); len > 0; len -= sizeof(*sig)) {
3227 out(",");
3228 print_md5sig(sig++);
3229 }
3230 }
3231 if (tb[INET_DIAG_ULP_INFO]) {
3232 struct rtattr *ulpinfo[INET_ULP_INFO_MAX + 1] = { 0 };
3233
3234 parse_rtattr_nested(ulpinfo, INET_ULP_INFO_MAX,
3235 tb[INET_DIAG_ULP_INFO]);
3236
3237 if (ulpinfo[INET_ULP_INFO_NAME])
3238 out(" tcp-ulp-%s",
3239 rta_getattr_str(ulpinfo[INET_ULP_INFO_NAME]));
3240
3241 if (ulpinfo[INET_ULP_INFO_TLS]) {
3242 struct rtattr *tlsinfo[TLS_INFO_MAX + 1] = { 0 };
3243
3244 parse_rtattr_nested(tlsinfo, TLS_INFO_MAX,
3245 ulpinfo[INET_ULP_INFO_TLS]);
3246
3247 tcp_tls_version(tlsinfo[TLS_INFO_VERSION]);
3248 tcp_tls_cipher(tlsinfo[TLS_INFO_CIPHER]);
3249 tcp_tls_conf("rxconf", tlsinfo[TLS_INFO_RXCONF]);
3250 tcp_tls_conf("txconf", tlsinfo[TLS_INFO_TXCONF]);
3251 if (!!tlsinfo[TLS_INFO_ZC_RO_TX])
3252 out(" zc_ro_tx");
3253 if (!!tlsinfo[TLS_INFO_RX_NO_PAD])
3254 out(" no_pad_rx");
3255 }
3256 if (ulpinfo[INET_ULP_INFO_MPTCP]) {
3257 struct rtattr *sfinfo[MPTCP_SUBFLOW_ATTR_MAX + 1] =
3258 { 0 };
3259
3260 parse_rtattr_nested(sfinfo, MPTCP_SUBFLOW_ATTR_MAX,
3261 ulpinfo[INET_ULP_INFO_MPTCP]);
3262 mptcp_subflow_info(sfinfo);
3263 }
3264 }
3265}
3266
3267static void mptcp_stats_print(struct mptcp_info *s)
3268{
3269 if (s->mptcpi_subflows)
3270 out(" subflows:%u", s->mptcpi_subflows);
3271 if (s->mptcpi_add_addr_signal)
3272 out(" add_addr_signal:%u", s->mptcpi_add_addr_signal);
3273 if (s->mptcpi_add_addr_accepted)
3274 out(" add_addr_accepted:%u", s->mptcpi_add_addr_accepted);
3275 if (s->mptcpi_subflows_max)
3276 out(" subflows_max:%u", s->mptcpi_subflows_max);
3277 if (s->mptcpi_add_addr_signal_max)
3278 out(" add_addr_signal_max:%u", s->mptcpi_add_addr_signal_max);
3279 if (s->mptcpi_add_addr_accepted_max)
3280 out(" add_addr_accepted_max:%u", s->mptcpi_add_addr_accepted_max);
3281 if (s->mptcpi_flags & MPTCP_INFO_FLAG_FALLBACK)
3282 out(" fallback");
3283 if (s->mptcpi_flags & MPTCP_INFO_FLAG_REMOTE_KEY_RECEIVED)
3284 out(" remote_key");
3285 if (s->mptcpi_token)
3286 out(" token:%x", s->mptcpi_token);
3287 if (s->mptcpi_write_seq)
3288 out(" write_seq:%llu", s->mptcpi_write_seq);
3289 if (s->mptcpi_snd_una)
3290 out(" snd_una:%llu", s->mptcpi_snd_una);
3291 if (s->mptcpi_rcv_nxt)
3292 out(" rcv_nxt:%llu", s->mptcpi_rcv_nxt);
3293 if (s->mptcpi_local_addr_used)
3294 out(" local_addr_used:%u", s->mptcpi_local_addr_used);
3295 if (s->mptcpi_local_addr_max)
3296 out(" local_addr_max:%u", s->mptcpi_local_addr_max);
3297 if (s->mptcpi_csum_enabled)
3298 out(" csum_enabled:%u", s->mptcpi_csum_enabled);
3299 if (s->mptcpi_retransmits)
3300 out(" retransmits:%u", s->mptcpi_retransmits);
3301 if (s->mptcpi_bytes_retrans)
3302 out(" bytes_retrans:%llu", s->mptcpi_bytes_retrans);
3303 if (s->mptcpi_bytes_sent)
3304 out(" bytes_sent:%llu", s->mptcpi_bytes_sent);
3305 if (s->mptcpi_bytes_received)
3306 out(" bytes_received:%llu", s->mptcpi_bytes_received);
3307 if (s->mptcpi_bytes_acked)
3308 out(" bytes_acked:%llu", s->mptcpi_bytes_acked);
3309 if (s->mptcpi_subflows_total)
3310 out(" subflows_total:%u", s->mptcpi_subflows_total);
3311 if (s->mptcpi_last_data_sent)
3312 out(" last_data_sent:%u", s->mptcpi_last_data_sent);
3313 if (s->mptcpi_last_data_recv)
3314 out(" last_data_recv:%u", s->mptcpi_last_data_recv);
3315 if (s->mptcpi_last_ack_recv)
3316 out(" last_ack_recv:%u", s->mptcpi_last_ack_recv);
3317}
3318
3319static void mptcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r,
3320 struct rtattr *tb[])
3321{
3322 print_skmeminfo(tb, INET_DIAG_SKMEMINFO);
3323
3324 if (tb[INET_DIAG_INFO]) {
3325 struct mptcp_info *info;
3326 int len = RTA_PAYLOAD(tb[INET_DIAG_INFO]);
3327
3328
3329 if (len < sizeof(*info)) {
3330 info = alloca(sizeof(*info));
3331 memcpy(info, RTA_DATA(tb[INET_DIAG_INFO]), len);
3332 memset((char *)info + len, 0, sizeof(*info) - len);
3333 } else
3334 info = RTA_DATA(tb[INET_DIAG_INFO]);
3335
3336 mptcp_stats_print(info);
3337 }
3338}
3339
3340static const char *format_host_sa(struct sockaddr_storage *sa)
3341{
3342 union {
3343 struct sockaddr_in sin;
3344 struct sockaddr_in6 sin6;
3345 } *saddr = (void *)sa;
3346
3347 switch (sa->ss_family) {
3348 case AF_INET:
3349 return format_host(AF_INET, 4, &saddr->sin.sin_addr);
3350 case AF_INET6:
3351 return format_host(AF_INET6, 16, &saddr->sin6.sin6_addr);
3352 default:
3353 return "";
3354 }
3355}
3356
3357static void sctp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r,
3358 struct rtattr *tb[])
3359{
3360 struct sockaddr_storage *sa;
3361 int len;
3362
3363 print_skmeminfo(tb, INET_DIAG_SKMEMINFO);
3364
3365 if (tb[INET_DIAG_LOCALS]) {
3366 len = RTA_PAYLOAD(tb[INET_DIAG_LOCALS]);
3367 sa = RTA_DATA(tb[INET_DIAG_LOCALS]);
3368
3369 out(" locals:%s", format_host_sa(sa));
3370 for (sa++, len -= sizeof(*sa); len > 0; sa++, len -= sizeof(*sa))
3371 out(",%s", format_host_sa(sa));
3372
3373 }
3374 if (tb[INET_DIAG_PEERS]) {
3375 len = RTA_PAYLOAD(tb[INET_DIAG_PEERS]);
3376 sa = RTA_DATA(tb[INET_DIAG_PEERS]);
3377
3378 out(" peers:%s", format_host_sa(sa));
3379 for (sa++, len -= sizeof(*sa); len > 0; sa++, len -= sizeof(*sa))
3380 out(",%s", format_host_sa(sa));
3381 }
3382 if (tb[INET_DIAG_INFO]) {
3383 struct sctp_info *info;
3384 len = RTA_PAYLOAD(tb[INET_DIAG_INFO]);
3385
3386
3387 if (len < sizeof(*info)) {
3388 info = alloca(sizeof(*info));
3389 memcpy(info, RTA_DATA(tb[INET_DIAG_INFO]), len);
3390 memset((char *)info + len, 0, sizeof(*info) - len);
3391 } else
3392 info = RTA_DATA(tb[INET_DIAG_INFO]);
3393
3394 sctp_stats_print(info);
3395 }
3396}
3397
3398static void parse_diag_msg(struct nlmsghdr *nlh, struct sockstat *s)
3399{
3400 struct rtattr *tb[INET_DIAG_MAX+1];
3401 struct inet_diag_msg *r = NLMSG_DATA(nlh);
3402
3403 parse_rtattr(tb, INET_DIAG_MAX, (struct rtattr *)(r+1),
3404 nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
3405
3406 s->state = r->idiag_state;
3407 s->local.family = s->remote.family = r->idiag_family;
3408 s->lport = ntohs(r->id.idiag_sport);
3409 s->rport = ntohs(r->id.idiag_dport);
3410 s->wq = r->idiag_wqueue;
3411 s->rq = r->idiag_rqueue;
3412 s->ino = r->idiag_inode;
3413 s->uid = r->idiag_uid;
3414 s->iface = r->id.idiag_if;
3415 s->sk = cookie_sk_get(&r->id.idiag_cookie[0]);
3416
3417 s->mark = 0;
3418 if (tb[INET_DIAG_MARK])
3419 s->mark = rta_getattr_u32(tb[INET_DIAG_MARK]);
3420 s->cgroup_id = 0;
3421 if (tb[INET_DIAG_CGROUP_ID])
3422 s->cgroup_id = rta_getattr_u64(tb[INET_DIAG_CGROUP_ID]);
3423 if (tb[INET_DIAG_PROTOCOL])
3424 s->raw_prot = rta_getattr_u8(tb[INET_DIAG_PROTOCOL]);
3425 else
3426 s->raw_prot = 0;
3427
3428 if (s->local.family == AF_INET)
3429 s->local.bytelen = s->remote.bytelen = 4;
3430 else
3431 s->local.bytelen = s->remote.bytelen = 16;
3432
3433 memcpy(s->local.data, r->id.idiag_src, s->local.bytelen);
3434 memcpy(s->remote.data, r->id.idiag_dst, s->local.bytelen);
3435}
3436
3437#ifdef ENABLE_BPF_SKSTORAGE_SUPPORT
3438
3439#define MAX_NR_BPF_MAP_ID_OPTS 32
3440
3441struct btf;
3442
3443static struct bpf_map_opts {
3444 unsigned int nr_maps;
3445 struct bpf_sk_storage_map_info {
3446 unsigned int id;
3447 int fd;
3448 struct bpf_map_info info;
3449 struct btf *btf;
3450 struct btf_dump *dump;
3451 } maps[MAX_NR_BPF_MAP_ID_OPTS];
3452 bool show_all;
3453} bpf_map_opts;
3454
3455static void bpf_map_opts_mixed_error(void)
3456{
3457 fprintf(stderr,
3458 "ss: --bpf-maps and --bpf-map-id cannot be used together\n");
3459}
3460
3461static int bpf_maps_opts_load_btf(struct bpf_map_info *info, struct btf **btf)
3462{
3463 if (info->btf_value_type_id) {
3464 *btf = btf__load_from_kernel_by_id(info->btf_id);
3465 if (!*btf) {
3466 fprintf(stderr, "ss: failed to load BTF for map ID %u\n",
3467 info->id);
3468 return -1;
3469 }
3470 } else {
3471 *btf = NULL;
3472 }
3473
3474 return 0;
3475}
3476
3477__attribute__((format(printf, 2, 0)))
3478static void out_bpf_sk_storage_print_fn(void *ctx, const char *fmt, va_list args)
3479{
3480 vout(fmt, args);
3481}
3482
3483static int bpf_map_opts_load_info(unsigned int map_id)
3484{
3485 struct btf_dump_opts dopts = {
3486 .sz = sizeof(struct btf_dump_opts)
3487 };
3488 struct bpf_map_info info = {};
3489 uint32_t len = sizeof(info);
3490 struct btf_dump *dump;
3491 struct btf *btf;
3492 int fd;
3493 int r;
3494
3495 if (bpf_map_opts.nr_maps == MAX_NR_BPF_MAP_ID_OPTS) {
3496 fprintf(stderr,
3497 "ss: too many (> %u) BPF socket-local storage maps found, skipping map ID %u\n",
3498 MAX_NR_BPF_MAP_ID_OPTS, map_id);
3499 return 0;
3500 }
3501
3502 fd = bpf_map_get_fd_by_id(map_id);
3503 if (fd < 0) {
3504 if (errno == -ENOENT)
3505 return 0;
3506
3507 fprintf(stderr, "ss: cannot get fd for BPF map ID %u%s\n",
3508 map_id, errno == EPERM ?
3509 ": missing root permissions, CAP_BPF, or CAP_SYS_ADMIN" : "");
3510 return -1;
3511 }
3512
3513 r = bpf_obj_get_info_by_fd(fd, &info, &len);
3514 if (r) {
3515 fprintf(stderr, "ss: failed to get info for BPF map ID %u\n",
3516 map_id);
3517 close(fd);
3518 return -1;
3519 }
3520
3521 if (info.type != BPF_MAP_TYPE_SK_STORAGE) {
3522 fprintf(stderr,
3523 "ss: BPF map with ID %s has type ID %d, expecting %d ('sk_storage')\n",
3524 optarg, info.type, BPF_MAP_TYPE_SK_STORAGE);
3525 close(fd);
3526 return -1;
3527 }
3528
3529 r = bpf_maps_opts_load_btf(&info, &btf);
3530 if (r) {
3531 close(fd);
3532 return -1;
3533 }
3534
3535 dump = btf_dump__new(btf, out_bpf_sk_storage_print_fn, NULL, &dopts);
3536 if (!dump) {
3537 btf__free(btf);
3538 close(fd);
3539 fprintf(stderr, "Failed to create btf_dump object\n");
3540 return -1;
3541 }
3542
3543 bpf_map_opts.maps[bpf_map_opts.nr_maps].id = map_id;
3544 bpf_map_opts.maps[bpf_map_opts.nr_maps].fd = fd;
3545 bpf_map_opts.maps[bpf_map_opts.nr_maps].info = info;
3546 bpf_map_opts.maps[bpf_map_opts.nr_maps].btf = btf;
3547 bpf_map_opts.maps[bpf_map_opts.nr_maps++].dump = dump;
3548
3549 return 0;
3550}
3551
3552static struct bpf_sk_storage_map_info *bpf_map_opts_get_info(
3553 unsigned int map_id)
3554{
3555 unsigned int i;
3556 int r;
3557
3558 for (i = 0; i < bpf_map_opts.nr_maps; ++i) {
3559 if (bpf_map_opts.maps[i].id == map_id)
3560 return &bpf_map_opts.maps[i];
3561 }
3562
3563 r = bpf_map_opts_load_info(map_id);
3564 if (r)
3565 return NULL;
3566
3567 return &bpf_map_opts.maps[bpf_map_opts.nr_maps - 1];
3568}
3569
3570static int bpf_map_opts_add_id(const char *optarg)
3571{
3572 size_t optarg_len;
3573 unsigned long id;
3574 char *end;
3575
3576 if (bpf_map_opts.show_all) {
3577 bpf_map_opts_mixed_error();
3578 return -1;
3579 }
3580
3581 optarg_len = strlen(optarg);
3582 id = strtoul(optarg, &end, 0);
3583 if (end != optarg + optarg_len || id == 0 || id >= UINT32_MAX) {
3584 fprintf(stderr, "ss: invalid BPF map ID %s\n", optarg);
3585 return -1;
3586 }
3587
3588
3589 if (!bpf_map_opts_get_info(id))
3590 return -1;
3591
3592 return 0;
3593}
3594
3595static void bpf_map_opts_destroy(void)
3596{
3597 int i;
3598
3599 for (i = 0; i < bpf_map_opts.nr_maps; ++i) {
3600 btf_dump__free(bpf_map_opts.maps[i].dump);
3601 btf__free(bpf_map_opts.maps[i].btf);
3602 close(bpf_map_opts.maps[i].fd);
3603 }
3604}
3605
3606static struct rtattr *bpf_map_opts_alloc_rta(void)
3607{
3608 struct rtattr *stgs_rta, *fd_rta;
3609 size_t total_size;
3610 unsigned int i;
3611 void *buf;
3612
3613
3614
3615
3616
3617 if (bpf_map_opts.show_all) {
3618 total_size = RTA_LENGTH(0);
3619 } else {
3620 total_size = RTA_LENGTH(RTA_LENGTH(sizeof(int)) *
3621 bpf_map_opts.nr_maps);
3622 }
3623
3624 buf = malloc(total_size);
3625 if (!buf)
3626 return NULL;
3627
3628 stgs_rta = buf;
3629 stgs_rta->rta_type = INET_DIAG_REQ_SK_BPF_STORAGES | NLA_F_NESTED;
3630 stgs_rta->rta_len = total_size;
3631
3632
3633
3634
3635
3636 if (bpf_map_opts.show_all)
3637 return stgs_rta;
3638
3639 buf = RTA_DATA(stgs_rta);
3640 for (i = 0; i < bpf_map_opts.nr_maps; i++) {
3641 int *fd;
3642
3643 fd_rta = buf;
3644 fd_rta->rta_type = SK_DIAG_BPF_STORAGE_REQ_MAP_FD;
3645 fd_rta->rta_len = RTA_LENGTH(sizeof(int));
3646
3647 fd = RTA_DATA(fd_rta);
3648 *fd = bpf_map_opts.maps[i].fd;
3649
3650 buf += fd_rta->rta_len;
3651 }
3652
3653 return stgs_rta;
3654}
3655
3656static void out_bpf_sk_storage_oneline(struct bpf_sk_storage_map_info *info,
3657 const void *data, size_t len)
3658{
3659 struct btf_dump_type_data_opts opts = {
3660 .sz = sizeof(struct btf_dump_type_data_opts),
3661 .emit_zeroes = 1,
3662 .compact = 1
3663 };
3664 int r;
3665
3666 out(" map_id:%d", info->id);
3667 r = btf_dump__dump_type_data(info->dump, info->info.btf_value_type_id,
3668 data, len, &opts);
3669 if (r < 0)
3670 out("failed to dump data: %d", r);
3671}
3672
3673static void out_bpf_sk_storage_multiline(struct bpf_sk_storage_map_info *info,
3674 const void *data, size_t len)
3675{
3676 struct btf_dump_type_data_opts opts = {
3677 .sz = sizeof(struct btf_dump_type_data_opts),
3678 .indent_level = 2,
3679 .emit_zeroes = 1
3680 };
3681 int r;
3682
3683 out("\n\tmap_id:%d [\n", info->id);
3684
3685 r = btf_dump__dump_type_data(info->dump, info->info.btf_value_type_id,
3686 data, len, &opts);
3687 if (r < 0)
3688 out("\t\tfailed to dump data: %d", r);
3689
3690 out("\n\t]");
3691}
3692
3693static void out_bpf_sk_storage(int map_id, const void *data, size_t len)
3694{
3695 struct bpf_sk_storage_map_info *map_info;
3696
3697 map_info = bpf_map_opts_get_info(map_id);
3698 if (!map_info) {
3699
3700
3701
3702 out("\n\tmap_id: %d failed to fetch info, skipping\n", map_id);
3703 return;
3704 }
3705
3706 if (map_info->info.value_size != len) {
3707 fprintf(stderr,
3708 "map_id: %d: invalid value size, expecting %u, got %lu\n",
3709 map_id, map_info->info.value_size, len);
3710 return;
3711 }
3712
3713 if (oneline)
3714 out_bpf_sk_storage_oneline(map_info, data, len);
3715 else
3716 out_bpf_sk_storage_multiline(map_info, data, len);
3717}
3718
3719static void show_sk_bpf_storages(struct rtattr *bpf_stgs)
3720{
3721 struct rtattr *tb[SK_DIAG_BPF_STORAGE_MAX + 1], *bpf_stg;
3722 unsigned int rem, map_id;
3723 struct rtattr *value;
3724
3725 for (bpf_stg = RTA_DATA(bpf_stgs), rem = RTA_PAYLOAD(bpf_stgs);
3726 RTA_OK(bpf_stg, rem); bpf_stg = RTA_NEXT(bpf_stg, rem)) {
3727
3728 if ((bpf_stg->rta_type & NLA_TYPE_MASK) != SK_DIAG_BPF_STORAGE)
3729 continue;
3730
3731 parse_rtattr_nested(tb, SK_DIAG_BPF_STORAGE_MAX,
3732 (struct rtattr *)bpf_stg);
3733
3734 if (tb[SK_DIAG_BPF_STORAGE_MAP_ID]) {
3735 map_id = rta_getattr_u32(tb[SK_DIAG_BPF_STORAGE_MAP_ID]);
3736 value = tb[SK_DIAG_BPF_STORAGE_MAP_VALUE];
3737
3738 out_bpf_sk_storage(map_id, RTA_DATA(value),
3739 RTA_PAYLOAD(value));
3740 }
3741 }
3742}
3743
3744static bool bpf_map_opts_is_enabled(void)
3745{
3746 return bpf_map_opts.nr_maps || bpf_map_opts.show_all;
3747}
3748#endif
3749
3750static int inet_show_sock(struct nlmsghdr *nlh,
3751 struct sockstat *s)
3752{
3753 struct rtattr *tb[INET_DIAG_MAX+1];
3754 struct inet_diag_msg *r = NLMSG_DATA(nlh);
3755 unsigned char v6only = 0;
3756
3757 parse_rtattr_flags(tb, INET_DIAG_MAX, (struct rtattr *)(r+1),
3758 nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)),
3759 NLA_F_NESTED);
3760
3761 if (tb[INET_DIAG_PROTOCOL])
3762 s->type = rta_getattr_u8(tb[INET_DIAG_PROTOCOL]);
3763
3764 if (s->local.family == AF_INET6 && tb[INET_DIAG_SKV6ONLY])
3765 v6only = rta_getattr_u8(tb[INET_DIAG_SKV6ONLY]);
3766
3767 inet_stats_print(s, v6only);
3768
3769 if (show_options) {
3770 struct tcpstat t = {};
3771
3772 t.timer = r->idiag_timer;
3773 t.timeout = r->idiag_expires;
3774 t.retrans = r->idiag_retrans;
3775 if (s->type == IPPROTO_SCTP)
3776 sctp_timer_print(&t);
3777 else
3778 tcp_timer_print(&t);
3779 }
3780
3781 if (show_details) {
3782 sock_details_print(s);
3783 if (s->local.family == AF_INET6 && tb[INET_DIAG_SKV6ONLY])
3784 out(" v6only:%u", v6only);
3785
3786 if (tb[INET_DIAG_SHUTDOWN]) {
3787 unsigned char mask;
3788
3789 mask = rta_getattr_u8(tb[INET_DIAG_SHUTDOWN]);
3790 out(" %c-%c",
3791 mask & 1 ? '-' : '<', mask & 2 ? '-' : '>');
3792 }
3793 }
3794
3795 if (show_tos) {
3796 if (tb[INET_DIAG_TOS])
3797 out(" tos:%#x", rta_getattr_u8(tb[INET_DIAG_TOS]));
3798 if (tb[INET_DIAG_TCLASS])
3799 out(" tclass:%#x", rta_getattr_u8(tb[INET_DIAG_TCLASS]));
3800 if (tb[INET_DIAG_CLASS_ID])
3801 out(" class_id:%#x", rta_getattr_u32(tb[INET_DIAG_CLASS_ID]));
3802 }
3803
3804 if (show_cgroup) {
3805 if (tb[INET_DIAG_CGROUP_ID])
3806 out(" cgroup:%s", cg_id_to_path(rta_getattr_u64(tb[INET_DIAG_CGROUP_ID])));
3807 }
3808
3809 if (show_inet_sockopt) {
3810 if (tb[INET_DIAG_SOCKOPT] && RTA_PAYLOAD(tb[INET_DIAG_SOCKOPT]) >=
3811 sizeof(struct inet_diag_sockopt)) {
3812 const struct inet_diag_sockopt *sockopt =
3813 RTA_DATA(tb[INET_DIAG_SOCKOPT]);
3814 if (!oneline)
3815 out("\n\tinet-sockopt: (");
3816 else
3817 out(" inet-sockopt: (");
3818 if (sockopt->recverr)
3819 out(" recverr");
3820 if (sockopt->is_icsk)
3821 out(" is_icsk");
3822 if (sockopt->freebind)
3823 out(" freebind");
3824 if (sockopt->hdrincl)
3825 out(" hdrincl");
3826 if (sockopt->mc_loop)
3827 out(" mc_loop");
3828 if (sockopt->transparent)
3829 out(" transparent");
3830 if (sockopt->mc_all)
3831 out(" mc_all");
3832 if (sockopt->nodefrag)
3833 out(" nodefrag");
3834 if (sockopt->bind_address_no_port)
3835 out(" bind_addr_no_port");
3836 if (sockopt->recverr_rfc4884)
3837 out(" recverr_rfc4884");
3838 if (sockopt->defer_connect)
3839 out(" defer_connect");
3840 out(")");
3841 }
3842 }
3843
3844 if (show_mem || (show_tcpinfo && s->type != IPPROTO_UDP)) {
3845 if (!oneline)
3846 out("\n\t");
3847 if (s->type == IPPROTO_SCTP)
3848 sctp_show_info(nlh, r, tb);
3849 else if (s->type == IPPROTO_MPTCP)
3850 mptcp_show_info(nlh, r, tb);
3851 else
3852 tcp_show_info(nlh, r, tb);
3853 }
3854 sctp_ino = s->ino;
3855
3856#ifdef ENABLE_BPF_SKSTORAGE_SUPPORT
3857 if (tb[INET_DIAG_SK_BPF_STORAGES])
3858 show_sk_bpf_storages(tb[INET_DIAG_SK_BPF_STORAGES]);
3859#endif
3860
3861 return 0;
3862}
3863
3864static int tcpdiag_send(int fd, int protocol, struct filter *f)
3865{
3866 struct sockaddr_nl nladdr = { .nl_family = AF_NETLINK };
3867 struct {
3868 struct nlmsghdr nlh;
3869 struct inet_diag_req r;
3870 } req = {
3871 .nlh.nlmsg_len = sizeof(req),
3872 .nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST,
3873 .nlh.nlmsg_seq = MAGIC_SEQ,
3874 .r.idiag_family = AF_INET,
3875 .r.idiag_states = f->states,
3876 };
3877 char *bc = NULL;
3878 int bclen;
3879 struct msghdr msg;
3880 struct rtattr rta;
3881 struct iovec iov[3];
3882 int iovlen = 1;
3883
3884 if (protocol == IPPROTO_TCP)
3885 req.nlh.nlmsg_type = TCPDIAG_GETSOCK;
3886 else if (protocol == IPPROTO_DCCP)
3887 req.nlh.nlmsg_type = DCCPDIAG_GETSOCK;
3888 else
3889 return -1;
3890
3891 if (show_mem) {
3892 req.r.idiag_ext |= (1<<(INET_DIAG_MEMINFO-1));
3893 req.r.idiag_ext |= (1<<(INET_DIAG_SKMEMINFO-1));
3894 }
3895
3896 if (show_tcpinfo) {
3897 req.r.idiag_ext |= (1<<(INET_DIAG_INFO-1));
3898 req.r.idiag_ext |= (1<<(INET_DIAG_VEGASINFO-1));
3899 req.r.idiag_ext |= (1<<(INET_DIAG_CONG-1));
3900 }
3901
3902 if (show_tos) {
3903 req.r.idiag_ext |= (1<<(INET_DIAG_TOS-1));
3904 req.r.idiag_ext |= (1<<(INET_DIAG_TCLASS-1));
3905 }
3906
3907 iov[0] = (struct iovec){
3908 .iov_base = &req,
3909 .iov_len = sizeof(req)
3910 };
3911 if (f->f) {
3912 bclen = ssfilter_bytecompile(f->f, &bc);
3913 if (bclen) {
3914 rta.rta_type = INET_DIAG_REQ_BYTECODE;
3915 rta.rta_len = RTA_LENGTH(bclen);
3916 iov[1] = (struct iovec){ &rta, sizeof(rta) };
3917 iov[2] = (struct iovec){ bc, bclen };
3918 req.nlh.nlmsg_len += RTA_LENGTH(bclen);
3919 iovlen = 3;
3920 }
3921 }
3922
3923 msg = (struct msghdr) {
3924 .msg_name = (void *)&nladdr,
3925 .msg_namelen = sizeof(nladdr),
3926 .msg_iov = iov,
3927 .msg_iovlen = iovlen,
3928 };
3929
3930 if (sendmsg(fd, &msg, 0) < 0) {
3931 close(fd);
3932 return -1;
3933 }
3934
3935 return 0;
3936}
3937
3938static int sockdiag_send(int family, int fd, int protocol, struct filter *f)
3939{
3940 struct sockaddr_nl nladdr = { .nl_family = AF_NETLINK };
3941 DIAG_REQUEST(req, struct inet_diag_req_v2 r);
3942 struct rtattr *bpf_rta = NULL;
3943 char *bc = NULL;
3944 int bclen;
3945 __u32 proto;
3946 struct msghdr msg;
3947 struct rtattr rta_bc;
3948 struct rtattr rta_proto;
3949 struct iovec iov[6];
3950 int iovlen = 1;
3951
3952 if (family == PF_UNSPEC)
3953 return tcpdiag_send(fd, protocol, f);
3954
3955 memset(&req.r, 0, sizeof(req.r));
3956 req.r.sdiag_family = family;
3957 req.r.sdiag_protocol = protocol;
3958 req.r.idiag_states = f->states;
3959 if (show_mem) {
3960 req.r.idiag_ext |= (1<<(INET_DIAG_MEMINFO-1));
3961 req.r.idiag_ext |= (1<<(INET_DIAG_SKMEMINFO-1));
3962 }
3963
3964 if (show_tcpinfo) {
3965 req.r.idiag_ext |= (1<<(INET_DIAG_INFO-1));
3966 req.r.idiag_ext |= (1<<(INET_DIAG_VEGASINFO-1));
3967 req.r.idiag_ext |= (1<<(INET_DIAG_CONG-1));
3968 }
3969
3970 if (show_tos) {
3971 req.r.idiag_ext |= (1<<(INET_DIAG_TOS-1));
3972 req.r.idiag_ext |= (1<<(INET_DIAG_TCLASS-1));
3973 }
3974
3975 iov[0] = (struct iovec){
3976 .iov_base = &req,
3977 .iov_len = sizeof(req)
3978 };
3979 if (f->f) {
3980 bclen = ssfilter_bytecompile(f->f, &bc);
3981 if (bclen) {
3982 rta_bc.rta_type = INET_DIAG_REQ_BYTECODE;
3983 rta_bc.rta_len = RTA_LENGTH(bclen);
3984 iov[1] = (struct iovec){ &rta_bc, sizeof(rta_bc) };
3985 iov[2] = (struct iovec){ bc, bclen };
3986 req.nlh.nlmsg_len += RTA_LENGTH(bclen);
3987 iovlen = 3;
3988 }
3989 }
3990
3991
3992 if (protocol > 255) {
3993 rta_proto.rta_type = INET_DIAG_REQ_PROTOCOL;
3994 rta_proto.rta_len = RTA_LENGTH(sizeof(proto));
3995 proto = protocol;
3996 iov[iovlen] = (struct iovec){ &rta_proto, sizeof(rta_proto) };
3997 iov[iovlen + 1] = (struct iovec){ &proto, sizeof(proto) };
3998 req.nlh.nlmsg_len += RTA_LENGTH(sizeof(proto));
3999 iovlen += 2;
4000 }
4001
4002#ifdef ENABLE_BPF_SKSTORAGE_SUPPORT
4003 if (bpf_map_opts_is_enabled()) {
4004 bpf_rta = bpf_map_opts_alloc_rta();
4005 if (!bpf_rta) {
4006 fprintf(stderr,
4007 "ss: cannot alloc request for --bpf-map\n");
4008 return -1;
4009 }
4010
4011 iov[iovlen++] = (struct iovec){ bpf_rta, bpf_rta->rta_len };
4012 req.nlh.nlmsg_len += bpf_rta->rta_len;
4013 }
4014#endif
4015
4016 msg = (struct msghdr) {
4017 .msg_name = (void *)&nladdr,
4018 .msg_namelen = sizeof(nladdr),
4019 .msg_iov = iov,
4020 .msg_iovlen = iovlen,
4021 };
4022
4023 if (sendmsg(fd, &msg, 0) < 0) {
4024 free(bpf_rta);
4025 close(fd);
4026 return -1;
4027 }
4028
4029 free(bpf_rta);
4030
4031 return 0;
4032}
4033
4034struct inet_diag_arg {
4035 struct filter *f;
4036 int protocol;
4037 struct rtnl_handle *rth;
4038};
4039
4040static int kill_inet_sock(struct nlmsghdr *h, void *arg, struct sockstat *s)
4041{
4042 struct inet_diag_msg *d = NLMSG_DATA(h);
4043 struct inet_diag_arg *diag_arg = arg;
4044 struct rtnl_handle *rth = diag_arg->rth;
4045
4046 DIAG_REQUEST(req, struct inet_diag_req_v2 r);
4047
4048 req.nlh.nlmsg_type = SOCK_DESTROY;
4049 req.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
4050 req.nlh.nlmsg_seq = ++rth->seq;
4051 req.r.sdiag_family = d->idiag_family;
4052 req.r.sdiag_protocol = diag_arg->protocol;
4053 req.r.id = d->id;
4054
4055 if (diag_arg->protocol == IPPROTO_RAW) {
4056 struct inet_diag_req_raw *raw = (void *)&req.r;
4057
4058 BUILD_BUG_ON(sizeof(req.r) != sizeof(*raw));
4059 raw->sdiag_raw_protocol = s->raw_prot;
4060 }
4061
4062 return rtnl_talk(rth, &req.nlh, NULL);
4063}
4064
4065static int show_one_inet_sock(struct nlmsghdr *h, void *arg)
4066{
4067 int err;
4068 struct inet_diag_arg *diag_arg = arg;
4069 struct inet_diag_msg *r = NLMSG_DATA(h);
4070 struct sockstat s = {};
4071
4072 if (!(diag_arg->f->families & FAMILY_MASK(r->idiag_family)))
4073 return 0;
4074
4075 parse_diag_msg(h, &s);
4076 s.type = diag_arg->protocol;
4077
4078 if (diag_arg->f->f && run_ssfilter(diag_arg->f->f, &s) == 0)
4079 return 0;
4080
4081 if (diag_arg->f->kill && kill_inet_sock(h, arg, &s) != 0) {
4082 if (errno == EOPNOTSUPP || errno == ENOENT) {
4083
4084 return 0;
4085 } else {
4086 perror("SOCK_DESTROY answers");
4087 return -1;
4088 }
4089 }
4090
4091 err = inet_show_sock(h, &s);
4092 if (err < 0)
4093 return err;
4094
4095 return 0;
4096}
4097
4098static int inet_show_netlink(struct filter *f, FILE *dump_fp, int protocol)
4099{
4100 int err = 0;
4101 struct rtnl_handle rth, rth2;
4102 int family = PF_INET;
4103 struct inet_diag_arg arg = { .f = f, .protocol = protocol };
4104
4105 if (rtnl_open_byproto(&rth, 0, NETLINK_SOCK_DIAG))
4106 return -1;
4107
4108 if (f->kill) {
4109 if (rtnl_open_byproto(&rth2, 0, NETLINK_SOCK_DIAG)) {
4110 rtnl_close(&rth);
4111 return -1;
4112 }
4113 arg.rth = &rth2;
4114 }
4115
4116 rth.dump = MAGIC_SEQ;
4117 rth.dump_fp = dump_fp;
4118 if (preferred_family == PF_INET6)
4119 family = PF_INET6;
4120
4121
4122
4123
4124
4125
4126 if (protocol > 255)
4127 rth.flags |= RTNL_HANDLE_F_SUPPRESS_NLERR;
4128
4129again:
4130 if ((err = sockdiag_send(family, rth.fd, protocol, f)))
4131 goto Exit;
4132
4133 if ((err = rtnl_dump_filter(&rth, show_one_inet_sock, &arg))) {
4134 if (family != PF_UNSPEC) {
4135 family = PF_UNSPEC;
4136 goto again;
4137 }
4138 goto Exit;
4139 }
4140 if (family == PF_INET && preferred_family != PF_INET) {
4141 family = PF_INET6;
4142 goto again;
4143 }
4144
4145Exit:
4146 rtnl_close(&rth);
4147 if (arg.rth)
4148 rtnl_close(arg.rth);
4149 return err;
4150}
4151
4152static int tcp_show_netlink_file(struct filter *f)
4153{
4154 FILE *fp;
4155 char buf[16384];
4156 int err = -1;
4157
4158 if ((fp = fopen(getenv("TCPDIAG_FILE"), "r")) == NULL) {
4159 perror("fopen($TCPDIAG_FILE)");
4160 return err;
4161 }
4162
4163 while (1) {
4164 int err2;
4165 size_t status, nitems;
4166 struct nlmsghdr *h = (struct nlmsghdr *)buf;
4167 struct sockstat s = {};
4168
4169 status = fread(buf, 1, sizeof(*h), fp);
4170 if (status != sizeof(*h)) {
4171 if (ferror(fp))
4172 perror("Reading header from $TCPDIAG_FILE");
4173 if (feof(fp))
4174 fprintf(stderr, "Unexpected EOF reading $TCPDIAG_FILE");
4175 break;
4176 }
4177
4178 nitems = NLMSG_ALIGN(h->nlmsg_len - sizeof(*h));
4179 status = fread(h+1, 1, nitems, fp);
4180
4181 if (status != nitems) {
4182 if (ferror(fp))
4183 perror("Reading $TCPDIAG_FILE");
4184 if (feof(fp))
4185 fprintf(stderr, "Unexpected EOF reading $TCPDIAG_FILE");
4186 break;
4187 }
4188
4189
4190 if (h->nlmsg_type == NLMSG_DONE) {
4191 err = 0;
4192 break;
4193 }
4194
4195 if (h->nlmsg_type == NLMSG_ERROR) {
4196 struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(h);
4197
4198 if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
4199 fprintf(stderr, "ERROR truncated\n");
4200 } else {
4201 errno = -err->error;
4202 perror("TCPDIAG answered");
4203 }
4204 break;
4205 }
4206
4207 parse_diag_msg(h, &s);
4208 s.type = IPPROTO_TCP;
4209
4210 if (f && f->f && run_ssfilter(f->f, &s) == 0)
4211 continue;
4212
4213 err2 = inet_show_sock(h, &s);
4214 if (err2 < 0) {
4215 err = err2;
4216 break;
4217 }
4218 }
4219
4220 fclose(fp);
4221 return err;
4222}
4223
4224static int tcp_show(struct filter *f)
4225{
4226 FILE *fp = NULL;
4227 char *buf = NULL;
4228 int bufsize = 1024*1024;
4229
4230 if (!filter_af_get(f, AF_INET) && !filter_af_get(f, AF_INET6))
4231 return 0;
4232
4233 dg_proto = TCP_PROTO;
4234
4235 if (getenv("TCPDIAG_FILE"))
4236 return tcp_show_netlink_file(f);
4237
4238 if (!getenv("PROC_NET_TCP") && !getenv("PROC_ROOT")
4239 && inet_show_netlink(f, NULL, IPPROTO_TCP) == 0)
4240 return 0;
4241
4242
4243 while (bufsize >= 64*1024) {
4244 if ((buf = malloc(bufsize)) != NULL)
4245 break;
4246 bufsize /= 2;
4247 }
4248 if (buf == NULL) {
4249 errno = ENOMEM;
4250 return -1;
4251 }
4252
4253 if (f->families & FAMILY_MASK(AF_INET)) {
4254 if ((fp = net_tcp_open()) == NULL)
4255 goto outerr;
4256
4257 setbuffer(fp, buf, bufsize);
4258 if (generic_record_read(fp, tcp_show_line, f, AF_INET))
4259 goto outerr;
4260 fclose(fp);
4261 }
4262
4263 if ((f->families & FAMILY_MASK(AF_INET6)) &&
4264 (fp = net_tcp6_open()) != NULL) {
4265 setbuffer(fp, buf, bufsize);
4266 if (generic_record_read(fp, tcp_show_line, f, AF_INET6))
4267 goto outerr;
4268 fclose(fp);
4269 }
4270
4271 free(buf);
4272 return 0;
4273
4274outerr:
4275 do {
4276 int saved_errno = errno;
4277
4278 free(buf);
4279 if (fp)
4280 fclose(fp);
4281 errno = saved_errno;
4282 return -1;
4283 } while (0);
4284}
4285
4286static int mptcp_show(struct filter *f)
4287{
4288 if (!filter_af_get(f, AF_INET) && !filter_af_get(f, AF_INET6))
4289 return 0;
4290
4291 if (!getenv("PROC_NET_MPTCP") && !getenv("PROC_ROOT")
4292 && inet_show_netlink(f, NULL, IPPROTO_MPTCP) == 0)
4293 return 0;
4294
4295 return 0;
4296}
4297
4298static int dccp_show(struct filter *f)
4299{
4300 if (!filter_af_get(f, AF_INET) && !filter_af_get(f, AF_INET6))
4301 return 0;
4302
4303 if (!getenv("PROC_NET_DCCP") && !getenv("PROC_ROOT")
4304 && inet_show_netlink(f, NULL, IPPROTO_DCCP) == 0)
4305 return 0;
4306
4307 return 0;
4308}
4309
4310static int sctp_show(struct filter *f)
4311{
4312 if (!filter_af_get(f, AF_INET) && !filter_af_get(f, AF_INET6))
4313 return 0;
4314
4315 if (!getenv("PROC_NET_SCTP") && !getenv("PROC_ROOT")
4316 && inet_show_netlink(f, NULL, IPPROTO_SCTP) == 0)
4317 return 0;
4318
4319 return 0;
4320}
4321
4322static int dgram_show_line(char *line, const struct filter *f, int family)
4323{
4324 struct sockstat s = {};
4325 char *loc, *rem, *data;
4326 char opt[256];
4327 int n;
4328
4329 if (proc_inet_split_line(line, &loc, &rem, &data))
4330 return -1;
4331
4332 int state = (data[1] >= 'A') ? (data[1] - 'A' + 10) : (data[1] - '0');
4333
4334 if (!(f->states & (1 << state)))
4335 return 0;
4336
4337 proc_parse_inet_addr(loc, rem, family, &s);
4338
4339 if (f->f && run_ssfilter(f->f, &s) == 0)
4340 return 0;
4341
4342 opt[0] = 0;
4343 n = sscanf(data, "%x %x:%x %*x:%*x %*x %d %*d %u %d %llx %[^\n]\n",
4344 &s.state, &s.wq, &s.rq,
4345 &s.uid, &s.ino,
4346 &s.refcnt, &s.sk, opt);
4347
4348 if (n < 9)
4349 opt[0] = 0;
4350
4351 s.type = dg_proto == UDP_PROTO ? IPPROTO_UDP : 0;
4352 inet_stats_print(&s, false);
4353
4354 if (show_details && opt[0])
4355 out(" opt:\"%s\"", opt);
4356
4357 return 0;
4358}
4359
4360static int udp_show(struct filter *f)
4361{
4362 FILE *fp = NULL;
4363
4364 if (!filter_af_get(f, AF_INET) && !filter_af_get(f, AF_INET6))
4365 return 0;
4366
4367 dg_proto = UDP_PROTO;
4368
4369 if (!getenv("PROC_NET_UDP") && !getenv("PROC_ROOT")
4370 && inet_show_netlink(f, NULL, IPPROTO_UDP) == 0)
4371 return 0;
4372
4373 if (f->families&FAMILY_MASK(AF_INET)) {
4374 if ((fp = net_udp_open()) == NULL)
4375 goto outerr;
4376 if (generic_record_read(fp, dgram_show_line, f, AF_INET))
4377 goto outerr;
4378 fclose(fp);
4379 }
4380
4381 if ((f->families&FAMILY_MASK(AF_INET6)) &&
4382 (fp = net_udp6_open()) != NULL) {
4383 if (generic_record_read(fp, dgram_show_line, f, AF_INET6))
4384 goto outerr;
4385 fclose(fp);
4386 }
4387 return 0;
4388
4389outerr:
4390 do {
4391 int saved_errno = errno;
4392
4393 if (fp)
4394 fclose(fp);
4395 errno = saved_errno;
4396 return -1;
4397 } while (0);
4398}
4399
4400static int raw_show(struct filter *f)
4401{
4402 FILE *fp = NULL;
4403
4404 if (!filter_af_get(f, AF_INET) && !filter_af_get(f, AF_INET6))
4405 return 0;
4406
4407 dg_proto = RAW_PROTO;
4408
4409 if (!getenv("PROC_NET_RAW") && !getenv("PROC_ROOT") &&
4410 inet_show_netlink(f, NULL, IPPROTO_RAW) == 0)
4411 return 0;
4412
4413 if (f->families&FAMILY_MASK(AF_INET)) {
4414 if ((fp = net_raw_open()) == NULL)
4415 goto outerr;
4416 if (generic_record_read(fp, dgram_show_line, f, AF_INET))
4417 goto outerr;
4418 fclose(fp);
4419 }
4420
4421 if ((f->families&FAMILY_MASK(AF_INET6)) &&
4422 (fp = net_raw6_open()) != NULL) {
4423 if (generic_record_read(fp, dgram_show_line, f, AF_INET6))
4424 goto outerr;
4425 fclose(fp);
4426 }
4427 return 0;
4428
4429outerr:
4430 do {
4431 int saved_errno = errno;
4432
4433 if (fp)
4434 fclose(fp);
4435 errno = saved_errno;
4436 return -1;
4437 } while (0);
4438}
4439
4440#define MAX_UNIX_REMEMBER (1024*1024/sizeof(struct sockstat))
4441
4442static void unix_list_drop_first(struct sockstat **list)
4443{
4444 struct sockstat *s = *list;
4445
4446 (*list) = (*list)->next;
4447 free(s->name);
4448 free(s);
4449}
4450
4451static bool unix_type_skip(struct sockstat *s, struct filter *f)
4452{
4453 if (s->type == SOCK_STREAM && !(f->dbs&(1<<UNIX_ST_DB)))
4454 return true;
4455 if (s->type == SOCK_DGRAM && !(f->dbs&(1<<UNIX_DG_DB)))
4456 return true;
4457 if (s->type == SOCK_SEQPACKET && !(f->dbs&(1<<UNIX_SQ_DB)))
4458 return true;
4459 return false;
4460}
4461
4462static void unix_stats_print(struct sockstat *s, struct filter *f)
4463{
4464 char port_name[30] = {};
4465
4466 sock_state_print(s);
4467
4468 sock_addr_print(s->name ?: "*", " ",
4469 uint_to_str(s->lport, port_name), NULL);
4470 sock_addr_print(s->peer_name ?: "*", " ",
4471 uint_to_str(s->rport, port_name), NULL);
4472
4473 proc_ctx_print(s);
4474}
4475
4476static int unix_show_sock(struct nlmsghdr *nlh, void *arg)
4477{
4478 struct filter *f = (struct filter *)arg;
4479 struct unix_diag_msg *r = NLMSG_DATA(nlh);
4480 struct rtattr *tb[UNIX_DIAG_MAX+1];
4481 char name[128];
4482 struct sockstat stat = { .name = "*", .peer_name = "*" };
4483
4484 parse_rtattr(tb, UNIX_DIAG_MAX, (struct rtattr *)(r+1),
4485 nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
4486
4487 stat.type = r->udiag_type;
4488 stat.state = r->udiag_state;
4489 stat.ino = stat.lport = r->udiag_ino;
4490 stat.local.family = stat.remote.family = AF_UNIX;
4491
4492 if (unix_type_skip(&stat, f))
4493 return 0;
4494
4495 if (tb[UNIX_DIAG_RQLEN]) {
4496 struct unix_diag_rqlen *rql = RTA_DATA(tb[UNIX_DIAG_RQLEN]);
4497
4498 stat.rq = rql->udiag_rqueue;
4499 stat.wq = rql->udiag_wqueue;
4500 }
4501 if (tb[UNIX_DIAG_NAME]) {
4502 int len = RTA_PAYLOAD(tb[UNIX_DIAG_NAME]);
4503
4504 memcpy(name, RTA_DATA(tb[UNIX_DIAG_NAME]), len);
4505 name[len] = '\0';
4506 if (name[0] == '\0') {
4507 int i;
4508 for (i = 0; i < len; i++)
4509 if (name[i] == '\0')
4510 name[i] = '@';
4511 }
4512 stat.name = &name[0];
4513 memcpy(stat.local.data, &stat.name, sizeof(stat.name));
4514 }
4515 if (tb[UNIX_DIAG_PEER])
4516 stat.rport = rta_getattr_u32(tb[UNIX_DIAG_PEER]);
4517
4518 if (f->f && run_ssfilter(f->f, &stat) == 0)
4519 return 0;
4520
4521 unix_stats_print(&stat, f);
4522
4523 if (show_mem)
4524 print_skmeminfo(tb, UNIX_DIAG_MEMINFO);
4525 if (show_details) {
4526 if (tb[UNIX_DIAG_SHUTDOWN]) {
4527 unsigned char mask;
4528
4529 mask = rta_getattr_u8(tb[UNIX_DIAG_SHUTDOWN]);
4530 out(" %c-%c",
4531 mask & 1 ? '-' : '<', mask & 2 ? '-' : '>');
4532 }
4533 if (tb[UNIX_DIAG_VFS]) {
4534 struct unix_diag_vfs *uv = RTA_DATA(tb[UNIX_DIAG_VFS]);
4535
4536 out(" ino:%u dev:%u/%u", uv->udiag_vfs_ino, major(uv->udiag_vfs_dev),
4537 minor(uv->udiag_vfs_dev));
4538 }
4539 if (tb[UNIX_DIAG_ICONS]) {
4540 int len = RTA_PAYLOAD(tb[UNIX_DIAG_ICONS]);
4541 __u32 *peers = RTA_DATA(tb[UNIX_DIAG_ICONS]);
4542 int i;
4543
4544 out(" peers:");
4545 for (i = 0; i < len / sizeof(__u32); i++)
4546 out(" %u", peers[i]);
4547 }
4548 }
4549
4550 return 0;
4551}
4552
4553static int handle_netlink_request(struct filter *f, struct nlmsghdr *req,
4554 size_t size, rtnl_filter_t show_one_sock)
4555{
4556 int ret = -1;
4557 struct rtnl_handle rth;
4558
4559 if (rtnl_open_byproto(&rth, 0, NETLINK_SOCK_DIAG))
4560 return -1;
4561
4562 rth.dump = MAGIC_SEQ;
4563
4564 if (rtnl_send(&rth, req, size) < 0)
4565 goto Exit;
4566
4567 if (rtnl_dump_filter(&rth, show_one_sock, f))
4568 goto Exit;
4569
4570 ret = 0;
4571Exit:
4572 rtnl_close(&rth);
4573 return ret;
4574}
4575
4576static int unix_show_netlink(struct filter *f)
4577{
4578 DIAG_REQUEST(req, struct unix_diag_req r);
4579
4580 req.r.sdiag_family = AF_UNIX;
4581 req.r.udiag_states = f->states;
4582 req.r.udiag_show = UDIAG_SHOW_NAME | UDIAG_SHOW_PEER | UDIAG_SHOW_RQLEN;
4583 if (show_mem)
4584 req.r.udiag_show |= UDIAG_SHOW_MEMINFO;
4585 if (show_details)
4586 req.r.udiag_show |= UDIAG_SHOW_VFS | UDIAG_SHOW_ICONS;
4587
4588 return handle_netlink_request(f, &req.nlh, sizeof(req), unix_show_sock);
4589}
4590
4591static int unix_show(struct filter *f)
4592{
4593 FILE *fp;
4594 char buf[256];
4595 char name[128];
4596 int newformat = 0;
4597 int cnt;
4598 struct sockstat *list = NULL;
4599 const int unix_state_map[] = { SS_CLOSE, SS_SYN_SENT,
4600 SS_ESTABLISHED, SS_CLOSING };
4601
4602 if (!filter_af_get(f, AF_UNIX))
4603 return 0;
4604
4605 if (!getenv("PROC_NET_UNIX") && !getenv("PROC_ROOT")
4606 && unix_show_netlink(f) == 0)
4607 return 0;
4608
4609 if ((fp = net_unix_open()) == NULL)
4610 return -1;
4611 if (!fgets(buf, sizeof(buf), fp)) {
4612 fclose(fp);
4613 return -1;
4614 }
4615
4616 if (memcmp(buf, "Peer", 4) == 0)
4617 newformat = 1;
4618 cnt = 0;
4619
4620 while (fgets(buf, sizeof(buf), fp)) {
4621 struct sockstat *u, **insp;
4622 int flags;
4623
4624 if (!(u = calloc(1, sizeof(*u))))
4625 break;
4626
4627 if (sscanf(buf, "%x: %x %x %x %x %x %d %s",
4628 &u->rport, &u->rq, &u->wq, &flags, &u->type,
4629 &u->state, &u->ino, name) < 8)
4630 name[0] = 0;
4631
4632 u->lport = u->ino;
4633 u->local.family = u->remote.family = AF_UNIX;
4634
4635 if (flags & (1 << 16)) {
4636 u->state = SS_LISTEN;
4637 } else if (u->state > 0 &&
4638 u->state <= ARRAY_SIZE(unix_state_map)) {
4639 u->state = unix_state_map[u->state-1];
4640 if (u->type == SOCK_DGRAM && u->state == SS_CLOSE && u->rport)
4641 u->state = SS_ESTABLISHED;
4642 }
4643 if (unix_type_skip(u, f) ||
4644 !(f->states & (1 << u->state))) {
4645 free(u);
4646 continue;
4647 }
4648
4649 if (!newformat) {
4650 u->rport = 0;
4651 u->rq = 0;
4652 u->wq = 0;
4653 }
4654
4655 if (name[0]) {
4656 u->name = strdup(name);
4657 if (!u->name) {
4658 free(u);
4659 break;
4660 }
4661 }
4662
4663 if (u->rport) {
4664 struct sockstat *p;
4665
4666 for (p = list; p; p = p->next) {
4667 if (u->rport == p->lport)
4668 break;
4669 }
4670 if (!p)
4671 u->peer_name = "?";
4672 else
4673 u->peer_name = p->name ? : "*";
4674 }
4675
4676 if (f->f) {
4677 struct sockstat st = {
4678 .local.family = AF_UNIX,
4679 .remote.family = AF_UNIX,
4680 };
4681
4682 memcpy(st.local.data, &u->name, sizeof(u->name));
4683
4684
4685
4686 if (u->peer_name && strcmp(u->peer_name, "*"))
4687 memcpy(st.remote.data, &u->peer_name,
4688 sizeof(u->peer_name));
4689 if (run_ssfilter(f->f, &st) == 0) {
4690 free(u->name);
4691 free(u);
4692 continue;
4693 }
4694 }
4695
4696 insp = &list;
4697 while (*insp) {
4698 if (u->type < (*insp)->type ||
4699 (u->type == (*insp)->type &&
4700 u->ino < (*insp)->ino))
4701 break;
4702 insp = &(*insp)->next;
4703 }
4704 u->next = *insp;
4705 *insp = u;
4706
4707 if (++cnt > MAX_UNIX_REMEMBER) {
4708 while (list) {
4709 unix_stats_print(list, f);
4710 unix_list_drop_first(&list);
4711 }
4712 cnt = 0;
4713 }
4714 }
4715 fclose(fp);
4716 while (list) {
4717 unix_stats_print(list, f);
4718 unix_list_drop_first(&list);
4719 }
4720
4721 return 0;
4722}
4723
4724static int packet_stats_print(struct sockstat *s, const struct filter *f)
4725{
4726 const char *addr, *port;
4727 char ll_name[16];
4728
4729 s->local.family = s->remote.family = AF_PACKET;
4730
4731 if (f->f) {
4732 s->local.data[0] = s->prot;
4733 if (run_ssfilter(f->f, s) == 0)
4734 return 1;
4735 }
4736
4737 sock_state_print(s);
4738
4739 if (s->prot == 3)
4740 addr = "*";
4741 else
4742 addr = ll_proto_n2a(htons(s->prot), ll_name, sizeof(ll_name));
4743
4744 if (s->iface == 0)
4745 port = "*";
4746 else
4747 port = xll_index_to_name(s->iface);
4748
4749 sock_addr_print(addr, ":", port, NULL);
4750 sock_addr_print("", "*", "", NULL);
4751
4752 proc_ctx_print(s);
4753
4754 if (show_details)
4755 sock_details_print(s);
4756
4757 return 0;
4758}
4759
4760static void packet_show_ring(struct packet_diag_ring *ring)
4761{
4762 out("blk_size:%d", ring->pdr_block_size);
4763 out(",blk_nr:%d", ring->pdr_block_nr);
4764 out(",frm_size:%d", ring->pdr_frame_size);
4765 out(",frm_nr:%d", ring->pdr_frame_nr);
4766 out(",tmo:%d", ring->pdr_retire_tmo);
4767 out(",features:0x%x", ring->pdr_features);
4768}
4769
4770static int packet_show_sock(struct nlmsghdr *nlh, void *arg)
4771{
4772 const struct filter *f = arg;
4773 struct packet_diag_msg *r = NLMSG_DATA(nlh);
4774 struct packet_diag_info *pinfo = NULL;
4775 struct packet_diag_ring *ring_rx = NULL, *ring_tx = NULL;
4776 struct rtattr *tb[PACKET_DIAG_MAX+1];
4777 struct sockstat stat = {};
4778 uint32_t fanout = 0;
4779 bool has_fanout = false;
4780
4781 parse_rtattr(tb, PACKET_DIAG_MAX, (struct rtattr *)(r+1),
4782 nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
4783
4784
4785 if (!tb[PACKET_DIAG_MEMINFO])
4786 return -1;
4787
4788 stat.type = r->pdiag_type;
4789 stat.prot = r->pdiag_num;
4790 stat.ino = r->pdiag_ino;
4791 stat.state = SS_CLOSE;
4792 stat.sk = cookie_sk_get(&r->pdiag_cookie[0]);
4793
4794 if (tb[PACKET_DIAG_MEMINFO]) {
4795 __u32 *skmeminfo = RTA_DATA(tb[PACKET_DIAG_MEMINFO]);
4796
4797 stat.rq = skmeminfo[SK_MEMINFO_RMEM_ALLOC];
4798 }
4799
4800 if (tb[PACKET_DIAG_INFO]) {
4801 pinfo = RTA_DATA(tb[PACKET_DIAG_INFO]);
4802 stat.lport = stat.iface = pinfo->pdi_index;
4803 }
4804
4805 if (tb[PACKET_DIAG_UID])
4806 stat.uid = rta_getattr_u32(tb[PACKET_DIAG_UID]);
4807
4808 if (tb[PACKET_DIAG_RX_RING])
4809 ring_rx = RTA_DATA(tb[PACKET_DIAG_RX_RING]);
4810
4811 if (tb[PACKET_DIAG_TX_RING])
4812 ring_tx = RTA_DATA(tb[PACKET_DIAG_TX_RING]);
4813
4814 if (tb[PACKET_DIAG_FANOUT]) {
4815 has_fanout = true;
4816 fanout = rta_getattr_u32(tb[PACKET_DIAG_FANOUT]);
4817 }
4818
4819 if (packet_stats_print(&stat, f))
4820 return 0;
4821
4822 if (show_details) {
4823 if (pinfo) {
4824 if (oneline)
4825 out(" ver:%d", pinfo->pdi_version);
4826 else
4827 out("\n\tver:%d", pinfo->pdi_version);
4828 out(" cpy_thresh:%d", pinfo->pdi_copy_thresh);
4829 out(" flags( ");
4830 if (pinfo->pdi_flags & PDI_RUNNING)
4831 out("running");
4832 if (pinfo->pdi_flags & PDI_AUXDATA)
4833 out(" auxdata");
4834 if (pinfo->pdi_flags & PDI_ORIGDEV)
4835 out(" origdev");
4836 if (pinfo->pdi_flags & PDI_VNETHDR)
4837 out(" vnethdr");
4838 if (pinfo->pdi_flags & PDI_LOSS)
4839 out(" loss");
4840 if (!pinfo->pdi_flags)
4841 out("0");
4842 out(" )");
4843 }
4844 if (ring_rx) {
4845 if (oneline)
4846 out(" ring_rx(");
4847 else
4848 out("\n\tring_rx(");
4849 packet_show_ring(ring_rx);
4850 out(")");
4851 }
4852 if (ring_tx) {
4853 if (oneline)
4854 out(" ring_tx(");
4855 else
4856 out("\n\tring_tx(");
4857 packet_show_ring(ring_tx);
4858 out(")");
4859 }
4860 if (has_fanout) {
4861 uint16_t type = (fanout >> 16) & 0xffff;
4862
4863 if (oneline)
4864 out(" fanout(");
4865 else
4866 out("\n\tfanout(");
4867 out("id:%d,", fanout & 0xffff);
4868 out("type:");
4869
4870 if (type == 0)
4871 out("hash");
4872 else if (type == 1)
4873 out("lb");
4874 else if (type == 2)
4875 out("cpu");
4876 else if (type == 3)
4877 out("roll");
4878 else if (type == 4)
4879 out("random");
4880 else if (type == 5)
4881 out("qm");
4882 else
4883 out("0x%x", type);
4884
4885 out(")");
4886 }
4887 }
4888
4889 if (show_bpf && tb[PACKET_DIAG_FILTER]) {
4890 struct sock_filter *fil =
4891 RTA_DATA(tb[PACKET_DIAG_FILTER]);
4892 int num = RTA_PAYLOAD(tb[PACKET_DIAG_FILTER]) /
4893 sizeof(struct sock_filter);
4894
4895 if (oneline)
4896 out(" bpf filter (%d): ", num);
4897 else
4898 out("\n\tbpf filter (%d): ", num);
4899 while (num) {
4900 out(" 0x%02x %u %u %u,",
4901 fil->code, fil->jt, fil->jf, fil->k);
4902 num--;
4903 fil++;
4904 }
4905 }
4906
4907 if (show_mem)
4908 print_skmeminfo(tb, PACKET_DIAG_MEMINFO);
4909 return 0;
4910}
4911
4912static int packet_show_netlink(struct filter *f)
4913{
4914 DIAG_REQUEST(req, struct packet_diag_req r);
4915
4916 req.r.sdiag_family = AF_PACKET;
4917 req.r.pdiag_show = PACKET_SHOW_INFO | PACKET_SHOW_MEMINFO |
4918 PACKET_SHOW_FILTER | PACKET_SHOW_RING_CFG | PACKET_SHOW_FANOUT;
4919
4920 return handle_netlink_request(f, &req.nlh, sizeof(req), packet_show_sock);
4921}
4922
4923static int packet_show_line(char *buf, const struct filter *f, int fam)
4924{
4925 unsigned long long sk;
4926 struct sockstat stat = {};
4927 int type, prot, iface, state, rq, uid, ino;
4928
4929 sscanf(buf, "%llx %*d %d %x %d %d %u %u %u",
4930 &sk,
4931 &type, &prot, &iface, &state,
4932 &rq, &uid, &ino);
4933
4934 if (type == SOCK_RAW && !(f->dbs & (1<<PACKET_R_DB)))
4935 return 0;
4936 if (type == SOCK_DGRAM && !(f->dbs & (1<<PACKET_DG_DB)))
4937 return 0;
4938
4939 stat.type = type;
4940 stat.prot = prot;
4941 stat.lport = stat.iface = iface;
4942 stat.state = state;
4943 stat.rq = rq;
4944 stat.uid = uid;
4945 stat.ino = ino;
4946 stat.state = SS_CLOSE;
4947
4948 if (packet_stats_print(&stat, f))
4949 return 0;
4950
4951 return 0;
4952}
4953
4954static int packet_show(struct filter *f)
4955{
4956 FILE *fp;
4957 int rc = 0;
4958
4959 if (!filter_af_get(f, AF_PACKET) || !(f->states & (1 << SS_CLOSE)))
4960 return 0;
4961
4962 if (!getenv("PROC_NET_PACKET") && !getenv("PROC_ROOT") &&
4963 packet_show_netlink(f) == 0)
4964 return 0;
4965
4966 if ((fp = net_packet_open()) == NULL)
4967 return -1;
4968 if (generic_record_read(fp, packet_show_line, f, AF_PACKET))
4969 rc = -1;
4970
4971 fclose(fp);
4972 return rc;
4973}
4974
4975static int xdp_stats_print(struct sockstat *s, const struct filter *f)
4976{
4977 const char *addr, *port;
4978 char q_str[16];
4979
4980 s->local.family = s->remote.family = AF_XDP;
4981
4982 if (f->f) {
4983 if (run_ssfilter(f->f, s) == 0)
4984 return 1;
4985 }
4986
4987 sock_state_print(s);
4988
4989 if (s->iface) {
4990 addr = xll_index_to_name(s->iface);
4991 snprintf(q_str, sizeof(q_str), "q%d", s->lport);
4992 port = q_str;
4993 sock_addr_print(addr, ":", port, NULL);
4994 } else {
4995 sock_addr_print("", "*", "", NULL);
4996 }
4997
4998 sock_addr_print("", "*", "", NULL);
4999
5000 proc_ctx_print(s);
5001
5002 if (show_details)
5003 sock_details_print(s);
5004
5005 return 0;
5006}
5007
5008static void xdp_show_ring(const char *name, struct xdp_diag_ring *ring)
5009{
5010 if (oneline)
5011 out(" %s(", name);
5012 else
5013 out("\n\t%s(", name);
5014 out("entries:%u", ring->entries);
5015 out(")");
5016}
5017
5018static void xdp_show_umem(struct xdp_diag_umem *umem, struct xdp_diag_ring *fr,
5019 struct xdp_diag_ring *cr)
5020{
5021 if (oneline)
5022 out(" tumem(");
5023 else
5024 out("\n\tumem(");
5025 out("id:%u", umem->id);
5026 out(",size:%llu", umem->size);
5027 out(",num_pages:%u", umem->num_pages);
5028 out(",chunk_size:%u", umem->chunk_size);
5029 out(",headroom:%u", umem->headroom);
5030 out(",ifindex:%u", umem->ifindex);
5031 out(",qid:%u", umem->queue_id);
5032 out(",zc:%u", umem->flags & XDP_DU_F_ZEROCOPY);
5033 out(",refs:%u", umem->refs);
5034 out(")");
5035
5036 if (fr)
5037 xdp_show_ring("fr", fr);
5038 if (cr)
5039 xdp_show_ring("cr", cr);
5040}
5041
5042static void xdp_show_stats(struct xdp_diag_stats *stats)
5043{
5044 if (oneline)
5045 out(" stats(");
5046 else
5047 out("\n\tstats(");
5048 out("rx dropped:%llu", stats->n_rx_dropped);
5049 out(",rx invalid:%llu", stats->n_rx_invalid);
5050 out(",rx queue full:%llu", stats->n_rx_full);
5051 out(",rx fill ring empty:%llu", stats->n_fill_ring_empty);
5052 out(",tx invalid:%llu", stats->n_tx_invalid);
5053 out(",tx ring empty:%llu", stats->n_tx_ring_empty);
5054 out(")");
5055}
5056
5057static int xdp_show_sock(struct nlmsghdr *nlh, void *arg)
5058{
5059 struct xdp_diag_ring *rx = NULL, *tx = NULL, *fr = NULL, *cr = NULL;
5060 struct xdp_diag_msg *msg = NLMSG_DATA(nlh);
5061 struct rtattr *tb[XDP_DIAG_MAX + 1];
5062 struct xdp_diag_info *info = NULL;
5063 struct xdp_diag_umem *umem = NULL;
5064 struct xdp_diag_stats *stats = NULL;
5065 const struct filter *f = arg;
5066 struct sockstat stat = {};
5067
5068 parse_rtattr(tb, XDP_DIAG_MAX, (struct rtattr *)(msg + 1),
5069 nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*msg)));
5070
5071 stat.type = msg->xdiag_type;
5072 stat.ino = msg->xdiag_ino;
5073 stat.state = SS_CLOSE;
5074 stat.sk = cookie_sk_get(&msg->xdiag_cookie[0]);
5075
5076 if (tb[XDP_DIAG_INFO]) {
5077 info = RTA_DATA(tb[XDP_DIAG_INFO]);
5078 stat.iface = info->ifindex;
5079 stat.lport = info->queue_id;
5080 }
5081
5082 if (tb[XDP_DIAG_UID])
5083 stat.uid = rta_getattr_u32(tb[XDP_DIAG_UID]);
5084 if (tb[XDP_DIAG_RX_RING])
5085 rx = RTA_DATA(tb[XDP_DIAG_RX_RING]);
5086 if (tb[XDP_DIAG_TX_RING])
5087 tx = RTA_DATA(tb[XDP_DIAG_TX_RING]);
5088 if (tb[XDP_DIAG_UMEM])
5089 umem = RTA_DATA(tb[XDP_DIAG_UMEM]);
5090 if (tb[XDP_DIAG_UMEM_FILL_RING])
5091 fr = RTA_DATA(tb[XDP_DIAG_UMEM_FILL_RING]);
5092 if (tb[XDP_DIAG_UMEM_COMPLETION_RING])
5093 cr = RTA_DATA(tb[XDP_DIAG_UMEM_COMPLETION_RING]);
5094 if (tb[XDP_DIAG_MEMINFO]) {
5095 __u32 *skmeminfo = RTA_DATA(tb[XDP_DIAG_MEMINFO]);
5096
5097 stat.rq = skmeminfo[SK_MEMINFO_RMEM_ALLOC];
5098 }
5099 if (tb[XDP_DIAG_STATS])
5100 stats = RTA_DATA(tb[XDP_DIAG_STATS]);
5101
5102 if (xdp_stats_print(&stat, f))
5103 return 0;
5104
5105 if (show_details) {
5106 if (rx)
5107 xdp_show_ring("rx", rx);
5108 if (tx)
5109 xdp_show_ring("tx", tx);
5110 if (umem)
5111 xdp_show_umem(umem, fr, cr);
5112 if (stats)
5113 xdp_show_stats(stats);
5114 }
5115
5116 if (show_mem)
5117 print_skmeminfo(tb, XDP_DIAG_MEMINFO);
5118
5119
5120 return 0;
5121}
5122
5123static int xdp_show(struct filter *f)
5124{
5125 DIAG_REQUEST(req, struct xdp_diag_req r);
5126
5127 if (!filter_af_get(f, AF_XDP) || !(f->states & (1 << SS_CLOSE)))
5128 return 0;
5129
5130 req.r.sdiag_family = AF_XDP;
5131 req.r.xdiag_show = XDP_SHOW_INFO | XDP_SHOW_RING_CFG | XDP_SHOW_UMEM |
5132 XDP_SHOW_MEMINFO | XDP_SHOW_STATS;
5133
5134 return handle_netlink_request(f, &req.nlh, sizeof(req), xdp_show_sock);
5135}
5136
5137static int netlink_show_one(struct filter *f,
5138 int prot, int pid, unsigned int groups,
5139 int state, int dst_pid, unsigned int dst_group,
5140 int rq, int wq,
5141 unsigned long long sk, unsigned long long cb)
5142{
5143 struct sockstat st = {
5144 .state = SS_CLOSE,
5145 .rq = rq,
5146 .wq = wq,
5147 .local.family = AF_NETLINK,
5148 .remote.family = AF_NETLINK,
5149 };
5150
5151 SPRINT_BUF(prot_buf) = {};
5152 const char *prot_name;
5153 char procname[64] = {};
5154
5155 if (f->f) {
5156 st.rport = -1;
5157 st.lport = pid;
5158 st.local.data[0] = prot;
5159 if (run_ssfilter(f->f, &st) == 0)
5160 return 1;
5161 }
5162
5163 sock_state_print(&st);
5164
5165 prot_name = nl_proto_n2a(prot, prot_buf, sizeof(prot_buf));
5166
5167 if (pid == -1) {
5168 procname[0] = '*';
5169 } else if (!numeric) {
5170 int done = 0;
5171
5172 if (!pid) {
5173 done = 1;
5174 strncpy(procname, "kernel", 7);
5175 } else if (pid > 0) {
5176 FILE *fp;
5177
5178 snprintf(procname, sizeof(procname), "%s/%d/stat",
5179 getenv("PROC_ROOT") ? : "/proc", pid);
5180 if ((fp = fopen(procname, "r")) != NULL) {
5181 if (fscanf(fp, "%*d (%[^)])", procname) == 1) {
5182 snprintf(procname+strlen(procname),
5183 sizeof(procname)-strlen(procname),
5184 "/%d", pid);
5185 done = 1;
5186 }
5187 fclose(fp);
5188 }
5189 }
5190 if (!done)
5191 int_to_str(pid, procname);
5192 } else {
5193 int_to_str(pid, procname);
5194 }
5195
5196 sock_addr_print(prot_name, ":", procname, NULL);
5197
5198 if (state == NETLINK_CONNECTED) {
5199 char dst_group_buf[30];
5200 char dst_pid_buf[30];
5201
5202 sock_addr_print(int_to_str(dst_group, dst_group_buf), ":",
5203 int_to_str(dst_pid, dst_pid_buf), NULL);
5204 } else {
5205 sock_addr_print("", "*", "", NULL);
5206 }
5207
5208 char *pid_context = NULL;
5209
5210 if (show_proc_ctx) {
5211
5212
5213
5214
5215
5216
5217 if (!pid)
5218 security_get_initial_context("kernel", &pid_context);
5219 else if (pid > 0)
5220 getpidcon(pid, &pid_context);
5221
5222 out(" proc_ctx=%s", pid_context ? : "unavailable");
5223 freecon(pid_context);
5224 }
5225
5226 if (show_details) {
5227 out(" sk=%llx cb=%llx groups=0x%08x", sk, cb, groups);
5228 }
5229
5230 return 0;
5231}
5232
5233static int netlink_show_sock(struct nlmsghdr *nlh, void *arg)
5234{
5235 struct filter *f = (struct filter *)arg;
5236 struct netlink_diag_msg *r = NLMSG_DATA(nlh);
5237 struct rtattr *tb[NETLINK_DIAG_MAX+1];
5238 int rq = 0, wq = 0;
5239 unsigned long groups = 0;
5240
5241 parse_rtattr(tb, NETLINK_DIAG_MAX, (struct rtattr *)(r+1),
5242 nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
5243
5244 if (tb[NETLINK_DIAG_GROUPS] && RTA_PAYLOAD(tb[NETLINK_DIAG_GROUPS]))
5245 groups = *(unsigned long *) RTA_DATA(tb[NETLINK_DIAG_GROUPS]);
5246
5247 if (tb[NETLINK_DIAG_MEMINFO]) {
5248 const __u32 *skmeminfo;
5249
5250 skmeminfo = RTA_DATA(tb[NETLINK_DIAG_MEMINFO]);
5251
5252 rq = skmeminfo[SK_MEMINFO_RMEM_ALLOC];
5253 wq = skmeminfo[SK_MEMINFO_WMEM_ALLOC];
5254 }
5255
5256 if (netlink_show_one(f, r->ndiag_protocol, r->ndiag_portid, groups,
5257 r->ndiag_state, r->ndiag_dst_portid, r->ndiag_dst_group,
5258 rq, wq, 0, 0)) {
5259 return 0;
5260 }
5261
5262 if (show_mem) {
5263 out("\t");
5264 print_skmeminfo(tb, NETLINK_DIAG_MEMINFO);
5265 }
5266
5267 return 0;
5268}
5269
5270static int netlink_show_netlink(struct filter *f)
5271{
5272 DIAG_REQUEST(req, struct netlink_diag_req r);
5273
5274 req.r.sdiag_family = AF_NETLINK;
5275 req.r.sdiag_protocol = NDIAG_PROTO_ALL;
5276 req.r.ndiag_show = NDIAG_SHOW_GROUPS | NDIAG_SHOW_MEMINFO;
5277
5278 return handle_netlink_request(f, &req.nlh, sizeof(req), netlink_show_sock);
5279}
5280
5281static int netlink_show(struct filter *f)
5282{
5283 FILE *fp;
5284 char buf[256];
5285 int prot, pid;
5286 unsigned int groups;
5287 int rq, wq, rc;
5288 unsigned long long sk, cb;
5289
5290 if (!filter_af_get(f, AF_NETLINK) || !(f->states & (1 << SS_CLOSE)))
5291 return 0;
5292
5293 if (!getenv("PROC_NET_NETLINK") && !getenv("PROC_ROOT") &&
5294 netlink_show_netlink(f) == 0)
5295 return 0;
5296
5297 if ((fp = net_netlink_open()) == NULL)
5298 return -1;
5299 if (!fgets(buf, sizeof(buf), fp)) {
5300 fclose(fp);
5301 return -1;
5302 }
5303
5304 while (fgets(buf, sizeof(buf), fp)) {
5305 sscanf(buf, "%llx %d %d %x %d %d %llx %d",
5306 &sk,
5307 &prot, &pid, &groups, &rq, &wq, &cb, &rc);
5308
5309 netlink_show_one(f, prot, pid, groups, 0, 0, 0, rq, wq, sk, cb);
5310 }
5311
5312 fclose(fp);
5313 return 0;
5314}
5315
5316static bool vsock_type_skip(struct sockstat *s, struct filter *f)
5317{
5318 if (s->type == SOCK_STREAM && !(f->dbs & (1 << VSOCK_ST_DB)))
5319 return true;
5320 if (s->type == SOCK_DGRAM && !(f->dbs & (1 << VSOCK_DG_DB)))
5321 return true;
5322 return false;
5323}
5324
5325static void vsock_addr_print(inet_prefix *a, __u32 port)
5326{
5327 char cid_str[sizeof("4294967295")];
5328 char port_str[sizeof("4294967295")];
5329 __u32 cid;
5330
5331 memcpy(&cid, a->data, sizeof(cid));
5332
5333 if (cid == ~(__u32)0)
5334 snprintf(cid_str, sizeof(cid_str), "*");
5335 else
5336 snprintf(cid_str, sizeof(cid_str), "%u", cid);
5337
5338 if (port == ~(__u32)0)
5339 snprintf(port_str, sizeof(port_str), "*");
5340 else
5341 snprintf(port_str, sizeof(port_str), "%u", port);
5342
5343 sock_addr_print(cid_str, ":", port_str, NULL);
5344}
5345
5346static void vsock_stats_print(struct sockstat *s, struct filter *f)
5347{
5348 sock_state_print(s);
5349
5350 vsock_addr_print(&s->local, s->lport);
5351 vsock_addr_print(&s->remote, s->rport);
5352
5353 proc_ctx_print(s);
5354}
5355
5356static int vsock_show_sock(struct nlmsghdr *nlh, void *arg)
5357{
5358 struct filter *f = (struct filter *)arg;
5359 struct vsock_diag_msg *r = NLMSG_DATA(nlh);
5360 struct sockstat stat = {
5361 .type = r->vdiag_type,
5362 .lport = r->vdiag_src_port,
5363 .rport = r->vdiag_dst_port,
5364 .state = r->vdiag_state,
5365 .ino = r->vdiag_ino,
5366 };
5367
5368 vsock_set_inet_prefix(&stat.local, r->vdiag_src_cid);
5369 vsock_set_inet_prefix(&stat.remote, r->vdiag_dst_cid);
5370
5371 if (vsock_type_skip(&stat, f))
5372 return 0;
5373
5374 if (f->f && run_ssfilter(f->f, &stat) == 0)
5375 return 0;
5376
5377 vsock_stats_print(&stat, f);
5378
5379 return 0;
5380}
5381
5382static int vsock_show(struct filter *f)
5383{
5384 DIAG_REQUEST(req, struct vsock_diag_req r);
5385
5386 if (!filter_af_get(f, AF_VSOCK))
5387 return 0;
5388
5389 req.r.sdiag_family = AF_VSOCK;
5390 req.r.vdiag_states = f->states;
5391
5392 return handle_netlink_request(f, &req.nlh, sizeof(req), vsock_show_sock);
5393}
5394
5395static void tipc_sock_addr_print(struct rtattr *net_addr, struct rtattr *id)
5396{
5397 uint32_t node = rta_getattr_u32(net_addr);
5398 uint32_t identity = rta_getattr_u32(id);
5399
5400 SPRINT_BUF(addr) = {};
5401 SPRINT_BUF(port) = {};
5402
5403 sprintf(addr, "%u", node);
5404 sprintf(port, "%u", identity);
5405 sock_addr_print(addr, ":", port, NULL);
5406
5407}
5408
5409static int tipc_show_sock(struct nlmsghdr *nlh, void *arg)
5410{
5411 struct rtattr *stat[TIPC_NLA_SOCK_STAT_MAX + 1] = {};
5412 struct rtattr *attrs[TIPC_NLA_SOCK_MAX + 1] = {};
5413 struct rtattr *con[TIPC_NLA_CON_MAX + 1] = {};
5414 struct rtattr *info[TIPC_NLA_MAX + 1] = {};
5415 struct rtattr *msg_ref;
5416 struct sockstat ss = {};
5417
5418 parse_rtattr(info, TIPC_NLA_MAX, NLMSG_DATA(nlh),
5419 NLMSG_PAYLOAD(nlh, 0));
5420
5421 if (!info[TIPC_NLA_SOCK])
5422 return 0;
5423
5424 msg_ref = info[TIPC_NLA_SOCK];
5425 parse_rtattr(attrs, TIPC_NLA_SOCK_MAX, RTA_DATA(msg_ref),
5426 RTA_PAYLOAD(msg_ref));
5427
5428 msg_ref = attrs[TIPC_NLA_SOCK_STAT];
5429 parse_rtattr(stat, TIPC_NLA_SOCK_STAT_MAX,
5430 RTA_DATA(msg_ref), RTA_PAYLOAD(msg_ref));
5431
5432
5433 ss.local.family = AF_TIPC;
5434 ss.type = rta_getattr_u32(attrs[TIPC_NLA_SOCK_TYPE]);
5435 ss.state = rta_getattr_u32(attrs[TIPC_NLA_SOCK_TIPC_STATE]);
5436 ss.uid = rta_getattr_u32(attrs[TIPC_NLA_SOCK_UID]);
5437 ss.ino = rta_getattr_u32(attrs[TIPC_NLA_SOCK_INO]);
5438 ss.rq = rta_getattr_u32(stat[TIPC_NLA_SOCK_STAT_RCVQ]);
5439 ss.wq = rta_getattr_u32(stat[TIPC_NLA_SOCK_STAT_SENDQ]);
5440 ss.sk = rta_getattr_u64(attrs[TIPC_NLA_SOCK_COOKIE]);
5441
5442 sock_state_print (&ss);
5443
5444 tipc_sock_addr_print(attrs[TIPC_NLA_SOCK_ADDR],
5445 attrs[TIPC_NLA_SOCK_REF]);
5446
5447 msg_ref = attrs[TIPC_NLA_SOCK_CON];
5448 if (msg_ref) {
5449 parse_rtattr(con, TIPC_NLA_CON_MAX,
5450 RTA_DATA(msg_ref), RTA_PAYLOAD(msg_ref));
5451
5452 tipc_sock_addr_print(con[TIPC_NLA_CON_NODE],
5453 con[TIPC_NLA_CON_SOCK]);
5454 } else
5455 sock_addr_print("", "-", "", NULL);
5456
5457 if (show_details)
5458 sock_details_print(&ss);
5459
5460 proc_ctx_print(&ss);
5461
5462 if (show_tipcinfo) {
5463 if (oneline)
5464 out(" type:%s", stype_nameg[ss.type]);
5465 else
5466 out("\n type:%s", stype_nameg[ss.type]);
5467 out(" cong:%s ",
5468 stat[TIPC_NLA_SOCK_STAT_LINK_CONG] ? "link" :
5469 stat[TIPC_NLA_SOCK_STAT_CONN_CONG] ? "conn" : "none");
5470 out(" drop:%d ",
5471 rta_getattr_u32(stat[TIPC_NLA_SOCK_STAT_DROP]));
5472
5473 if (attrs[TIPC_NLA_SOCK_HAS_PUBL])
5474 out(" publ");
5475
5476 if (con[TIPC_NLA_CON_FLAG])
5477 out(" via {%u,%u} ",
5478 rta_getattr_u32(con[TIPC_NLA_CON_TYPE]),
5479 rta_getattr_u32(con[TIPC_NLA_CON_INST]));
5480 }
5481
5482 return 0;
5483}
5484
5485static int tipc_show(struct filter *f)
5486{
5487 DIAG_REQUEST(req, struct tipc_sock_diag_req r);
5488
5489 memset(&req.r, 0, sizeof(req.r));
5490 req.r.sdiag_family = AF_TIPC;
5491 req.r.tidiag_states = f->states;
5492
5493 return handle_netlink_request(f, &req.nlh, sizeof(req), tipc_show_sock);
5494}
5495
5496struct sock_diag_msg {
5497 __u8 sdiag_family;
5498};
5499
5500static int generic_show_sock(struct nlmsghdr *nlh, void *arg)
5501{
5502 struct sock_diag_msg *r = NLMSG_DATA(nlh);
5503 struct inet_diag_arg inet_arg = { .f = arg, .protocol = IPPROTO_MAX };
5504 int ret;
5505
5506 switch (r->sdiag_family) {
5507 case AF_INET:
5508 case AF_INET6:
5509 inet_arg.rth = inet_arg.f->rth_for_killing;
5510 ret = show_one_inet_sock(nlh, &inet_arg);
5511 break;
5512 case AF_UNIX:
5513 ret = unix_show_sock(nlh, arg);
5514 break;
5515 case AF_PACKET:
5516 ret = packet_show_sock(nlh, arg);
5517 break;
5518 case AF_NETLINK:
5519 ret = netlink_show_sock(nlh, arg);
5520 break;
5521 case AF_VSOCK:
5522 ret = vsock_show_sock(nlh, arg);
5523 break;
5524 case AF_XDP:
5525 ret = xdp_show_sock(nlh, arg);
5526 break;
5527 default:
5528 ret = -1;
5529 }
5530
5531 render();
5532
5533 return ret;
5534}
5535
5536static int handle_follow_request(struct filter *f)
5537{
5538 int ret = 0;
5539 int groups = 0;
5540 struct rtnl_handle rth, rth2;
5541
5542 if (f->families & FAMILY_MASK(AF_INET) && f->dbs & (1 << TCP_DB))
5543 groups |= 1 << (SKNLGRP_INET_TCP_DESTROY - 1);
5544 if (f->families & FAMILY_MASK(AF_INET) && f->dbs & (1 << UDP_DB))
5545 groups |= 1 << (SKNLGRP_INET_UDP_DESTROY - 1);
5546 if (f->families & FAMILY_MASK(AF_INET6) && f->dbs & (1 << TCP_DB))
5547 groups |= 1 << (SKNLGRP_INET6_TCP_DESTROY - 1);
5548 if (f->families & FAMILY_MASK(AF_INET6) && f->dbs & (1 << UDP_DB))
5549 groups |= 1 << (SKNLGRP_INET6_UDP_DESTROY - 1);
5550
5551 if (groups == 0)
5552 return -1;
5553
5554 if (rtnl_open_byproto(&rth, groups, NETLINK_SOCK_DIAG))
5555 return -1;
5556
5557 rth.dump = 0;
5558 rth.local.nl_pid = 0;
5559
5560 if (f->kill) {
5561 if (rtnl_open_byproto(&rth2, groups, NETLINK_SOCK_DIAG)) {
5562 rtnl_close(&rth);
5563 return -1;
5564 }
5565 f->rth_for_killing = &rth2;
5566 }
5567
5568 if (rtnl_dump_filter(&rth, generic_show_sock, f))
5569 ret = -1;
5570
5571 rtnl_close(&rth);
5572 if (f->rth_for_killing)
5573 rtnl_close(f->rth_for_killing);
5574 return ret;
5575}
5576
5577static int get_snmp_int(char *proto, char *key, int *result)
5578{
5579 char buf[1024];
5580 FILE *fp;
5581 int protolen = strlen(proto);
5582 int keylen = strlen(key);
5583
5584 *result = 0;
5585
5586 if ((fp = net_snmp_open()) == NULL)
5587 return -1;
5588
5589 while (fgets(buf, sizeof(buf), fp) != NULL) {
5590 char *p = buf;
5591 int pos = 0;
5592
5593 if (memcmp(buf, proto, protolen))
5594 continue;
5595 while ((p = strchr(p, ' ')) != NULL) {
5596 pos++;
5597 p++;
5598 if (memcmp(p, key, keylen) == 0 &&
5599 (p[keylen] == ' ' || p[keylen] == '\n'))
5600 break;
5601 }
5602 if (fgets(buf, sizeof(buf), fp) == NULL)
5603 break;
5604 if (memcmp(buf, proto, protolen))
5605 break;
5606 p = buf;
5607 while ((p = strchr(p, ' ')) != NULL) {
5608 p++;
5609 if (--pos == 0) {
5610 sscanf(p, "%d", result);
5611 fclose(fp);
5612 return 0;
5613 }
5614 }
5615 }
5616
5617 fclose(fp);
5618 errno = ESRCH;
5619 return -1;
5620}
5621
5622
5623
5624
5625struct ssummary {
5626 int socks;
5627 int tcp_mem;
5628 int tcp_total;
5629 int tcp_orphans;
5630 int tcp_tws;
5631 int tcp4_hashed;
5632 int udp4;
5633 int raw4;
5634 int frag4;
5635 int frag4_mem;
5636 int tcp6_hashed;
5637 int udp6;
5638 int raw6;
5639 int frag6;
5640 int frag6_mem;
5641};
5642
5643static void get_sockstat_line(char *line, struct ssummary *s)
5644{
5645 char id[256], rem[256];
5646
5647 if (sscanf(line, "%[^ ] %[^\n]\n", id, rem) != 2)
5648 return;
5649
5650 if (strcmp(id, "sockets:") == 0)
5651 sscanf(rem, "%*s%d", &s->socks);
5652 else if (strcmp(id, "UDP:") == 0)
5653 sscanf(rem, "%*s%d", &s->udp4);
5654 else if (strcmp(id, "UDP6:") == 0)
5655 sscanf(rem, "%*s%d", &s->udp6);
5656 else if (strcmp(id, "RAW:") == 0)
5657 sscanf(rem, "%*s%d", &s->raw4);
5658 else if (strcmp(id, "RAW6:") == 0)
5659 sscanf(rem, "%*s%d", &s->raw6);
5660 else if (strcmp(id, "TCP6:") == 0)
5661 sscanf(rem, "%*s%d", &s->tcp6_hashed);
5662 else if (strcmp(id, "FRAG:") == 0)
5663 sscanf(rem, "%*s%d%*s%d", &s->frag4, &s->frag4_mem);
5664 else if (strcmp(id, "FRAG6:") == 0)
5665 sscanf(rem, "%*s%d%*s%d", &s->frag6, &s->frag6_mem);
5666 else if (strcmp(id, "TCP:") == 0)
5667 sscanf(rem, "%*s%d%*s%d%*s%d%*s%d%*s%d",
5668 &s->tcp4_hashed,
5669 &s->tcp_orphans, &s->tcp_tws, &s->tcp_total, &s->tcp_mem);
5670}
5671
5672static int get_sockstat(struct ssummary *s)
5673{
5674 char buf[256];
5675 FILE *fp;
5676
5677 memset(s, 0, sizeof(*s));
5678
5679 if ((fp = net_sockstat_open()) == NULL)
5680 return -1;
5681 while (fgets(buf, sizeof(buf), fp) != NULL)
5682 get_sockstat_line(buf, s);
5683 fclose(fp);
5684
5685 if ((fp = net_sockstat6_open()) == NULL)
5686 return 0;
5687 while (fgets(buf, sizeof(buf), fp) != NULL)
5688 get_sockstat_line(buf, s);
5689 fclose(fp);
5690
5691 return 0;
5692}
5693
5694static int print_summary(void)
5695{
5696 struct ssummary s;
5697 int tcp_estab;
5698
5699 if (get_sockstat(&s) < 0)
5700 perror("ss: get_sockstat");
5701 if (get_snmp_int("Tcp:", "CurrEstab", &tcp_estab) < 0)
5702 perror("ss: get_snmpstat");
5703
5704 printf("Total: %d\n", s.socks);
5705
5706 printf("TCP: %d (estab %d, closed %d, orphaned %d, timewait %d)\n",
5707 s.tcp_total + s.tcp_tws, tcp_estab,
5708 s.tcp_total - (s.tcp4_hashed + s.tcp6_hashed - s.tcp_tws),
5709 s.tcp_orphans, s.tcp_tws);
5710
5711 printf("\n");
5712 printf("Transport Total IP IPv6\n");
5713 printf("RAW %-9d %-9d %-9d\n", s.raw4+s.raw6, s.raw4, s.raw6);
5714 printf("UDP %-9d %-9d %-9d\n", s.udp4+s.udp6, s.udp4, s.udp6);
5715 printf("TCP %-9d %-9d %-9d\n", s.tcp4_hashed+s.tcp6_hashed, s.tcp4_hashed, s.tcp6_hashed);
5716 printf("INET %-9d %-9d %-9d\n",
5717 s.raw4+s.udp4+s.tcp4_hashed+
5718 s.raw6+s.udp6+s.tcp6_hashed,
5719 s.raw4+s.udp4+s.tcp4_hashed,
5720 s.raw6+s.udp6+s.tcp6_hashed);
5721 printf("FRAG %-9d %-9d %-9d\n", s.frag4+s.frag6, s.frag4, s.frag6);
5722
5723 printf("\n");
5724
5725 return 0;
5726}
5727
5728static void _usage(FILE *dest)
5729{
5730 fprintf(dest,
5731"Usage: ss [ OPTIONS ]\n"
5732" ss [ OPTIONS ] [ FILTER ]\n"
5733" -h, --help this message\n"
5734" -V, --version output version information\n"
5735" -n, --numeric don't resolve service names\n"
5736" -r, --resolve resolve host names\n"
5737" -a, --all display all sockets\n"
5738" -l, --listening display listening sockets\n"
5739" -B, --bound-inactive display TCP bound but inactive sockets\n"
5740" -o, --options show timer information\n"
5741" -e, --extended show detailed socket information\n"
5742" -m, --memory show socket memory usage\n"
5743" -p, --processes show process using socket\n"
5744" -T, --threads show thread using socket\n"
5745" -i, --info show internal TCP information\n"
5746" --tipcinfo show internal tipc socket information\n"
5747" -s, --summary show socket usage summary\n"
5748" --tos show tos and priority information\n"
5749" --cgroup show cgroup information\n"
5750" -b, --bpf show bpf filter socket information\n"
5751#ifdef ENABLE_BPF_SKSTORAGE_SUPPORT
5752" --bpf-maps show all BPF socket-local storage maps\n"
5753" --bpf-map-id=MAP-ID show a BPF socket-local storage map\n"
5754#endif
5755" -E, --events continually display sockets as they are destroyed\n"
5756" -Z, --context display task SELinux security contexts\n"
5757" -z, --contexts display task and socket SELinux security contexts\n"
5758" -N, --net switch to the specified network namespace name\n"
5759"\n"
5760" -4, --ipv4 display only IP version 4 sockets\n"
5761" -6, --ipv6 display only IP version 6 sockets\n"
5762" -0, --packet display PACKET sockets\n"
5763" -t, --tcp display only TCP sockets\n"
5764" -M, --mptcp display only MPTCP sockets\n"
5765" -S, --sctp display only SCTP sockets\n"
5766" -u, --udp display only UDP sockets\n"
5767" -d, --dccp display only DCCP sockets\n"
5768" -w, --raw display only RAW sockets\n"
5769" -x, --unix display only Unix domain sockets\n"
5770" --tipc display only TIPC sockets\n"
5771" --vsock display only vsock sockets\n"
5772" --xdp display only XDP sockets\n"
5773" -f, --family=FAMILY display sockets of type FAMILY\n"
5774" FAMILY := {inet|inet6|link|unix|netlink|vsock|tipc|xdp|help}\n"
5775"\n"
5776" -K, --kill forcibly close sockets, display what was closed\n"
5777" -H, --no-header Suppress header line\n"
5778" -Q, --no-queues Suppress sending and receiving queue columns\n"
5779" -O, --oneline socket's data printed on a single line\n"
5780" --inet-sockopt show various inet socket options\n"
5781"\n"
5782" -A, --query=QUERY, --socket=QUERY\n"
5783" QUERY := {all|inet|tcp|mptcp|udp|raw|unix|unix_dgram|unix_stream|unix_seqpacket|packet|packet_raw|packet_dgram|netlink|dccp|sctp|vsock_stream|vsock_dgram|tipc|xdp}[,QUERY]\n"
5784"\n"
5785" -D, --diag=FILE Dump raw information about TCP sockets to FILE\n"
5786" -F, --filter=FILE read filter information from FILE\n"
5787" FILTER := [ state STATE-FILTER ] [ EXPRESSION ]\n"
5788" STATE-FILTER := {all|connected|synchronized|bucket|big|TCP-STATES}\n"
5789" TCP-STATES := {established|syn-sent|syn-recv|fin-wait-{1,2}|time-wait|closed|close-wait|last-ack|listening|closing}\n"
5790" connected := {established|syn-sent|syn-recv|fin-wait-{1,2}|time-wait|close-wait|last-ack|closing}\n"
5791" synchronized := {established|syn-recv|fin-wait-{1,2}|time-wait|close-wait|last-ack|closing}\n"
5792" bucket := {syn-recv|time-wait}\n"
5793" big := {established|syn-sent|fin-wait-{1,2}|closed|close-wait|last-ack|listening|closing}\n"
5794 );
5795}
5796
5797static void help(void) __attribute__((noreturn));
5798static void help(void)
5799{
5800 _usage(stdout);
5801 exit(0);
5802}
5803
5804static void usage(void) __attribute__((noreturn));
5805static void usage(void)
5806{
5807 _usage(stderr);
5808 exit(-1);
5809}
5810
5811
5812static int scan_state(const char *state)
5813{
5814 static const char * const sstate_namel[] = {
5815 "UNKNOWN",
5816 [SS_ESTABLISHED] = "established",
5817 [SS_SYN_SENT] = "syn-sent",
5818 [SS_SYN_RECV] = "syn-recv",
5819 [SS_FIN_WAIT1] = "fin-wait-1",
5820 [SS_FIN_WAIT2] = "fin-wait-2",
5821 [SS_TIME_WAIT] = "time-wait",
5822 [SS_CLOSE] = "unconnected",
5823 [SS_CLOSE_WAIT] = "close-wait",
5824 [SS_LAST_ACK] = "last-ack",
5825 [SS_LISTEN] = "listening",
5826 [SS_CLOSING] = "closing",
5827 [SS_NEW_SYN_RECV] = "new-syn-recv",
5828 [SS_BOUND_INACTIVE] = "bound-inactive",
5829 };
5830 int i;
5831
5832
5833
5834
5835 if (strcasecmp(state, "new-syn-recv") == 0)
5836 goto wrong_state;
5837
5838 if (strcasecmp(state, "close") == 0 ||
5839 strcasecmp(state, "closed") == 0)
5840 return (1<<SS_CLOSE);
5841 if (strcasecmp(state, "syn-rcv") == 0)
5842 return (1<<SS_SYN_RECV);
5843 if (strcasecmp(state, "established") == 0)
5844 return (1<<SS_ESTABLISHED);
5845 if (strcasecmp(state, "all") == 0)
5846 return SS_ALL;
5847 if (strcasecmp(state, "connected") == 0)
5848 return SS_ALL & ~((1<<SS_CLOSE)|(1<<SS_LISTEN));
5849 if (strcasecmp(state, "synchronized") == 0)
5850 return SS_ALL & ~((1<<SS_CLOSE)|(1<<SS_LISTEN)|(1<<SS_SYN_SENT));
5851 if (strcasecmp(state, "bucket") == 0)
5852 return (1<<SS_SYN_RECV)|(1<<SS_TIME_WAIT);
5853 if (strcasecmp(state, "big") == 0)
5854 return SS_ALL & ~((1<<SS_SYN_RECV)|(1<<SS_TIME_WAIT));
5855 for (i = 0; i < SS_MAX; i++) {
5856 if (strcasecmp(state, sstate_namel[i]) == 0)
5857 return (1<<i);
5858 }
5859
5860wrong_state:
5861 fprintf(stderr, "ss: wrong state name: %s\n", state);
5862 exit(-1);
5863}
5864
5865
5866#define OPT_VSOCK 256
5867
5868
5869#define OPT_TIPCSOCK 257
5870#define OPT_TIPCINFO 258
5871
5872#define OPT_TOS 259
5873
5874
5875#define OPT_XDPSOCK 260
5876
5877#define OPT_CGROUP 261
5878
5879#define OPT_INET_SOCKOPT 262
5880
5881#define OPT_BPF_MAPS 263
5882#define OPT_BPF_MAP_ID 264
5883
5884static const struct option long_opts[] = {
5885 { "numeric", 0, 0, 'n' },
5886 { "resolve", 0, 0, 'r' },
5887 { "options", 0, 0, 'o' },
5888 { "extended", 0, 0, 'e' },
5889 { "memory", 0, 0, 'm' },
5890 { "info", 0, 0, 'i' },
5891 { "processes", 0, 0, 'p' },
5892 { "threads", 0, 0, 'T' },
5893 { "bpf", 0, 0, 'b' },
5894 { "events", 0, 0, 'E' },
5895 { "dccp", 0, 0, 'd' },
5896 { "tcp", 0, 0, 't' },
5897 { "sctp", 0, 0, 'S' },
5898 { "udp", 0, 0, 'u' },
5899 { "raw", 0, 0, 'w' },
5900 { "unix", 0, 0, 'x' },
5901 { "tipc", 0, 0, OPT_TIPCSOCK},
5902 { "vsock", 0, 0, OPT_VSOCK },
5903 { "all", 0, 0, 'a' },
5904 { "listening", 0, 0, 'l' },
5905 { "bound-inactive", 0, 0, 'B' },
5906 { "ipv4", 0, 0, '4' },
5907 { "ipv6", 0, 0, '6' },
5908 { "packet", 0, 0, '0' },
5909 { "family", 1, 0, 'f' },
5910 { "socket", 1, 0, 'A' },
5911 { "query", 1, 0, 'A' },
5912 { "summary", 0, 0, 's' },
5913 { "diag", 1, 0, 'D' },
5914 { "filter", 1, 0, 'F' },
5915 { "version", 0, 0, 'V' },
5916 { "help", 0, 0, 'h' },
5917 { "context", 0, 0, 'Z' },
5918 { "contexts", 0, 0, 'z' },
5919 { "net", 1, 0, 'N' },
5920 { "tipcinfo", 0, 0, OPT_TIPCINFO},
5921 { "tos", 0, 0, OPT_TOS },
5922 { "cgroup", 0, 0, OPT_CGROUP },
5923 { "kill", 0, 0, 'K' },
5924 { "no-header", 0, 0, 'H' },
5925 { "no-queues", 0, 0, 'Q' },
5926 { "xdp", 0, 0, OPT_XDPSOCK},
5927 { "mptcp", 0, 0, 'M' },
5928 { "oneline", 0, 0, 'O' },
5929 { "inet-sockopt", 0, 0, OPT_INET_SOCKOPT },
5930#ifdef ENABLE_BPF_SKSTORAGE_SUPPORT
5931 { "bpf-maps", 0, 0, OPT_BPF_MAPS},
5932 { "bpf-map-id", 1, 0, OPT_BPF_MAP_ID},
5933#endif
5934 { 0 }
5935
5936};
5937
5938int main(int argc, char *argv[])
5939{
5940 int saw_states = 0;
5941 int saw_query = 0;
5942 int do_summary = 0;
5943 const char *dump_tcpdiag = NULL;
5944 FILE *filter_fp = NULL;
5945 int ch;
5946 int state_filter = 0;
5947
5948 while ((ch = getopt_long(argc, argv,
5949 "dhalBetuwxnro460spTbEf:mMiA:D:F:vVzZN:KHQSO",
5950 long_opts, NULL)) != EOF) {
5951 switch (ch) {
5952 case 'n':
5953 numeric = 1;
5954 break;
5955 case 'r':
5956 resolve_hosts = 1;
5957 break;
5958 case 'o':
5959 show_options = 1;
5960 break;
5961 case 'e':
5962 show_options = 1;
5963 show_details++;
5964 break;
5965 case 'm':
5966 show_mem = 1;
5967 break;
5968 case 'i':
5969 show_tcpinfo = 1;
5970 break;
5971 case 'p':
5972 show_processes++;
5973 break;
5974 case 'T':
5975 show_threads++;
5976 break;
5977 case 'b':
5978 show_options = 1;
5979 show_bpf++;
5980 break;
5981 case 'E':
5982 follow_events = 1;
5983 break;
5984 case 'd':
5985 filter_db_set(¤t_filter, DCCP_DB, true);
5986 break;
5987 case 't':
5988 filter_db_set(¤t_filter, TCP_DB, true);
5989 break;
5990 case 'S':
5991 filter_db_set(¤t_filter, SCTP_DB, true);
5992 break;
5993 case 'u':
5994 filter_db_set(¤t_filter, UDP_DB, true);
5995 break;
5996 case 'w':
5997 filter_db_set(¤t_filter, RAW_DB, true);
5998 break;
5999 case 'x':
6000 filter_af_set(¤t_filter, AF_UNIX);
6001 break;
6002 case OPT_VSOCK:
6003 filter_af_set(¤t_filter, AF_VSOCK);
6004 break;
6005 case OPT_TIPCSOCK:
6006 filter_af_set(¤t_filter, AF_TIPC);
6007 break;
6008 case 'a':
6009 state_filter = SS_ALL;
6010 break;
6011 case 'l':
6012 state_filter = (1 << SS_LISTEN) | (1 << SS_CLOSE);
6013 break;
6014 case 'B':
6015 state_filter = 1 << SS_BOUND_INACTIVE;
6016 break;
6017 case '4':
6018 filter_af_set(¤t_filter, AF_INET);
6019 break;
6020 case '6':
6021 filter_af_set(¤t_filter, AF_INET6);
6022 break;
6023 case '0':
6024 filter_af_set(¤t_filter, AF_PACKET);
6025 break;
6026 case OPT_XDPSOCK:
6027 filter_af_set(¤t_filter, AF_XDP);
6028 break;
6029 case 'M':
6030 filter_db_set(¤t_filter, MPTCP_DB, true);
6031 break;
6032 case 'f':
6033 if (strcmp(optarg, "inet") == 0)
6034 filter_af_set(¤t_filter, AF_INET);
6035 else if (strcmp(optarg, "inet6") == 0)
6036 filter_af_set(¤t_filter, AF_INET6);
6037 else if (strcmp(optarg, "link") == 0)
6038 filter_af_set(¤t_filter, AF_PACKET);
6039 else if (strcmp(optarg, "unix") == 0)
6040 filter_af_set(¤t_filter, AF_UNIX);
6041 else if (strcmp(optarg, "netlink") == 0)
6042 filter_af_set(¤t_filter, AF_NETLINK);
6043 else if (strcmp(optarg, "tipc") == 0)
6044 filter_af_set(¤t_filter, AF_TIPC);
6045 else if (strcmp(optarg, "vsock") == 0)
6046 filter_af_set(¤t_filter, AF_VSOCK);
6047 else if (strcmp(optarg, "xdp") == 0)
6048 filter_af_set(¤t_filter, AF_XDP);
6049 else if (strcmp(optarg, "help") == 0)
6050 help();
6051 else {
6052 fprintf(stderr, "ss: \"%s\" is invalid family\n",
6053 optarg);
6054 usage();
6055 }
6056 break;
6057 case 'A':
6058 {
6059 char *p, *p1;
6060
6061 if (!saw_query) {
6062 current_filter.dbs = 0;
6063 state_filter = state_filter ?
6064 state_filter : SS_CONN;
6065 saw_query = 1;
6066 do_default = 0;
6067 }
6068 p = p1 = optarg;
6069 do {
6070 if ((p1 = strchr(p, ',')) != NULL)
6071 *p1 = 0;
6072 if (filter_db_parse(¤t_filter, p)) {
6073 fprintf(stderr, "ss: \"%s\" is illegal socket table id\n", p);
6074 usage();
6075 }
6076 p = p1 + 1;
6077 } while (p1);
6078 break;
6079 }
6080 case 's':
6081 do_summary = 1;
6082 break;
6083 case 'D':
6084 dump_tcpdiag = optarg;
6085 break;
6086 case 'F':
6087 if (filter_fp) {
6088 fprintf(stderr, "More than one filter file\n");
6089 exit(-1);
6090 }
6091 if (optarg[0] == '-')
6092 filter_fp = stdin;
6093 else
6094 filter_fp = fopen(optarg, "r");
6095 if (!filter_fp) {
6096 perror("fopen filter file");
6097 exit(-1);
6098 }
6099 break;
6100 case 'v':
6101 case 'V':
6102 printf("ss utility, iproute2-%s\n", version);
6103 exit(0);
6104 case 'z':
6105 show_sock_ctx++;
6106
6107 case 'Z':
6108 if (!is_selinux_enabled()) {
6109 fprintf(stderr, "ss: SELinux is not enabled.\n");
6110 exit(1);
6111 }
6112 show_proc_ctx++;
6113 break;
6114 case 'N':
6115 if (netns_switch(optarg))
6116 exit(1);
6117 break;
6118 case OPT_TIPCINFO:
6119 show_tipcinfo = 1;
6120 break;
6121 case OPT_TOS:
6122 show_tos = 1;
6123 break;
6124 case OPT_CGROUP:
6125 show_cgroup = 1;
6126 break;
6127 case 'K':
6128 current_filter.kill = 1;
6129 break;
6130 case 'H':
6131 show_header = 0;
6132 break;
6133 case 'Q':
6134 show_queues = 0;
6135 break;
6136 case 'O':
6137 oneline = 1;
6138 break;
6139 case OPT_INET_SOCKOPT:
6140 show_inet_sockopt = 1;
6141 break;
6142#ifdef ENABLE_BPF_SKSTORAGE_SUPPORT
6143 case OPT_BPF_MAPS:
6144 if (bpf_map_opts.nr_maps) {
6145 bpf_map_opts_mixed_error();
6146 return -1;
6147 }
6148 bpf_map_opts.show_all = true;
6149 break;
6150 case OPT_BPF_MAP_ID:
6151 if (bpf_map_opts_add_id(optarg))
6152 exit(1);
6153 break;
6154#endif
6155 case 'h':
6156 help();
6157 case '?':
6158 default:
6159 usage();
6160 }
6161 }
6162
6163 if (show_processes || show_threads || show_proc_ctx || show_sock_ctx)
6164 user_ent_hash_build();
6165
6166 argc -= optind;
6167 argv += optind;
6168
6169 if (do_summary) {
6170 print_summary();
6171 if (do_default && argc == 0)
6172 exit(0);
6173 }
6174
6175 while (argc > 0) {
6176 if (strcmp(*argv, "state") == 0) {
6177 NEXT_ARG();
6178 if (!saw_states)
6179 state_filter = 0;
6180 state_filter |= scan_state(*argv);
6181 saw_states = 1;
6182 } else if (strcmp(*argv, "exclude") == 0 ||
6183 strcmp(*argv, "excl") == 0) {
6184 NEXT_ARG();
6185 if (!saw_states)
6186 state_filter = SS_ALL;
6187 state_filter &= ~scan_state(*argv);
6188 saw_states = 1;
6189 } else {
6190 break;
6191 }
6192 argc--; argv++;
6193 }
6194
6195 if (do_default) {
6196 state_filter = state_filter ? state_filter : SS_CONN;
6197 filter_db_parse(¤t_filter, "all");
6198 }
6199
6200 filter_states_set(¤t_filter, state_filter);
6201 filter_merge_defaults(¤t_filter);
6202
6203#ifdef HAVE_RPC
6204 if (!numeric && resolve_hosts &&
6205 (current_filter.dbs & (UNIX_DBM|INET_L4_DBM)))
6206 init_service_resolver();
6207#endif
6208
6209 if (current_filter.dbs == 0) {
6210 fprintf(stderr, "ss: no socket tables to show with such filter.\n");
6211 exit(0);
6212 }
6213 if (current_filter.families == 0) {
6214 fprintf(stderr, "ss: no families to show with such filter.\n");
6215 exit(0);
6216 }
6217 if (current_filter.states == 0) {
6218 fprintf(stderr, "ss: no socket states to show with such filter.\n");
6219 exit(0);
6220 }
6221
6222 if (dump_tcpdiag) {
6223 FILE *dump_fp = stdout;
6224
6225 if (!(current_filter.dbs & (1<<TCP_DB))) {
6226 fprintf(stderr, "ss: tcpdiag dump requested and no tcp in filter.\n");
6227 exit(0);
6228 }
6229 if (dump_tcpdiag[0] != '-') {
6230 dump_fp = fopen(dump_tcpdiag, "w");
6231 if (!dump_fp) {
6232 perror("fopen dump file");
6233 exit(-1);
6234 }
6235 }
6236 inet_show_netlink(¤t_filter, dump_fp, IPPROTO_TCP);
6237 fflush(dump_fp);
6238 exit(0);
6239 }
6240
6241 if (ssfilter_parse(¤t_filter.f, argc, argv, filter_fp))
6242 usage();
6243
6244 if (!show_processes)
6245 columns[COL_PROC].disabled = 1;
6246
6247 if (!show_queues) {
6248 columns[COL_SENDQ].disabled = 1;
6249 columns[COL_RECVQ].disabled = 1;
6250 }
6251
6252 if (!(current_filter.dbs & (current_filter.dbs - 1)))
6253 columns[COL_NETID].disabled = 1;
6254
6255 if (!(current_filter.states & (current_filter.states - 1)))
6256 columns[COL_STATE].disabled = 1;
6257
6258 if (show_header)
6259 print_header();
6260
6261 fflush(stdout);
6262
6263 if (follow_events)
6264 exit(handle_follow_request(¤t_filter));
6265
6266 if (current_filter.dbs & (1<<NETLINK_DB))
6267 netlink_show(¤t_filter);
6268 if (current_filter.dbs & PACKET_DBM)
6269 packet_show(¤t_filter);
6270 if (current_filter.dbs & UNIX_DBM)
6271 unix_show(¤t_filter);
6272 if (current_filter.dbs & (1<<RAW_DB))
6273 raw_show(¤t_filter);
6274 if (current_filter.dbs & (1<<UDP_DB))
6275 udp_show(¤t_filter);
6276 if (current_filter.dbs & (1<<TCP_DB))
6277 tcp_show(¤t_filter);
6278 if (current_filter.dbs & (1<<DCCP_DB))
6279 dccp_show(¤t_filter);
6280 if (current_filter.dbs & (1<<SCTP_DB))
6281 sctp_show(¤t_filter);
6282 if (current_filter.dbs & VSOCK_DBM)
6283 vsock_show(¤t_filter);
6284 if (current_filter.dbs & (1<<TIPC_DB))
6285 tipc_show(¤t_filter);
6286 if (current_filter.dbs & (1<<XDP_DB))
6287 xdp_show(¤t_filter);
6288 if (current_filter.dbs & (1<<MPTCP_DB))
6289 mptcp_show(¤t_filter);
6290
6291 if (show_processes || show_threads || show_proc_ctx || show_sock_ctx)
6292 user_ent_destroy();
6293
6294#ifdef ENABLE_BPF_SKSTORAGE_SUPPORT
6295 bpf_map_opts_destroy();
6296#endif
6297
6298 render();
6299
6300 return 0;
6301}
6302