]> git.proxmox.com Git - mirror_iproute2.git/blob - misc/ss.c
766fdc5f5bb6b9ce6bc42e8beb88086e2b707645
[mirror_iproute2.git] / misc / ss.c
1 /*
2 * ss.c "sockstat", socket statistics
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
10 */
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15 #include <fcntl.h>
16 #include <sys/ioctl.h>
17 #include <sys/socket.h>
18 #include <sys/uio.h>
19 #include <sys/sysmacros.h>
20 #include <netinet/in.h>
21 #include <string.h>
22 #include <errno.h>
23 #include <netdb.h>
24 #include <arpa/inet.h>
25 #include <dirent.h>
26 #include <fnmatch.h>
27 #include <getopt.h>
28 #include <stdbool.h>
29 #include <limits.h>
30 #include <stdarg.h>
31
32 #include "utils.h"
33 #include "rt_names.h"
34 #include "ll_map.h"
35 #include "libnetlink.h"
36 #include "namespace.h"
37 #include "SNAPSHOT.h"
38
39 #include <linux/tcp.h>
40 #include <linux/sock_diag.h>
41 #include <linux/inet_diag.h>
42 #include <linux/unix_diag.h>
43 #include <linux/netdevice.h> /* for MAX_ADDR_LEN */
44 #include <linux/filter.h>
45 #include <linux/packet_diag.h>
46 #include <linux/netlink_diag.h>
47 #include <linux/sctp.h>
48 #include <linux/vm_sockets_diag.h>
49 #include <linux/net.h>
50 #include <linux/tipc.h>
51 #include <linux/tipc_netlink.h>
52 #include <linux/tipc_sockets_diag.h>
53
54 /* AF_VSOCK/PF_VSOCK is only provided since glibc 2.18 */
55 #ifndef PF_VSOCK
56 #define PF_VSOCK 40
57 #endif
58 #ifndef AF_VSOCK
59 #define AF_VSOCK PF_VSOCK
60 #endif
61
62 #define MAGIC_SEQ 123456
63 #define BUF_CHUNK (1024 * 1024)
64 #define LEN_ALIGN(x) (((x) + 1) & ~1)
65
66 #define DIAG_REQUEST(_req, _r) \
67 struct { \
68 struct nlmsghdr nlh; \
69 _r; \
70 } _req = { \
71 .nlh = { \
72 .nlmsg_type = SOCK_DIAG_BY_FAMILY, \
73 .nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST,\
74 .nlmsg_seq = MAGIC_SEQ, \
75 .nlmsg_len = sizeof(_req), \
76 }, \
77 }
78
79 #if HAVE_SELINUX
80 #include <selinux/selinux.h>
81 #else
82 /* Stubs for SELinux functions */
83 static int is_selinux_enabled(void)
84 {
85 return -1;
86 }
87
88 static int getpidcon(pid_t pid, char **context)
89 {
90 *context = NULL;
91 return -1;
92 }
93
94 static int getfilecon(char *path, char **context)
95 {
96 *context = NULL;
97 return -1;
98 }
99
100 static int security_get_initial_context(char *name, char **context)
101 {
102 *context = NULL;
103 return -1;
104 }
105 #endif
106
107 static int resolve_services = 1;
108 int preferred_family = AF_UNSPEC;
109 static int show_options;
110 int show_details;
111 static int show_users;
112 static int show_mem;
113 static int show_tcpinfo;
114 static int show_bpf;
115 static int show_proc_ctx;
116 static int show_sock_ctx;
117 static int show_header = 1;
118 static int follow_events;
119 static int sctp_ino;
120 static int show_tipcinfo;
121 static int show_tos;
122
123 enum col_id {
124 COL_NETID,
125 COL_STATE,
126 COL_RECVQ,
127 COL_SENDQ,
128 COL_ADDR,
129 COL_SERV,
130 COL_RADDR,
131 COL_RSERV,
132 COL_EXT,
133 COL_MAX
134 };
135
136 enum col_align {
137 ALIGN_LEFT,
138 ALIGN_CENTER,
139 ALIGN_RIGHT
140 };
141
142 struct column {
143 const enum col_align align;
144 const char *header;
145 const char *ldelim;
146 int disabled;
147 int width; /* Calculated, including additional layout spacing */
148 int max_len; /* Measured maximum field length in this column */
149 };
150
151 static struct column columns[] = {
152 { ALIGN_LEFT, "Netid", "", 0, 0, 0 },
153 { ALIGN_LEFT, "State", " ", 0, 0, 0 },
154 { ALIGN_LEFT, "Recv-Q", " ", 0, 0, 0 },
155 { ALIGN_LEFT, "Send-Q", " ", 0, 0, 0 },
156 { ALIGN_RIGHT, "Local Address:", " ", 0, 0, 0 },
157 { ALIGN_LEFT, "Port", "", 0, 0, 0 },
158 { ALIGN_RIGHT, "Peer Address:", " ", 0, 0, 0 },
159 { ALIGN_LEFT, "Port", "", 0, 0, 0 },
160 { ALIGN_LEFT, "", "", 0, 0, 0 },
161 };
162
163 static struct column *current_field = columns;
164
165 /* Output buffer: chained chunks of BUF_CHUNK bytes. Each field is written to
166 * the buffer as a variable size token. A token consists of a 16 bits length
167 * field, followed by a string which is not NULL-terminated.
168 *
169 * A new chunk is allocated and linked when the current chunk doesn't have
170 * enough room to store the current token as a whole.
171 */
172 struct buf_chunk {
173 struct buf_chunk *next; /* Next chained chunk */
174 char *end; /* Current end of content */
175 char data[0];
176 };
177
178 struct buf_token {
179 uint16_t len; /* Data length, excluding length descriptor */
180 char data[0];
181 };
182
183 static struct {
184 struct buf_token *cur; /* Position of current token in chunk */
185 struct buf_chunk *head; /* First chunk */
186 struct buf_chunk *tail; /* Current chunk */
187 } buffer;
188
189 static const char *TCP_PROTO = "tcp";
190 static const char *SCTP_PROTO = "sctp";
191 static const char *UDP_PROTO = "udp";
192 static const char *RAW_PROTO = "raw";
193 static const char *dg_proto;
194
195 enum {
196 TCP_DB,
197 DCCP_DB,
198 UDP_DB,
199 RAW_DB,
200 UNIX_DG_DB,
201 UNIX_ST_DB,
202 UNIX_SQ_DB,
203 PACKET_DG_DB,
204 PACKET_R_DB,
205 NETLINK_DB,
206 SCTP_DB,
207 VSOCK_ST_DB,
208 VSOCK_DG_DB,
209 TIPC_DB,
210 MAX_DB
211 };
212
213 #define PACKET_DBM ((1<<PACKET_DG_DB)|(1<<PACKET_R_DB))
214 #define UNIX_DBM ((1<<UNIX_DG_DB)|(1<<UNIX_ST_DB)|(1<<UNIX_SQ_DB))
215 #define ALL_DB ((1<<MAX_DB)-1)
216 #define INET_L4_DBM ((1<<TCP_DB)|(1<<UDP_DB)|(1<<DCCP_DB)|(1<<SCTP_DB))
217 #define INET_DBM (INET_L4_DBM | (1<<RAW_DB))
218 #define VSOCK_DBM ((1<<VSOCK_ST_DB)|(1<<VSOCK_DG_DB))
219
220 enum {
221 SS_UNKNOWN,
222 SS_ESTABLISHED,
223 SS_SYN_SENT,
224 SS_SYN_RECV,
225 SS_FIN_WAIT1,
226 SS_FIN_WAIT2,
227 SS_TIME_WAIT,
228 SS_CLOSE,
229 SS_CLOSE_WAIT,
230 SS_LAST_ACK,
231 SS_LISTEN,
232 SS_CLOSING,
233 SS_MAX
234 };
235
236 enum {
237 SCTP_STATE_CLOSED = 0,
238 SCTP_STATE_COOKIE_WAIT = 1,
239 SCTP_STATE_COOKIE_ECHOED = 2,
240 SCTP_STATE_ESTABLISHED = 3,
241 SCTP_STATE_SHUTDOWN_PENDING = 4,
242 SCTP_STATE_SHUTDOWN_SENT = 5,
243 SCTP_STATE_SHUTDOWN_RECEIVED = 6,
244 SCTP_STATE_SHUTDOWN_ACK_SENT = 7,
245 };
246
247 #define SS_ALL ((1 << SS_MAX) - 1)
248 #define SS_CONN (SS_ALL & ~((1<<SS_LISTEN)|(1<<SS_CLOSE)|(1<<SS_TIME_WAIT)|(1<<SS_SYN_RECV)))
249 #define TIPC_SS_CONN ((1<<SS_ESTABLISHED)|(1<<SS_LISTEN)|(1<<SS_CLOSE))
250
251 #include "ssfilter.h"
252
253 struct filter {
254 int dbs;
255 int states;
256 uint64_t families;
257 struct ssfilter *f;
258 bool kill;
259 struct rtnl_handle *rth_for_killing;
260 };
261
262 #define FAMILY_MASK(family) ((uint64_t)1 << (family))
263
264 static const struct filter default_dbs[MAX_DB] = {
265 [TCP_DB] = {
266 .states = SS_CONN,
267 .families = FAMILY_MASK(AF_INET) | FAMILY_MASK(AF_INET6),
268 },
269 [DCCP_DB] = {
270 .states = SS_CONN,
271 .families = FAMILY_MASK(AF_INET) | FAMILY_MASK(AF_INET6),
272 },
273 [UDP_DB] = {
274 .states = (1 << SS_ESTABLISHED),
275 .families = FAMILY_MASK(AF_INET) | FAMILY_MASK(AF_INET6),
276 },
277 [RAW_DB] = {
278 .states = (1 << SS_ESTABLISHED),
279 .families = FAMILY_MASK(AF_INET) | FAMILY_MASK(AF_INET6),
280 },
281 [UNIX_DG_DB] = {
282 .states = (1 << SS_CLOSE),
283 .families = FAMILY_MASK(AF_UNIX),
284 },
285 [UNIX_ST_DB] = {
286 .states = SS_CONN,
287 .families = FAMILY_MASK(AF_UNIX),
288 },
289 [UNIX_SQ_DB] = {
290 .states = SS_CONN,
291 .families = FAMILY_MASK(AF_UNIX),
292 },
293 [PACKET_DG_DB] = {
294 .states = (1 << SS_CLOSE),
295 .families = FAMILY_MASK(AF_PACKET),
296 },
297 [PACKET_R_DB] = {
298 .states = (1 << SS_CLOSE),
299 .families = FAMILY_MASK(AF_PACKET),
300 },
301 [NETLINK_DB] = {
302 .states = (1 << SS_CLOSE),
303 .families = FAMILY_MASK(AF_NETLINK),
304 },
305 [SCTP_DB] = {
306 .states = SS_CONN,
307 .families = FAMILY_MASK(AF_INET) | FAMILY_MASK(AF_INET6),
308 },
309 [VSOCK_ST_DB] = {
310 .states = SS_CONN,
311 .families = FAMILY_MASK(AF_VSOCK),
312 },
313 [VSOCK_DG_DB] = {
314 .states = SS_CONN,
315 .families = FAMILY_MASK(AF_VSOCK),
316 },
317 [TIPC_DB] = {
318 .states = TIPC_SS_CONN,
319 .families = FAMILY_MASK(AF_TIPC),
320 },
321 };
322
323 static const struct filter default_afs[AF_MAX] = {
324 [AF_INET] = {
325 .dbs = INET_DBM,
326 .states = SS_CONN,
327 },
328 [AF_INET6] = {
329 .dbs = INET_DBM,
330 .states = SS_CONN,
331 },
332 [AF_UNIX] = {
333 .dbs = UNIX_DBM,
334 .states = SS_CONN,
335 },
336 [AF_PACKET] = {
337 .dbs = PACKET_DBM,
338 .states = (1 << SS_CLOSE),
339 },
340 [AF_NETLINK] = {
341 .dbs = (1 << NETLINK_DB),
342 .states = (1 << SS_CLOSE),
343 },
344 [AF_VSOCK] = {
345 .dbs = VSOCK_DBM,
346 .states = SS_CONN,
347 },
348 [AF_TIPC] = {
349 .dbs = (1 << TIPC_DB),
350 .states = TIPC_SS_CONN,
351 },
352 };
353
354 static int do_default = 1;
355 static struct filter current_filter;
356
357 static void filter_db_set(struct filter *f, int db, bool enable)
358 {
359 if (enable) {
360 f->states |= default_dbs[db].states;
361 f->dbs |= 1 << db;
362 } else {
363 f->dbs &= ~(1 << db);
364 }
365 do_default = 0;
366 }
367
368 static int filter_db_parse(struct filter *f, const char *s)
369 {
370 const struct {
371 const char *name;
372 int dbs[MAX_DB + 1];
373 } db_name_tbl[] = {
374 #define ENTRY(name, ...) { #name, { __VA_ARGS__, MAX_DB } }
375 ENTRY(all, UDP_DB, DCCP_DB, TCP_DB, RAW_DB,
376 UNIX_ST_DB, UNIX_DG_DB, UNIX_SQ_DB,
377 PACKET_R_DB, PACKET_DG_DB, NETLINK_DB,
378 SCTP_DB, VSOCK_ST_DB, VSOCK_DG_DB),
379 ENTRY(inet, UDP_DB, DCCP_DB, TCP_DB, SCTP_DB, RAW_DB),
380 ENTRY(udp, UDP_DB),
381 ENTRY(dccp, DCCP_DB),
382 ENTRY(tcp, TCP_DB),
383 ENTRY(sctp, SCTP_DB),
384 ENTRY(raw, RAW_DB),
385 ENTRY(unix, UNIX_ST_DB, UNIX_DG_DB, UNIX_SQ_DB),
386 ENTRY(unix_stream, UNIX_ST_DB),
387 ENTRY(u_str, UNIX_ST_DB), /* alias for unix_stream */
388 ENTRY(unix_dgram, UNIX_DG_DB),
389 ENTRY(u_dgr, UNIX_DG_DB), /* alias for unix_dgram */
390 ENTRY(unix_seqpacket, UNIX_SQ_DB),
391 ENTRY(u_seq, UNIX_SQ_DB), /* alias for unix_seqpacket */
392 ENTRY(packet, PACKET_R_DB, PACKET_DG_DB),
393 ENTRY(packet_raw, PACKET_R_DB),
394 ENTRY(p_raw, PACKET_R_DB), /* alias for packet_raw */
395 ENTRY(packet_dgram, PACKET_DG_DB),
396 ENTRY(p_dgr, PACKET_DG_DB), /* alias for packet_dgram */
397 ENTRY(netlink, NETLINK_DB),
398 ENTRY(vsock, VSOCK_ST_DB, VSOCK_DG_DB),
399 ENTRY(vsock_stream, VSOCK_ST_DB),
400 ENTRY(v_str, VSOCK_ST_DB), /* alias for vsock_stream */
401 ENTRY(vsock_dgram, VSOCK_DG_DB),
402 ENTRY(v_dgr, VSOCK_DG_DB), /* alias for vsock_dgram */
403 #undef ENTRY
404 };
405 bool enable = true;
406 unsigned int i;
407 const int *dbp;
408
409 if (s[0] == '!') {
410 enable = false;
411 s++;
412 }
413 for (i = 0; i < ARRAY_SIZE(db_name_tbl); i++) {
414 if (strcmp(s, db_name_tbl[i].name))
415 continue;
416 for (dbp = db_name_tbl[i].dbs; *dbp != MAX_DB; dbp++)
417 filter_db_set(f, *dbp, enable);
418 return 0;
419 }
420 return -1;
421 }
422
423 static void filter_af_set(struct filter *f, int af)
424 {
425 f->states |= default_afs[af].states;
426 f->families |= FAMILY_MASK(af);
427 do_default = 0;
428 preferred_family = af;
429 }
430
431 static int filter_af_get(struct filter *f, int af)
432 {
433 return !!(f->families & FAMILY_MASK(af));
434 }
435
436 static void filter_states_set(struct filter *f, int states)
437 {
438 if (states)
439 f->states = states;
440 }
441
442 static void filter_merge_defaults(struct filter *f)
443 {
444 int db;
445 int af;
446
447 for (db = 0; db < MAX_DB; db++) {
448 if (!(f->dbs & (1 << db)))
449 continue;
450
451 if (!(default_dbs[db].families & f->families))
452 f->families |= default_dbs[db].families;
453 }
454 for (af = 0; af < AF_MAX; af++) {
455 if (!(f->families & FAMILY_MASK(af)))
456 continue;
457
458 if (!(default_afs[af].dbs & f->dbs))
459 f->dbs |= default_afs[af].dbs;
460 }
461 }
462
463 static FILE *generic_proc_open(const char *env, const char *name)
464 {
465 const char *p = getenv(env);
466 char store[128];
467
468 if (!p) {
469 p = getenv("PROC_ROOT") ? : "/proc";
470 snprintf(store, sizeof(store)-1, "%s/%s", p, name);
471 p = store;
472 }
473
474 return fopen(p, "r");
475 }
476 #define net_tcp_open() generic_proc_open("PROC_NET_TCP", "net/tcp")
477 #define net_tcp6_open() generic_proc_open("PROC_NET_TCP6", "net/tcp6")
478 #define net_udp_open() generic_proc_open("PROC_NET_UDP", "net/udp")
479 #define net_udp6_open() generic_proc_open("PROC_NET_UDP6", "net/udp6")
480 #define net_raw_open() generic_proc_open("PROC_NET_RAW", "net/raw")
481 #define net_raw6_open() generic_proc_open("PROC_NET_RAW6", "net/raw6")
482 #define net_unix_open() generic_proc_open("PROC_NET_UNIX", "net/unix")
483 #define net_packet_open() generic_proc_open("PROC_NET_PACKET", \
484 "net/packet")
485 #define net_netlink_open() generic_proc_open("PROC_NET_NETLINK", \
486 "net/netlink")
487 #define net_sockstat_open() generic_proc_open("PROC_NET_SOCKSTAT", \
488 "net/sockstat")
489 #define net_sockstat6_open() generic_proc_open("PROC_NET_SOCKSTAT6", \
490 "net/sockstat6")
491 #define net_snmp_open() generic_proc_open("PROC_NET_SNMP", "net/snmp")
492 #define ephemeral_ports_open() generic_proc_open("PROC_IP_LOCAL_PORT_RANGE", \
493 "sys/net/ipv4/ip_local_port_range")
494
495 struct user_ent {
496 struct user_ent *next;
497 unsigned int ino;
498 int pid;
499 int fd;
500 char *process;
501 char *process_ctx;
502 char *socket_ctx;
503 };
504
505 #define USER_ENT_HASH_SIZE 256
506 static struct user_ent *user_ent_hash[USER_ENT_HASH_SIZE];
507
508 static int user_ent_hashfn(unsigned int ino)
509 {
510 int val = (ino >> 24) ^ (ino >> 16) ^ (ino >> 8) ^ ino;
511
512 return val & (USER_ENT_HASH_SIZE - 1);
513 }
514
515 static void user_ent_add(unsigned int ino, char *process,
516 int pid, int fd,
517 char *proc_ctx,
518 char *sock_ctx)
519 {
520 struct user_ent *p, **pp;
521
522 p = malloc(sizeof(struct user_ent));
523 if (!p) {
524 fprintf(stderr, "ss: failed to malloc buffer\n");
525 abort();
526 }
527 p->next = NULL;
528 p->ino = ino;
529 p->pid = pid;
530 p->fd = fd;
531 p->process = strdup(process);
532 p->process_ctx = strdup(proc_ctx);
533 p->socket_ctx = strdup(sock_ctx);
534
535 pp = &user_ent_hash[user_ent_hashfn(ino)];
536 p->next = *pp;
537 *pp = p;
538 }
539
540 static void user_ent_destroy(void)
541 {
542 struct user_ent *p, *p_next;
543 int cnt = 0;
544
545 while (cnt != USER_ENT_HASH_SIZE) {
546 p = user_ent_hash[cnt];
547 while (p) {
548 free(p->process);
549 free(p->process_ctx);
550 free(p->socket_ctx);
551 p_next = p->next;
552 free(p);
553 p = p_next;
554 }
555 cnt++;
556 }
557 }
558
559 static void user_ent_hash_build(void)
560 {
561 const char *root = getenv("PROC_ROOT") ? : "/proc/";
562 struct dirent *d;
563 char name[1024];
564 int nameoff;
565 DIR *dir;
566 char *pid_context;
567 char *sock_context;
568 const char *no_ctx = "unavailable";
569 static int user_ent_hash_build_init;
570
571 /* If show_users & show_proc_ctx set only do this once */
572 if (user_ent_hash_build_init != 0)
573 return;
574
575 user_ent_hash_build_init = 1;
576
577 strlcpy(name, root, sizeof(name));
578
579 if (strlen(name) == 0 || name[strlen(name)-1] != '/')
580 strcat(name, "/");
581
582 nameoff = strlen(name);
583
584 dir = opendir(name);
585 if (!dir)
586 return;
587
588 while ((d = readdir(dir)) != NULL) {
589 struct dirent *d1;
590 char process[16];
591 char *p;
592 int pid, pos;
593 DIR *dir1;
594 char crap;
595
596 if (sscanf(d->d_name, "%d%c", &pid, &crap) != 1)
597 continue;
598
599 if (getpidcon(pid, &pid_context) != 0)
600 pid_context = strdup(no_ctx);
601
602 snprintf(name + nameoff, sizeof(name) - nameoff, "%d/fd/", pid);
603 pos = strlen(name);
604 if ((dir1 = opendir(name)) == NULL) {
605 free(pid_context);
606 continue;
607 }
608
609 process[0] = '\0';
610 p = process;
611
612 while ((d1 = readdir(dir1)) != NULL) {
613 const char *pattern = "socket:[";
614 unsigned int ino;
615 char lnk[64];
616 int fd;
617 ssize_t link_len;
618 char tmp[1024];
619
620 if (sscanf(d1->d_name, "%d%c", &fd, &crap) != 1)
621 continue;
622
623 snprintf(name+pos, sizeof(name) - pos, "%d", fd);
624
625 link_len = readlink(name, lnk, sizeof(lnk)-1);
626 if (link_len == -1)
627 continue;
628 lnk[link_len] = '\0';
629
630 if (strncmp(lnk, pattern, strlen(pattern)))
631 continue;
632
633 sscanf(lnk, "socket:[%u]", &ino);
634
635 snprintf(tmp, sizeof(tmp), "%s/%d/fd/%s",
636 root, pid, d1->d_name);
637
638 if (getfilecon(tmp, &sock_context) <= 0)
639 sock_context = strdup(no_ctx);
640
641 if (*p == '\0') {
642 FILE *fp;
643
644 snprintf(tmp, sizeof(tmp), "%s/%d/stat",
645 root, pid);
646 if ((fp = fopen(tmp, "r")) != NULL) {
647 if (fscanf(fp, "%*d (%[^)])", p) < 1)
648 ; /* ignore */
649 fclose(fp);
650 }
651 }
652 user_ent_add(ino, p, pid, fd,
653 pid_context, sock_context);
654 free(sock_context);
655 }
656 free(pid_context);
657 closedir(dir1);
658 }
659 closedir(dir);
660 }
661
662 enum entry_types {
663 USERS,
664 PROC_CTX,
665 PROC_SOCK_CTX
666 };
667
668 #define ENTRY_BUF_SIZE 512
669 static int find_entry(unsigned int ino, char **buf, int type)
670 {
671 struct user_ent *p;
672 int cnt = 0;
673 char *ptr;
674 char *new_buf;
675 int len, new_buf_len;
676 int buf_used = 0;
677 int buf_len = 0;
678
679 if (!ino)
680 return 0;
681
682 p = user_ent_hash[user_ent_hashfn(ino)];
683 ptr = *buf = NULL;
684 while (p) {
685 if (p->ino != ino)
686 goto next;
687
688 while (1) {
689 ptr = *buf + buf_used;
690 switch (type) {
691 case USERS:
692 len = snprintf(ptr, buf_len - buf_used,
693 "(\"%s\",pid=%d,fd=%d),",
694 p->process, p->pid, p->fd);
695 break;
696 case PROC_CTX:
697 len = snprintf(ptr, buf_len - buf_used,
698 "(\"%s\",pid=%d,proc_ctx=%s,fd=%d),",
699 p->process, p->pid,
700 p->process_ctx, p->fd);
701 break;
702 case PROC_SOCK_CTX:
703 len = snprintf(ptr, buf_len - buf_used,
704 "(\"%s\",pid=%d,proc_ctx=%s,fd=%d,sock_ctx=%s),",
705 p->process, p->pid,
706 p->process_ctx, p->fd,
707 p->socket_ctx);
708 break;
709 default:
710 fprintf(stderr, "ss: invalid type: %d\n", type);
711 abort();
712 }
713
714 if (len < 0 || len >= buf_len - buf_used) {
715 new_buf_len = buf_len + ENTRY_BUF_SIZE;
716 new_buf = realloc(*buf, new_buf_len);
717 if (!new_buf) {
718 fprintf(stderr, "ss: failed to malloc buffer\n");
719 abort();
720 }
721 *buf = new_buf;
722 buf_len = new_buf_len;
723 continue;
724 } else {
725 buf_used += len;
726 break;
727 }
728 }
729 cnt++;
730 next:
731 p = p->next;
732 }
733 if (buf_used) {
734 ptr = *buf + buf_used;
735 ptr[-1] = '\0';
736 }
737 return cnt;
738 }
739
740 static unsigned long long cookie_sk_get(const uint32_t *cookie)
741 {
742 return (((unsigned long long)cookie[1] << 31) << 1) | cookie[0];
743 }
744
745 static const char *sctp_sstate_name[] = {
746 [SCTP_STATE_CLOSED] = "CLOSED",
747 [SCTP_STATE_COOKIE_WAIT] = "COOKIE_WAIT",
748 [SCTP_STATE_COOKIE_ECHOED] = "COOKIE_ECHOED",
749 [SCTP_STATE_ESTABLISHED] = "ESTAB",
750 [SCTP_STATE_SHUTDOWN_PENDING] = "SHUTDOWN_PENDING",
751 [SCTP_STATE_SHUTDOWN_SENT] = "SHUTDOWN_SENT",
752 [SCTP_STATE_SHUTDOWN_RECEIVED] = "SHUTDOWN_RECEIVED",
753 [SCTP_STATE_SHUTDOWN_ACK_SENT] = "ACK_SENT",
754 };
755
756 static const char * const stype_nameg[] = {
757 "UNKNOWN",
758 [SOCK_STREAM] = "STREAM",
759 [SOCK_DGRAM] = "DGRAM",
760 [SOCK_RDM] = "RDM",
761 [SOCK_SEQPACKET] = "SEQPACKET",
762 };
763
764 struct sockstat {
765 struct sockstat *next;
766 unsigned int type;
767 uint16_t prot;
768 uint16_t raw_prot;
769 inet_prefix local;
770 inet_prefix remote;
771 int lport;
772 int rport;
773 int state;
774 int rq, wq;
775 unsigned int ino;
776 unsigned int uid;
777 int refcnt;
778 unsigned int iface;
779 unsigned long long sk;
780 char *name;
781 char *peer_name;
782 __u32 mark;
783 };
784
785 struct dctcpstat {
786 unsigned int ce_state;
787 unsigned int alpha;
788 unsigned int ab_ecn;
789 unsigned int ab_tot;
790 bool enabled;
791 };
792
793 struct tcpstat {
794 struct sockstat ss;
795 unsigned int timer;
796 unsigned int timeout;
797 int probes;
798 char cong_alg[16];
799 double rto, ato, rtt, rttvar;
800 int qack, ssthresh, backoff;
801 double send_bps;
802 int snd_wscale;
803 int rcv_wscale;
804 int mss;
805 int rcv_mss;
806 int advmss;
807 unsigned int pmtu;
808 unsigned int cwnd;
809 unsigned int lastsnd;
810 unsigned int lastrcv;
811 unsigned int lastack;
812 double pacing_rate;
813 double pacing_rate_max;
814 double delivery_rate;
815 unsigned long long bytes_acked;
816 unsigned long long bytes_received;
817 unsigned int segs_out;
818 unsigned int segs_in;
819 unsigned int data_segs_out;
820 unsigned int data_segs_in;
821 unsigned int unacked;
822 unsigned int retrans;
823 unsigned int retrans_total;
824 unsigned int lost;
825 unsigned int sacked;
826 unsigned int fackets;
827 unsigned int reordering;
828 unsigned int not_sent;
829 unsigned int delivered;
830 unsigned int delivered_ce;
831 unsigned int dsack_dups;
832 unsigned int reord_seen;
833 double rcv_rtt;
834 double min_rtt;
835 int rcv_space;
836 unsigned int rcv_ssthresh;
837 unsigned long long busy_time;
838 unsigned long long rwnd_limited;
839 unsigned long long sndbuf_limited;
840 unsigned long long bytes_sent;
841 unsigned long long bytes_retrans;
842 bool has_ts_opt;
843 bool has_sack_opt;
844 bool has_ecn_opt;
845 bool has_ecnseen_opt;
846 bool has_fastopen_opt;
847 bool has_wscale_opt;
848 bool app_limited;
849 struct dctcpstat *dctcp;
850 struct tcp_bbr_info *bbr_info;
851 };
852
853 /* SCTP assocs share the same inode number with their parent endpoint. So if we
854 * have seen the inode number before, it must be an assoc instead of the next
855 * endpoint. */
856 static bool is_sctp_assoc(struct sockstat *s, const char *sock_name)
857 {
858 if (strcmp(sock_name, "sctp"))
859 return false;
860 if (!sctp_ino || sctp_ino != s->ino)
861 return false;
862 return true;
863 }
864
865 static const char *unix_netid_name(int type)
866 {
867 switch (type) {
868 case SOCK_STREAM:
869 return "u_str";
870 case SOCK_SEQPACKET:
871 return "u_seq";
872 case SOCK_DGRAM:
873 default:
874 return "u_dgr";
875 }
876 }
877
878 static const char *proto_name(int protocol)
879 {
880 switch (protocol) {
881 case 0:
882 return "raw";
883 case IPPROTO_UDP:
884 return "udp";
885 case IPPROTO_TCP:
886 return "tcp";
887 case IPPROTO_SCTP:
888 return "sctp";
889 case IPPROTO_DCCP:
890 return "dccp";
891 case IPPROTO_ICMPV6:
892 return "icmp6";
893 }
894
895 return "???";
896 }
897
898 static const char *vsock_netid_name(int type)
899 {
900 switch (type) {
901 case SOCK_STREAM:
902 return "v_str";
903 case SOCK_DGRAM:
904 return "v_dgr";
905 default:
906 return "???";
907 }
908 }
909
910 static const char *tipc_netid_name(int type)
911 {
912 switch (type) {
913 case SOCK_STREAM:
914 return "ti_st";
915 case SOCK_DGRAM:
916 return "ti_dg";
917 case SOCK_RDM:
918 return "ti_rd";
919 case SOCK_SEQPACKET:
920 return "ti_sq";
921 default:
922 return "???";
923 }
924 }
925
926 /* Allocate and initialize a new buffer chunk */
927 static struct buf_chunk *buf_chunk_new(void)
928 {
929 struct buf_chunk *new = malloc(BUF_CHUNK);
930
931 if (!new)
932 abort();
933
934 new->next = NULL;
935
936 /* This is also the last block */
937 buffer.tail = new;
938
939 /* Next token will be stored at the beginning of chunk data area, and
940 * its initial length is zero.
941 */
942 buffer.cur = (struct buf_token *)new->data;
943 buffer.cur->len = 0;
944
945 new->end = buffer.cur->data;
946
947 return new;
948 }
949
950 /* Return available tail room in given chunk */
951 static int buf_chunk_avail(struct buf_chunk *chunk)
952 {
953 return BUF_CHUNK - offsetof(struct buf_chunk, data) -
954 (chunk->end - chunk->data);
955 }
956
957 /* Update end pointer and token length, link new chunk if we hit the end of the
958 * current one. Return -EAGAIN if we got a new chunk, caller has to print again.
959 */
960 static int buf_update(int len)
961 {
962 struct buf_chunk *chunk = buffer.tail;
963 struct buf_token *t = buffer.cur;
964
965 /* Claim success if new content fits in the current chunk, and anyway
966 * if this is the first token in the chunk: in the latter case,
967 * allocating a new chunk won't help, so we'll just cut the output.
968 */
969 if ((len < buf_chunk_avail(chunk) && len != -1 /* glibc < 2.0.6 */) ||
970 t == (struct buf_token *)chunk->data) {
971 len = min(len, buf_chunk_avail(chunk));
972
973 /* Total field length can't exceed 2^16 bytes, cut as needed */
974 len = min(len, USHRT_MAX - t->len);
975
976 chunk->end += len;
977 t->len += len;
978 return 0;
979 }
980
981 /* Content truncated, time to allocate more */
982 chunk->next = buf_chunk_new();
983
984 /* Copy current token over to new chunk, including length descriptor */
985 memcpy(chunk->next->data, t, sizeof(t->len) + t->len);
986 chunk->next->end += t->len;
987
988 /* Discard partially written field in old chunk */
989 chunk->end -= t->len + sizeof(t->len);
990
991 return -EAGAIN;
992 }
993
994 /* Append content to buffer as part of the current field */
995 __attribute__((format(printf, 1, 2)))
996 static void out(const char *fmt, ...)
997 {
998 struct column *f = current_field;
999 va_list args;
1000 char *pos;
1001 int len;
1002
1003 if (f->disabled)
1004 return;
1005
1006 if (!buffer.head)
1007 buffer.head = buf_chunk_new();
1008
1009 again: /* Append to buffer: if we have a new chunk, print again */
1010
1011 pos = buffer.cur->data + buffer.cur->len;
1012 va_start(args, fmt);
1013
1014 /* Limit to tail room. If we hit the limit, buf_update() will tell us */
1015 len = vsnprintf(pos, buf_chunk_avail(buffer.tail), fmt, args);
1016 va_end(args);
1017
1018 if (buf_update(len))
1019 goto again;
1020 }
1021
1022 static int print_left_spacing(struct column *f, int stored, int printed)
1023 {
1024 int s;
1025
1026 if (!f->width || f->align == ALIGN_LEFT)
1027 return 0;
1028
1029 s = f->width - stored - printed;
1030 if (f->align == ALIGN_CENTER)
1031 /* If count of total spacing is odd, shift right by one */
1032 s = (s + 1) / 2;
1033
1034 if (s > 0)
1035 return printf("%*c", s, ' ');
1036
1037 return 0;
1038 }
1039
1040 static void print_right_spacing(struct column *f, int printed)
1041 {
1042 int s;
1043
1044 if (!f->width || f->align == ALIGN_RIGHT)
1045 return;
1046
1047 s = f->width - printed;
1048 if (f->align == ALIGN_CENTER)
1049 s /= 2;
1050
1051 if (s > 0)
1052 printf("%*c", s, ' ');
1053 }
1054
1055 /* Done with field: update buffer pointer, start new token after current one */
1056 static void field_flush(struct column *f)
1057 {
1058 struct buf_chunk *chunk;
1059 unsigned int pad;
1060
1061 if (f->disabled)
1062 return;
1063
1064 chunk = buffer.tail;
1065 pad = buffer.cur->len % 2;
1066
1067 if (buffer.cur->len > f->max_len)
1068 f->max_len = buffer.cur->len;
1069
1070 /* We need a new chunk if we can't store the next length descriptor.
1071 * Mind the gap between end of previous token and next aligned position
1072 * for length descriptor.
1073 */
1074 if (buf_chunk_avail(chunk) - pad < sizeof(buffer.cur->len)) {
1075 chunk->end += pad;
1076 chunk->next = buf_chunk_new();
1077 return;
1078 }
1079
1080 buffer.cur = (struct buf_token *)(buffer.cur->data +
1081 LEN_ALIGN(buffer.cur->len));
1082 buffer.cur->len = 0;
1083 buffer.tail->end = buffer.cur->data;
1084 }
1085
1086 static int field_is_last(struct column *f)
1087 {
1088 return f - columns == COL_MAX - 1;
1089 }
1090
1091 static void field_next(void)
1092 {
1093 field_flush(current_field);
1094
1095 if (field_is_last(current_field))
1096 current_field = columns;
1097 else
1098 current_field++;
1099 }
1100
1101 /* Walk through fields and flush them until we reach the desired one */
1102 static void field_set(enum col_id id)
1103 {
1104 while (id != current_field - columns)
1105 field_next();
1106 }
1107
1108 /* Print header for all non-empty columns */
1109 static void print_header(void)
1110 {
1111 while (!field_is_last(current_field)) {
1112 if (!current_field->disabled)
1113 out("%s", current_field->header);
1114 field_next();
1115 }
1116 }
1117
1118 /* Get the next available token in the buffer starting from the current token */
1119 static struct buf_token *buf_token_next(struct buf_token *cur)
1120 {
1121 struct buf_chunk *chunk = buffer.tail;
1122
1123 /* If we reached the end of chunk contents, get token from next chunk */
1124 if (cur->data + LEN_ALIGN(cur->len) == chunk->end) {
1125 buffer.tail = chunk = chunk->next;
1126 return chunk ? (struct buf_token *)chunk->data : NULL;
1127 }
1128
1129 return (struct buf_token *)(cur->data + LEN_ALIGN(cur->len));
1130 }
1131
1132 /* Free up all allocated buffer chunks */
1133 static void buf_free_all(void)
1134 {
1135 struct buf_chunk *tmp;
1136
1137 for (buffer.tail = buffer.head; buffer.tail; ) {
1138 tmp = buffer.tail;
1139 buffer.tail = buffer.tail->next;
1140 free(tmp);
1141 }
1142 buffer.head = NULL;
1143 }
1144
1145 /* Get current screen width, default to 80 columns if TIOCGWINSZ fails */
1146 static int render_screen_width(void)
1147 {
1148 int width = 80;
1149
1150 if (isatty(STDOUT_FILENO)) {
1151 struct winsize w;
1152
1153 if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) != -1) {
1154 if (w.ws_col > 0)
1155 width = w.ws_col;
1156 }
1157 }
1158
1159 return width;
1160 }
1161
1162 /* Calculate column width from contents length. If columns don't fit on one
1163 * line, break them into the least possible amount of lines and keep them
1164 * aligned across lines. Available screen space is equally spread between fields
1165 * as additional spacing.
1166 */
1167 static void render_calc_width(void)
1168 {
1169 int screen_width = render_screen_width();
1170 struct column *c, *eol = columns - 1;
1171 int first, len = 0, linecols = 0;
1172
1173 /* First pass: set width for each column to measured content length */
1174 for (first = 1, c = columns; c - columns < COL_MAX; c++) {
1175 if (c->disabled)
1176 continue;
1177
1178 if (!first && c->max_len)
1179 c->width = c->max_len + strlen(c->ldelim);
1180 else
1181 c->width = c->max_len;
1182
1183 /* But don't exceed screen size. If we exceed the screen size
1184 * for even a single field, it will just start on a line of its
1185 * own and then naturally wrap.
1186 */
1187 c->width = min(c->width, screen_width);
1188
1189 if (c->width)
1190 first = 0;
1191 }
1192
1193 /* Second pass: find out newlines and distribute available spacing */
1194 for (c = columns; c - columns < COL_MAX; c++) {
1195 int pad, spacing, rem, last;
1196 struct column *tmp;
1197
1198 if (!c->width)
1199 continue;
1200
1201 linecols++;
1202 len += c->width;
1203
1204 for (last = 1, tmp = c + 1; tmp - columns < COL_MAX; tmp++) {
1205 if (tmp->width) {
1206 last = 0;
1207 break;
1208 }
1209 }
1210
1211 if (!last && len < screen_width) {
1212 /* Columns fit on screen so far, nothing to do yet */
1213 continue;
1214 }
1215
1216 if (len == screen_width) {
1217 /* Exact fit, just start with new line */
1218 goto newline;
1219 }
1220
1221 if (len > screen_width) {
1222 /* Screen width exceeded: go back one column */
1223 len -= c->width;
1224 c--;
1225 linecols--;
1226 }
1227
1228 /* Distribute remaining space to columns on this line */
1229 pad = screen_width - len;
1230 spacing = pad / linecols;
1231 rem = pad % linecols;
1232 for (tmp = c; tmp > eol; tmp--) {
1233 if (!tmp->width)
1234 continue;
1235
1236 tmp->width += spacing;
1237 if (rem) {
1238 tmp->width++;
1239 rem--;
1240 }
1241 }
1242
1243 newline:
1244 /* Line break: reset line counters, mark end-of-line */
1245 eol = c;
1246 len = 0;
1247 linecols = 0;
1248 }
1249 }
1250
1251 /* Render buffered output with spacing and delimiters, then free up buffers */
1252 static void render(void)
1253 {
1254 struct buf_token *token;
1255 int printed, line_started = 0;
1256 struct column *f;
1257
1258 if (!buffer.head)
1259 return;
1260
1261 token = (struct buf_token *)buffer.head->data;
1262
1263 /* Ensure end alignment of last token, it wasn't necessarily flushed */
1264 buffer.tail->end += buffer.cur->len % 2;
1265
1266 render_calc_width();
1267
1268 /* Rewind and replay */
1269 buffer.tail = buffer.head;
1270
1271 f = columns;
1272 while (!f->width)
1273 f++;
1274
1275 while (token) {
1276 /* Print left delimiter only if we already started a line */
1277 if (line_started++)
1278 printed = printf("%s", f->ldelim);
1279 else
1280 printed = 0;
1281
1282 /* Print field content from token data with spacing */
1283 printed += print_left_spacing(f, token->len, printed);
1284 printed += fwrite(token->data, 1, token->len, stdout);
1285 print_right_spacing(f, printed);
1286
1287 /* Go to next non-empty field, deal with end-of-line */
1288 do {
1289 if (field_is_last(f)) {
1290 printf("\n");
1291 f = columns;
1292 line_started = 0;
1293 } else {
1294 f++;
1295 }
1296 } while (f->disabled);
1297
1298 token = buf_token_next(token);
1299 }
1300
1301 buf_free_all();
1302 current_field = columns;
1303 }
1304
1305 static void sock_state_print(struct sockstat *s)
1306 {
1307 const char *sock_name;
1308 static const char * const sstate_name[] = {
1309 "UNKNOWN",
1310 [SS_ESTABLISHED] = "ESTAB",
1311 [SS_SYN_SENT] = "SYN-SENT",
1312 [SS_SYN_RECV] = "SYN-RECV",
1313 [SS_FIN_WAIT1] = "FIN-WAIT-1",
1314 [SS_FIN_WAIT2] = "FIN-WAIT-2",
1315 [SS_TIME_WAIT] = "TIME-WAIT",
1316 [SS_CLOSE] = "UNCONN",
1317 [SS_CLOSE_WAIT] = "CLOSE-WAIT",
1318 [SS_LAST_ACK] = "LAST-ACK",
1319 [SS_LISTEN] = "LISTEN",
1320 [SS_CLOSING] = "CLOSING",
1321 };
1322
1323 switch (s->local.family) {
1324 case AF_UNIX:
1325 sock_name = unix_netid_name(s->type);
1326 break;
1327 case AF_INET:
1328 case AF_INET6:
1329 sock_name = proto_name(s->type);
1330 break;
1331 case AF_PACKET:
1332 sock_name = s->type == SOCK_RAW ? "p_raw" : "p_dgr";
1333 break;
1334 case AF_NETLINK:
1335 sock_name = "nl";
1336 break;
1337 case AF_TIPC:
1338 sock_name = tipc_netid_name(s->type);
1339 break;
1340 case AF_VSOCK:
1341 sock_name = vsock_netid_name(s->type);
1342 break;
1343 default:
1344 sock_name = "unknown";
1345 }
1346
1347 if (is_sctp_assoc(s, sock_name)) {
1348 field_set(COL_STATE); /* Empty Netid field */
1349 out("`- %s", sctp_sstate_name[s->state]);
1350 } else {
1351 field_set(COL_NETID);
1352 out("%s", sock_name);
1353 field_set(COL_STATE);
1354 out("%s", sstate_name[s->state]);
1355 }
1356
1357 field_set(COL_RECVQ);
1358 out("%-6d", s->rq);
1359 field_set(COL_SENDQ);
1360 out("%-6d", s->wq);
1361 field_set(COL_ADDR);
1362 }
1363
1364 static void sock_details_print(struct sockstat *s)
1365 {
1366 if (s->uid)
1367 out(" uid:%u", s->uid);
1368
1369 out(" ino:%u", s->ino);
1370 out(" sk:%llx", s->sk);
1371
1372 if (s->mark)
1373 out(" fwmark:0x%x", s->mark);
1374 }
1375
1376 static void sock_addr_print(const char *addr, char *delim, const char *port,
1377 const char *ifname)
1378 {
1379 if (ifname)
1380 out("%s" "%%" "%s%s", addr, ifname, delim);
1381 else
1382 out("%s%s", addr, delim);
1383
1384 field_next();
1385 out("%s", port);
1386 field_next();
1387 }
1388
1389 static const char *print_ms_timer(unsigned int timeout)
1390 {
1391 static char buf[64];
1392 int secs, msecs, minutes;
1393
1394 secs = timeout/1000;
1395 minutes = secs/60;
1396 secs = secs%60;
1397 msecs = timeout%1000;
1398 buf[0] = 0;
1399 if (minutes) {
1400 msecs = 0;
1401 snprintf(buf, sizeof(buf)-16, "%dmin", minutes);
1402 if (minutes > 9)
1403 secs = 0;
1404 }
1405 if (secs) {
1406 if (secs > 9)
1407 msecs = 0;
1408 sprintf(buf+strlen(buf), "%d%s", secs, msecs ? "." : "sec");
1409 }
1410 if (msecs)
1411 sprintf(buf+strlen(buf), "%03dms", msecs);
1412 return buf;
1413 }
1414
1415 struct scache {
1416 struct scache *next;
1417 int port;
1418 char *name;
1419 const char *proto;
1420 };
1421
1422 static struct scache *rlist;
1423
1424 static void init_service_resolver(void)
1425 {
1426 char buf[128];
1427 FILE *fp = popen("/usr/sbin/rpcinfo -p 2>/dev/null", "r");
1428
1429 if (!fp)
1430 return;
1431
1432 if (!fgets(buf, sizeof(buf), fp)) {
1433 pclose(fp);
1434 return;
1435 }
1436 while (fgets(buf, sizeof(buf), fp) != NULL) {
1437 unsigned int progn, port;
1438 char proto[128], prog[128] = "rpc.";
1439 struct scache *c;
1440
1441 if (sscanf(buf, "%u %*d %s %u %s",
1442 &progn, proto, &port, prog+4) != 4)
1443 continue;
1444
1445 if (!(c = malloc(sizeof(*c))))
1446 continue;
1447
1448 c->port = port;
1449 c->name = strdup(prog);
1450 if (strcmp(proto, TCP_PROTO) == 0)
1451 c->proto = TCP_PROTO;
1452 else if (strcmp(proto, UDP_PROTO) == 0)
1453 c->proto = UDP_PROTO;
1454 else if (strcmp(proto, SCTP_PROTO) == 0)
1455 c->proto = SCTP_PROTO;
1456 else
1457 c->proto = NULL;
1458 c->next = rlist;
1459 rlist = c;
1460 }
1461 pclose(fp);
1462 }
1463
1464 /* Even do not try default linux ephemeral port ranges:
1465 * default /etc/services contains so much of useless crap
1466 * wouldbe "allocated" to this area that resolution
1467 * is really harmful. I shrug each time when seeing
1468 * "socks" or "cfinger" in dumps.
1469 */
1470 static int is_ephemeral(int port)
1471 {
1472 static int min = 0, max;
1473
1474 if (!min) {
1475 FILE *f = ephemeral_ports_open();
1476
1477 if (!f || fscanf(f, "%d %d", &min, &max) < 2) {
1478 min = 1024;
1479 max = 4999;
1480 }
1481 if (f)
1482 fclose(f);
1483 }
1484 return port >= min && port <= max;
1485 }
1486
1487
1488 static const char *__resolve_service(int port)
1489 {
1490 struct scache *c;
1491
1492 for (c = rlist; c; c = c->next) {
1493 if (c->port == port && c->proto == dg_proto)
1494 return c->name;
1495 }
1496
1497 if (!is_ephemeral(port)) {
1498 static int notfirst;
1499 struct servent *se;
1500
1501 if (!notfirst) {
1502 setservent(1);
1503 notfirst = 1;
1504 }
1505 se = getservbyport(htons(port), dg_proto);
1506 if (se)
1507 return se->s_name;
1508 }
1509
1510 return NULL;
1511 }
1512
1513 #define SCACHE_BUCKETS 1024
1514 static struct scache *cache_htab[SCACHE_BUCKETS];
1515
1516 static const char *resolve_service(int port)
1517 {
1518 static char buf[128];
1519 struct scache *c;
1520 const char *res;
1521 int hash;
1522
1523 if (port == 0) {
1524 buf[0] = '*';
1525 buf[1] = 0;
1526 return buf;
1527 }
1528
1529 if (!resolve_services)
1530 goto do_numeric;
1531
1532 if (dg_proto == RAW_PROTO)
1533 return inet_proto_n2a(port, buf, sizeof(buf));
1534
1535
1536 hash = (port^(((unsigned long)dg_proto)>>2)) % SCACHE_BUCKETS;
1537
1538 for (c = cache_htab[hash]; c; c = c->next) {
1539 if (c->port == port && c->proto == dg_proto)
1540 goto do_cache;
1541 }
1542
1543 c = malloc(sizeof(*c));
1544 if (!c)
1545 goto do_numeric;
1546 res = __resolve_service(port);
1547 c->port = port;
1548 c->name = res ? strdup(res) : NULL;
1549 c->proto = dg_proto;
1550 c->next = cache_htab[hash];
1551 cache_htab[hash] = c;
1552
1553 do_cache:
1554 if (c->name)
1555 return c->name;
1556
1557 do_numeric:
1558 sprintf(buf, "%u", port);
1559 return buf;
1560 }
1561
1562 static void inet_addr_print(const inet_prefix *a, int port,
1563 unsigned int ifindex, bool v6only)
1564 {
1565 char buf[1024];
1566 const char *ap = buf;
1567 const char *ifname = NULL;
1568
1569 if (a->family == AF_INET) {
1570 ap = format_host(AF_INET, 4, a->data);
1571 } else {
1572 if (!v6only &&
1573 !memcmp(a->data, &in6addr_any, sizeof(in6addr_any))) {
1574 buf[0] = '*';
1575 buf[1] = 0;
1576 } else {
1577 ap = format_host(a->family, 16, a->data);
1578
1579 /* Numeric IPv6 addresses should be bracketed */
1580 if (strchr(ap, ':')) {
1581 snprintf(buf, sizeof(buf),
1582 "[%s]", ap);
1583 ap = buf;
1584 }
1585 }
1586 }
1587
1588 if (ifindex)
1589 ifname = ll_index_to_name(ifindex);
1590
1591 sock_addr_print(ap, ":", resolve_service(port), ifname);
1592 }
1593
1594 struct aafilter {
1595 inet_prefix addr;
1596 int port;
1597 unsigned int iface;
1598 __u32 mark;
1599 __u32 mask;
1600 struct aafilter *next;
1601 };
1602
1603 static int inet2_addr_match(const inet_prefix *a, const inet_prefix *p,
1604 int plen)
1605 {
1606 if (!inet_addr_match(a, p, plen))
1607 return 0;
1608
1609 /* Cursed "v4 mapped" addresses: v4 mapped socket matches
1610 * pure IPv4 rule, but v4-mapped rule selects only v4-mapped
1611 * sockets. Fair? */
1612 if (p->family == AF_INET && a->family == AF_INET6) {
1613 if (a->data[0] == 0 && a->data[1] == 0 &&
1614 a->data[2] == htonl(0xffff)) {
1615 inet_prefix tmp = *a;
1616
1617 tmp.data[0] = a->data[3];
1618 return inet_addr_match(&tmp, p, plen);
1619 }
1620 }
1621 return 1;
1622 }
1623
1624 static int unix_match(const inet_prefix *a, const inet_prefix *p)
1625 {
1626 char *addr, *pattern;
1627
1628 memcpy(&addr, a->data, sizeof(addr));
1629 memcpy(&pattern, p->data, sizeof(pattern));
1630 if (pattern == NULL)
1631 return 1;
1632 if (addr == NULL)
1633 addr = "";
1634 return !fnmatch(pattern, addr, 0);
1635 }
1636
1637 static int run_ssfilter(struct ssfilter *f, struct sockstat *s)
1638 {
1639 switch (f->type) {
1640 case SSF_S_AUTO:
1641 {
1642 if (s->local.family == AF_UNIX) {
1643 char *p;
1644
1645 memcpy(&p, s->local.data, sizeof(p));
1646 return p == NULL || (p[0] == '@' && strlen(p) == 6 &&
1647 strspn(p+1, "0123456789abcdef") == 5);
1648 }
1649 if (s->local.family == AF_PACKET)
1650 return s->lport == 0 && s->local.data[0] == 0;
1651 if (s->local.family == AF_NETLINK)
1652 return s->lport < 0;
1653 if (s->local.family == AF_VSOCK)
1654 return s->lport > 1023;
1655
1656 return is_ephemeral(s->lport);
1657 }
1658 case SSF_DCOND:
1659 {
1660 struct aafilter *a = (void *)f->pred;
1661
1662 if (a->addr.family == AF_UNIX)
1663 return unix_match(&s->remote, &a->addr);
1664 if (a->port != -1 && a->port != s->rport)
1665 return 0;
1666 if (a->addr.bitlen) {
1667 do {
1668 if (!inet2_addr_match(&s->remote, &a->addr, a->addr.bitlen))
1669 return 1;
1670 } while ((a = a->next) != NULL);
1671 return 0;
1672 }
1673 return 1;
1674 }
1675 case SSF_SCOND:
1676 {
1677 struct aafilter *a = (void *)f->pred;
1678
1679 if (a->addr.family == AF_UNIX)
1680 return unix_match(&s->local, &a->addr);
1681 if (a->port != -1 && a->port != s->lport)
1682 return 0;
1683 if (a->addr.bitlen) {
1684 do {
1685 if (!inet2_addr_match(&s->local, &a->addr, a->addr.bitlen))
1686 return 1;
1687 } while ((a = a->next) != NULL);
1688 return 0;
1689 }
1690 return 1;
1691 }
1692 case SSF_D_GE:
1693 {
1694 struct aafilter *a = (void *)f->pred;
1695
1696 return s->rport >= a->port;
1697 }
1698 case SSF_D_LE:
1699 {
1700 struct aafilter *a = (void *)f->pred;
1701
1702 return s->rport <= a->port;
1703 }
1704 case SSF_S_GE:
1705 {
1706 struct aafilter *a = (void *)f->pred;
1707
1708 return s->lport >= a->port;
1709 }
1710 case SSF_S_LE:
1711 {
1712 struct aafilter *a = (void *)f->pred;
1713
1714 return s->lport <= a->port;
1715 }
1716 case SSF_DEVCOND:
1717 {
1718 struct aafilter *a = (void *)f->pred;
1719
1720 return s->iface == a->iface;
1721 }
1722 case SSF_MARKMASK:
1723 {
1724 struct aafilter *a = (void *)f->pred;
1725
1726 return (s->mark & a->mask) == a->mark;
1727 }
1728 /* Yup. It is recursion. Sorry. */
1729 case SSF_AND:
1730 return run_ssfilter(f->pred, s) && run_ssfilter(f->post, s);
1731 case SSF_OR:
1732 return run_ssfilter(f->pred, s) || run_ssfilter(f->post, s);
1733 case SSF_NOT:
1734 return !run_ssfilter(f->pred, s);
1735 default:
1736 abort();
1737 }
1738 }
1739
1740 /* Relocate external jumps by reloc. */
1741 static void ssfilter_patch(char *a, int len, int reloc)
1742 {
1743 while (len > 0) {
1744 struct inet_diag_bc_op *op = (struct inet_diag_bc_op *)a;
1745
1746 if (op->no == len+4)
1747 op->no += reloc;
1748 len -= op->yes;
1749 a += op->yes;
1750 }
1751 if (len < 0)
1752 abort();
1753 }
1754
1755 static int ssfilter_bytecompile(struct ssfilter *f, char **bytecode)
1756 {
1757 switch (f->type) {
1758 case SSF_S_AUTO:
1759 {
1760 if (!(*bytecode = malloc(4))) abort();
1761 ((struct inet_diag_bc_op *)*bytecode)[0] = (struct inet_diag_bc_op){ INET_DIAG_BC_AUTO, 4, 8 };
1762 return 4;
1763 }
1764 case SSF_DCOND:
1765 case SSF_SCOND:
1766 {
1767 struct aafilter *a = (void *)f->pred;
1768 struct aafilter *b;
1769 char *ptr;
1770 int code = (f->type == SSF_DCOND ? INET_DIAG_BC_D_COND : INET_DIAG_BC_S_COND);
1771 int len = 0;
1772
1773 for (b = a; b; b = b->next) {
1774 len += 4 + sizeof(struct inet_diag_hostcond);
1775 if (a->addr.family == AF_INET6)
1776 len += 16;
1777 else
1778 len += 4;
1779 if (b->next)
1780 len += 4;
1781 }
1782 if (!(ptr = malloc(len))) abort();
1783 *bytecode = ptr;
1784 for (b = a; b; b = b->next) {
1785 struct inet_diag_bc_op *op = (struct inet_diag_bc_op *)ptr;
1786 int alen = (a->addr.family == AF_INET6 ? 16 : 4);
1787 int oplen = alen + 4 + sizeof(struct inet_diag_hostcond);
1788 struct inet_diag_hostcond *cond = (struct inet_diag_hostcond *)(ptr+4);
1789
1790 *op = (struct inet_diag_bc_op){ code, oplen, oplen+4 };
1791 cond->family = a->addr.family;
1792 cond->port = a->port;
1793 cond->prefix_len = a->addr.bitlen;
1794 memcpy(cond->addr, a->addr.data, alen);
1795 ptr += oplen;
1796 if (b->next) {
1797 op = (struct inet_diag_bc_op *)ptr;
1798 *op = (struct inet_diag_bc_op){ INET_DIAG_BC_JMP, 4, len - (ptr-*bytecode)};
1799 ptr += 4;
1800 }
1801 }
1802 return ptr - *bytecode;
1803 }
1804 case SSF_D_GE:
1805 {
1806 struct aafilter *x = (void *)f->pred;
1807
1808 if (!(*bytecode = malloc(8))) abort();
1809 ((struct inet_diag_bc_op *)*bytecode)[0] = (struct inet_diag_bc_op){ INET_DIAG_BC_D_GE, 8, 12 };
1810 ((struct inet_diag_bc_op *)*bytecode)[1] = (struct inet_diag_bc_op){ 0, 0, x->port };
1811 return 8;
1812 }
1813 case SSF_D_LE:
1814 {
1815 struct aafilter *x = (void *)f->pred;
1816
1817 if (!(*bytecode = malloc(8))) abort();
1818 ((struct inet_diag_bc_op *)*bytecode)[0] = (struct inet_diag_bc_op){ INET_DIAG_BC_D_LE, 8, 12 };
1819 ((struct inet_diag_bc_op *)*bytecode)[1] = (struct inet_diag_bc_op){ 0, 0, x->port };
1820 return 8;
1821 }
1822 case SSF_S_GE:
1823 {
1824 struct aafilter *x = (void *)f->pred;
1825
1826 if (!(*bytecode = malloc(8))) abort();
1827 ((struct inet_diag_bc_op *)*bytecode)[0] = (struct inet_diag_bc_op){ INET_DIAG_BC_S_GE, 8, 12 };
1828 ((struct inet_diag_bc_op *)*bytecode)[1] = (struct inet_diag_bc_op){ 0, 0, x->port };
1829 return 8;
1830 }
1831 case SSF_S_LE:
1832 {
1833 struct aafilter *x = (void *)f->pred;
1834
1835 if (!(*bytecode = malloc(8))) abort();
1836 ((struct inet_diag_bc_op *)*bytecode)[0] = (struct inet_diag_bc_op){ INET_DIAG_BC_S_LE, 8, 12 };
1837 ((struct inet_diag_bc_op *)*bytecode)[1] = (struct inet_diag_bc_op){ 0, 0, x->port };
1838 return 8;
1839 }
1840
1841 case SSF_AND:
1842 {
1843 char *a1 = NULL, *a2 = NULL, *a;
1844 int l1, l2;
1845
1846 l1 = ssfilter_bytecompile(f->pred, &a1);
1847 l2 = ssfilter_bytecompile(f->post, &a2);
1848 if (!l1 || !l2) {
1849 free(a1);
1850 free(a2);
1851 return 0;
1852 }
1853 if (!(a = malloc(l1+l2))) abort();
1854 memcpy(a, a1, l1);
1855 memcpy(a+l1, a2, l2);
1856 free(a1); free(a2);
1857 ssfilter_patch(a, l1, l2);
1858 *bytecode = a;
1859 return l1+l2;
1860 }
1861 case SSF_OR:
1862 {
1863 char *a1 = NULL, *a2 = NULL, *a;
1864 int l1, l2;
1865
1866 l1 = ssfilter_bytecompile(f->pred, &a1);
1867 l2 = ssfilter_bytecompile(f->post, &a2);
1868 if (!l1 || !l2) {
1869 free(a1);
1870 free(a2);
1871 return 0;
1872 }
1873 if (!(a = malloc(l1+l2+4))) abort();
1874 memcpy(a, a1, l1);
1875 memcpy(a+l1+4, a2, l2);
1876 free(a1); free(a2);
1877 *(struct inet_diag_bc_op *)(a+l1) = (struct inet_diag_bc_op){ INET_DIAG_BC_JMP, 4, l2+4 };
1878 *bytecode = a;
1879 return l1+l2+4;
1880 }
1881 case SSF_NOT:
1882 {
1883 char *a1 = NULL, *a;
1884 int l1;
1885
1886 l1 = ssfilter_bytecompile(f->pred, &a1);
1887 if (!l1) {
1888 free(a1);
1889 return 0;
1890 }
1891 if (!(a = malloc(l1+4))) abort();
1892 memcpy(a, a1, l1);
1893 free(a1);
1894 *(struct inet_diag_bc_op *)(a+l1) = (struct inet_diag_bc_op){ INET_DIAG_BC_JMP, 4, 8 };
1895 *bytecode = a;
1896 return l1+4;
1897 }
1898 case SSF_DEVCOND:
1899 {
1900 /* bytecompile for SSF_DEVCOND not supported yet */
1901 return 0;
1902 }
1903 case SSF_MARKMASK:
1904 {
1905 struct aafilter *a = (void *)f->pred;
1906 struct instr {
1907 struct inet_diag_bc_op op;
1908 struct inet_diag_markcond cond;
1909 };
1910 int inslen = sizeof(struct instr);
1911
1912 if (!(*bytecode = malloc(inslen))) abort();
1913 ((struct instr *)*bytecode)[0] = (struct instr) {
1914 { INET_DIAG_BC_MARK_COND, inslen, inslen + 4 },
1915 { a->mark, a->mask},
1916 };
1917
1918 return inslen;
1919 }
1920 default:
1921 abort();
1922 }
1923 }
1924
1925 static int remember_he(struct aafilter *a, struct hostent *he)
1926 {
1927 char **ptr = he->h_addr_list;
1928 int cnt = 0;
1929 int len;
1930
1931 if (he->h_addrtype == AF_INET)
1932 len = 4;
1933 else if (he->h_addrtype == AF_INET6)
1934 len = 16;
1935 else
1936 return 0;
1937
1938 while (*ptr) {
1939 struct aafilter *b = a;
1940
1941 if (a->addr.bitlen) {
1942 if ((b = malloc(sizeof(*b))) == NULL)
1943 return cnt;
1944 *b = *a;
1945 a->next = b;
1946 }
1947 memcpy(b->addr.data, *ptr, len);
1948 b->addr.bytelen = len;
1949 b->addr.bitlen = len*8;
1950 b->addr.family = he->h_addrtype;
1951 ptr++;
1952 cnt++;
1953 }
1954 return cnt;
1955 }
1956
1957 static int get_dns_host(struct aafilter *a, const char *addr, int fam)
1958 {
1959 static int notfirst;
1960 int cnt = 0;
1961 struct hostent *he;
1962
1963 a->addr.bitlen = 0;
1964 if (!notfirst) {
1965 sethostent(1);
1966 notfirst = 1;
1967 }
1968 he = gethostbyname2(addr, fam == AF_UNSPEC ? AF_INET : fam);
1969 if (he)
1970 cnt = remember_he(a, he);
1971 if (fam == AF_UNSPEC) {
1972 he = gethostbyname2(addr, AF_INET6);
1973 if (he)
1974 cnt += remember_he(a, he);
1975 }
1976 return !cnt;
1977 }
1978
1979 static int xll_initted;
1980
1981 static void xll_init(void)
1982 {
1983 struct rtnl_handle rth;
1984
1985 if (rtnl_open(&rth, 0) < 0)
1986 exit(1);
1987
1988 ll_init_map(&rth);
1989 rtnl_close(&rth);
1990 xll_initted = 1;
1991 }
1992
1993 static const char *xll_index_to_name(int index)
1994 {
1995 if (!xll_initted)
1996 xll_init();
1997 return ll_index_to_name(index);
1998 }
1999
2000 static int xll_name_to_index(const char *dev)
2001 {
2002 if (!xll_initted)
2003 xll_init();
2004 return ll_name_to_index(dev);
2005 }
2006
2007 void *parse_devcond(char *name)
2008 {
2009 struct aafilter a = { .iface = 0 };
2010 struct aafilter *res;
2011
2012 a.iface = xll_name_to_index(name);
2013 if (a.iface == 0) {
2014 char *end;
2015 unsigned long n;
2016
2017 n = strtoul(name, &end, 0);
2018 if (!end || end == name || *end || n > UINT_MAX)
2019 return NULL;
2020
2021 a.iface = n;
2022 }
2023
2024 res = malloc(sizeof(*res));
2025 *res = a;
2026
2027 return res;
2028 }
2029
2030 static void vsock_set_inet_prefix(inet_prefix *a, __u32 cid)
2031 {
2032 *a = (inet_prefix){
2033 .bytelen = sizeof(cid),
2034 .family = AF_VSOCK,
2035 };
2036 memcpy(a->data, &cid, sizeof(cid));
2037 }
2038
2039 void *parse_hostcond(char *addr, bool is_port)
2040 {
2041 char *port = NULL;
2042 struct aafilter a = { .port = -1 };
2043 struct aafilter *res;
2044 int fam = preferred_family;
2045 struct filter *f = &current_filter;
2046
2047 if (fam == AF_UNIX || strncmp(addr, "unix:", 5) == 0) {
2048 char *p;
2049
2050 a.addr.family = AF_UNIX;
2051 if (strncmp(addr, "unix:", 5) == 0)
2052 addr += 5;
2053 p = strdup(addr);
2054 a.addr.bitlen = 8*strlen(p);
2055 memcpy(a.addr.data, &p, sizeof(p));
2056 fam = AF_UNIX;
2057 goto out;
2058 }
2059
2060 if (fam == AF_PACKET || strncmp(addr, "link:", 5) == 0) {
2061 a.addr.family = AF_PACKET;
2062 a.addr.bitlen = 0;
2063 if (strncmp(addr, "link:", 5) == 0)
2064 addr += 5;
2065 port = strchr(addr, ':');
2066 if (port) {
2067 *port = 0;
2068 if (port[1] && strcmp(port+1, "*")) {
2069 if (get_integer(&a.port, port+1, 0)) {
2070 if ((a.port = xll_name_to_index(port+1)) <= 0)
2071 return NULL;
2072 }
2073 }
2074 }
2075 if (addr[0] && strcmp(addr, "*")) {
2076 unsigned short tmp;
2077
2078 a.addr.bitlen = 32;
2079 if (ll_proto_a2n(&tmp, addr))
2080 return NULL;
2081 a.addr.data[0] = ntohs(tmp);
2082 }
2083 fam = AF_PACKET;
2084 goto out;
2085 }
2086
2087 if (fam == AF_NETLINK || strncmp(addr, "netlink:", 8) == 0) {
2088 a.addr.family = AF_NETLINK;
2089 a.addr.bitlen = 0;
2090 if (strncmp(addr, "netlink:", 8) == 0)
2091 addr += 8;
2092 port = strchr(addr, ':');
2093 if (port) {
2094 *port = 0;
2095 if (port[1] && strcmp(port+1, "*")) {
2096 if (get_integer(&a.port, port+1, 0)) {
2097 if (strcmp(port+1, "kernel") == 0)
2098 a.port = 0;
2099 else
2100 return NULL;
2101 }
2102 }
2103 }
2104 if (addr[0] && strcmp(addr, "*")) {
2105 a.addr.bitlen = 32;
2106 if (nl_proto_a2n(&a.addr.data[0], addr) == -1)
2107 return NULL;
2108 }
2109 fam = AF_NETLINK;
2110 goto out;
2111 }
2112
2113 if (fam == AF_VSOCK || strncmp(addr, "vsock:", 6) == 0) {
2114 __u32 cid = ~(__u32)0;
2115
2116 a.addr.family = AF_VSOCK;
2117 if (strncmp(addr, "vsock:", 6) == 0)
2118 addr += 6;
2119
2120 if (is_port)
2121 port = addr;
2122 else {
2123 port = strchr(addr, ':');
2124 if (port) {
2125 *port = '\0';
2126 port++;
2127 }
2128 }
2129
2130 if (port && strcmp(port, "*") &&
2131 get_u32((__u32 *)&a.port, port, 0))
2132 return NULL;
2133
2134 if (addr[0] && strcmp(addr, "*")) {
2135 a.addr.bitlen = 32;
2136 if (get_u32(&cid, addr, 0))
2137 return NULL;
2138 }
2139 vsock_set_inet_prefix(&a.addr, cid);
2140 fam = AF_VSOCK;
2141 goto out;
2142 }
2143
2144 if (fam == AF_INET || !strncmp(addr, "inet:", 5)) {
2145 fam = AF_INET;
2146 if (!strncmp(addr, "inet:", 5))
2147 addr += 5;
2148 } else if (fam == AF_INET6 || !strncmp(addr, "inet6:", 6)) {
2149 fam = AF_INET6;
2150 if (!strncmp(addr, "inet6:", 6))
2151 addr += 6;
2152 }
2153
2154 /* URL-like literal [] */
2155 if (addr[0] == '[') {
2156 addr++;
2157 if ((port = strchr(addr, ']')) == NULL)
2158 return NULL;
2159 *port++ = 0;
2160 } else if (addr[0] == '*') {
2161 port = addr+1;
2162 } else {
2163 port = strrchr(strchr(addr, '/') ? : addr, ':');
2164 }
2165
2166 if (is_port)
2167 port = addr;
2168
2169 if (port && *port) {
2170 if (*port == ':')
2171 *port++ = 0;
2172
2173 if (*port && *port != '*') {
2174 if (get_integer(&a.port, port, 0)) {
2175 struct servent *se1 = NULL;
2176 struct servent *se2 = NULL;
2177
2178 if (current_filter.dbs&(1<<UDP_DB))
2179 se1 = getservbyname(port, UDP_PROTO);
2180 if (current_filter.dbs&(1<<TCP_DB))
2181 se2 = getservbyname(port, TCP_PROTO);
2182 if (se1 && se2 && se1->s_port != se2->s_port) {
2183 fprintf(stderr, "Error: ambiguous port \"%s\".\n", port);
2184 return NULL;
2185 }
2186 if (!se1)
2187 se1 = se2;
2188 if (se1) {
2189 a.port = ntohs(se1->s_port);
2190 } else {
2191 struct scache *s;
2192
2193 for (s = rlist; s; s = s->next) {
2194 if ((s->proto == UDP_PROTO &&
2195 (current_filter.dbs&(1<<UDP_DB))) ||
2196 (s->proto == TCP_PROTO &&
2197 (current_filter.dbs&(1<<TCP_DB)))) {
2198 if (s->name && strcmp(s->name, port) == 0) {
2199 if (a.port > 0 && a.port != s->port) {
2200 fprintf(stderr, "Error: ambiguous port \"%s\".\n", port);
2201 return NULL;
2202 }
2203 a.port = s->port;
2204 }
2205 }
2206 }
2207 if (a.port <= 0) {
2208 fprintf(stderr, "Error: \"%s\" does not look like a port.\n", port);
2209 return NULL;
2210 }
2211 }
2212 }
2213 }
2214 }
2215 if (!is_port && *addr && *addr != '*') {
2216 if (get_prefix_1(&a.addr, addr, fam)) {
2217 if (get_dns_host(&a, addr, fam)) {
2218 fprintf(stderr, "Error: an inet prefix is expected rather than \"%s\".\n", addr);
2219 return NULL;
2220 }
2221 }
2222 }
2223
2224 out:
2225 if (fam != AF_UNSPEC) {
2226 int states = f->states;
2227 f->families = 0;
2228 filter_af_set(f, fam);
2229 filter_states_set(f, states);
2230 }
2231
2232 res = malloc(sizeof(*res));
2233 if (res)
2234 memcpy(res, &a, sizeof(a));
2235 return res;
2236 }
2237
2238 void *parse_markmask(const char *markmask)
2239 {
2240 struct aafilter a, *res;
2241
2242 if (strchr(markmask, '/')) {
2243 if (sscanf(markmask, "%i/%i", &a.mark, &a.mask) != 2)
2244 return NULL;
2245 } else {
2246 a.mask = 0xffffffff;
2247 if (sscanf(markmask, "%i", &a.mark) != 1)
2248 return NULL;
2249 }
2250
2251 res = malloc(sizeof(*res));
2252 if (res)
2253 memcpy(res, &a, sizeof(a));
2254 return res;
2255 }
2256
2257 static void proc_ctx_print(struct sockstat *s)
2258 {
2259 char *buf;
2260
2261 if (show_proc_ctx || show_sock_ctx) {
2262 if (find_entry(s->ino, &buf,
2263 (show_proc_ctx & show_sock_ctx) ?
2264 PROC_SOCK_CTX : PROC_CTX) > 0) {
2265 out(" users:(%s)", buf);
2266 free(buf);
2267 }
2268 } else if (show_users) {
2269 if (find_entry(s->ino, &buf, USERS) > 0) {
2270 out(" users:(%s)", buf);
2271 free(buf);
2272 }
2273 }
2274 }
2275
2276 static void inet_stats_print(struct sockstat *s, bool v6only)
2277 {
2278 sock_state_print(s);
2279
2280 inet_addr_print(&s->local, s->lport, s->iface, v6only);
2281 inet_addr_print(&s->remote, s->rport, 0, v6only);
2282
2283 proc_ctx_print(s);
2284 }
2285
2286 static int proc_parse_inet_addr(char *loc, char *rem, int family, struct
2287 sockstat * s)
2288 {
2289 s->local.family = s->remote.family = family;
2290 if (family == AF_INET) {
2291 sscanf(loc, "%x:%x", s->local.data, (unsigned *)&s->lport);
2292 sscanf(rem, "%x:%x", s->remote.data, (unsigned *)&s->rport);
2293 s->local.bytelen = s->remote.bytelen = 4;
2294 return 0;
2295 } else {
2296 sscanf(loc, "%08x%08x%08x%08x:%x",
2297 s->local.data,
2298 s->local.data + 1,
2299 s->local.data + 2,
2300 s->local.data + 3,
2301 &s->lport);
2302 sscanf(rem, "%08x%08x%08x%08x:%x",
2303 s->remote.data,
2304 s->remote.data + 1,
2305 s->remote.data + 2,
2306 s->remote.data + 3,
2307 &s->rport);
2308 s->local.bytelen = s->remote.bytelen = 16;
2309 return 0;
2310 }
2311 return -1;
2312 }
2313
2314 static int proc_inet_split_line(char *line, char **loc, char **rem, char **data)
2315 {
2316 char *p;
2317
2318 if ((p = strchr(line, ':')) == NULL)
2319 return -1;
2320
2321 *loc = p+2;
2322 if ((p = strchr(*loc, ':')) == NULL)
2323 return -1;
2324
2325 p[5] = 0;
2326 *rem = p+6;
2327 if ((p = strchr(*rem, ':')) == NULL)
2328 return -1;
2329
2330 p[5] = 0;
2331 *data = p+6;
2332 return 0;
2333 }
2334
2335 static char *sprint_bw(char *buf, double bw)
2336 {
2337 if (bw > 1000000.)
2338 sprintf(buf, "%.1fM", bw / 1000000.);
2339 else if (bw > 1000.)
2340 sprintf(buf, "%.1fK", bw / 1000.);
2341 else
2342 sprintf(buf, "%g", bw);
2343
2344 return buf;
2345 }
2346
2347 static void sctp_stats_print(struct sctp_info *s)
2348 {
2349 if (s->sctpi_tag)
2350 out(" tag:%x", s->sctpi_tag);
2351 if (s->sctpi_state)
2352 out(" state:%s", sctp_sstate_name[s->sctpi_state]);
2353 if (s->sctpi_rwnd)
2354 out(" rwnd:%d", s->sctpi_rwnd);
2355 if (s->sctpi_unackdata)
2356 out(" unackdata:%d", s->sctpi_unackdata);
2357 if (s->sctpi_penddata)
2358 out(" penddata:%d", s->sctpi_penddata);
2359 if (s->sctpi_instrms)
2360 out(" instrms:%d", s->sctpi_instrms);
2361 if (s->sctpi_outstrms)
2362 out(" outstrms:%d", s->sctpi_outstrms);
2363 if (s->sctpi_inqueue)
2364 out(" inqueue:%d", s->sctpi_inqueue);
2365 if (s->sctpi_outqueue)
2366 out(" outqueue:%d", s->sctpi_outqueue);
2367 if (s->sctpi_overall_error)
2368 out(" overerr:%d", s->sctpi_overall_error);
2369 if (s->sctpi_max_burst)
2370 out(" maxburst:%d", s->sctpi_max_burst);
2371 if (s->sctpi_maxseg)
2372 out(" maxseg:%d", s->sctpi_maxseg);
2373 if (s->sctpi_peer_rwnd)
2374 out(" prwnd:%d", s->sctpi_peer_rwnd);
2375 if (s->sctpi_peer_tag)
2376 out(" ptag:%x", s->sctpi_peer_tag);
2377 if (s->sctpi_peer_capable)
2378 out(" pcapable:%d", s->sctpi_peer_capable);
2379 if (s->sctpi_peer_sack)
2380 out(" psack:%d", s->sctpi_peer_sack);
2381 if (s->sctpi_s_autoclose)
2382 out(" autoclose:%d", s->sctpi_s_autoclose);
2383 if (s->sctpi_s_adaptation_ind)
2384 out(" adapind:%d", s->sctpi_s_adaptation_ind);
2385 if (s->sctpi_s_pd_point)
2386 out(" pdpoint:%d", s->sctpi_s_pd_point);
2387 if (s->sctpi_s_nodelay)
2388 out(" nodealy:%d", s->sctpi_s_nodelay);
2389 if (s->sctpi_s_disable_fragments)
2390 out(" nofrag:%d", s->sctpi_s_disable_fragments);
2391 if (s->sctpi_s_v4mapped)
2392 out(" v4mapped:%d", s->sctpi_s_v4mapped);
2393 if (s->sctpi_s_frag_interleave)
2394 out(" fraginl:%d", s->sctpi_s_frag_interleave);
2395 }
2396
2397 static void tcp_stats_print(struct tcpstat *s)
2398 {
2399 char b1[64];
2400
2401 if (s->has_ts_opt)
2402 out(" ts");
2403 if (s->has_sack_opt)
2404 out(" sack");
2405 if (s->has_ecn_opt)
2406 out(" ecn");
2407 if (s->has_ecnseen_opt)
2408 out(" ecnseen");
2409 if (s->has_fastopen_opt)
2410 out(" fastopen");
2411 if (s->cong_alg[0])
2412 out(" %s", s->cong_alg);
2413 if (s->has_wscale_opt)
2414 out(" wscale:%d,%d", s->snd_wscale, s->rcv_wscale);
2415 if (s->rto)
2416 out(" rto:%g", s->rto);
2417 if (s->backoff)
2418 out(" backoff:%u", s->backoff);
2419 if (s->rtt)
2420 out(" rtt:%g/%g", s->rtt, s->rttvar);
2421 if (s->ato)
2422 out(" ato:%g", s->ato);
2423
2424 if (s->qack)
2425 out(" qack:%d", s->qack);
2426 if (s->qack & 1)
2427 out(" bidir");
2428
2429 if (s->mss)
2430 out(" mss:%d", s->mss);
2431 if (s->pmtu)
2432 out(" pmtu:%u", s->pmtu);
2433 if (s->rcv_mss)
2434 out(" rcvmss:%d", s->rcv_mss);
2435 if (s->advmss)
2436 out(" advmss:%d", s->advmss);
2437 if (s->cwnd)
2438 out(" cwnd:%u", s->cwnd);
2439 if (s->ssthresh)
2440 out(" ssthresh:%d", s->ssthresh);
2441
2442 if (s->bytes_sent)
2443 out(" bytes_sent:%llu", s->bytes_sent);
2444 if (s->bytes_retrans)
2445 out(" bytes_retrans:%llu", s->bytes_retrans);
2446 if (s->bytes_acked)
2447 out(" bytes_acked:%llu", s->bytes_acked);
2448 if (s->bytes_received)
2449 out(" bytes_received:%llu", s->bytes_received);
2450 if (s->segs_out)
2451 out(" segs_out:%u", s->segs_out);
2452 if (s->segs_in)
2453 out(" segs_in:%u", s->segs_in);
2454 if (s->data_segs_out)
2455 out(" data_segs_out:%u", s->data_segs_out);
2456 if (s->data_segs_in)
2457 out(" data_segs_in:%u", s->data_segs_in);
2458
2459 if (s->dctcp && s->dctcp->enabled) {
2460 struct dctcpstat *dctcp = s->dctcp;
2461
2462 out(" dctcp:(ce_state:%u,alpha:%u,ab_ecn:%u,ab_tot:%u)",
2463 dctcp->ce_state, dctcp->alpha, dctcp->ab_ecn,
2464 dctcp->ab_tot);
2465 } else if (s->dctcp) {
2466 out(" dctcp:fallback_mode");
2467 }
2468
2469 if (s->bbr_info) {
2470 __u64 bw;
2471
2472 bw = s->bbr_info->bbr_bw_hi;
2473 bw <<= 32;
2474 bw |= s->bbr_info->bbr_bw_lo;
2475
2476 out(" bbr:(bw:%sbps,mrtt:%g",
2477 sprint_bw(b1, bw * 8.0),
2478 (double)s->bbr_info->bbr_min_rtt / 1000.0);
2479 if (s->bbr_info->bbr_pacing_gain)
2480 out(",pacing_gain:%g",
2481 (double)s->bbr_info->bbr_pacing_gain / 256.0);
2482 if (s->bbr_info->bbr_cwnd_gain)
2483 out(",cwnd_gain:%g",
2484 (double)s->bbr_info->bbr_cwnd_gain / 256.0);
2485 out(")");
2486 }
2487
2488 if (s->send_bps)
2489 out(" send %sbps", sprint_bw(b1, s->send_bps));
2490 if (s->lastsnd)
2491 out(" lastsnd:%u", s->lastsnd);
2492 if (s->lastrcv)
2493 out(" lastrcv:%u", s->lastrcv);
2494 if (s->lastack)
2495 out(" lastack:%u", s->lastack);
2496
2497 if (s->pacing_rate) {
2498 out(" pacing_rate %sbps", sprint_bw(b1, s->pacing_rate));
2499 if (s->pacing_rate_max)
2500 out("/%sbps", sprint_bw(b1, s->pacing_rate_max));
2501 }
2502
2503 if (s->delivery_rate)
2504 out(" delivery_rate %sbps", sprint_bw(b1, s->delivery_rate));
2505 if (s->delivered)
2506 out(" delivered:%u", s->delivered);
2507 if (s->delivered_ce)
2508 out(" delivered_ce:%u", s->delivered_ce);
2509 if (s->app_limited)
2510 out(" app_limited");
2511
2512 if (s->busy_time) {
2513 out(" busy:%llums", s->busy_time / 1000);
2514 if (s->rwnd_limited)
2515 out(" rwnd_limited:%llums(%.1f%%)",
2516 s->rwnd_limited / 1000,
2517 100.0 * s->rwnd_limited / s->busy_time);
2518 if (s->sndbuf_limited)
2519 out(" sndbuf_limited:%llums(%.1f%%)",
2520 s->sndbuf_limited / 1000,
2521 100.0 * s->sndbuf_limited / s->busy_time);
2522 }
2523
2524 if (s->unacked)
2525 out(" unacked:%u", s->unacked);
2526 if (s->retrans || s->retrans_total)
2527 out(" retrans:%u/%u", s->retrans, s->retrans_total);
2528 if (s->lost)
2529 out(" lost:%u", s->lost);
2530 if (s->sacked && s->ss.state != SS_LISTEN)
2531 out(" sacked:%u", s->sacked);
2532 if (s->dsack_dups)
2533 out(" dsack_dups:%u", s->dsack_dups);
2534 if (s->fackets)
2535 out(" fackets:%u", s->fackets);
2536 if (s->reordering != 3)
2537 out(" reordering:%d", s->reordering);
2538 if (s->reord_seen)
2539 out(" reord_seen:%d", s->reord_seen);
2540 if (s->rcv_rtt)
2541 out(" rcv_rtt:%g", s->rcv_rtt);
2542 if (s->rcv_space)
2543 out(" rcv_space:%d", s->rcv_space);
2544 if (s->rcv_ssthresh)
2545 out(" rcv_ssthresh:%u", s->rcv_ssthresh);
2546 if (s->not_sent)
2547 out(" notsent:%u", s->not_sent);
2548 if (s->min_rtt)
2549 out(" minrtt:%g", s->min_rtt);
2550 }
2551
2552 static void tcp_timer_print(struct tcpstat *s)
2553 {
2554 static const char * const tmr_name[] = {
2555 "off",
2556 "on",
2557 "keepalive",
2558 "timewait",
2559 "persist",
2560 "unknown"
2561 };
2562
2563 if (s->timer) {
2564 if (s->timer > 4)
2565 s->timer = 5;
2566 out(" timer:(%s,%s,%d)",
2567 tmr_name[s->timer],
2568 print_ms_timer(s->timeout),
2569 s->retrans);
2570 }
2571 }
2572
2573 static void sctp_timer_print(struct tcpstat *s)
2574 {
2575 if (s->timer)
2576 out(" timer:(T3_RTX,%s,%d)",
2577 print_ms_timer(s->timeout), s->retrans);
2578 }
2579
2580 static int tcp_show_line(char *line, const struct filter *f, int family)
2581 {
2582 int rto = 0, ato = 0;
2583 struct tcpstat s = {};
2584 char *loc, *rem, *data;
2585 char opt[256];
2586 int n;
2587 int hz = get_user_hz();
2588
2589 if (proc_inet_split_line(line, &loc, &rem, &data))
2590 return -1;
2591
2592 int state = (data[1] >= 'A') ? (data[1] - 'A' + 10) : (data[1] - '0');
2593
2594 if (!(f->states & (1 << state)))
2595 return 0;
2596
2597 proc_parse_inet_addr(loc, rem, family, &s.ss);
2598
2599 if (f->f && run_ssfilter(f->f, &s.ss) == 0)
2600 return 0;
2601
2602 opt[0] = 0;
2603 n = sscanf(data, "%x %x:%x %x:%x %x %d %d %u %d %llx %d %d %d %u %d %[^\n]\n",
2604 &s.ss.state, &s.ss.wq, &s.ss.rq,
2605 &s.timer, &s.timeout, &s.retrans, &s.ss.uid, &s.probes,
2606 &s.ss.ino, &s.ss.refcnt, &s.ss.sk, &rto, &ato, &s.qack, &s.cwnd,
2607 &s.ssthresh, opt);
2608
2609 if (n < 17)
2610 opt[0] = 0;
2611
2612 if (n < 12) {
2613 rto = 0;
2614 s.cwnd = 2;
2615 s.ssthresh = -1;
2616 ato = s.qack = 0;
2617 }
2618
2619 s.retrans = s.timer != 1 ? s.probes : s.retrans;
2620 s.timeout = (s.timeout * 1000 + hz - 1) / hz;
2621 s.ato = (double)ato / hz;
2622 s.qack /= 2;
2623 s.rto = (double)rto;
2624 s.ssthresh = s.ssthresh == -1 ? 0 : s.ssthresh;
2625 s.rto = s.rto != 3 * hz ? s.rto / hz : 0;
2626 s.ss.type = IPPROTO_TCP;
2627
2628 inet_stats_print(&s.ss, false);
2629
2630 if (show_options)
2631 tcp_timer_print(&s);
2632
2633 if (show_details) {
2634 sock_details_print(&s.ss);
2635 if (opt[0])
2636 out(" opt:\"%s\"", opt);
2637 }
2638
2639 if (show_tcpinfo)
2640 tcp_stats_print(&s);
2641
2642 return 0;
2643 }
2644
2645 static int generic_record_read(FILE *fp,
2646 int (*worker)(char*, const struct filter *, int),
2647 const struct filter *f, int fam)
2648 {
2649 char line[256];
2650
2651 /* skip header */
2652 if (fgets(line, sizeof(line), fp) == NULL)
2653 goto outerr;
2654
2655 while (fgets(line, sizeof(line), fp) != NULL) {
2656 int n = strlen(line);
2657
2658 if (n == 0 || line[n-1] != '\n') {
2659 errno = -EINVAL;
2660 return -1;
2661 }
2662 line[n-1] = 0;
2663
2664 if (worker(line, f, fam) < 0)
2665 return 0;
2666 }
2667 outerr:
2668
2669 return ferror(fp) ? -1 : 0;
2670 }
2671
2672 static void print_skmeminfo(struct rtattr *tb[], int attrtype)
2673 {
2674 const __u32 *skmeminfo;
2675
2676 if (!tb[attrtype]) {
2677 if (attrtype == INET_DIAG_SKMEMINFO) {
2678 if (!tb[INET_DIAG_MEMINFO])
2679 return;
2680
2681 const struct inet_diag_meminfo *minfo =
2682 RTA_DATA(tb[INET_DIAG_MEMINFO]);
2683
2684 out(" mem:(r%u,w%u,f%u,t%u)",
2685 minfo->idiag_rmem,
2686 minfo->idiag_wmem,
2687 minfo->idiag_fmem,
2688 minfo->idiag_tmem);
2689 }
2690 return;
2691 }
2692
2693 skmeminfo = RTA_DATA(tb[attrtype]);
2694
2695 out(" skmem:(r%u,rb%u,t%u,tb%u,f%u,w%u,o%u",
2696 skmeminfo[SK_MEMINFO_RMEM_ALLOC],
2697 skmeminfo[SK_MEMINFO_RCVBUF],
2698 skmeminfo[SK_MEMINFO_WMEM_ALLOC],
2699 skmeminfo[SK_MEMINFO_SNDBUF],
2700 skmeminfo[SK_MEMINFO_FWD_ALLOC],
2701 skmeminfo[SK_MEMINFO_WMEM_QUEUED],
2702 skmeminfo[SK_MEMINFO_OPTMEM]);
2703
2704 if (RTA_PAYLOAD(tb[attrtype]) >=
2705 (SK_MEMINFO_BACKLOG + 1) * sizeof(__u32))
2706 out(",bl%u", skmeminfo[SK_MEMINFO_BACKLOG]);
2707
2708 if (RTA_PAYLOAD(tb[attrtype]) >=
2709 (SK_MEMINFO_DROPS + 1) * sizeof(__u32))
2710 out(",d%u", skmeminfo[SK_MEMINFO_DROPS]);
2711
2712 out(")");
2713 }
2714
2715 static void print_md5sig(struct tcp_diag_md5sig *sig)
2716 {
2717 out("%s/%d=",
2718 format_host(sig->tcpm_family,
2719 sig->tcpm_family == AF_INET6 ? 16 : 4,
2720 &sig->tcpm_addr),
2721 sig->tcpm_prefixlen);
2722 print_escape_buf(sig->tcpm_key, sig->tcpm_keylen, " ,");
2723 }
2724
2725 #define TCPI_HAS_OPT(info, opt) !!(info->tcpi_options & (opt))
2726
2727 static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r,
2728 struct rtattr *tb[])
2729 {
2730 double rtt = 0;
2731 struct tcpstat s = {};
2732
2733 s.ss.state = r->idiag_state;
2734
2735 print_skmeminfo(tb, INET_DIAG_SKMEMINFO);
2736
2737 if (tb[INET_DIAG_INFO]) {
2738 struct tcp_info *info;
2739 int len = RTA_PAYLOAD(tb[INET_DIAG_INFO]);
2740
2741 /* workaround for older kernels with less fields */
2742 if (len < sizeof(*info)) {
2743 info = alloca(sizeof(*info));
2744 memcpy(info, RTA_DATA(tb[INET_DIAG_INFO]), len);
2745 memset((char *)info + len, 0, sizeof(*info) - len);
2746 } else
2747 info = RTA_DATA(tb[INET_DIAG_INFO]);
2748
2749 if (show_options) {
2750 s.has_ts_opt = TCPI_HAS_OPT(info, TCPI_OPT_TIMESTAMPS);
2751 s.has_sack_opt = TCPI_HAS_OPT(info, TCPI_OPT_SACK);
2752 s.has_ecn_opt = TCPI_HAS_OPT(info, TCPI_OPT_ECN);
2753 s.has_ecnseen_opt = TCPI_HAS_OPT(info, TCPI_OPT_ECN_SEEN);
2754 s.has_fastopen_opt = TCPI_HAS_OPT(info, TCPI_OPT_SYN_DATA);
2755 }
2756
2757 if (tb[INET_DIAG_CONG])
2758 strncpy(s.cong_alg,
2759 rta_getattr_str(tb[INET_DIAG_CONG]),
2760 sizeof(s.cong_alg) - 1);
2761
2762 if (TCPI_HAS_OPT(info, TCPI_OPT_WSCALE)) {
2763 s.has_wscale_opt = true;
2764 s.snd_wscale = info->tcpi_snd_wscale;
2765 s.rcv_wscale = info->tcpi_rcv_wscale;
2766 }
2767
2768 if (info->tcpi_rto && info->tcpi_rto != 3000000)
2769 s.rto = (double)info->tcpi_rto / 1000;
2770
2771 s.backoff = info->tcpi_backoff;
2772 s.rtt = (double)info->tcpi_rtt / 1000;
2773 s.rttvar = (double)info->tcpi_rttvar / 1000;
2774 s.ato = (double)info->tcpi_ato / 1000;
2775 s.mss = info->tcpi_snd_mss;
2776 s.rcv_mss = info->tcpi_rcv_mss;
2777 s.advmss = info->tcpi_advmss;
2778 s.rcv_space = info->tcpi_rcv_space;
2779 s.rcv_rtt = (double)info->tcpi_rcv_rtt / 1000;
2780 s.lastsnd = info->tcpi_last_data_sent;
2781 s.lastrcv = info->tcpi_last_data_recv;
2782 s.lastack = info->tcpi_last_ack_recv;
2783 s.unacked = info->tcpi_unacked;
2784 s.retrans = info->tcpi_retrans;
2785 s.retrans_total = info->tcpi_total_retrans;
2786 s.lost = info->tcpi_lost;
2787 s.sacked = info->tcpi_sacked;
2788 s.fackets = info->tcpi_fackets;
2789 s.reordering = info->tcpi_reordering;
2790 s.rcv_ssthresh = info->tcpi_rcv_ssthresh;
2791 s.cwnd = info->tcpi_snd_cwnd;
2792 s.pmtu = info->tcpi_pmtu;
2793
2794 if (info->tcpi_snd_ssthresh < 0xFFFF)
2795 s.ssthresh = info->tcpi_snd_ssthresh;
2796
2797 rtt = (double) info->tcpi_rtt;
2798 if (tb[INET_DIAG_VEGASINFO]) {
2799 const struct tcpvegas_info *vinfo
2800 = RTA_DATA(tb[INET_DIAG_VEGASINFO]);
2801
2802 if (vinfo->tcpv_enabled &&
2803 vinfo->tcpv_rtt && vinfo->tcpv_rtt != 0x7fffffff)
2804 rtt = vinfo->tcpv_rtt;
2805 }
2806
2807 if (tb[INET_DIAG_DCTCPINFO]) {
2808 struct dctcpstat *dctcp = malloc(sizeof(struct
2809 dctcpstat));
2810
2811 const struct tcp_dctcp_info *dinfo
2812 = RTA_DATA(tb[INET_DIAG_DCTCPINFO]);
2813
2814 dctcp->enabled = !!dinfo->dctcp_enabled;
2815 dctcp->ce_state = dinfo->dctcp_ce_state;
2816 dctcp->alpha = dinfo->dctcp_alpha;
2817 dctcp->ab_ecn = dinfo->dctcp_ab_ecn;
2818 dctcp->ab_tot = dinfo->dctcp_ab_tot;
2819 s.dctcp = dctcp;
2820 }
2821
2822 if (tb[INET_DIAG_BBRINFO]) {
2823 const void *bbr_info = RTA_DATA(tb[INET_DIAG_BBRINFO]);
2824 int len = min(RTA_PAYLOAD(tb[INET_DIAG_BBRINFO]),
2825 sizeof(*s.bbr_info));
2826
2827 s.bbr_info = calloc(1, sizeof(*s.bbr_info));
2828 if (s.bbr_info && bbr_info)
2829 memcpy(s.bbr_info, bbr_info, len);
2830 }
2831
2832 if (rtt > 0 && info->tcpi_snd_mss && info->tcpi_snd_cwnd) {
2833 s.send_bps = (double) info->tcpi_snd_cwnd *
2834 (double)info->tcpi_snd_mss * 8000000. / rtt;
2835 }
2836
2837 if (info->tcpi_pacing_rate &&
2838 info->tcpi_pacing_rate != ~0ULL) {
2839 s.pacing_rate = info->tcpi_pacing_rate * 8.;
2840
2841 if (info->tcpi_max_pacing_rate &&
2842 info->tcpi_max_pacing_rate != ~0ULL)
2843 s.pacing_rate_max = info->tcpi_max_pacing_rate * 8.;
2844 }
2845 s.bytes_acked = info->tcpi_bytes_acked;
2846 s.bytes_received = info->tcpi_bytes_received;
2847 s.segs_out = info->tcpi_segs_out;
2848 s.segs_in = info->tcpi_segs_in;
2849 s.data_segs_out = info->tcpi_data_segs_out;
2850 s.data_segs_in = info->tcpi_data_segs_in;
2851 s.not_sent = info->tcpi_notsent_bytes;
2852 if (info->tcpi_min_rtt && info->tcpi_min_rtt != ~0U)
2853 s.min_rtt = (double) info->tcpi_min_rtt / 1000;
2854 s.delivery_rate = info->tcpi_delivery_rate * 8.;
2855 s.app_limited = info->tcpi_delivery_rate_app_limited;
2856 s.busy_time = info->tcpi_busy_time;
2857 s.rwnd_limited = info->tcpi_rwnd_limited;
2858 s.sndbuf_limited = info->tcpi_sndbuf_limited;
2859 s.delivered = info->tcpi_delivered;
2860 s.delivered_ce = info->tcpi_delivered_ce;
2861 s.dsack_dups = info->tcpi_dsack_dups;
2862 s.reord_seen = info->tcpi_reord_seen;
2863 s.bytes_sent = info->tcpi_bytes_sent;
2864 s.bytes_retrans = info->tcpi_bytes_retrans;
2865 tcp_stats_print(&s);
2866 free(s.dctcp);
2867 free(s.bbr_info);
2868 }
2869 if (tb[INET_DIAG_MD5SIG]) {
2870 struct tcp_diag_md5sig *sig = RTA_DATA(tb[INET_DIAG_MD5SIG]);
2871 int len = RTA_PAYLOAD(tb[INET_DIAG_MD5SIG]);
2872
2873 out(" md5keys:");
2874 print_md5sig(sig++);
2875 for (len -= sizeof(*sig); len > 0; len -= sizeof(*sig)) {
2876 out(",");
2877 print_md5sig(sig++);
2878 }
2879 }
2880 }
2881
2882 static const char *format_host_sa(struct sockaddr_storage *sa)
2883 {
2884 union {
2885 struct sockaddr_in sin;
2886 struct sockaddr_in6 sin6;
2887 } *saddr = (void *)sa;
2888
2889 switch (sa->ss_family) {
2890 case AF_INET:
2891 return format_host(AF_INET, 4, &saddr->sin.sin_addr);
2892 case AF_INET6:
2893 return format_host(AF_INET6, 16, &saddr->sin6.sin6_addr);
2894 default:
2895 return "";
2896 }
2897 }
2898
2899 static void sctp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r,
2900 struct rtattr *tb[])
2901 {
2902 struct sockaddr_storage *sa;
2903 int len;
2904
2905 print_skmeminfo(tb, INET_DIAG_SKMEMINFO);
2906
2907 if (tb[INET_DIAG_LOCALS]) {
2908 len = RTA_PAYLOAD(tb[INET_DIAG_LOCALS]);
2909 sa = RTA_DATA(tb[INET_DIAG_LOCALS]);
2910
2911 out("locals:%s", format_host_sa(sa));
2912 for (sa++, len -= sizeof(*sa); len > 0; sa++, len -= sizeof(*sa))
2913 out(",%s", format_host_sa(sa));
2914
2915 }
2916 if (tb[INET_DIAG_PEERS]) {
2917 len = RTA_PAYLOAD(tb[INET_DIAG_PEERS]);
2918 sa = RTA_DATA(tb[INET_DIAG_PEERS]);
2919
2920 out(" peers:%s", format_host_sa(sa));
2921 for (sa++, len -= sizeof(*sa); len > 0; sa++, len -= sizeof(*sa))
2922 out(",%s", format_host_sa(sa));
2923 }
2924 if (tb[INET_DIAG_INFO]) {
2925 struct sctp_info *info;
2926 len = RTA_PAYLOAD(tb[INET_DIAG_INFO]);
2927
2928 /* workaround for older kernels with less fields */
2929 if (len < sizeof(*info)) {
2930 info = alloca(sizeof(*info));
2931 memcpy(info, RTA_DATA(tb[INET_DIAG_INFO]), len);
2932 memset((char *)info + len, 0, sizeof(*info) - len);
2933 } else
2934 info = RTA_DATA(tb[INET_DIAG_INFO]);
2935
2936 sctp_stats_print(info);
2937 }
2938 }
2939
2940 static void parse_diag_msg(struct nlmsghdr *nlh, struct sockstat *s)
2941 {
2942 struct rtattr *tb[INET_DIAG_MAX+1];
2943 struct inet_diag_msg *r = NLMSG_DATA(nlh);
2944
2945 parse_rtattr(tb, INET_DIAG_MAX, (struct rtattr *)(r+1),
2946 nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
2947
2948 s->state = r->idiag_state;
2949 s->local.family = s->remote.family = r->idiag_family;
2950 s->lport = ntohs(r->id.idiag_sport);
2951 s->rport = ntohs(r->id.idiag_dport);
2952 s->wq = r->idiag_wqueue;
2953 s->rq = r->idiag_rqueue;
2954 s->ino = r->idiag_inode;
2955 s->uid = r->idiag_uid;
2956 s->iface = r->id.idiag_if;
2957 s->sk = cookie_sk_get(&r->id.idiag_cookie[0]);
2958
2959 s->mark = 0;
2960 if (tb[INET_DIAG_MARK])
2961 s->mark = rta_getattr_u32(tb[INET_DIAG_MARK]);
2962 if (tb[INET_DIAG_PROTOCOL])
2963 s->raw_prot = rta_getattr_u8(tb[INET_DIAG_PROTOCOL]);
2964 else
2965 s->raw_prot = 0;
2966
2967 if (s->local.family == AF_INET)
2968 s->local.bytelen = s->remote.bytelen = 4;
2969 else
2970 s->local.bytelen = s->remote.bytelen = 16;
2971
2972 memcpy(s->local.data, r->id.idiag_src, s->local.bytelen);
2973 memcpy(s->remote.data, r->id.idiag_dst, s->local.bytelen);
2974 }
2975
2976 static int inet_show_sock(struct nlmsghdr *nlh,
2977 struct sockstat *s)
2978 {
2979 struct rtattr *tb[INET_DIAG_MAX+1];
2980 struct inet_diag_msg *r = NLMSG_DATA(nlh);
2981 unsigned char v6only = 0;
2982
2983 parse_rtattr(tb, INET_DIAG_MAX, (struct rtattr *)(r+1),
2984 nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
2985
2986 if (tb[INET_DIAG_PROTOCOL])
2987 s->type = rta_getattr_u8(tb[INET_DIAG_PROTOCOL]);
2988
2989 if (s->local.family == AF_INET6 && tb[INET_DIAG_SKV6ONLY])
2990 v6only = rta_getattr_u8(tb[INET_DIAG_SKV6ONLY]);
2991
2992 inet_stats_print(s, v6only);
2993
2994 if (show_options) {
2995 struct tcpstat t = {};
2996
2997 t.timer = r->idiag_timer;
2998 t.timeout = r->idiag_expires;
2999 t.retrans = r->idiag_retrans;
3000 if (s->type == IPPROTO_SCTP)
3001 sctp_timer_print(&t);
3002 else
3003 tcp_timer_print(&t);
3004 }
3005
3006 if (show_details) {
3007 sock_details_print(s);
3008 if (s->local.family == AF_INET6 && tb[INET_DIAG_SKV6ONLY])
3009 out(" v6only:%u", v6only);
3010
3011 if (tb[INET_DIAG_SHUTDOWN]) {
3012 unsigned char mask;
3013
3014 mask = rta_getattr_u8(tb[INET_DIAG_SHUTDOWN]);
3015 out(" %c-%c",
3016 mask & 1 ? '-' : '<', mask & 2 ? '-' : '>');
3017 }
3018 }
3019
3020 if (show_tos) {
3021 if (tb[INET_DIAG_TOS])
3022 out(" tos:%#x", rta_getattr_u8(tb[INET_DIAG_TOS]));
3023 if (tb[INET_DIAG_TCLASS])
3024 out(" tclass:%#x", rta_getattr_u8(tb[INET_DIAG_TCLASS]));
3025 if (tb[INET_DIAG_CLASS_ID])
3026 out(" class_id:%#x", rta_getattr_u32(tb[INET_DIAG_CLASS_ID]));
3027 }
3028
3029 if (show_mem || (show_tcpinfo && s->type != IPPROTO_UDP)) {
3030 out("\n\t");
3031 if (s->type == IPPROTO_SCTP)
3032 sctp_show_info(nlh, r, tb);
3033 else
3034 tcp_show_info(nlh, r, tb);
3035 }
3036 sctp_ino = s->ino;
3037
3038 return 0;
3039 }
3040
3041 static int tcpdiag_send(int fd, int protocol, struct filter *f)
3042 {
3043 struct sockaddr_nl nladdr = { .nl_family = AF_NETLINK };
3044 struct {
3045 struct nlmsghdr nlh;
3046 struct inet_diag_req r;
3047 } req = {
3048 .nlh.nlmsg_len = sizeof(req),
3049 .nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST,
3050 .nlh.nlmsg_seq = MAGIC_SEQ,
3051 .r.idiag_family = AF_INET,
3052 .r.idiag_states = f->states,
3053 };
3054 char *bc = NULL;
3055 int bclen;
3056 struct msghdr msg;
3057 struct rtattr rta;
3058 struct iovec iov[3];
3059 int iovlen = 1;
3060
3061 if (protocol == IPPROTO_UDP)
3062 return -1;
3063
3064 if (protocol == IPPROTO_TCP)
3065 req.nlh.nlmsg_type = TCPDIAG_GETSOCK;
3066 else
3067 req.nlh.nlmsg_type = DCCPDIAG_GETSOCK;
3068 if (show_mem) {
3069 req.r.idiag_ext |= (1<<(INET_DIAG_MEMINFO-1));
3070 req.r.idiag_ext |= (1<<(INET_DIAG_SKMEMINFO-1));
3071 }
3072
3073 if (show_tcpinfo) {
3074 req.r.idiag_ext |= (1<<(INET_DIAG_INFO-1));
3075 req.r.idiag_ext |= (1<<(INET_DIAG_VEGASINFO-1));
3076 req.r.idiag_ext |= (1<<(INET_DIAG_CONG-1));
3077 }
3078
3079 if (show_tos) {
3080 req.r.idiag_ext |= (1<<(INET_DIAG_TOS-1));
3081 req.r.idiag_ext |= (1<<(INET_DIAG_TCLASS-1));
3082 }
3083
3084 iov[0] = (struct iovec){
3085 .iov_base = &req,
3086 .iov_len = sizeof(req)
3087 };
3088 if (f->f) {
3089 bclen = ssfilter_bytecompile(f->f, &bc);
3090 if (bclen) {
3091 rta.rta_type = INET_DIAG_REQ_BYTECODE;
3092 rta.rta_len = RTA_LENGTH(bclen);
3093 iov[1] = (struct iovec){ &rta, sizeof(rta) };
3094 iov[2] = (struct iovec){ bc, bclen };
3095 req.nlh.nlmsg_len += RTA_LENGTH(bclen);
3096 iovlen = 3;
3097 }
3098 }
3099
3100 msg = (struct msghdr) {
3101 .msg_name = (void *)&nladdr,
3102 .msg_namelen = sizeof(nladdr),
3103 .msg_iov = iov,
3104 .msg_iovlen = iovlen,
3105 };
3106
3107 if (sendmsg(fd, &msg, 0) < 0) {
3108 close(fd);
3109 return -1;
3110 }
3111
3112 return 0;
3113 }
3114
3115 static int sockdiag_send(int family, int fd, int protocol, struct filter *f)
3116 {
3117 struct sockaddr_nl nladdr = { .nl_family = AF_NETLINK };
3118 DIAG_REQUEST(req, struct inet_diag_req_v2 r);
3119 char *bc = NULL;
3120 int bclen;
3121 struct msghdr msg;
3122 struct rtattr rta;
3123 struct iovec iov[3];
3124 int iovlen = 1;
3125
3126 if (family == PF_UNSPEC)
3127 return tcpdiag_send(fd, protocol, f);
3128
3129 memset(&req.r, 0, sizeof(req.r));
3130 req.r.sdiag_family = family;
3131 req.r.sdiag_protocol = protocol;
3132 req.r.idiag_states = f->states;
3133 if (show_mem) {
3134 req.r.idiag_ext |= (1<<(INET_DIAG_MEMINFO-1));
3135 req.r.idiag_ext |= (1<<(INET_DIAG_SKMEMINFO-1));
3136 }
3137
3138 if (show_tcpinfo) {
3139 req.r.idiag_ext |= (1<<(INET_DIAG_INFO-1));
3140 req.r.idiag_ext |= (1<<(INET_DIAG_VEGASINFO-1));
3141 req.r.idiag_ext |= (1<<(INET_DIAG_CONG-1));
3142 }
3143
3144 if (show_tos) {
3145 req.r.idiag_ext |= (1<<(INET_DIAG_TOS-1));
3146 req.r.idiag_ext |= (1<<(INET_DIAG_TCLASS-1));
3147 }
3148
3149 iov[0] = (struct iovec){
3150 .iov_base = &req,
3151 .iov_len = sizeof(req)
3152 };
3153 if (f->f) {
3154 bclen = ssfilter_bytecompile(f->f, &bc);
3155 if (bclen) {
3156 rta.rta_type = INET_DIAG_REQ_BYTECODE;
3157 rta.rta_len = RTA_LENGTH(bclen);
3158 iov[1] = (struct iovec){ &rta, sizeof(rta) };
3159 iov[2] = (struct iovec){ bc, bclen };
3160 req.nlh.nlmsg_len += RTA_LENGTH(bclen);
3161 iovlen = 3;
3162 }
3163 }
3164
3165 msg = (struct msghdr) {
3166 .msg_name = (void *)&nladdr,
3167 .msg_namelen = sizeof(nladdr),
3168 .msg_iov = iov,
3169 .msg_iovlen = iovlen,
3170 };
3171
3172 if (sendmsg(fd, &msg, 0) < 0) {
3173 close(fd);
3174 return -1;
3175 }
3176
3177 return 0;
3178 }
3179
3180 struct inet_diag_arg {
3181 struct filter *f;
3182 int protocol;
3183 struct rtnl_handle *rth;
3184 };
3185
3186 static int kill_inet_sock(struct nlmsghdr *h, void *arg, struct sockstat *s)
3187 {
3188 struct inet_diag_msg *d = NLMSG_DATA(h);
3189 struct inet_diag_arg *diag_arg = arg;
3190 struct rtnl_handle *rth = diag_arg->rth;
3191
3192 DIAG_REQUEST(req, struct inet_diag_req_v2 r);
3193
3194 req.nlh.nlmsg_type = SOCK_DESTROY;
3195 req.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
3196 req.nlh.nlmsg_seq = ++rth->seq;
3197 req.r.sdiag_family = d->idiag_family;
3198 req.r.sdiag_protocol = diag_arg->protocol;
3199 req.r.id = d->id;
3200
3201 if (diag_arg->protocol == IPPROTO_RAW) {
3202 struct inet_diag_req_raw *raw = (void *)&req.r;
3203
3204 BUILD_BUG_ON(sizeof(req.r) != sizeof(*raw));
3205 raw->sdiag_raw_protocol = s->raw_prot;
3206 }
3207
3208 return rtnl_talk(rth, &req.nlh, NULL);
3209 }
3210
3211 static int show_one_inet_sock(struct nlmsghdr *h, void *arg)
3212 {
3213 int err;
3214 struct inet_diag_arg *diag_arg = arg;
3215 struct inet_diag_msg *r = NLMSG_DATA(h);
3216 struct sockstat s = {};
3217
3218 if (!(diag_arg->f->families & FAMILY_MASK(r->idiag_family)))
3219 return 0;
3220
3221 parse_diag_msg(h, &s);
3222 s.type = diag_arg->protocol;
3223
3224 if (diag_arg->f->f && run_ssfilter(diag_arg->f->f, &s) == 0)
3225 return 0;
3226
3227 if (diag_arg->f->kill && kill_inet_sock(h, arg, &s) != 0) {
3228 if (errno == EOPNOTSUPP || errno == ENOENT) {
3229 /* Socket can't be closed, or is already closed. */
3230 return 0;
3231 } else {
3232 perror("SOCK_DESTROY answers");
3233 return -1;
3234 }
3235 }
3236
3237 err = inet_show_sock(h, &s);
3238 if (err < 0)
3239 return err;
3240
3241 return 0;
3242 }
3243
3244 static int inet_show_netlink(struct filter *f, FILE *dump_fp, int protocol)
3245 {
3246 int err = 0;
3247 struct rtnl_handle rth, rth2;
3248 int family = PF_INET;
3249 struct inet_diag_arg arg = { .f = f, .protocol = protocol };
3250
3251 if (rtnl_open_byproto(&rth, 0, NETLINK_SOCK_DIAG))
3252 return -1;
3253
3254 if (f->kill) {
3255 if (rtnl_open_byproto(&rth2, 0, NETLINK_SOCK_DIAG)) {
3256 rtnl_close(&rth);
3257 return -1;
3258 }
3259 arg.rth = &rth2;
3260 }
3261
3262 rth.dump = MAGIC_SEQ;
3263 rth.dump_fp = dump_fp;
3264 if (preferred_family == PF_INET6)
3265 family = PF_INET6;
3266
3267 again:
3268 if ((err = sockdiag_send(family, rth.fd, protocol, f)))
3269 goto Exit;
3270
3271 if ((err = rtnl_dump_filter(&rth, show_one_inet_sock, &arg))) {
3272 if (family != PF_UNSPEC) {
3273 family = PF_UNSPEC;
3274 goto again;
3275 }
3276 goto Exit;
3277 }
3278 if (family == PF_INET && preferred_family != PF_INET) {
3279 family = PF_INET6;
3280 goto again;
3281 }
3282
3283 Exit:
3284 rtnl_close(&rth);
3285 if (arg.rth)
3286 rtnl_close(arg.rth);
3287 return err;
3288 }
3289
3290 static int tcp_show_netlink_file(struct filter *f)
3291 {
3292 FILE *fp;
3293 char buf[16384];
3294 int err = -1;
3295
3296 if ((fp = fopen(getenv("TCPDIAG_FILE"), "r")) == NULL) {
3297 perror("fopen($TCPDIAG_FILE)");
3298 return err;
3299 }
3300
3301 while (1) {
3302 int status, err2;
3303 struct nlmsghdr *h = (struct nlmsghdr *)buf;
3304 struct sockstat s = {};
3305
3306 status = fread(buf, 1, sizeof(*h), fp);
3307 if (status < 0) {
3308 perror("Reading header from $TCPDIAG_FILE");
3309 break;
3310 }
3311 if (status != sizeof(*h)) {
3312 perror("Unexpected EOF reading $TCPDIAG_FILE");
3313 break;
3314 }
3315
3316 status = fread(h+1, 1, NLMSG_ALIGN(h->nlmsg_len-sizeof(*h)), fp);
3317
3318 if (status < 0) {
3319 perror("Reading $TCPDIAG_FILE");
3320 break;
3321 }
3322 if (status + sizeof(*h) < h->nlmsg_len) {
3323 perror("Unexpected EOF reading $TCPDIAG_FILE");
3324 break;
3325 }
3326
3327 /* The only legal exit point */
3328 if (h->nlmsg_type == NLMSG_DONE) {
3329 err = 0;
3330 break;
3331 }
3332
3333 if (h->nlmsg_type == NLMSG_ERROR) {
3334 struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(h);
3335
3336 if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
3337 fprintf(stderr, "ERROR truncated\n");
3338 } else {
3339 errno = -err->error;
3340 perror("TCPDIAG answered");
3341 }
3342 break;
3343 }
3344
3345 parse_diag_msg(h, &s);
3346 s.type = IPPROTO_TCP;
3347
3348 if (f && f->f && run_ssfilter(f->f, &s) == 0)
3349 continue;
3350
3351 err2 = inet_show_sock(h, &s);
3352 if (err2 < 0) {
3353 err = err2;
3354 break;
3355 }
3356 }
3357
3358 fclose(fp);
3359 return err;
3360 }
3361
3362 static int tcp_show(struct filter *f)
3363 {
3364 FILE *fp = NULL;
3365 char *buf = NULL;
3366 int bufsize = 1024*1024;
3367
3368 if (!filter_af_get(f, AF_INET) && !filter_af_get(f, AF_INET6))
3369 return 0;
3370
3371 dg_proto = TCP_PROTO;
3372
3373 if (getenv("TCPDIAG_FILE"))
3374 return tcp_show_netlink_file(f);
3375
3376 if (!getenv("PROC_NET_TCP") && !getenv("PROC_ROOT")
3377 && inet_show_netlink(f, NULL, IPPROTO_TCP) == 0)
3378 return 0;
3379
3380 /* Sigh... We have to parse /proc/net/tcp... */
3381 while (bufsize >= 64*1024) {
3382 if ((buf = malloc(bufsize)) != NULL)
3383 break;
3384 bufsize /= 2;
3385 }
3386 if (buf == NULL) {
3387 errno = ENOMEM;
3388 return -1;
3389 }
3390
3391 if (f->families & FAMILY_MASK(AF_INET)) {
3392 if ((fp = net_tcp_open()) == NULL)
3393 goto outerr;
3394
3395 setbuffer(fp, buf, bufsize);
3396 if (generic_record_read(fp, tcp_show_line, f, AF_INET))
3397 goto outerr;
3398 fclose(fp);
3399 }
3400
3401 if ((f->families & FAMILY_MASK(AF_INET6)) &&
3402 (fp = net_tcp6_open()) != NULL) {
3403 setbuffer(fp, buf, bufsize);
3404 if (generic_record_read(fp, tcp_show_line, f, AF_INET6))
3405 goto outerr;
3406 fclose(fp);
3407 }
3408
3409 free(buf);
3410 return 0;
3411
3412 outerr:
3413 do {
3414 int saved_errno = errno;
3415
3416 free(buf);
3417 if (fp)
3418 fclose(fp);
3419 errno = saved_errno;
3420 return -1;
3421 } while (0);
3422 }
3423
3424 static int dccp_show(struct filter *f)
3425 {
3426 if (!filter_af_get(f, AF_INET) && !filter_af_get(f, AF_INET6))
3427 return 0;
3428
3429 if (!getenv("PROC_NET_DCCP") && !getenv("PROC_ROOT")
3430 && inet_show_netlink(f, NULL, IPPROTO_DCCP) == 0)
3431 return 0;
3432
3433 return 0;
3434 }
3435
3436 static int sctp_show(struct filter *f)
3437 {
3438 if (!filter_af_get(f, AF_INET) && !filter_af_get(f, AF_INET6))
3439 return 0;
3440
3441 if (!getenv("PROC_NET_SCTP") && !getenv("PROC_ROOT")
3442 && inet_show_netlink(f, NULL, IPPROTO_SCTP) == 0)
3443 return 0;
3444
3445 return 0;
3446 }
3447
3448 static int dgram_show_line(char *line, const struct filter *f, int family)
3449 {
3450 struct sockstat s = {};
3451 char *loc, *rem, *data;
3452 char opt[256];
3453 int n;
3454
3455 if (proc_inet_split_line(line, &loc, &rem, &data))
3456 return -1;
3457
3458 int state = (data[1] >= 'A') ? (data[1] - 'A' + 10) : (data[1] - '0');
3459
3460 if (!(f->states & (1 << state)))
3461 return 0;
3462
3463 proc_parse_inet_addr(loc, rem, family, &s);
3464
3465 if (f->f && run_ssfilter(f->f, &s) == 0)
3466 return 0;
3467
3468 opt[0] = 0;
3469 n = sscanf(data, "%x %x:%x %*x:%*x %*x %d %*d %u %d %llx %[^\n]\n",
3470 &s.state, &s.wq, &s.rq,
3471 &s.uid, &s.ino,
3472 &s.refcnt, &s.sk, opt);
3473
3474 if (n < 9)
3475 opt[0] = 0;
3476
3477 s.type = dg_proto == UDP_PROTO ? IPPROTO_UDP : 0;
3478 inet_stats_print(&s, false);
3479
3480 if (show_details && opt[0])
3481 out(" opt:\"%s\"", opt);
3482
3483 return 0;
3484 }
3485
3486 static int udp_show(struct filter *f)
3487 {
3488 FILE *fp = NULL;
3489
3490 if (!filter_af_get(f, AF_INET) && !filter_af_get(f, AF_INET6))
3491 return 0;
3492
3493 dg_proto = UDP_PROTO;
3494
3495 if (!getenv("PROC_NET_UDP") && !getenv("PROC_ROOT")
3496 && inet_show_netlink(f, NULL, IPPROTO_UDP) == 0)
3497 return 0;
3498
3499 if (f->families&FAMILY_MASK(AF_INET)) {
3500 if ((fp = net_udp_open()) == NULL)
3501 goto outerr;
3502 if (generic_record_read(fp, dgram_show_line, f, AF_INET))
3503 goto outerr;
3504 fclose(fp);
3505 }
3506
3507 if ((f->families&FAMILY_MASK(AF_INET6)) &&
3508 (fp = net_udp6_open()) != NULL) {
3509 if (generic_record_read(fp, dgram_show_line, f, AF_INET6))
3510 goto outerr;
3511 fclose(fp);
3512 }
3513 return 0;
3514
3515 outerr:
3516 do {
3517 int saved_errno = errno;
3518
3519 if (fp)
3520 fclose(fp);
3521 errno = saved_errno;
3522 return -1;
3523 } while (0);
3524 }
3525
3526 static int raw_show(struct filter *f)
3527 {
3528 FILE *fp = NULL;
3529
3530 if (!filter_af_get(f, AF_INET) && !filter_af_get(f, AF_INET6))
3531 return 0;
3532
3533 dg_proto = RAW_PROTO;
3534
3535 if (!getenv("PROC_NET_RAW") && !getenv("PROC_ROOT") &&
3536 inet_show_netlink(f, NULL, IPPROTO_RAW) == 0)
3537 return 0;
3538
3539 if (f->families&FAMILY_MASK(AF_INET)) {
3540 if ((fp = net_raw_open()) == NULL)
3541 goto outerr;
3542 if (generic_record_read(fp, dgram_show_line, f, AF_INET))
3543 goto outerr;
3544 fclose(fp);
3545 }
3546
3547 if ((f->families&FAMILY_MASK(AF_INET6)) &&
3548 (fp = net_raw6_open()) != NULL) {
3549 if (generic_record_read(fp, dgram_show_line, f, AF_INET6))
3550 goto outerr;
3551 fclose(fp);
3552 }
3553 return 0;
3554
3555 outerr:
3556 do {
3557 int saved_errno = errno;
3558
3559 if (fp)
3560 fclose(fp);
3561 errno = saved_errno;
3562 return -1;
3563 } while (0);
3564 }
3565
3566 #define MAX_UNIX_REMEMBER (1024*1024/sizeof(struct sockstat))
3567
3568 static void unix_list_drop_first(struct sockstat **list)
3569 {
3570 struct sockstat *s = *list;
3571
3572 (*list) = (*list)->next;
3573 free(s->name);
3574 free(s);
3575 }
3576
3577 static bool unix_type_skip(struct sockstat *s, struct filter *f)
3578 {
3579 if (s->type == SOCK_STREAM && !(f->dbs&(1<<UNIX_ST_DB)))
3580 return true;
3581 if (s->type == SOCK_DGRAM && !(f->dbs&(1<<UNIX_DG_DB)))
3582 return true;
3583 if (s->type == SOCK_SEQPACKET && !(f->dbs&(1<<UNIX_SQ_DB)))
3584 return true;
3585 return false;
3586 }
3587
3588 static void unix_stats_print(struct sockstat *s, struct filter *f)
3589 {
3590 char port_name[30] = {};
3591
3592 sock_state_print(s);
3593
3594 sock_addr_print(s->name ?: "*", " ",
3595 int_to_str(s->lport, port_name), NULL);
3596 sock_addr_print(s->peer_name ?: "*", " ",
3597 int_to_str(s->rport, port_name), NULL);
3598
3599 proc_ctx_print(s);
3600 }
3601
3602 static int unix_show_sock(struct nlmsghdr *nlh, void *arg)
3603 {
3604 struct filter *f = (struct filter *)arg;
3605 struct unix_diag_msg *r = NLMSG_DATA(nlh);
3606 struct rtattr *tb[UNIX_DIAG_MAX+1];
3607 char name[128];
3608 struct sockstat stat = { .name = "*", .peer_name = "*" };
3609
3610 parse_rtattr(tb, UNIX_DIAG_MAX, (struct rtattr *)(r+1),
3611 nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
3612
3613 stat.type = r->udiag_type;
3614 stat.state = r->udiag_state;
3615 stat.ino = stat.lport = r->udiag_ino;
3616 stat.local.family = stat.remote.family = AF_UNIX;
3617
3618 if (unix_type_skip(&stat, f))
3619 return 0;
3620
3621 if (tb[UNIX_DIAG_RQLEN]) {
3622 struct unix_diag_rqlen *rql = RTA_DATA(tb[UNIX_DIAG_RQLEN]);
3623
3624 stat.rq = rql->udiag_rqueue;
3625 stat.wq = rql->udiag_wqueue;
3626 }
3627 if (tb[UNIX_DIAG_NAME]) {
3628 int len = RTA_PAYLOAD(tb[UNIX_DIAG_NAME]);
3629
3630 memcpy(name, RTA_DATA(tb[UNIX_DIAG_NAME]), len);
3631 name[len] = '\0';
3632 if (name[0] == '\0') {
3633 int i;
3634 for (i = 0; i < len; i++)
3635 if (name[i] == '\0')
3636 name[i] = '@';
3637 }
3638 stat.name = &name[0];
3639 memcpy(stat.local.data, &stat.name, sizeof(stat.name));
3640 }
3641 if (tb[UNIX_DIAG_PEER])
3642 stat.rport = rta_getattr_u32(tb[UNIX_DIAG_PEER]);
3643
3644 if (f->f && run_ssfilter(f->f, &stat) == 0)
3645 return 0;
3646
3647 unix_stats_print(&stat, f);
3648
3649 if (show_mem)
3650 print_skmeminfo(tb, UNIX_DIAG_MEMINFO);
3651 if (show_details) {
3652 if (tb[UNIX_DIAG_SHUTDOWN]) {
3653 unsigned char mask;
3654
3655 mask = rta_getattr_u8(tb[UNIX_DIAG_SHUTDOWN]);
3656 out(" %c-%c",
3657 mask & 1 ? '-' : '<', mask & 2 ? '-' : '>');
3658 }
3659 if (tb[UNIX_DIAG_VFS]) {
3660 struct unix_diag_vfs *uv = RTA_DATA(tb[UNIX_DIAG_VFS]);
3661
3662 out(" ino:%u dev:%u/%u", uv->udiag_vfs_ino, major(uv->udiag_vfs_dev),
3663 minor(uv->udiag_vfs_dev));
3664 }
3665 if (tb[UNIX_DIAG_ICONS]) {
3666 int len = RTA_PAYLOAD(tb[UNIX_DIAG_ICONS]);
3667 __u32 *peers = RTA_DATA(tb[UNIX_DIAG_ICONS]);
3668 int i;
3669
3670 out(" peers:");
3671 for (i = 0; i < len / sizeof(__u32); i++)
3672 out(" %u", peers[i]);
3673 }
3674 }
3675
3676 return 0;
3677 }
3678
3679 static int handle_netlink_request(struct filter *f, struct nlmsghdr *req,
3680 size_t size, rtnl_filter_t show_one_sock)
3681 {
3682 int ret = -1;
3683 struct rtnl_handle rth;
3684
3685 if (rtnl_open_byproto(&rth, 0, NETLINK_SOCK_DIAG))
3686 return -1;
3687
3688 rth.dump = MAGIC_SEQ;
3689
3690 if (rtnl_send(&rth, req, size) < 0)
3691 goto Exit;
3692
3693 if (rtnl_dump_filter(&rth, show_one_sock, f))
3694 goto Exit;
3695
3696 ret = 0;
3697 Exit:
3698 rtnl_close(&rth);
3699 return ret;
3700 }
3701
3702 static int unix_show_netlink(struct filter *f)
3703 {
3704 DIAG_REQUEST(req, struct unix_diag_req r);
3705
3706 req.r.sdiag_family = AF_UNIX;
3707 req.r.udiag_states = f->states;
3708 req.r.udiag_show = UDIAG_SHOW_NAME | UDIAG_SHOW_PEER | UDIAG_SHOW_RQLEN;
3709 if (show_mem)
3710 req.r.udiag_show |= UDIAG_SHOW_MEMINFO;
3711 if (show_details)
3712 req.r.udiag_show |= UDIAG_SHOW_VFS | UDIAG_SHOW_ICONS;
3713
3714 return handle_netlink_request(f, &req.nlh, sizeof(req), unix_show_sock);
3715 }
3716
3717 static int unix_show(struct filter *f)
3718 {
3719 FILE *fp;
3720 char buf[256];
3721 char name[128];
3722 int newformat = 0;
3723 int cnt;
3724 struct sockstat *list = NULL;
3725 const int unix_state_map[] = { SS_CLOSE, SS_SYN_SENT,
3726 SS_ESTABLISHED, SS_CLOSING };
3727
3728 if (!filter_af_get(f, AF_UNIX))
3729 return 0;
3730
3731 if (!getenv("PROC_NET_UNIX") && !getenv("PROC_ROOT")
3732 && unix_show_netlink(f) == 0)
3733 return 0;
3734
3735 if ((fp = net_unix_open()) == NULL)
3736 return -1;
3737 if (!fgets(buf, sizeof(buf), fp)) {
3738 fclose(fp);
3739 return -1;
3740 }
3741
3742 if (memcmp(buf, "Peer", 4) == 0)
3743 newformat = 1;
3744 cnt = 0;
3745
3746 while (fgets(buf, sizeof(buf), fp)) {
3747 struct sockstat *u, **insp;
3748 int flags;
3749
3750 if (!(u = calloc(1, sizeof(*u))))
3751 break;
3752
3753 if (sscanf(buf, "%x: %x %x %x %x %x %d %s",
3754 &u->rport, &u->rq, &u->wq, &flags, &u->type,
3755 &u->state, &u->ino, name) < 8)
3756 name[0] = 0;
3757
3758 u->lport = u->ino;
3759 u->local.family = u->remote.family = AF_UNIX;
3760
3761 if (flags & (1 << 16)) {
3762 u->state = SS_LISTEN;
3763 } else if (u->state > 0 &&
3764 u->state <= ARRAY_SIZE(unix_state_map)) {
3765 u->state = unix_state_map[u->state-1];
3766 if (u->type == SOCK_DGRAM && u->state == SS_CLOSE && u->rport)
3767 u->state = SS_ESTABLISHED;
3768 }
3769 if (unix_type_skip(u, f) ||
3770 !(f->states & (1 << u->state))) {
3771 free(u);
3772 continue;
3773 }
3774
3775 if (!newformat) {
3776 u->rport = 0;
3777 u->rq = 0;
3778 u->wq = 0;
3779 }
3780
3781 if (name[0]) {
3782 u->name = strdup(name);
3783 if (!u->name) {
3784 free(u);
3785 break;
3786 }
3787 }
3788
3789 if (u->rport) {
3790 struct sockstat *p;
3791
3792 for (p = list; p; p = p->next) {
3793 if (u->rport == p->lport)
3794 break;
3795 }
3796 if (!p)
3797 u->peer_name = "?";
3798 else
3799 u->peer_name = p->name ? : "*";
3800 }
3801
3802 if (f->f) {
3803 struct sockstat st = {
3804 .local.family = AF_UNIX,
3805 .remote.family = AF_UNIX,
3806 };
3807
3808 memcpy(st.local.data, &u->name, sizeof(u->name));
3809 /* when parsing the old format rport is set to 0 and
3810 * therefore peer_name remains NULL
3811 */
3812 if (u->peer_name && strcmp(u->peer_name, "*"))
3813 memcpy(st.remote.data, &u->peer_name,
3814 sizeof(u->peer_name));
3815 if (run_ssfilter(f->f, &st) == 0) {
3816 free(u->name);
3817 free(u);
3818 continue;
3819 }
3820 }
3821
3822 insp = &list;
3823 while (*insp) {
3824 if (u->type < (*insp)->type ||
3825 (u->type == (*insp)->type &&
3826 u->ino < (*insp)->ino))
3827 break;
3828 insp = &(*insp)->next;
3829 }
3830 u->next = *insp;
3831 *insp = u;
3832
3833 if (++cnt > MAX_UNIX_REMEMBER) {
3834 while (list) {
3835 unix_stats_print(list, f);
3836 unix_list_drop_first(&list);
3837 }
3838 cnt = 0;
3839 }
3840 }
3841 fclose(fp);
3842 while (list) {
3843 unix_stats_print(list, f);
3844 unix_list_drop_first(&list);
3845 }
3846
3847 return 0;
3848 }
3849
3850 static int packet_stats_print(struct sockstat *s, const struct filter *f)
3851 {
3852 const char *addr, *port;
3853 char ll_name[16];
3854
3855 s->local.family = s->remote.family = AF_PACKET;
3856
3857 if (f->f) {
3858 s->local.data[0] = s->prot;
3859 if (run_ssfilter(f->f, s) == 0)
3860 return 1;
3861 }
3862
3863 sock_state_print(s);
3864
3865 if (s->prot == 3)
3866 addr = "*";
3867 else
3868 addr = ll_proto_n2a(htons(s->prot), ll_name, sizeof(ll_name));
3869
3870 if (s->iface == 0)
3871 port = "*";
3872 else
3873 port = xll_index_to_name(s->iface);
3874
3875 sock_addr_print(addr, ":", port, NULL);
3876 sock_addr_print("", "*", "", NULL);
3877
3878 proc_ctx_print(s);
3879
3880 if (show_details)
3881 sock_details_print(s);
3882
3883 return 0;
3884 }
3885
3886 static void packet_show_ring(struct packet_diag_ring *ring)
3887 {
3888 out("blk_size:%d", ring->pdr_block_size);
3889 out(",blk_nr:%d", ring->pdr_block_nr);
3890 out(",frm_size:%d", ring->pdr_frame_size);
3891 out(",frm_nr:%d", ring->pdr_frame_nr);
3892 out(",tmo:%d", ring->pdr_retire_tmo);
3893 out(",features:0x%x", ring->pdr_features);
3894 }
3895
3896 static int packet_show_sock(struct nlmsghdr *nlh, void *arg)
3897 {
3898 const struct filter *f = arg;
3899 struct packet_diag_msg *r = NLMSG_DATA(nlh);
3900 struct packet_diag_info *pinfo = NULL;
3901 struct packet_diag_ring *ring_rx = NULL, *ring_tx = NULL;
3902 struct rtattr *tb[PACKET_DIAG_MAX+1];
3903 struct sockstat stat = {};
3904 uint32_t fanout = 0;
3905 bool has_fanout = false;
3906
3907 parse_rtattr(tb, PACKET_DIAG_MAX, (struct rtattr *)(r+1),
3908 nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
3909
3910 /* use /proc/net/packet if all info are not available */
3911 if (!tb[PACKET_DIAG_MEMINFO])
3912 return -1;
3913
3914 stat.type = r->pdiag_type;
3915 stat.prot = r->pdiag_num;
3916 stat.ino = r->pdiag_ino;
3917 stat.state = SS_CLOSE;
3918 stat.sk = cookie_sk_get(&r->pdiag_cookie[0]);
3919
3920 if (tb[PACKET_DIAG_MEMINFO]) {
3921 __u32 *skmeminfo = RTA_DATA(tb[PACKET_DIAG_MEMINFO]);
3922
3923 stat.rq = skmeminfo[SK_MEMINFO_RMEM_ALLOC];
3924 }
3925
3926 if (tb[PACKET_DIAG_INFO]) {
3927 pinfo = RTA_DATA(tb[PACKET_DIAG_INFO]);
3928 stat.lport = stat.iface = pinfo->pdi_index;
3929 }
3930
3931 if (tb[PACKET_DIAG_UID])
3932 stat.uid = rta_getattr_u32(tb[PACKET_DIAG_UID]);
3933
3934 if (tb[PACKET_DIAG_RX_RING])
3935 ring_rx = RTA_DATA(tb[PACKET_DIAG_RX_RING]);
3936
3937 if (tb[PACKET_DIAG_TX_RING])
3938 ring_tx = RTA_DATA(tb[PACKET_DIAG_TX_RING]);
3939
3940 if (tb[PACKET_DIAG_FANOUT]) {
3941 has_fanout = true;
3942 fanout = rta_getattr_u32(tb[PACKET_DIAG_FANOUT]);
3943 }
3944
3945 if (packet_stats_print(&stat, f))
3946 return 0;
3947
3948 if (show_details) {
3949 if (pinfo) {
3950 out("\n\tver:%d", pinfo->pdi_version);
3951 out(" cpy_thresh:%d", pinfo->pdi_copy_thresh);
3952 out(" flags( ");
3953 if (pinfo->pdi_flags & PDI_RUNNING)
3954 out("running");
3955 if (pinfo->pdi_flags & PDI_AUXDATA)
3956 out(" auxdata");
3957 if (pinfo->pdi_flags & PDI_ORIGDEV)
3958 out(" origdev");
3959 if (pinfo->pdi_flags & PDI_VNETHDR)
3960 out(" vnethdr");
3961 if (pinfo->pdi_flags & PDI_LOSS)
3962 out(" loss");
3963 if (!pinfo->pdi_flags)
3964 out("0");
3965 out(" )");
3966 }
3967 if (ring_rx) {
3968 out("\n\tring_rx(");
3969 packet_show_ring(ring_rx);
3970 out(")");
3971 }
3972 if (ring_tx) {
3973 out("\n\tring_tx(");
3974 packet_show_ring(ring_tx);
3975 out(")");
3976 }
3977 if (has_fanout) {
3978 uint16_t type = (fanout >> 16) & 0xffff;
3979
3980 out("\n\tfanout(");
3981 out("id:%d,", fanout & 0xffff);
3982 out("type:");
3983
3984 if (type == 0)
3985 out("hash");
3986 else if (type == 1)
3987 out("lb");
3988 else if (type == 2)
3989 out("cpu");
3990 else if (type == 3)
3991 out("roll");
3992 else if (type == 4)
3993 out("random");
3994 else if (type == 5)
3995 out("qm");
3996 else
3997 out("0x%x", type);
3998
3999 out(")");
4000 }
4001 }
4002
4003 if (show_bpf && tb[PACKET_DIAG_FILTER]) {
4004 struct sock_filter *fil =
4005 RTA_DATA(tb[PACKET_DIAG_FILTER]);
4006 int num = RTA_PAYLOAD(tb[PACKET_DIAG_FILTER]) /
4007 sizeof(struct sock_filter);
4008
4009 out("\n\tbpf filter (%d): ", num);
4010 while (num) {
4011 out(" 0x%02x %u %u %u,",
4012 fil->code, fil->jt, fil->jf, fil->k);
4013 num--;
4014 fil++;
4015 }
4016 }
4017
4018 if (show_mem)
4019 print_skmeminfo(tb, PACKET_DIAG_MEMINFO);
4020 return 0;
4021 }
4022
4023 static int packet_show_netlink(struct filter *f)
4024 {
4025 DIAG_REQUEST(req, struct packet_diag_req r);
4026
4027 req.r.sdiag_family = AF_PACKET;
4028 req.r.pdiag_show = PACKET_SHOW_INFO | PACKET_SHOW_MEMINFO |
4029 PACKET_SHOW_FILTER | PACKET_SHOW_RING_CFG | PACKET_SHOW_FANOUT;
4030
4031 return handle_netlink_request(f, &req.nlh, sizeof(req), packet_show_sock);
4032 }
4033
4034 static int packet_show_line(char *buf, const struct filter *f, int fam)
4035 {
4036 unsigned long long sk;
4037 struct sockstat stat = {};
4038 int type, prot, iface, state, rq, uid, ino;
4039
4040 sscanf(buf, "%llx %*d %d %x %d %d %u %u %u",
4041 &sk,
4042 &type, &prot, &iface, &state,
4043 &rq, &uid, &ino);
4044
4045 if (stat.type == SOCK_RAW && !(f->dbs&(1<<PACKET_R_DB)))
4046 return 0;
4047 if (stat.type == SOCK_DGRAM && !(f->dbs&(1<<PACKET_DG_DB)))
4048 return 0;
4049
4050 stat.type = type;
4051 stat.prot = prot;
4052 stat.lport = stat.iface = iface;
4053 stat.state = state;
4054 stat.rq = rq;
4055 stat.uid = uid;
4056 stat.ino = ino;
4057 stat.state = SS_CLOSE;
4058
4059 if (packet_stats_print(&stat, f))
4060 return 0;
4061
4062 return 0;
4063 }
4064
4065 static int packet_show(struct filter *f)
4066 {
4067 FILE *fp;
4068 int rc = 0;
4069
4070 if (!filter_af_get(f, AF_PACKET) || !(f->states & (1 << SS_CLOSE)))
4071 return 0;
4072
4073 if (!getenv("PROC_NET_PACKET") && !getenv("PROC_ROOT") &&
4074 packet_show_netlink(f) == 0)
4075 return 0;
4076
4077 if ((fp = net_packet_open()) == NULL)
4078 return -1;
4079 if (generic_record_read(fp, packet_show_line, f, AF_PACKET))
4080 rc = -1;
4081
4082 fclose(fp);
4083 return rc;
4084 }
4085
4086 static int netlink_show_one(struct filter *f,
4087 int prot, int pid, unsigned int groups,
4088 int state, int dst_pid, unsigned int dst_group,
4089 int rq, int wq,
4090 unsigned long long sk, unsigned long long cb)
4091 {
4092 struct sockstat st = {
4093 .state = SS_CLOSE,
4094 .rq = rq,
4095 .wq = wq,
4096 .local.family = AF_NETLINK,
4097 .remote.family = AF_NETLINK,
4098 };
4099
4100 SPRINT_BUF(prot_buf) = {};
4101 const char *prot_name;
4102 char procname[64] = {};
4103
4104 if (f->f) {
4105 st.rport = -1;
4106 st.lport = pid;
4107 st.local.data[0] = prot;
4108 if (run_ssfilter(f->f, &st) == 0)
4109 return 1;
4110 }
4111
4112 sock_state_print(&st);
4113
4114 if (resolve_services)
4115 prot_name = nl_proto_n2a(prot, prot_buf, sizeof(prot_buf));
4116 else
4117 prot_name = int_to_str(prot, prot_buf);
4118
4119 if (pid == -1) {
4120 procname[0] = '*';
4121 } else if (resolve_services) {
4122 int done = 0;
4123
4124 if (!pid) {
4125 done = 1;
4126 strncpy(procname, "kernel", 7);
4127 } else if (pid > 0) {
4128 FILE *fp;
4129
4130 snprintf(procname, sizeof(procname), "%s/%d/stat",
4131 getenv("PROC_ROOT") ? : "/proc", pid);
4132 if ((fp = fopen(procname, "r")) != NULL) {
4133 if (fscanf(fp, "%*d (%[^)])", procname) == 1) {
4134 snprintf(procname+strlen(procname),
4135 sizeof(procname)-strlen(procname),
4136 "/%d", pid);
4137 done = 1;
4138 }
4139 fclose(fp);
4140 }
4141 }
4142 if (!done)
4143 int_to_str(pid, procname);
4144 } else {
4145 int_to_str(pid, procname);
4146 }
4147
4148 sock_addr_print(prot_name, ":", procname, NULL);
4149
4150 if (state == NETLINK_CONNECTED) {
4151 char dst_group_buf[30];
4152 char dst_pid_buf[30];
4153
4154 sock_addr_print(int_to_str(dst_group, dst_group_buf), ":",
4155 int_to_str(dst_pid, dst_pid_buf), NULL);
4156 } else {
4157 sock_addr_print("", "*", "", NULL);
4158 }
4159
4160 char *pid_context = NULL;
4161
4162 if (show_proc_ctx) {
4163 /* The pid value will either be:
4164 * 0 if destination kernel - show kernel initial context.
4165 * A valid process pid - use getpidcon.
4166 * A unique value allocated by the kernel or netlink user
4167 * to the process - show context as "not available".
4168 */
4169 if (!pid)
4170 security_get_initial_context("kernel", &pid_context);
4171 else if (pid > 0)
4172 getpidcon(pid, &pid_context);
4173
4174 out(" proc_ctx=%s", pid_context ? : "unavailable");
4175 free(pid_context);
4176 }
4177
4178 if (show_details) {
4179 out(" sk=%llx cb=%llx groups=0x%08x", sk, cb, groups);
4180 }
4181
4182 return 0;
4183 }
4184
4185 static int netlink_show_sock(struct nlmsghdr *nlh, void *arg)
4186 {
4187 struct filter *f = (struct filter *)arg;
4188 struct netlink_diag_msg *r = NLMSG_DATA(nlh);
4189 struct rtattr *tb[NETLINK_DIAG_MAX+1];
4190 int rq = 0, wq = 0;
4191 unsigned long groups = 0;
4192
4193 parse_rtattr(tb, NETLINK_DIAG_MAX, (struct rtattr *)(r+1),
4194 nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
4195
4196 if (tb[NETLINK_DIAG_GROUPS] && RTA_PAYLOAD(tb[NETLINK_DIAG_GROUPS]))
4197 groups = *(unsigned long *) RTA_DATA(tb[NETLINK_DIAG_GROUPS]);
4198
4199 if (tb[NETLINK_DIAG_MEMINFO]) {
4200 const __u32 *skmeminfo;
4201
4202 skmeminfo = RTA_DATA(tb[NETLINK_DIAG_MEMINFO]);
4203
4204 rq = skmeminfo[SK_MEMINFO_RMEM_ALLOC];
4205 wq = skmeminfo[SK_MEMINFO_WMEM_ALLOC];
4206 }
4207
4208 if (netlink_show_one(f, r->ndiag_protocol, r->ndiag_portid, groups,
4209 r->ndiag_state, r->ndiag_dst_portid, r->ndiag_dst_group,
4210 rq, wq, 0, 0)) {
4211 return 0;
4212 }
4213
4214 if (show_mem) {
4215 out("\t");
4216 print_skmeminfo(tb, NETLINK_DIAG_MEMINFO);
4217 }
4218
4219 return 0;
4220 }
4221
4222 static int netlink_show_netlink(struct filter *f)
4223 {
4224 DIAG_REQUEST(req, struct netlink_diag_req r);
4225
4226 req.r.sdiag_family = AF_NETLINK;
4227 req.r.sdiag_protocol = NDIAG_PROTO_ALL;
4228 req.r.ndiag_show = NDIAG_SHOW_GROUPS | NDIAG_SHOW_MEMINFO;
4229
4230 return handle_netlink_request(f, &req.nlh, sizeof(req), netlink_show_sock);
4231 }
4232
4233 static int netlink_show(struct filter *f)
4234 {
4235 FILE *fp;
4236 char buf[256];
4237 int prot, pid;
4238 unsigned int groups;
4239 int rq, wq, rc;
4240 unsigned long long sk, cb;
4241
4242 if (!filter_af_get(f, AF_NETLINK) || !(f->states & (1 << SS_CLOSE)))
4243 return 0;
4244
4245 if (!getenv("PROC_NET_NETLINK") && !getenv("PROC_ROOT") &&
4246 netlink_show_netlink(f) == 0)
4247 return 0;
4248
4249 if ((fp = net_netlink_open()) == NULL)
4250 return -1;
4251 if (!fgets(buf, sizeof(buf), fp)) {
4252 fclose(fp);
4253 return -1;
4254 }
4255
4256 while (fgets(buf, sizeof(buf), fp)) {
4257 sscanf(buf, "%llx %d %d %x %d %d %llx %d",
4258 &sk,
4259 &prot, &pid, &groups, &rq, &wq, &cb, &rc);
4260
4261 netlink_show_one(f, prot, pid, groups, 0, 0, 0, rq, wq, sk, cb);
4262 }
4263
4264 fclose(fp);
4265 return 0;
4266 }
4267
4268 static bool vsock_type_skip(struct sockstat *s, struct filter *f)
4269 {
4270 if (s->type == SOCK_STREAM && !(f->dbs & (1 << VSOCK_ST_DB)))
4271 return true;
4272 if (s->type == SOCK_DGRAM && !(f->dbs & (1 << VSOCK_DG_DB)))
4273 return true;
4274 return false;
4275 }
4276
4277 static void vsock_addr_print(inet_prefix *a, __u32 port)
4278 {
4279 char cid_str[sizeof("4294967295")];
4280 char port_str[sizeof("4294967295")];
4281 __u32 cid;
4282
4283 memcpy(&cid, a->data, sizeof(cid));
4284
4285 if (cid == ~(__u32)0)
4286 snprintf(cid_str, sizeof(cid_str), "*");
4287 else
4288 snprintf(cid_str, sizeof(cid_str), "%u", cid);
4289
4290 if (port == ~(__u32)0)
4291 snprintf(port_str, sizeof(port_str), "*");
4292 else
4293 snprintf(port_str, sizeof(port_str), "%u", port);
4294
4295 sock_addr_print(cid_str, ":", port_str, NULL);
4296 }
4297
4298 static void vsock_stats_print(struct sockstat *s, struct filter *f)
4299 {
4300 sock_state_print(s);
4301
4302 vsock_addr_print(&s->local, s->lport);
4303 vsock_addr_print(&s->remote, s->rport);
4304
4305 proc_ctx_print(s);
4306 }
4307
4308 static int vsock_show_sock(struct nlmsghdr *nlh, void *arg)
4309 {
4310 struct filter *f = (struct filter *)arg;
4311 struct vsock_diag_msg *r = NLMSG_DATA(nlh);
4312 struct sockstat stat = {
4313 .type = r->vdiag_type,
4314 .lport = r->vdiag_src_port,
4315 .rport = r->vdiag_dst_port,
4316 .state = r->vdiag_state,
4317 .ino = r->vdiag_ino,
4318 };
4319
4320 vsock_set_inet_prefix(&stat.local, r->vdiag_src_cid);
4321 vsock_set_inet_prefix(&stat.remote, r->vdiag_dst_cid);
4322
4323 if (vsock_type_skip(&stat, f))
4324 return 0;
4325
4326 if (f->f && run_ssfilter(f->f, &stat) == 0)
4327 return 0;
4328
4329 vsock_stats_print(&stat, f);
4330
4331 return 0;
4332 }
4333
4334 static int vsock_show(struct filter *f)
4335 {
4336 DIAG_REQUEST(req, struct vsock_diag_req r);
4337
4338 if (!filter_af_get(f, AF_VSOCK))
4339 return 0;
4340
4341 req.r.sdiag_family = AF_VSOCK;
4342 req.r.vdiag_states = f->states;
4343
4344 return handle_netlink_request(f, &req.nlh, sizeof(req), vsock_show_sock);
4345 }
4346
4347 static void tipc_sock_addr_print(struct rtattr *net_addr, struct rtattr *id)
4348 {
4349 uint32_t node = rta_getattr_u32(net_addr);
4350 uint32_t identity = rta_getattr_u32(id);
4351
4352 SPRINT_BUF(addr) = {};
4353 SPRINT_BUF(port) = {};
4354
4355 sprintf(addr, "%u", node);
4356 sprintf(port, "%u", identity);
4357 sock_addr_print(addr, ":", port, NULL);
4358
4359 }
4360
4361 static int tipc_show_sock(struct nlmsghdr *nlh, void *arg)
4362 {
4363 struct rtattr *stat[TIPC_NLA_SOCK_STAT_MAX + 1] = {};
4364 struct rtattr *attrs[TIPC_NLA_SOCK_MAX + 1] = {};
4365 struct rtattr *con[TIPC_NLA_CON_MAX + 1] = {};
4366 struct rtattr *info[TIPC_NLA_MAX + 1] = {};
4367 struct rtattr *msg_ref;
4368 struct sockstat ss = {};
4369
4370 parse_rtattr(info, TIPC_NLA_MAX, NLMSG_DATA(nlh),
4371 NLMSG_PAYLOAD(nlh, 0));
4372
4373 if (!info[TIPC_NLA_SOCK])
4374 return 0;
4375
4376 msg_ref = info[TIPC_NLA_SOCK];
4377 parse_rtattr(attrs, TIPC_NLA_SOCK_MAX, RTA_DATA(msg_ref),
4378 RTA_PAYLOAD(msg_ref));
4379
4380 msg_ref = attrs[TIPC_NLA_SOCK_STAT];
4381 parse_rtattr(stat, TIPC_NLA_SOCK_STAT_MAX,
4382 RTA_DATA(msg_ref), RTA_PAYLOAD(msg_ref));
4383
4384
4385 ss.local.family = AF_TIPC;
4386 ss.type = rta_getattr_u32(attrs[TIPC_NLA_SOCK_TYPE]);
4387 ss.state = rta_getattr_u32(attrs[TIPC_NLA_SOCK_TIPC_STATE]);
4388 ss.uid = rta_getattr_u32(attrs[TIPC_NLA_SOCK_UID]);
4389 ss.ino = rta_getattr_u32(attrs[TIPC_NLA_SOCK_INO]);
4390 ss.rq = rta_getattr_u32(stat[TIPC_NLA_SOCK_STAT_RCVQ]);
4391 ss.wq = rta_getattr_u32(stat[TIPC_NLA_SOCK_STAT_SENDQ]);
4392 ss.sk = rta_getattr_u64(attrs[TIPC_NLA_SOCK_COOKIE]);
4393
4394 sock_state_print (&ss);
4395
4396 tipc_sock_addr_print(attrs[TIPC_NLA_SOCK_ADDR],
4397 attrs[TIPC_NLA_SOCK_REF]);
4398
4399 msg_ref = attrs[TIPC_NLA_SOCK_CON];
4400 if (msg_ref) {
4401 parse_rtattr(con, TIPC_NLA_CON_MAX,
4402 RTA_DATA(msg_ref), RTA_PAYLOAD(msg_ref));
4403
4404 tipc_sock_addr_print(con[TIPC_NLA_CON_NODE],
4405 con[TIPC_NLA_CON_SOCK]);
4406 } else
4407 sock_addr_print("", "-", "", NULL);
4408
4409 if (show_details)
4410 sock_details_print(&ss);
4411
4412 proc_ctx_print(&ss);
4413
4414 if (show_tipcinfo) {
4415 out("\n type:%s", stype_nameg[ss.type]);
4416 out(" cong:%s ",
4417 stat[TIPC_NLA_SOCK_STAT_LINK_CONG] ? "link" :
4418 stat[TIPC_NLA_SOCK_STAT_CONN_CONG] ? "conn" : "none");
4419 out(" drop:%d ",
4420 rta_getattr_u32(stat[TIPC_NLA_SOCK_STAT_DROP]));
4421
4422 if (attrs[TIPC_NLA_SOCK_HAS_PUBL])
4423 out(" publ");
4424
4425 if (con[TIPC_NLA_CON_FLAG])
4426 out(" via {%u,%u} ",
4427 rta_getattr_u32(con[TIPC_NLA_CON_TYPE]),
4428 rta_getattr_u32(con[TIPC_NLA_CON_INST]));
4429 }
4430
4431 return 0;
4432 }
4433
4434 static int tipc_show(struct filter *f)
4435 {
4436 DIAG_REQUEST(req, struct tipc_sock_diag_req r);
4437
4438 memset(&req.r, 0, sizeof(req.r));
4439 req.r.sdiag_family = AF_TIPC;
4440 req.r.tidiag_states = f->states;
4441
4442 return handle_netlink_request(f, &req.nlh, sizeof(req), tipc_show_sock);
4443 }
4444
4445 struct sock_diag_msg {
4446 __u8 sdiag_family;
4447 };
4448
4449 static int generic_show_sock(struct nlmsghdr *nlh, void *arg)
4450 {
4451 struct sock_diag_msg *r = NLMSG_DATA(nlh);
4452 struct inet_diag_arg inet_arg = { .f = arg, .protocol = IPPROTO_MAX };
4453 int ret;
4454
4455 switch (r->sdiag_family) {
4456 case AF_INET:
4457 case AF_INET6:
4458 inet_arg.rth = inet_arg.f->rth_for_killing;
4459 ret = show_one_inet_sock(nlh, &inet_arg);
4460 break;
4461 case AF_UNIX:
4462 ret = unix_show_sock(nlh, arg);
4463 break;
4464 case AF_PACKET:
4465 ret = packet_show_sock(nlh, arg);
4466 break;
4467 case AF_NETLINK:
4468 ret = netlink_show_sock(nlh, arg);
4469 break;
4470 case AF_VSOCK:
4471 ret = vsock_show_sock(nlh, arg);
4472 break;
4473 default:
4474 ret = -1;
4475 }
4476
4477 render();
4478
4479 return ret;
4480 }
4481
4482 static int handle_follow_request(struct filter *f)
4483 {
4484 int ret = 0;
4485 int groups = 0;
4486 struct rtnl_handle rth, rth2;
4487
4488 if (f->families & FAMILY_MASK(AF_INET) && f->dbs & (1 << TCP_DB))
4489 groups |= 1 << (SKNLGRP_INET_TCP_DESTROY - 1);
4490 if (f->families & FAMILY_MASK(AF_INET) && f->dbs & (1 << UDP_DB))
4491 groups |= 1 << (SKNLGRP_INET_UDP_DESTROY - 1);
4492 if (f->families & FAMILY_MASK(AF_INET6) && f->dbs & (1 << TCP_DB))
4493 groups |= 1 << (SKNLGRP_INET6_TCP_DESTROY - 1);
4494 if (f->families & FAMILY_MASK(AF_INET6) && f->dbs & (1 << UDP_DB))
4495 groups |= 1 << (SKNLGRP_INET6_UDP_DESTROY - 1);
4496
4497 if (groups == 0)
4498 return -1;
4499
4500 if (rtnl_open_byproto(&rth, groups, NETLINK_SOCK_DIAG))
4501 return -1;
4502
4503 rth.dump = 0;
4504 rth.local.nl_pid = 0;
4505
4506 if (f->kill) {
4507 if (rtnl_open_byproto(&rth2, groups, NETLINK_SOCK_DIAG)) {
4508 rtnl_close(&rth);
4509 return -1;
4510 }
4511 f->rth_for_killing = &rth2;
4512 }
4513
4514 if (rtnl_dump_filter(&rth, generic_show_sock, f))
4515 ret = -1;
4516
4517 rtnl_close(&rth);
4518 if (f->rth_for_killing)
4519 rtnl_close(f->rth_for_killing);
4520 return ret;
4521 }
4522
4523 static int get_snmp_int(char *proto, char *key, int *result)
4524 {
4525 char buf[1024];
4526 FILE *fp;
4527 int protolen = strlen(proto);
4528 int keylen = strlen(key);
4529
4530 *result = 0;
4531
4532 if ((fp = net_snmp_open()) == NULL)
4533 return -1;
4534
4535 while (fgets(buf, sizeof(buf), fp) != NULL) {
4536 char *p = buf;
4537 int pos = 0;
4538
4539 if (memcmp(buf, proto, protolen))
4540 continue;
4541 while ((p = strchr(p, ' ')) != NULL) {
4542 pos++;
4543 p++;
4544 if (memcmp(p, key, keylen) == 0 &&
4545 (p[keylen] == ' ' || p[keylen] == '\n'))
4546 break;
4547 }
4548 if (fgets(buf, sizeof(buf), fp) == NULL)
4549 break;
4550 if (memcmp(buf, proto, protolen))
4551 break;
4552 p = buf;
4553 while ((p = strchr(p, ' ')) != NULL) {
4554 p++;
4555 if (--pos == 0) {
4556 sscanf(p, "%d", result);
4557 fclose(fp);
4558 return 0;
4559 }
4560 }
4561 }
4562
4563 fclose(fp);
4564 errno = ESRCH;
4565 return -1;
4566 }
4567
4568
4569 /* Get stats from sockstat */
4570
4571 struct ssummary {
4572 int socks;
4573 int tcp_mem;
4574 int tcp_total;
4575 int tcp_orphans;
4576 int tcp_tws;
4577 int tcp4_hashed;
4578 int udp4;
4579 int raw4;
4580 int frag4;
4581 int frag4_mem;
4582 int tcp6_hashed;
4583 int udp6;
4584 int raw6;
4585 int frag6;
4586 int frag6_mem;
4587 };
4588
4589 static void get_sockstat_line(char *line, struct ssummary *s)
4590 {
4591 char id[256], rem[256];
4592
4593 if (sscanf(line, "%[^ ] %[^\n]\n", id, rem) != 2)
4594 return;
4595
4596 if (strcmp(id, "sockets:") == 0)
4597 sscanf(rem, "%*s%d", &s->socks);
4598 else if (strcmp(id, "UDP:") == 0)
4599 sscanf(rem, "%*s%d", &s->udp4);
4600 else if (strcmp(id, "UDP6:") == 0)
4601 sscanf(rem, "%*s%d", &s->udp6);
4602 else if (strcmp(id, "RAW:") == 0)
4603 sscanf(rem, "%*s%d", &s->raw4);
4604 else if (strcmp(id, "RAW6:") == 0)
4605 sscanf(rem, "%*s%d", &s->raw6);
4606 else if (strcmp(id, "TCP6:") == 0)
4607 sscanf(rem, "%*s%d", &s->tcp6_hashed);
4608 else if (strcmp(id, "FRAG:") == 0)
4609 sscanf(rem, "%*s%d%*s%d", &s->frag4, &s->frag4_mem);
4610 else if (strcmp(id, "FRAG6:") == 0)
4611 sscanf(rem, "%*s%d%*s%d", &s->frag6, &s->frag6_mem);
4612 else if (strcmp(id, "TCP:") == 0)
4613 sscanf(rem, "%*s%d%*s%d%*s%d%*s%d%*s%d",
4614 &s->tcp4_hashed,
4615 &s->tcp_orphans, &s->tcp_tws, &s->tcp_total, &s->tcp_mem);
4616 }
4617
4618 static int get_sockstat(struct ssummary *s)
4619 {
4620 char buf[256];
4621 FILE *fp;
4622
4623 memset(s, 0, sizeof(*s));
4624
4625 if ((fp = net_sockstat_open()) == NULL)
4626 return -1;
4627 while (fgets(buf, sizeof(buf), fp) != NULL)
4628 get_sockstat_line(buf, s);
4629 fclose(fp);
4630
4631 if ((fp = net_sockstat6_open()) == NULL)
4632 return 0;
4633 while (fgets(buf, sizeof(buf), fp) != NULL)
4634 get_sockstat_line(buf, s);
4635 fclose(fp);
4636
4637 return 0;
4638 }
4639
4640 static int print_summary(void)
4641 {
4642 struct ssummary s;
4643 int tcp_estab;
4644
4645 if (get_sockstat(&s) < 0)
4646 perror("ss: get_sockstat");
4647 if (get_snmp_int("Tcp:", "CurrEstab", &tcp_estab) < 0)
4648 perror("ss: get_snmpstat");
4649
4650 printf("Total: %d\n", s.socks);
4651
4652 printf("TCP: %d (estab %d, closed %d, orphaned %d, timewait %d)\n",
4653 s.tcp_total + s.tcp_tws, tcp_estab,
4654 s.tcp_total - (s.tcp4_hashed + s.tcp6_hashed - s.tcp_tws),
4655 s.tcp_orphans, s.tcp_tws);
4656
4657 printf("\n");
4658 printf("Transport Total IP IPv6\n");
4659 printf("RAW %-9d %-9d %-9d\n", s.raw4+s.raw6, s.raw4, s.raw6);
4660 printf("UDP %-9d %-9d %-9d\n", s.udp4+s.udp6, s.udp4, s.udp6);
4661 printf("TCP %-9d %-9d %-9d\n", s.tcp4_hashed+s.tcp6_hashed, s.tcp4_hashed, s.tcp6_hashed);
4662 printf("INET %-9d %-9d %-9d\n",
4663 s.raw4+s.udp4+s.tcp4_hashed+
4664 s.raw6+s.udp6+s.tcp6_hashed,
4665 s.raw4+s.udp4+s.tcp4_hashed,
4666 s.raw6+s.udp6+s.tcp6_hashed);
4667 printf("FRAG %-9d %-9d %-9d\n", s.frag4+s.frag6, s.frag4, s.frag6);
4668
4669 printf("\n");
4670
4671 return 0;
4672 }
4673
4674 static void _usage(FILE *dest)
4675 {
4676 fprintf(dest,
4677 "Usage: ss [ OPTIONS ]\n"
4678 " ss [ OPTIONS ] [ FILTER ]\n"
4679 " -h, --help this message\n"
4680 " -V, --version output version information\n"
4681 " -n, --numeric don't resolve service names\n"
4682 " -r, --resolve resolve host names\n"
4683 " -a, --all display all sockets\n"
4684 " -l, --listening display listening sockets\n"
4685 " -o, --options show timer information\n"
4686 " -e, --extended show detailed socket information\n"
4687 " -m, --memory show socket memory usage\n"
4688 " -p, --processes show process using socket\n"
4689 " -i, --info show internal TCP information\n"
4690 " --tipcinfo show internal tipc socket information\n"
4691 " -s, --summary show socket usage summary\n"
4692 " --tos show tos and priority information\n"
4693 " -b, --bpf show bpf filter socket information\n"
4694 " -E, --events continually display sockets as they are destroyed\n"
4695 " -Z, --context display process SELinux security contexts\n"
4696 " -z, --contexts display process and socket SELinux security contexts\n"
4697 " -N, --net switch to the specified network namespace name\n"
4698 "\n"
4699 " -4, --ipv4 display only IP version 4 sockets\n"
4700 " -6, --ipv6 display only IP version 6 sockets\n"
4701 " -0, --packet display PACKET sockets\n"
4702 " -t, --tcp display only TCP sockets\n"
4703 " -S, --sctp display only SCTP sockets\n"
4704 " -u, --udp display only UDP sockets\n"
4705 " -d, --dccp display only DCCP sockets\n"
4706 " -w, --raw display only RAW sockets\n"
4707 " -x, --unix display only Unix domain sockets\n"
4708 " --tipc display only TIPC sockets\n"
4709 " --vsock display only vsock sockets\n"
4710 " -f, --family=FAMILY display sockets of type FAMILY\n"
4711 " FAMILY := {inet|inet6|link|unix|netlink|vsock|tipc|help}\n"
4712 "\n"
4713 " -K, --kill forcibly close sockets, display what was closed\n"
4714 " -H, --no-header Suppress header line\n"
4715 "\n"
4716 " -A, --query=QUERY, --socket=QUERY\n"
4717 " QUERY := {all|inet|tcp|udp|raw|unix|unix_dgram|unix_stream|unix_seqpacket|packet|netlink|vsock_stream|vsock_dgram|tipc}[,QUERY]\n"
4718 "\n"
4719 " -D, --diag=FILE Dump raw information about TCP sockets to FILE\n"
4720 " -F, --filter=FILE read filter information from FILE\n"
4721 " FILTER := [ state STATE-FILTER ] [ EXPRESSION ]\n"
4722 " STATE-FILTER := {all|connected|synchronized|bucket|big|TCP-STATES}\n"
4723 " TCP-STATES := {established|syn-sent|syn-recv|fin-wait-{1,2}|time-wait|closed|close-wait|last-ack|listening|closing}\n"
4724 " connected := {established|syn-sent|syn-recv|fin-wait-{1,2}|time-wait|close-wait|last-ack|closing}\n"
4725 " synchronized := {established|syn-recv|fin-wait-{1,2}|time-wait|close-wait|last-ack|closing}\n"
4726 " bucket := {syn-recv|time-wait}\n"
4727 " big := {established|syn-sent|fin-wait-{1,2}|closed|close-wait|last-ack|listening|closing}\n"
4728 );
4729 }
4730
4731 static void help(void) __attribute__((noreturn));
4732 static void help(void)
4733 {
4734 _usage(stdout);
4735 exit(0);
4736 }
4737
4738 static void usage(void) __attribute__((noreturn));
4739 static void usage(void)
4740 {
4741 _usage(stderr);
4742 exit(-1);
4743 }
4744
4745
4746 static int scan_state(const char *state)
4747 {
4748 static const char * const sstate_namel[] = {
4749 "UNKNOWN",
4750 [SS_ESTABLISHED] = "established",
4751 [SS_SYN_SENT] = "syn-sent",
4752 [SS_SYN_RECV] = "syn-recv",
4753 [SS_FIN_WAIT1] = "fin-wait-1",
4754 [SS_FIN_WAIT2] = "fin-wait-2",
4755 [SS_TIME_WAIT] = "time-wait",
4756 [SS_CLOSE] = "unconnected",
4757 [SS_CLOSE_WAIT] = "close-wait",
4758 [SS_LAST_ACK] = "last-ack",
4759 [SS_LISTEN] = "listening",
4760 [SS_CLOSING] = "closing",
4761 };
4762 int i;
4763
4764 if (strcasecmp(state, "close") == 0 ||
4765 strcasecmp(state, "closed") == 0)
4766 return (1<<SS_CLOSE);
4767 if (strcasecmp(state, "syn-rcv") == 0)
4768 return (1<<SS_SYN_RECV);
4769 if (strcasecmp(state, "established") == 0)
4770 return (1<<SS_ESTABLISHED);
4771 if (strcasecmp(state, "all") == 0)
4772 return SS_ALL;
4773 if (strcasecmp(state, "connected") == 0)
4774 return SS_ALL & ~((1<<SS_CLOSE)|(1<<SS_LISTEN));
4775 if (strcasecmp(state, "synchronized") == 0)
4776 return SS_ALL & ~((1<<SS_CLOSE)|(1<<SS_LISTEN)|(1<<SS_SYN_SENT));
4777 if (strcasecmp(state, "bucket") == 0)
4778 return (1<<SS_SYN_RECV)|(1<<SS_TIME_WAIT);
4779 if (strcasecmp(state, "big") == 0)
4780 return SS_ALL & ~((1<<SS_SYN_RECV)|(1<<SS_TIME_WAIT));
4781 for (i = 0; i < SS_MAX; i++) {
4782 if (strcasecmp(state, sstate_namel[i]) == 0)
4783 return (1<<i);
4784 }
4785
4786 fprintf(stderr, "ss: wrong state name: %s\n", state);
4787 exit(-1);
4788 }
4789
4790 /* Values 'v' and 'V' are already used so a non-character is used */
4791 #define OPT_VSOCK 256
4792
4793 /* Values of 't' are already used so a non-character is used */
4794 #define OPT_TIPCSOCK 257
4795 #define OPT_TIPCINFO 258
4796
4797 #define OPT_TOS 259
4798
4799 static const struct option long_opts[] = {
4800 { "numeric", 0, 0, 'n' },
4801 { "resolve", 0, 0, 'r' },
4802 { "options", 0, 0, 'o' },
4803 { "extended", 0, 0, 'e' },
4804 { "memory", 0, 0, 'm' },
4805 { "info", 0, 0, 'i' },
4806 { "processes", 0, 0, 'p' },
4807 { "bpf", 0, 0, 'b' },
4808 { "events", 0, 0, 'E' },
4809 { "dccp", 0, 0, 'd' },
4810 { "tcp", 0, 0, 't' },
4811 { "sctp", 0, 0, 'S' },
4812 { "udp", 0, 0, 'u' },
4813 { "raw", 0, 0, 'w' },
4814 { "unix", 0, 0, 'x' },
4815 { "tipc", 0, 0, OPT_TIPCSOCK},
4816 { "vsock", 0, 0, OPT_VSOCK },
4817 { "all", 0, 0, 'a' },
4818 { "listening", 0, 0, 'l' },
4819 { "ipv4", 0, 0, '4' },
4820 { "ipv6", 0, 0, '6' },
4821 { "packet", 0, 0, '0' },
4822 { "family", 1, 0, 'f' },
4823 { "socket", 1, 0, 'A' },
4824 { "query", 1, 0, 'A' },
4825 { "summary", 0, 0, 's' },
4826 { "diag", 1, 0, 'D' },
4827 { "filter", 1, 0, 'F' },
4828 { "version", 0, 0, 'V' },
4829 { "help", 0, 0, 'h' },
4830 { "context", 0, 0, 'Z' },
4831 { "contexts", 0, 0, 'z' },
4832 { "net", 1, 0, 'N' },
4833 { "tipcinfo", 0, 0, OPT_TIPCINFO},
4834 { "tos", 0, 0, OPT_TOS },
4835 { "kill", 0, 0, 'K' },
4836 { "no-header", 0, 0, 'H' },
4837 { 0 }
4838
4839 };
4840
4841 int main(int argc, char *argv[])
4842 {
4843 int saw_states = 0;
4844 int saw_query = 0;
4845 int do_summary = 0;
4846 const char *dump_tcpdiag = NULL;
4847 FILE *filter_fp = NULL;
4848 int ch;
4849 int state_filter = 0;
4850
4851 while ((ch = getopt_long(argc, argv,
4852 "dhaletuwxnro460spbEf:miA:D:F:vVzZN:KHS",
4853 long_opts, NULL)) != EOF) {
4854 switch (ch) {
4855 case 'n':
4856 resolve_services = 0;
4857 break;
4858 case 'r':
4859 resolve_hosts = 1;
4860 break;
4861 case 'o':
4862 show_options = 1;
4863 break;
4864 case 'e':
4865 show_options = 1;
4866 show_details++;
4867 break;
4868 case 'm':
4869 show_mem = 1;
4870 break;
4871 case 'i':
4872 show_tcpinfo = 1;
4873 break;
4874 case 'p':
4875 show_users++;
4876 user_ent_hash_build();
4877 break;
4878 case 'b':
4879 show_options = 1;
4880 show_bpf++;
4881 break;
4882 case 'E':
4883 follow_events = 1;
4884 break;
4885 case 'd':
4886 filter_db_set(&current_filter, DCCP_DB, true);
4887 break;
4888 case 't':
4889 filter_db_set(&current_filter, TCP_DB, true);
4890 break;
4891 case 'S':
4892 filter_db_set(&current_filter, SCTP_DB, true);
4893 break;
4894 case 'u':
4895 filter_db_set(&current_filter, UDP_DB, true);
4896 break;
4897 case 'w':
4898 filter_db_set(&current_filter, RAW_DB, true);
4899 break;
4900 case 'x':
4901 filter_af_set(&current_filter, AF_UNIX);
4902 break;
4903 case OPT_VSOCK:
4904 filter_af_set(&current_filter, AF_VSOCK);
4905 break;
4906 case OPT_TIPCSOCK:
4907 filter_af_set(&current_filter, AF_TIPC);
4908 break;
4909 case 'a':
4910 state_filter = SS_ALL;
4911 break;
4912 case 'l':
4913 state_filter = (1 << SS_LISTEN) | (1 << SS_CLOSE);
4914 break;
4915 case '4':
4916 filter_af_set(&current_filter, AF_INET);
4917 break;
4918 case '6':
4919 filter_af_set(&current_filter, AF_INET6);
4920 break;
4921 case '0':
4922 filter_af_set(&current_filter, AF_PACKET);
4923 break;
4924 case 'f':
4925 if (strcmp(optarg, "inet") == 0)
4926 filter_af_set(&current_filter, AF_INET);
4927 else if (strcmp(optarg, "inet6") == 0)
4928 filter_af_set(&current_filter, AF_INET6);
4929 else if (strcmp(optarg, "link") == 0)
4930 filter_af_set(&current_filter, AF_PACKET);
4931 else if (strcmp(optarg, "unix") == 0)
4932 filter_af_set(&current_filter, AF_UNIX);
4933 else if (strcmp(optarg, "netlink") == 0)
4934 filter_af_set(&current_filter, AF_NETLINK);
4935 else if (strcmp(optarg, "tipc") == 0)
4936 filter_af_set(&current_filter, AF_TIPC);
4937 else if (strcmp(optarg, "vsock") == 0)
4938 filter_af_set(&current_filter, AF_VSOCK);
4939 else if (strcmp(optarg, "help") == 0)
4940 help();
4941 else {
4942 fprintf(stderr, "ss: \"%s\" is invalid family\n",
4943 optarg);
4944 usage();
4945 }
4946 break;
4947 case 'A':
4948 {
4949 char *p, *p1;
4950
4951 if (!saw_query) {
4952 current_filter.dbs = 0;
4953 state_filter = state_filter ?
4954 state_filter : SS_CONN;
4955 saw_query = 1;
4956 do_default = 0;
4957 }
4958 p = p1 = optarg;
4959 do {
4960 if ((p1 = strchr(p, ',')) != NULL)
4961 *p1 = 0;
4962 if (filter_db_parse(&current_filter, p)) {
4963 fprintf(stderr, "ss: \"%s\" is illegal socket table id\n", p);
4964 usage();
4965 }
4966 p = p1 + 1;
4967 } while (p1);
4968 break;
4969 }
4970 case 's':
4971 do_summary = 1;
4972 break;
4973 case 'D':
4974 dump_tcpdiag = optarg;
4975 break;
4976 case 'F':
4977 if (filter_fp) {
4978 fprintf(stderr, "More than one filter file\n");
4979 exit(-1);
4980 }
4981 if (optarg[0] == '-')
4982 filter_fp = stdin;
4983 else
4984 filter_fp = fopen(optarg, "r");
4985 if (!filter_fp) {
4986 perror("fopen filter file");
4987 exit(-1);
4988 }
4989 break;
4990 case 'v':
4991 case 'V':
4992 printf("ss utility, iproute2-ss%s\n", SNAPSHOT);
4993 exit(0);
4994 case 'z':
4995 show_sock_ctx++;
4996 /* fall through */
4997 case 'Z':
4998 if (is_selinux_enabled() <= 0) {
4999 fprintf(stderr, "ss: SELinux is not enabled.\n");
5000 exit(1);
5001 }
5002 show_proc_ctx++;
5003 user_ent_hash_build();
5004 break;
5005 case 'N':
5006 if (netns_switch(optarg))
5007 exit(1);
5008 break;
5009 case OPT_TIPCINFO:
5010 show_tipcinfo = 1;
5011 break;
5012 case OPT_TOS:
5013 show_tos = 1;
5014 break;
5015 case 'K':
5016 current_filter.kill = 1;
5017 break;
5018 case 'H':
5019 show_header = 0;
5020 break;
5021 case 'h':
5022 help();
5023 case '?':
5024 default:
5025 usage();
5026 }
5027 }
5028
5029 argc -= optind;
5030 argv += optind;
5031
5032 if (do_summary) {
5033 print_summary();
5034 if (do_default && argc == 0)
5035 exit(0);
5036 }
5037
5038 while (argc > 0) {
5039 if (strcmp(*argv, "state") == 0) {
5040 NEXT_ARG();
5041 if (!saw_states)
5042 state_filter = 0;
5043 state_filter |= scan_state(*argv);
5044 saw_states = 1;
5045 } else if (strcmp(*argv, "exclude") == 0 ||
5046 strcmp(*argv, "excl") == 0) {
5047 NEXT_ARG();
5048 if (!saw_states)
5049 state_filter = SS_ALL;
5050 state_filter &= ~scan_state(*argv);
5051 saw_states = 1;
5052 } else {
5053 break;
5054 }
5055 argc--; argv++;
5056 }
5057
5058 if (do_default) {
5059 state_filter = state_filter ? state_filter : SS_CONN;
5060 filter_db_parse(&current_filter, "all");
5061 }
5062
5063 filter_states_set(&current_filter, state_filter);
5064 filter_merge_defaults(&current_filter);
5065
5066 if (resolve_services && resolve_hosts &&
5067 (current_filter.dbs & (UNIX_DBM|INET_L4_DBM)))
5068 init_service_resolver();
5069
5070 if (current_filter.dbs == 0) {
5071 fprintf(stderr, "ss: no socket tables to show with such filter.\n");
5072 exit(0);
5073 }
5074 if (current_filter.families == 0) {
5075 fprintf(stderr, "ss: no families to show with such filter.\n");
5076 exit(0);
5077 }
5078 if (current_filter.states == 0) {
5079 fprintf(stderr, "ss: no socket states to show with such filter.\n");
5080 exit(0);
5081 }
5082
5083 if (dump_tcpdiag) {
5084 FILE *dump_fp = stdout;
5085
5086 if (!(current_filter.dbs & (1<<TCP_DB))) {
5087 fprintf(stderr, "ss: tcpdiag dump requested and no tcp in filter.\n");
5088 exit(0);
5089 }
5090 if (dump_tcpdiag[0] != '-') {
5091 dump_fp = fopen(dump_tcpdiag, "w");
5092 if (!dump_tcpdiag) {
5093 perror("fopen dump file");
5094 exit(-1);
5095 }
5096 }
5097 inet_show_netlink(&current_filter, dump_fp, IPPROTO_TCP);
5098 fflush(dump_fp);
5099 exit(0);
5100 }
5101
5102 if (ssfilter_parse(&current_filter.f, argc, argv, filter_fp))
5103 usage();
5104
5105 if (!(current_filter.dbs & (current_filter.dbs - 1)))
5106 columns[COL_NETID].disabled = 1;
5107
5108 if (!(current_filter.states & (current_filter.states - 1)))
5109 columns[COL_STATE].disabled = 1;
5110
5111 if (show_header)
5112 print_header();
5113
5114 fflush(stdout);
5115
5116 if (follow_events)
5117 exit(handle_follow_request(&current_filter));
5118
5119 if (current_filter.dbs & (1<<NETLINK_DB))
5120 netlink_show(&current_filter);
5121 if (current_filter.dbs & PACKET_DBM)
5122 packet_show(&current_filter);
5123 if (current_filter.dbs & UNIX_DBM)
5124 unix_show(&current_filter);
5125 if (current_filter.dbs & (1<<RAW_DB))
5126 raw_show(&current_filter);
5127 if (current_filter.dbs & (1<<UDP_DB))
5128 udp_show(&current_filter);
5129 if (current_filter.dbs & (1<<TCP_DB))
5130 tcp_show(&current_filter);
5131 if (current_filter.dbs & (1<<DCCP_DB))
5132 dccp_show(&current_filter);
5133 if (current_filter.dbs & (1<<SCTP_DB))
5134 sctp_show(&current_filter);
5135 if (current_filter.dbs & VSOCK_DBM)
5136 vsock_show(&current_filter);
5137 if (current_filter.dbs & (1<<TIPC_DB))
5138 tipc_show(&current_filter);
5139
5140 if (show_users || show_proc_ctx || show_sock_ctx)
5141 user_ent_destroy();
5142
5143 render();
5144
5145 return 0;
5146 }