2 * ss.c "sockstat", socket statistics
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.
9 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
16 #include <sys/ioctl.h>
17 #include <sys/socket.h>
19 #include <sys/sysmacros.h>
20 #include <netinet/in.h>
24 #include <arpa/inet.h>
36 #include "libnetlink.h"
37 #include "namespace.h"
42 #include <linux/tcp.h>
43 #include <linux/unix_diag.h>
44 #include <linux/netdevice.h> /* for MAX_ADDR_LEN */
45 #include <linux/filter.h>
46 #include <linux/xdp_diag.h>
47 #include <linux/packet_diag.h>
48 #include <linux/netlink_diag.h>
49 #include <linux/sctp.h>
50 #include <linux/vm_sockets_diag.h>
51 #include <linux/net.h>
52 #include <linux/tipc.h>
53 #include <linux/tipc_netlink.h>
54 #include <linux/tipc_sockets_diag.h>
55 #include <linux/tls.h>
56 #include <linux/mptcp.h>
58 /* AF_VSOCK/PF_VSOCK is only provided since glibc 2.18 */
63 #define AF_VSOCK PF_VSOCK
67 #define IPPROTO_MPTCP 262
70 #define BUF_CHUNK (1024 * 1024) /* Buffer chunk allocation size */
71 #define BUF_CHUNKS_MAX 5 /* Maximum number of allocated buffer chunks */
72 #define LEN_ALIGN(x) (((x) + 1) & ~1)
75 #include <selinux/selinux.h>
77 /* Stubs for SELinux functions */
78 static int is_selinux_enabled(void)
83 static int getpidcon(pid_t pid
, char **context
)
89 static int getfilecon(char *path
, char **context
)
95 static int security_get_initial_context(char *name
, char **context
)
102 int preferred_family
= AF_UNSPEC
;
103 static int show_options
;
105 static int show_users
;
107 static int show_tcpinfo
;
109 static int show_proc_ctx
;
110 static int show_sock_ctx
;
111 static int show_header
= 1;
112 static int follow_events
;
114 static int show_tipcinfo
;
116 static int show_cgroup
;
117 static int show_inet_sockopt
;
141 const enum col_align align
;
145 int width
; /* Calculated, including additional layout spacing */
146 int max_len
; /* Measured maximum field length in this column */
149 static struct column columns
[] = {
150 { ALIGN_LEFT
, "Netid", "", 0, 0, 0 },
151 { ALIGN_LEFT
, "State", " ", 0, 0, 0 },
152 { ALIGN_LEFT
, "Recv-Q", " ", 0, 0, 0 },
153 { ALIGN_LEFT
, "Send-Q", " ", 0, 0, 0 },
154 { ALIGN_RIGHT
, "Local Address:", " ", 0, 0, 0 },
155 { ALIGN_LEFT
, "Port", "", 0, 0, 0 },
156 { ALIGN_RIGHT
, "Peer Address:", " ", 0, 0, 0 },
157 { ALIGN_LEFT
, "Port", "", 0, 0, 0 },
158 { ALIGN_LEFT
, "Process", "", 0, 0, 0 },
159 { ALIGN_LEFT
, "", "", 0, 0, 0 },
162 static struct column
*current_field
= columns
;
164 /* Output buffer: chained chunks of BUF_CHUNK bytes. Each field is written to
165 * the buffer as a variable size token. A token consists of a 16 bits length
166 * field, followed by a string which is not NULL-terminated.
168 * A new chunk is allocated and linked when the current chunk doesn't have
169 * enough room to store the current token as a whole.
172 struct buf_chunk
*next
; /* Next chained chunk */
173 char *end
; /* Current end of content */
178 uint16_t len
; /* Data length, excluding length descriptor */
183 struct buf_token
*cur
; /* Position of current token in chunk */
184 struct buf_chunk
*head
; /* First chunk */
185 struct buf_chunk
*tail
; /* Current chunk */
186 int chunks
; /* Number of allocated chunks */
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
;
215 #define PACKET_DBM ((1<<PACKET_DG_DB)|(1<<PACKET_R_DB))
216 #define UNIX_DBM ((1<<UNIX_DG_DB)|(1<<UNIX_ST_DB)|(1<<UNIX_SQ_DB))
217 #define ALL_DB ((1<<MAX_DB)-1)
218 #define INET_L4_DBM ((1<<TCP_DB)|(1<<MPTCP_DB)|(1<<UDP_DB)|(1<<DCCP_DB)|(1<<SCTP_DB))
219 #define INET_DBM (INET_L4_DBM | (1<<RAW_DB))
220 #define VSOCK_DBM ((1<<VSOCK_ST_DB)|(1<<VSOCK_DG_DB))
239 SCTP_STATE_CLOSED
= 0,
240 SCTP_STATE_COOKIE_WAIT
= 1,
241 SCTP_STATE_COOKIE_ECHOED
= 2,
242 SCTP_STATE_ESTABLISHED
= 3,
243 SCTP_STATE_SHUTDOWN_PENDING
= 4,
244 SCTP_STATE_SHUTDOWN_SENT
= 5,
245 SCTP_STATE_SHUTDOWN_RECEIVED
= 6,
246 SCTP_STATE_SHUTDOWN_ACK_SENT
= 7,
249 #define SS_ALL ((1 << SS_MAX) - 1)
250 #define SS_CONN (SS_ALL & ~((1<<SS_LISTEN)|(1<<SS_CLOSE)|(1<<SS_TIME_WAIT)|(1<<SS_SYN_RECV)))
251 #define TIPC_SS_CONN ((1<<SS_ESTABLISHED)|(1<<SS_LISTEN)|(1<<SS_CLOSE))
253 #include "ssfilter.h"
261 struct rtnl_handle
*rth_for_killing
;
264 #define FAMILY_MASK(family) ((uint64_t)1 << (family))
266 static const struct filter default_dbs
[MAX_DB
] = {
269 .families
= FAMILY_MASK(AF_INET
) | FAMILY_MASK(AF_INET6
),
273 .families
= FAMILY_MASK(AF_INET
) | FAMILY_MASK(AF_INET6
),
277 .families
= FAMILY_MASK(AF_INET
) | FAMILY_MASK(AF_INET6
),
280 .states
= (1 << SS_ESTABLISHED
),
281 .families
= FAMILY_MASK(AF_INET
) | FAMILY_MASK(AF_INET6
),
284 .states
= (1 << SS_ESTABLISHED
),
285 .families
= FAMILY_MASK(AF_INET
) | FAMILY_MASK(AF_INET6
),
288 .states
= (1 << SS_CLOSE
),
289 .families
= FAMILY_MASK(AF_UNIX
),
293 .families
= FAMILY_MASK(AF_UNIX
),
297 .families
= FAMILY_MASK(AF_UNIX
),
300 .states
= (1 << SS_CLOSE
),
301 .families
= FAMILY_MASK(AF_PACKET
),
304 .states
= (1 << SS_CLOSE
),
305 .families
= FAMILY_MASK(AF_PACKET
),
308 .states
= (1 << SS_CLOSE
),
309 .families
= FAMILY_MASK(AF_NETLINK
),
313 .families
= FAMILY_MASK(AF_INET
) | FAMILY_MASK(AF_INET6
),
317 .families
= FAMILY_MASK(AF_VSOCK
),
321 .families
= FAMILY_MASK(AF_VSOCK
),
324 .states
= TIPC_SS_CONN
,
325 .families
= FAMILY_MASK(AF_TIPC
),
328 .states
= (1 << SS_CLOSE
),
329 .families
= FAMILY_MASK(AF_XDP
),
333 static const struct filter default_afs
[AF_MAX
] = {
348 .states
= (1 << SS_CLOSE
),
351 .dbs
= (1 << NETLINK_DB
),
352 .states
= (1 << SS_CLOSE
),
359 .dbs
= (1 << TIPC_DB
),
360 .states
= TIPC_SS_CONN
,
363 .dbs
= (1 << XDP_DB
),
364 .states
= (1 << SS_CLOSE
),
368 static int do_default
= 1;
369 static struct filter current_filter
;
371 static void filter_db_set(struct filter
*f
, int db
, bool enable
)
374 f
->states
|= default_dbs
[db
].states
;
377 f
->dbs
&= ~(1 << db
);
382 static int filter_db_parse(struct filter
*f
, const char *s
)
388 #define ENTRY(name, ...) { #name, { __VA_ARGS__, MAX_DB } }
389 ENTRY(all
, UDP_DB
, DCCP_DB
, TCP_DB
, MPTCP_DB
, RAW_DB
,
390 UNIX_ST_DB
, UNIX_DG_DB
, UNIX_SQ_DB
,
391 PACKET_R_DB
, PACKET_DG_DB
, NETLINK_DB
,
392 SCTP_DB
, VSOCK_ST_DB
, VSOCK_DG_DB
, XDP_DB
),
393 ENTRY(inet
, UDP_DB
, DCCP_DB
, TCP_DB
, MPTCP_DB
, SCTP_DB
, RAW_DB
),
395 ENTRY(dccp
, DCCP_DB
),
397 ENTRY(mptcp
, MPTCP_DB
),
398 ENTRY(sctp
, SCTP_DB
),
400 ENTRY(unix
, UNIX_ST_DB
, UNIX_DG_DB
, UNIX_SQ_DB
),
401 ENTRY(unix_stream
, UNIX_ST_DB
),
402 ENTRY(u_str
, UNIX_ST_DB
), /* alias for unix_stream */
403 ENTRY(unix_dgram
, UNIX_DG_DB
),
404 ENTRY(u_dgr
, UNIX_DG_DB
), /* alias for unix_dgram */
405 ENTRY(unix_seqpacket
, UNIX_SQ_DB
),
406 ENTRY(u_seq
, UNIX_SQ_DB
), /* alias for unix_seqpacket */
407 ENTRY(packet
, PACKET_R_DB
, PACKET_DG_DB
),
408 ENTRY(packet_raw
, PACKET_R_DB
),
409 ENTRY(p_raw
, PACKET_R_DB
), /* alias for packet_raw */
410 ENTRY(packet_dgram
, PACKET_DG_DB
),
411 ENTRY(p_dgr
, PACKET_DG_DB
), /* alias for packet_dgram */
412 ENTRY(netlink
, NETLINK_DB
),
413 ENTRY(vsock
, VSOCK_ST_DB
, VSOCK_DG_DB
),
414 ENTRY(vsock_stream
, VSOCK_ST_DB
),
415 ENTRY(v_str
, VSOCK_ST_DB
), /* alias for vsock_stream */
416 ENTRY(vsock_dgram
, VSOCK_DG_DB
),
417 ENTRY(v_dgr
, VSOCK_DG_DB
), /* alias for vsock_dgram */
429 for (i
= 0; i
< ARRAY_SIZE(db_name_tbl
); i
++) {
430 if (strcmp(s
, db_name_tbl
[i
].name
))
432 for (dbp
= db_name_tbl
[i
].dbs
; *dbp
!= MAX_DB
; dbp
++)
433 filter_db_set(f
, *dbp
, enable
);
439 static void filter_af_set(struct filter
*f
, int af
)
441 f
->states
|= default_afs
[af
].states
;
442 f
->families
|= FAMILY_MASK(af
);
444 preferred_family
= af
;
447 static int filter_af_get(struct filter
*f
, int af
)
449 return !!(f
->families
& FAMILY_MASK(af
));
452 static void filter_states_set(struct filter
*f
, int states
)
458 static void filter_merge_defaults(struct filter
*f
)
463 for (db
= 0; db
< MAX_DB
; db
++) {
464 if (!(f
->dbs
& (1 << db
)))
467 if (!(default_dbs
[db
].families
& f
->families
))
468 f
->families
|= default_dbs
[db
].families
;
470 for (af
= 0; af
< AF_MAX
; af
++) {
471 if (!(f
->families
& FAMILY_MASK(af
)))
474 if (!(default_afs
[af
].dbs
& f
->dbs
))
475 f
->dbs
|= default_afs
[af
].dbs
;
479 static FILE *generic_proc_open(const char *env
, const char *name
)
481 const char *p
= getenv(env
);
485 p
= getenv("PROC_ROOT") ? : "/proc";
486 snprintf(store
, sizeof(store
)-1, "%s/%s", p
, name
);
490 return fopen(p
, "r");
492 #define net_tcp_open() generic_proc_open("PROC_NET_TCP", "net/tcp")
493 #define net_tcp6_open() generic_proc_open("PROC_NET_TCP6", "net/tcp6")
494 #define net_udp_open() generic_proc_open("PROC_NET_UDP", "net/udp")
495 #define net_udp6_open() generic_proc_open("PROC_NET_UDP6", "net/udp6")
496 #define net_raw_open() generic_proc_open("PROC_NET_RAW", "net/raw")
497 #define net_raw6_open() generic_proc_open("PROC_NET_RAW6", "net/raw6")
498 #define net_unix_open() generic_proc_open("PROC_NET_UNIX", "net/unix")
499 #define net_packet_open() generic_proc_open("PROC_NET_PACKET", \
501 #define net_netlink_open() generic_proc_open("PROC_NET_NETLINK", \
503 #define net_sockstat_open() generic_proc_open("PROC_NET_SOCKSTAT", \
505 #define net_sockstat6_open() generic_proc_open("PROC_NET_SOCKSTAT6", \
507 #define net_snmp_open() generic_proc_open("PROC_NET_SNMP", "net/snmp")
508 #define ephemeral_ports_open() generic_proc_open("PROC_IP_LOCAL_PORT_RANGE", \
509 "sys/net/ipv4/ip_local_port_range")
512 struct user_ent
*next
;
521 #define USER_ENT_HASH_SIZE 256
522 static struct user_ent
*user_ent_hash
[USER_ENT_HASH_SIZE
];
524 static int user_ent_hashfn(unsigned int ino
)
526 int val
= (ino
>> 24) ^ (ino
>> 16) ^ (ino
>> 8) ^ ino
;
528 return val
& (USER_ENT_HASH_SIZE
- 1);
531 static void user_ent_add(unsigned int ino
, char *process
,
536 struct user_ent
*p
, **pp
;
538 p
= malloc(sizeof(struct user_ent
));
540 fprintf(stderr
, "ss: failed to malloc buffer\n");
547 p
->process
= strdup(process
);
548 p
->process_ctx
= strdup(proc_ctx
);
549 p
->socket_ctx
= strdup(sock_ctx
);
551 pp
= &user_ent_hash
[user_ent_hashfn(ino
)];
556 static void user_ent_destroy(void)
558 struct user_ent
*p
, *p_next
;
561 while (cnt
!= USER_ENT_HASH_SIZE
) {
562 p
= user_ent_hash
[cnt
];
565 free(p
->process_ctx
);
575 static void user_ent_hash_build(void)
577 const char *root
= getenv("PROC_ROOT") ? : "/proc/";
584 const char *no_ctx
= "unavailable";
585 static int user_ent_hash_build_init
;
587 /* If show_users & show_proc_ctx set only do this once */
588 if (user_ent_hash_build_init
!= 0)
591 user_ent_hash_build_init
= 1;
593 strlcpy(name
, root
, sizeof(name
));
595 if (strlen(name
) == 0 || name
[strlen(name
)-1] != '/')
598 nameoff
= strlen(name
);
604 while ((d
= readdir(dir
)) != NULL
) {
612 if (sscanf(d
->d_name
, "%d%c", &pid
, &crap
) != 1)
615 if (getpidcon(pid
, &pid_context
) != 0)
616 pid_context
= strdup(no_ctx
);
618 snprintf(name
+ nameoff
, sizeof(name
) - nameoff
, "%d/fd/", pid
);
620 if ((dir1
= opendir(name
)) == NULL
) {
628 while ((d1
= readdir(dir1
)) != NULL
) {
629 const char *pattern
= "socket:[";
636 if (sscanf(d1
->d_name
, "%d%c", &fd
, &crap
) != 1)
639 snprintf(name
+pos
, sizeof(name
) - pos
, "%d", fd
);
641 link_len
= readlink(name
, lnk
, sizeof(lnk
)-1);
644 lnk
[link_len
] = '\0';
646 if (strncmp(lnk
, pattern
, strlen(pattern
)))
649 sscanf(lnk
, "socket:[%u]", &ino
);
651 snprintf(tmp
, sizeof(tmp
), "%s/%d/fd/%s",
652 root
, pid
, d1
->d_name
);
654 if (getfilecon(tmp
, &sock_context
) <= 0)
655 sock_context
= strdup(no_ctx
);
660 snprintf(tmp
, sizeof(tmp
), "%s/%d/stat",
662 if ((fp
= fopen(tmp
, "r")) != NULL
) {
663 if (fscanf(fp
, "%*d (%[^)])", p
) < 1)
668 user_ent_add(ino
, p
, pid
, fd
,
669 pid_context
, sock_context
);
684 #define ENTRY_BUF_SIZE 512
685 static int find_entry(unsigned int ino
, char **buf
, int type
)
691 int len
, new_buf_len
;
698 p
= user_ent_hash
[user_ent_hashfn(ino
)];
705 ptr
= *buf
+ buf_used
;
708 len
= snprintf(ptr
, buf_len
- buf_used
,
709 "(\"%s\",pid=%d,fd=%d),",
710 p
->process
, p
->pid
, p
->fd
);
713 len
= snprintf(ptr
, buf_len
- buf_used
,
714 "(\"%s\",pid=%d,proc_ctx=%s,fd=%d),",
716 p
->process_ctx
, p
->fd
);
719 len
= snprintf(ptr
, buf_len
- buf_used
,
720 "(\"%s\",pid=%d,proc_ctx=%s,fd=%d,sock_ctx=%s),",
722 p
->process_ctx
, p
->fd
,
726 fprintf(stderr
, "ss: invalid type: %d\n", type
);
730 if (len
< 0 || len
>= buf_len
- buf_used
) {
731 new_buf_len
= buf_len
+ ENTRY_BUF_SIZE
;
732 new_buf
= realloc(*buf
, new_buf_len
);
734 fprintf(stderr
, "ss: failed to malloc buffer\n");
738 buf_len
= new_buf_len
;
750 ptr
= *buf
+ buf_used
;
756 static unsigned long long cookie_sk_get(const uint32_t *cookie
)
758 return (((unsigned long long)cookie
[1] << 31) << 1) | cookie
[0];
761 static const char *sctp_sstate_name
[] = {
762 [SCTP_STATE_CLOSED
] = "CLOSED",
763 [SCTP_STATE_COOKIE_WAIT
] = "COOKIE_WAIT",
764 [SCTP_STATE_COOKIE_ECHOED
] = "COOKIE_ECHOED",
765 [SCTP_STATE_ESTABLISHED
] = "ESTAB",
766 [SCTP_STATE_SHUTDOWN_PENDING
] = "SHUTDOWN_PENDING",
767 [SCTP_STATE_SHUTDOWN_SENT
] = "SHUTDOWN_SENT",
768 [SCTP_STATE_SHUTDOWN_RECEIVED
] = "SHUTDOWN_RECEIVED",
769 [SCTP_STATE_SHUTDOWN_ACK_SENT
] = "ACK_SENT",
772 static const char * const stype_nameg
[] = {
774 [SOCK_STREAM
] = "STREAM",
775 [SOCK_DGRAM
] = "DGRAM",
777 [SOCK_SEQPACKET
] = "SEQPACKET",
781 struct sockstat
*next
;
795 unsigned long long sk
;
803 unsigned int ce_state
;
813 unsigned int timeout
;
816 double rto
, ato
, rtt
, rttvar
;
817 int qack
, ssthresh
, backoff
;
826 unsigned int lastsnd
;
827 unsigned int lastrcv
;
828 unsigned int lastack
;
830 double pacing_rate_max
;
831 double delivery_rate
;
832 unsigned long long bytes_acked
;
833 unsigned long long bytes_received
;
834 unsigned int segs_out
;
835 unsigned int segs_in
;
836 unsigned int data_segs_out
;
837 unsigned int data_segs_in
;
838 unsigned int unacked
;
839 unsigned int retrans
;
840 unsigned int retrans_total
;
843 unsigned int fackets
;
844 unsigned int reordering
;
845 unsigned int not_sent
;
846 unsigned int delivered
;
847 unsigned int delivered_ce
;
848 unsigned int dsack_dups
;
849 unsigned int reord_seen
;
853 unsigned int rcv_ssthresh
;
854 unsigned long long busy_time
;
855 unsigned long long rwnd_limited
;
856 unsigned long long sndbuf_limited
;
857 unsigned long long bytes_sent
;
858 unsigned long long bytes_retrans
;
862 bool has_ecnseen_opt
;
863 bool has_fastopen_opt
;
866 struct dctcpstat
*dctcp
;
867 struct tcp_bbr_info
*bbr_info
;
870 /* SCTP assocs share the same inode number with their parent endpoint. So if we
871 * have seen the inode number before, it must be an assoc instead of the next
873 static bool is_sctp_assoc(struct sockstat
*s
, const char *sock_name
)
875 if (strcmp(sock_name
, "sctp"))
877 if (!sctp_ino
|| sctp_ino
!= s
->ino
)
882 static const char *unix_netid_name(int type
)
895 static const char *proto_name(int protocol
)
917 static const char *vsock_netid_name(int type
)
929 static const char *tipc_netid_name(int type
)
945 /* Allocate and initialize a new buffer chunk */
946 static struct buf_chunk
*buf_chunk_new(void)
948 struct buf_chunk
*new = malloc(BUF_CHUNK
);
955 /* This is also the last block */
958 /* Next token will be stored at the beginning of chunk data area, and
959 * its initial length is zero.
961 buffer
.cur
= (struct buf_token
*)new->data
;
964 new->end
= buffer
.cur
->data
;
971 /* Return available tail room in given chunk */
972 static int buf_chunk_avail(struct buf_chunk
*chunk
)
974 return BUF_CHUNK
- offsetof(struct buf_chunk
, data
) -
975 (chunk
->end
- chunk
->data
);
978 /* Update end pointer and token length, link new chunk if we hit the end of the
979 * current one. Return -EAGAIN if we got a new chunk, caller has to print again.
981 static int buf_update(int len
)
983 struct buf_chunk
*chunk
= buffer
.tail
;
984 struct buf_token
*t
= buffer
.cur
;
986 /* Claim success if new content fits in the current chunk, and anyway
987 * if this is the first token in the chunk: in the latter case,
988 * allocating a new chunk won't help, so we'll just cut the output.
990 if ((len
< buf_chunk_avail(chunk
) && len
!= -1 /* glibc < 2.0.6 */) ||
991 t
== (struct buf_token
*)chunk
->data
) {
992 len
= min(len
, buf_chunk_avail(chunk
));
994 /* Total field length can't exceed 2^16 bytes, cut as needed */
995 len
= min(len
, USHRT_MAX
- t
->len
);
1002 /* Content truncated, time to allocate more */
1003 chunk
->next
= buf_chunk_new();
1005 /* Copy current token over to new chunk, including length descriptor */
1006 memcpy(chunk
->next
->data
, t
, sizeof(t
->len
) + t
->len
);
1007 chunk
->next
->end
+= t
->len
;
1009 /* Discard partially written field in old chunk */
1010 chunk
->end
-= t
->len
+ sizeof(t
->len
);
1015 /* Append content to buffer as part of the current field */
1016 __attribute__((format(printf
, 1, 2)))
1017 static void out(const char *fmt
, ...)
1019 struct column
*f
= current_field
;
1028 buffer
.head
= buf_chunk_new();
1030 again
: /* Append to buffer: if we have a new chunk, print again */
1032 pos
= buffer
.cur
->data
+ buffer
.cur
->len
;
1033 va_start(args
, fmt
);
1035 /* Limit to tail room. If we hit the limit, buf_update() will tell us */
1036 len
= vsnprintf(pos
, buf_chunk_avail(buffer
.tail
), fmt
, args
);
1039 if (buf_update(len
))
1043 static int print_left_spacing(struct column
*f
, int stored
, int printed
)
1047 if (!f
->width
|| f
->align
== ALIGN_LEFT
)
1050 s
= f
->width
- stored
- printed
;
1051 if (f
->align
== ALIGN_CENTER
)
1052 /* If count of total spacing is odd, shift right by one */
1056 return printf("%*c", s
, ' ');
1061 static void print_right_spacing(struct column
*f
, int printed
)
1065 if (!f
->width
|| f
->align
== ALIGN_RIGHT
)
1068 s
= f
->width
- printed
;
1069 if (f
->align
== ALIGN_CENTER
)
1073 printf("%*c", s
, ' ');
1076 /* Done with field: update buffer pointer, start new token after current one */
1077 static void field_flush(struct column
*f
)
1079 struct buf_chunk
*chunk
;
1085 chunk
= buffer
.tail
;
1086 pad
= buffer
.cur
->len
% 2;
1088 if (buffer
.cur
->len
> f
->max_len
)
1089 f
->max_len
= buffer
.cur
->len
;
1091 /* We need a new chunk if we can't store the next length descriptor.
1092 * Mind the gap between end of previous token and next aligned position
1093 * for length descriptor.
1095 if (buf_chunk_avail(chunk
) - pad
< sizeof(buffer
.cur
->len
)) {
1097 chunk
->next
= buf_chunk_new();
1101 buffer
.cur
= (struct buf_token
*)(buffer
.cur
->data
+
1102 LEN_ALIGN(buffer
.cur
->len
));
1103 buffer
.cur
->len
= 0;
1104 buffer
.tail
->end
= buffer
.cur
->data
;
1107 static int field_is_last(struct column
*f
)
1109 return f
- columns
== COL_MAX
- 1;
1112 /* Get the next available token in the buffer starting from the current token */
1113 static struct buf_token
*buf_token_next(struct buf_token
*cur
)
1115 struct buf_chunk
*chunk
= buffer
.tail
;
1117 /* If we reached the end of chunk contents, get token from next chunk */
1118 if (cur
->data
+ LEN_ALIGN(cur
->len
) == chunk
->end
) {
1119 buffer
.tail
= chunk
= chunk
->next
;
1120 return chunk
? (struct buf_token
*)chunk
->data
: NULL
;
1123 return (struct buf_token
*)(cur
->data
+ LEN_ALIGN(cur
->len
));
1126 /* Free up all allocated buffer chunks */
1127 static void buf_free_all(void)
1129 struct buf_chunk
*tmp
;
1131 for (buffer
.tail
= buffer
.head
; buffer
.tail
; ) {
1133 buffer
.tail
= buffer
.tail
->next
;
1140 /* Get current screen width, returns -1 if TIOCGWINSZ fails */
1141 static int render_screen_width(void)
1145 if (isatty(STDOUT_FILENO
)) {
1148 if (ioctl(STDOUT_FILENO
, TIOCGWINSZ
, &w
) != -1) {
1157 /* Calculate column width from contents length. If columns don't fit on one
1158 * line, break them into the least possible amount of lines and keep them
1159 * aligned across lines. Available screen space is equally spread between fields
1160 * as additional spacing.
1162 static void render_calc_width(void)
1164 int screen_width
, first
, len
= 0, linecols
= 0;
1165 struct column
*c
, *eol
= columns
- 1;
1166 bool compact_output
= false;
1168 screen_width
= render_screen_width();
1169 if (screen_width
== -1) {
1170 screen_width
= INT_MAX
;
1171 compact_output
= true;
1174 /* First pass: set width for each column to measured content length */
1175 for (first
= 1, c
= columns
; c
- columns
< COL_MAX
; c
++) {
1179 if (!first
&& c
->max_len
)
1180 c
->width
= c
->max_len
+ strlen(c
->ldelim
);
1182 c
->width
= c
->max_len
;
1184 /* But don't exceed screen size. If we exceed the screen size
1185 * for even a single field, it will just start on a line of its
1186 * own and then naturally wrap.
1188 c
->width
= min(c
->width
, screen_width
);
1194 if (compact_output
) {
1195 /* Compact output, skip extending columns. */
1199 /* Second pass: find out newlines and distribute available spacing */
1200 for (c
= columns
; c
- columns
< COL_MAX
; c
++) {
1201 int pad
, spacing
, rem
, last
;
1210 for (last
= 1, tmp
= c
+ 1; tmp
- columns
< COL_MAX
; tmp
++) {
1217 if (!last
&& len
< screen_width
) {
1218 /* Columns fit on screen so far, nothing to do yet */
1222 if (len
== screen_width
) {
1223 /* Exact fit, just start with new line */
1227 if (len
> screen_width
) {
1228 /* Screen width exceeded: go back one column */
1234 /* Distribute remaining space to columns on this line */
1235 pad
= screen_width
- len
;
1236 spacing
= pad
/ linecols
;
1237 rem
= pad
% linecols
;
1238 for (tmp
= c
; tmp
> eol
; tmp
--) {
1242 tmp
->width
+= spacing
;
1250 /* Line break: reset line counters, mark end-of-line */
1257 /* Render buffered output with spacing and delimiters, then free up buffers */
1258 static void render(void)
1260 struct buf_token
*token
;
1261 int printed
, line_started
= 0;
1267 token
= (struct buf_token
*)buffer
.head
->data
;
1269 /* Ensure end alignment of last token, it wasn't necessarily flushed */
1270 buffer
.tail
->end
+= buffer
.cur
->len
% 2;
1272 render_calc_width();
1274 /* Rewind and replay */
1275 buffer
.tail
= buffer
.head
;
1282 /* Print left delimiter only if we already started a line */
1284 printed
= printf("%s", f
->ldelim
);
1288 /* Print field content from token data with spacing */
1289 printed
+= print_left_spacing(f
, token
->len
, printed
);
1290 printed
+= fwrite(token
->data
, 1, token
->len
, stdout
);
1291 print_right_spacing(f
, printed
);
1293 /* Go to next non-empty field, deal with end-of-line */
1295 if (field_is_last(f
)) {
1302 } while (f
->disabled
);
1304 token
= buf_token_next(token
);
1306 /* Deal with final end-of-line when the last non-empty field printed
1307 * is not the last field.
1313 current_field
= columns
;
1316 /* Move to next field, and render buffer if we reached the maximum number of
1317 * chunks, at the last field in a line.
1319 static void field_next(void)
1321 if (field_is_last(current_field
) && buffer
.chunks
>= BUF_CHUNKS_MAX
) {
1326 field_flush(current_field
);
1327 if (field_is_last(current_field
))
1328 current_field
= columns
;
1333 /* Walk through fields and flush them until we reach the desired one */
1334 static void field_set(enum col_id id
)
1336 while (id
!= current_field
- columns
)
1340 /* Print header for all non-empty columns */
1341 static void print_header(void)
1343 while (!field_is_last(current_field
)) {
1344 if (!current_field
->disabled
)
1345 out("%s", current_field
->header
);
1350 static void sock_state_print(struct sockstat
*s
)
1352 const char *sock_name
;
1353 static const char * const sstate_name
[] = {
1355 [SS_ESTABLISHED
] = "ESTAB",
1356 [SS_SYN_SENT
] = "SYN-SENT",
1357 [SS_SYN_RECV
] = "SYN-RECV",
1358 [SS_FIN_WAIT1
] = "FIN-WAIT-1",
1359 [SS_FIN_WAIT2
] = "FIN-WAIT-2",
1360 [SS_TIME_WAIT
] = "TIME-WAIT",
1361 [SS_CLOSE
] = "UNCONN",
1362 [SS_CLOSE_WAIT
] = "CLOSE-WAIT",
1363 [SS_LAST_ACK
] = "LAST-ACK",
1364 [SS_LISTEN
] = "LISTEN",
1365 [SS_CLOSING
] = "CLOSING",
1368 switch (s
->local
.family
) {
1370 sock_name
= unix_netid_name(s
->type
);
1374 sock_name
= proto_name(s
->type
);
1377 sock_name
= s
->type
== SOCK_RAW
? "p_raw" : "p_dgr";
1383 sock_name
= tipc_netid_name(s
->type
);
1386 sock_name
= vsock_netid_name(s
->type
);
1392 sock_name
= "unknown";
1395 if (is_sctp_assoc(s
, sock_name
)) {
1396 field_set(COL_STATE
); /* Empty Netid field */
1397 out("`- %s", sctp_sstate_name
[s
->state
]);
1399 field_set(COL_NETID
);
1400 out("%s", sock_name
);
1401 field_set(COL_STATE
);
1402 out("%s", sstate_name
[s
->state
]);
1405 field_set(COL_RECVQ
);
1407 field_set(COL_SENDQ
);
1409 field_set(COL_ADDR
);
1412 static void sock_details_print(struct sockstat
*s
)
1415 out(" uid:%u", s
->uid
);
1417 out(" ino:%u", s
->ino
);
1418 out(" sk:%llx", s
->sk
);
1421 out(" fwmark:0x%x", s
->mark
);
1424 out(" cgroup:%s", cg_id_to_path(s
->cgroup_id
));
1427 static void sock_addr_print(const char *addr
, char *delim
, const char *port
,
1431 out("%s" "%%" "%s%s", addr
, ifname
, delim
);
1433 out("%s%s", addr
, delim
);
1440 static const char *print_ms_timer(unsigned int timeout
)
1442 static char buf
[64];
1443 int secs
, msecs
, minutes
;
1445 secs
= timeout
/1000;
1448 msecs
= timeout
%1000;
1452 snprintf(buf
, sizeof(buf
)-16, "%dmin", minutes
);
1459 sprintf(buf
+strlen(buf
), "%d%s", secs
, msecs
? "." : "sec");
1462 sprintf(buf
+strlen(buf
), "%03dms", msecs
);
1467 struct scache
*next
;
1473 static struct scache
*rlist
;
1475 static void init_service_resolver(void)
1478 FILE *fp
= popen("/usr/sbin/rpcinfo -p 2>/dev/null", "r");
1483 if (!fgets(buf
, sizeof(buf
), fp
)) {
1487 while (fgets(buf
, sizeof(buf
), fp
) != NULL
) {
1488 unsigned int progn
, port
;
1489 char proto
[128], prog
[128] = "rpc.";
1492 if (sscanf(buf
, "%u %*d %s %u %s",
1493 &progn
, proto
, &port
, prog
+4) != 4)
1496 if (!(c
= malloc(sizeof(*c
))))
1500 c
->name
= strdup(prog
);
1501 if (strcmp(proto
, TCP_PROTO
) == 0)
1502 c
->proto
= TCP_PROTO
;
1503 else if (strcmp(proto
, UDP_PROTO
) == 0)
1504 c
->proto
= UDP_PROTO
;
1505 else if (strcmp(proto
, SCTP_PROTO
) == 0)
1506 c
->proto
= SCTP_PROTO
;
1515 /* Even do not try default linux ephemeral port ranges:
1516 * default /etc/services contains so much of useless crap
1517 * wouldbe "allocated" to this area that resolution
1518 * is really harmful. I shrug each time when seeing
1519 * "socks" or "cfinger" in dumps.
1521 static int is_ephemeral(int port
)
1523 static int min
= 0, max
;
1526 FILE *f
= ephemeral_ports_open();
1528 if (!f
|| fscanf(f
, "%d %d", &min
, &max
) < 2) {
1535 return port
>= min
&& port
<= max
;
1539 static const char *__resolve_service(int port
)
1543 for (c
= rlist
; c
; c
= c
->next
) {
1544 if (c
->port
== port
&& c
->proto
== dg_proto
)
1548 if (!is_ephemeral(port
)) {
1549 static int notfirst
;
1556 se
= getservbyport(htons(port
), dg_proto
);
1564 #define SCACHE_BUCKETS 1024
1565 static struct scache
*cache_htab
[SCACHE_BUCKETS
];
1567 static const char *resolve_service(int port
)
1569 static char buf
[128];
1583 if (dg_proto
== RAW_PROTO
)
1584 return inet_proto_n2a(port
, buf
, sizeof(buf
));
1587 hash
= (port
^(((unsigned long)dg_proto
)>>2)) % SCACHE_BUCKETS
;
1589 for (c
= cache_htab
[hash
]; c
; c
= c
->next
) {
1590 if (c
->port
== port
&& c
->proto
== dg_proto
)
1594 c
= malloc(sizeof(*c
));
1597 res
= __resolve_service(port
);
1599 c
->name
= res
? strdup(res
) : NULL
;
1600 c
->proto
= dg_proto
;
1601 c
->next
= cache_htab
[hash
];
1602 cache_htab
[hash
] = c
;
1609 sprintf(buf
, "%u", port
);
1613 static void inet_addr_print(const inet_prefix
*a
, int port
,
1614 unsigned int ifindex
, bool v6only
)
1617 const char *ap
= buf
;
1618 const char *ifname
= NULL
;
1620 if (a
->family
== AF_INET
) {
1621 ap
= format_host(AF_INET
, 4, a
->data
);
1624 !memcmp(a
->data
, &in6addr_any
, sizeof(in6addr_any
))) {
1628 ap
= format_host(a
->family
, 16, a
->data
);
1630 /* Numeric IPv6 addresses should be bracketed */
1631 if (strchr(ap
, ':')) {
1632 snprintf(buf
, sizeof(buf
),
1640 ifname
= ll_index_to_name(ifindex
);
1642 sock_addr_print(ap
, ":", resolve_service(port
), ifname
);
1652 struct aafilter
*next
;
1655 static int inet2_addr_match(const inet_prefix
*a
, const inet_prefix
*p
,
1658 if (!inet_addr_match(a
, p
, plen
))
1661 /* Cursed "v4 mapped" addresses: v4 mapped socket matches
1662 * pure IPv4 rule, but v4-mapped rule selects only v4-mapped
1664 if (p
->family
== AF_INET
&& a
->family
== AF_INET6
) {
1665 if (a
->data
[0] == 0 && a
->data
[1] == 0 &&
1666 a
->data
[2] == htonl(0xffff)) {
1667 inet_prefix tmp
= *a
;
1669 tmp
.data
[0] = a
->data
[3];
1670 return inet_addr_match(&tmp
, p
, plen
);
1676 static int unix_match(const inet_prefix
*a
, const inet_prefix
*p
)
1678 char *addr
, *pattern
;
1680 memcpy(&addr
, a
->data
, sizeof(addr
));
1681 memcpy(&pattern
, p
->data
, sizeof(pattern
));
1682 if (pattern
== NULL
)
1686 return !fnmatch(pattern
, addr
, FNM_CASEFOLD
);
1689 static int run_ssfilter(struct ssfilter
*f
, struct sockstat
*s
)
1694 if (s
->local
.family
== AF_UNIX
) {
1697 memcpy(&p
, s
->local
.data
, sizeof(p
));
1698 return p
== NULL
|| (p
[0] == '@' && strlen(p
) == 6 &&
1699 strspn(p
+1, "0123456789abcdef") == 5);
1701 if (s
->local
.family
== AF_PACKET
)
1702 return s
->lport
== 0 && s
->local
.data
[0] == 0;
1703 if (s
->local
.family
== AF_NETLINK
)
1704 return s
->lport
< 0;
1705 if (s
->local
.family
== AF_VSOCK
)
1706 return s
->lport
> 1023;
1708 return is_ephemeral(s
->lport
);
1712 struct aafilter
*a
= (void *)f
->pred
;
1714 if (a
->addr
.family
== AF_UNIX
)
1715 return unix_match(&s
->remote
, &a
->addr
);
1716 if (a
->port
!= -1 && a
->port
!= s
->rport
)
1718 if (a
->addr
.bitlen
) {
1720 if (!inet2_addr_match(&s
->remote
, &a
->addr
, a
->addr
.bitlen
))
1722 } while ((a
= a
->next
) != NULL
);
1729 struct aafilter
*a
= (void *)f
->pred
;
1731 if (a
->addr
.family
== AF_UNIX
)
1732 return unix_match(&s
->local
, &a
->addr
);
1733 if (a
->port
!= -1 && a
->port
!= s
->lport
)
1735 if (a
->addr
.bitlen
) {
1737 if (!inet2_addr_match(&s
->local
, &a
->addr
, a
->addr
.bitlen
))
1739 } while ((a
= a
->next
) != NULL
);
1746 struct aafilter
*a
= (void *)f
->pred
;
1748 return s
->rport
>= a
->port
;
1752 struct aafilter
*a
= (void *)f
->pred
;
1754 return s
->rport
<= a
->port
;
1758 struct aafilter
*a
= (void *)f
->pred
;
1760 return s
->lport
>= a
->port
;
1764 struct aafilter
*a
= (void *)f
->pred
;
1766 return s
->lport
<= a
->port
;
1770 struct aafilter
*a
= (void *)f
->pred
;
1772 return s
->iface
== a
->iface
;
1776 struct aafilter
*a
= (void *)f
->pred
;
1778 return (s
->mark
& a
->mask
) == a
->mark
;
1780 case SSF_CGROUPCOND
:
1782 struct aafilter
*a
= (void *)f
->pred
;
1784 return s
->cgroup_id
== a
->cgroup_id
;
1786 /* Yup. It is recursion. Sorry. */
1788 return run_ssfilter(f
->pred
, s
) && run_ssfilter(f
->post
, s
);
1790 return run_ssfilter(f
->pred
, s
) || run_ssfilter(f
->post
, s
);
1792 return !run_ssfilter(f
->pred
, s
);
1798 /* Relocate external jumps by reloc. */
1799 static void ssfilter_patch(char *a
, int len
, int reloc
)
1802 struct inet_diag_bc_op
*op
= (struct inet_diag_bc_op
*)a
;
1804 if (op
->no
== len
+4)
1813 static int ssfilter_bytecompile(struct ssfilter
*f
, char **bytecode
)
1818 if (!(*bytecode
= malloc(4))) abort();
1819 ((struct inet_diag_bc_op
*)*bytecode
)[0] = (struct inet_diag_bc_op
){ INET_DIAG_BC_AUTO
, 4, 8 };
1825 struct aafilter
*a
= (void *)f
->pred
;
1828 int code
= (f
->type
== SSF_DCOND
? INET_DIAG_BC_D_COND
: INET_DIAG_BC_S_COND
);
1831 for (b
= a
; b
; b
= b
->next
) {
1832 len
+= 4 + sizeof(struct inet_diag_hostcond
);
1833 if (a
->addr
.family
== AF_INET6
)
1840 if (!(ptr
= malloc(len
))) abort();
1842 for (b
= a
; b
; b
= b
->next
) {
1843 struct inet_diag_bc_op
*op
= (struct inet_diag_bc_op
*)ptr
;
1844 int alen
= (a
->addr
.family
== AF_INET6
? 16 : 4);
1845 int oplen
= alen
+ 4 + sizeof(struct inet_diag_hostcond
);
1846 struct inet_diag_hostcond
*cond
= (struct inet_diag_hostcond
*)(ptr
+4);
1848 *op
= (struct inet_diag_bc_op
){ code
, oplen
, oplen
+4 };
1849 cond
->family
= a
->addr
.family
;
1850 cond
->port
= a
->port
;
1851 cond
->prefix_len
= a
->addr
.bitlen
;
1852 memcpy(cond
->addr
, a
->addr
.data
, alen
);
1855 op
= (struct inet_diag_bc_op
*)ptr
;
1856 *op
= (struct inet_diag_bc_op
){ INET_DIAG_BC_JMP
, 4, len
- (ptr
-*bytecode
)};
1860 return ptr
- *bytecode
;
1864 struct aafilter
*x
= (void *)f
->pred
;
1866 if (!(*bytecode
= malloc(8))) abort();
1867 ((struct inet_diag_bc_op
*)*bytecode
)[0] = (struct inet_diag_bc_op
){ INET_DIAG_BC_D_GE
, 8, 12 };
1868 ((struct inet_diag_bc_op
*)*bytecode
)[1] = (struct inet_diag_bc_op
){ 0, 0, x
->port
};
1873 struct aafilter
*x
= (void *)f
->pred
;
1875 if (!(*bytecode
= malloc(8))) abort();
1876 ((struct inet_diag_bc_op
*)*bytecode
)[0] = (struct inet_diag_bc_op
){ INET_DIAG_BC_D_LE
, 8, 12 };
1877 ((struct inet_diag_bc_op
*)*bytecode
)[1] = (struct inet_diag_bc_op
){ 0, 0, x
->port
};
1882 struct aafilter
*x
= (void *)f
->pred
;
1884 if (!(*bytecode
= malloc(8))) abort();
1885 ((struct inet_diag_bc_op
*)*bytecode
)[0] = (struct inet_diag_bc_op
){ INET_DIAG_BC_S_GE
, 8, 12 };
1886 ((struct inet_diag_bc_op
*)*bytecode
)[1] = (struct inet_diag_bc_op
){ 0, 0, x
->port
};
1891 struct aafilter
*x
= (void *)f
->pred
;
1893 if (!(*bytecode
= malloc(8))) abort();
1894 ((struct inet_diag_bc_op
*)*bytecode
)[0] = (struct inet_diag_bc_op
){ INET_DIAG_BC_S_LE
, 8, 12 };
1895 ((struct inet_diag_bc_op
*)*bytecode
)[1] = (struct inet_diag_bc_op
){ 0, 0, x
->port
};
1901 char *a1
= NULL
, *a2
= NULL
, *a
;
1904 l1
= ssfilter_bytecompile(f
->pred
, &a1
);
1905 l2
= ssfilter_bytecompile(f
->post
, &a2
);
1911 if (!(a
= malloc(l1
+l2
))) abort();
1913 memcpy(a
+l1
, a2
, l2
);
1915 ssfilter_patch(a
, l1
, l2
);
1921 char *a1
= NULL
, *a2
= NULL
, *a
;
1924 l1
= ssfilter_bytecompile(f
->pred
, &a1
);
1925 l2
= ssfilter_bytecompile(f
->post
, &a2
);
1931 if (!(a
= malloc(l1
+l2
+4))) abort();
1933 memcpy(a
+l1
+4, a2
, l2
);
1935 *(struct inet_diag_bc_op
*)(a
+l1
) = (struct inet_diag_bc_op
){ INET_DIAG_BC_JMP
, 4, l2
+4 };
1941 char *a1
= NULL
, *a
;
1944 l1
= ssfilter_bytecompile(f
->pred
, &a1
);
1949 if (!(a
= malloc(l1
+4))) abort();
1952 *(struct inet_diag_bc_op
*)(a
+l1
) = (struct inet_diag_bc_op
){ INET_DIAG_BC_JMP
, 4, 8 };
1958 /* bytecompile for SSF_DEVCOND not supported yet */
1963 struct aafilter
*a
= (void *)f
->pred
;
1965 struct inet_diag_bc_op op
;
1966 struct inet_diag_markcond cond
;
1968 int inslen
= sizeof(struct instr
);
1970 if (!(*bytecode
= malloc(inslen
))) abort();
1971 ((struct instr
*)*bytecode
)[0] = (struct instr
) {
1972 { INET_DIAG_BC_MARK_COND
, inslen
, inslen
+ 4 },
1973 { a
->mark
, a
->mask
},
1978 case SSF_CGROUPCOND
:
1980 struct aafilter
*a
= (void *)f
->pred
;
1982 struct inet_diag_bc_op op
;
1984 } __attribute__((packed
));
1985 int inslen
= sizeof(struct instr
);
1987 if (!(*bytecode
= malloc(inslen
))) abort();
1988 ((struct instr
*)*bytecode
)[0] = (struct instr
) {
1989 { INET_DIAG_BC_CGROUP_COND
, inslen
, inslen
+ 4 },
2000 static int remember_he(struct aafilter
*a
, struct hostent
*he
)
2002 char **ptr
= he
->h_addr_list
;
2006 if (he
->h_addrtype
== AF_INET
)
2008 else if (he
->h_addrtype
== AF_INET6
)
2014 struct aafilter
*b
= a
;
2016 if (a
->addr
.bitlen
) {
2017 if ((b
= malloc(sizeof(*b
))) == NULL
)
2022 memcpy(b
->addr
.data
, *ptr
, len
);
2023 b
->addr
.bytelen
= len
;
2024 b
->addr
.bitlen
= len
*8;
2025 b
->addr
.family
= he
->h_addrtype
;
2032 static int get_dns_host(struct aafilter
*a
, const char *addr
, int fam
)
2034 static int notfirst
;
2043 he
= gethostbyname2(addr
, fam
== AF_UNSPEC
? AF_INET
: fam
);
2045 cnt
= remember_he(a
, he
);
2046 if (fam
== AF_UNSPEC
) {
2047 he
= gethostbyname2(addr
, AF_INET6
);
2049 cnt
+= remember_he(a
, he
);
2054 static int xll_initted
;
2056 static void xll_init(void)
2058 struct rtnl_handle rth
;
2060 if (rtnl_open(&rth
, 0) < 0)
2068 static const char *xll_index_to_name(int index
)
2072 return ll_index_to_name(index
);
2075 static int xll_name_to_index(const char *dev
)
2079 return ll_name_to_index(dev
);
2082 void *parse_devcond(char *name
)
2084 struct aafilter a
= { .iface
= 0 };
2085 struct aafilter
*res
;
2087 a
.iface
= xll_name_to_index(name
);
2092 n
= strtoul(name
, &end
, 0);
2093 if (!end
|| end
== name
|| *end
|| n
> UINT_MAX
)
2099 res
= malloc(sizeof(*res
));
2105 static void vsock_set_inet_prefix(inet_prefix
*a
, __u32 cid
)
2108 .bytelen
= sizeof(cid
),
2111 memcpy(a
->data
, &cid
, sizeof(cid
));
2114 void *parse_hostcond(char *addr
, bool is_port
)
2117 struct aafilter a
= { .port
= -1 };
2118 struct aafilter
*res
;
2119 int fam
= preferred_family
;
2120 struct filter
*f
= ¤t_filter
;
2122 if (fam
== AF_UNIX
|| strncmp(addr
, "unix:", 5) == 0) {
2125 a
.addr
.family
= AF_UNIX
;
2126 if (strncmp(addr
, "unix:", 5) == 0)
2129 a
.addr
.bitlen
= 8*strlen(p
);
2130 memcpy(a
.addr
.data
, &p
, sizeof(p
));
2135 if (fam
== AF_PACKET
|| strncmp(addr
, "link:", 5) == 0) {
2136 a
.addr
.family
= AF_PACKET
;
2138 if (strncmp(addr
, "link:", 5) == 0)
2140 port
= strchr(addr
, ':');
2143 if (port
[1] && strcmp(port
+1, "*")) {
2144 if (get_integer(&a
.port
, port
+1, 0)) {
2145 if ((a
.port
= xll_name_to_index(port
+1)) <= 0)
2150 if (addr
[0] && strcmp(addr
, "*")) {
2154 if (ll_proto_a2n(&tmp
, addr
))
2156 a
.addr
.data
[0] = ntohs(tmp
);
2162 if (fam
== AF_NETLINK
|| strncmp(addr
, "netlink:", 8) == 0) {
2163 a
.addr
.family
= AF_NETLINK
;
2165 if (strncmp(addr
, "netlink:", 8) == 0)
2167 port
= strchr(addr
, ':');
2170 if (port
[1] && strcmp(port
+1, "*")) {
2171 if (get_integer(&a
.port
, port
+1, 0)) {
2172 if (strcmp(port
+1, "kernel") == 0)
2179 if (addr
[0] && strcmp(addr
, "*")) {
2181 if (nl_proto_a2n(&a
.addr
.data
[0], addr
) == -1)
2188 if (fam
== AF_VSOCK
|| strncmp(addr
, "vsock:", 6) == 0) {
2189 __u32 cid
= ~(__u32
)0;
2191 a
.addr
.family
= AF_VSOCK
;
2192 if (strncmp(addr
, "vsock:", 6) == 0)
2198 port
= strchr(addr
, ':');
2205 if (port
&& strcmp(port
, "*") &&
2206 get_u32((__u32
*)&a
.port
, port
, 0))
2209 if (addr
[0] && strcmp(addr
, "*")) {
2211 if (get_u32(&cid
, addr
, 0))
2214 vsock_set_inet_prefix(&a
.addr
, cid
);
2219 if (fam
== AF_INET
|| !strncmp(addr
, "inet:", 5)) {
2221 if (!strncmp(addr
, "inet:", 5))
2223 } else if (fam
== AF_INET6
|| !strncmp(addr
, "inet6:", 6)) {
2225 if (!strncmp(addr
, "inet6:", 6))
2229 /* URL-like literal [] */
2230 if (addr
[0] == '[') {
2232 if ((port
= strchr(addr
, ']')) == NULL
)
2235 } else if (addr
[0] == '*') {
2238 port
= strrchr(strchr(addr
, '/') ? : addr
, ':');
2244 if (port
&& *port
) {
2248 if (*port
&& *port
!= '*') {
2249 if (get_integer(&a
.port
, port
, 0)) {
2250 struct servent
*se1
= NULL
;
2251 struct servent
*se2
= NULL
;
2253 if (current_filter
.dbs
&(1<<UDP_DB
))
2254 se1
= getservbyname(port
, UDP_PROTO
);
2255 if (current_filter
.dbs
&(1<<TCP_DB
))
2256 se2
= getservbyname(port
, TCP_PROTO
);
2257 if (se1
&& se2
&& se1
->s_port
!= se2
->s_port
) {
2258 fprintf(stderr
, "Error: ambiguous port \"%s\".\n", port
);
2264 a
.port
= ntohs(se1
->s_port
);
2268 for (s
= rlist
; s
; s
= s
->next
) {
2269 if ((s
->proto
== UDP_PROTO
&&
2270 (current_filter
.dbs
&(1<<UDP_DB
))) ||
2271 (s
->proto
== TCP_PROTO
&&
2272 (current_filter
.dbs
&(1<<TCP_DB
)))) {
2273 if (s
->name
&& strcmp(s
->name
, port
) == 0) {
2274 if (a
.port
> 0 && a
.port
!= s
->port
) {
2275 fprintf(stderr
, "Error: ambiguous port \"%s\".\n", port
);
2283 fprintf(stderr
, "Error: \"%s\" does not look like a port.\n", port
);
2290 if (!is_port
&& *addr
&& *addr
!= '*') {
2291 if (get_prefix_1(&a
.addr
, addr
, fam
)) {
2292 if (get_dns_host(&a
, addr
, fam
)) {
2293 fprintf(stderr
, "Error: an inet prefix is expected rather than \"%s\".\n", addr
);
2300 if (fam
!= AF_UNSPEC
) {
2301 int states
= f
->states
;
2303 filter_af_set(f
, fam
);
2304 filter_states_set(f
, states
);
2307 res
= malloc(sizeof(*res
));
2309 memcpy(res
, &a
, sizeof(a
));
2313 void *parse_markmask(const char *markmask
)
2315 struct aafilter a
, *res
;
2317 if (strchr(markmask
, '/')) {
2318 if (sscanf(markmask
, "%i/%i", &a
.mark
, &a
.mask
) != 2)
2321 a
.mask
= 0xffffffff;
2322 if (sscanf(markmask
, "%i", &a
.mark
) != 1)
2326 res
= malloc(sizeof(*res
));
2328 memcpy(res
, &a
, sizeof(a
));
2332 void *parse_cgroupcond(const char *path
)
2334 struct aafilter
*res
;
2337 id
= get_cgroup2_id(path
);
2341 res
= malloc(sizeof(*res
));
2343 res
->cgroup_id
= id
;
2348 static void proc_ctx_print(struct sockstat
*s
)
2352 if (show_proc_ctx
|| show_sock_ctx
) {
2353 if (find_entry(s
->ino
, &buf
,
2354 (show_proc_ctx
& show_sock_ctx
) ?
2355 PROC_SOCK_CTX
: PROC_CTX
) > 0) {
2356 out(" users:(%s)", buf
);
2359 } else if (show_users
) {
2360 if (find_entry(s
->ino
, &buf
, USERS
) > 0) {
2361 out(" users:(%s)", buf
);
2367 static void inet_stats_print(struct sockstat
*s
, bool v6only
)
2369 sock_state_print(s
);
2371 inet_addr_print(&s
->local
, s
->lport
, s
->iface
, v6only
);
2372 inet_addr_print(&s
->remote
, s
->rport
, 0, v6only
);
2377 static int proc_parse_inet_addr(char *loc
, char *rem
, int family
, struct
2380 s
->local
.family
= s
->remote
.family
= family
;
2381 if (family
== AF_INET
) {
2382 sscanf(loc
, "%x:%x", s
->local
.data
, (unsigned *)&s
->lport
);
2383 sscanf(rem
, "%x:%x", s
->remote
.data
, (unsigned *)&s
->rport
);
2384 s
->local
.bytelen
= s
->remote
.bytelen
= 4;
2387 sscanf(loc
, "%08x%08x%08x%08x:%x",
2393 sscanf(rem
, "%08x%08x%08x%08x:%x",
2399 s
->local
.bytelen
= s
->remote
.bytelen
= 16;
2405 static int proc_inet_split_line(char *line
, char **loc
, char **rem
, char **data
)
2409 if ((p
= strchr(line
, ':')) == NULL
)
2413 if ((p
= strchr(*loc
, ':')) == NULL
)
2418 if ((p
= strchr(*rem
, ':')) == NULL
)
2427 * Display bandwidth in standard units
2428 * See: https://en.wikipedia.org/wiki/Data-rate_units
2429 * bw is in bits per second
2431 static char *sprint_bw(char *buf
, double bw
)
2434 sprintf(buf
, "%.0f", bw
);
2435 else if (bw
>= 1e12
)
2436 sprintf(buf
, "%.3gT", bw
/ 1e12
);
2438 sprintf(buf
, "%.3gG", bw
/ 1e9
);
2440 sprintf(buf
, "%.3gM", bw
/ 1e6
);
2442 sprintf(buf
, "%.3gk", bw
/ 1e3
);
2444 sprintf(buf
, "%g", bw
);
2449 static void sctp_stats_print(struct sctp_info
*s
)
2452 out(" tag:%x", s
->sctpi_tag
);
2454 out(" state:%s", sctp_sstate_name
[s
->sctpi_state
]);
2456 out(" rwnd:%d", s
->sctpi_rwnd
);
2457 if (s
->sctpi_unackdata
)
2458 out(" unackdata:%d", s
->sctpi_unackdata
);
2459 if (s
->sctpi_penddata
)
2460 out(" penddata:%d", s
->sctpi_penddata
);
2461 if (s
->sctpi_instrms
)
2462 out(" instrms:%d", s
->sctpi_instrms
);
2463 if (s
->sctpi_outstrms
)
2464 out(" outstrms:%d", s
->sctpi_outstrms
);
2465 if (s
->sctpi_inqueue
)
2466 out(" inqueue:%d", s
->sctpi_inqueue
);
2467 if (s
->sctpi_outqueue
)
2468 out(" outqueue:%d", s
->sctpi_outqueue
);
2469 if (s
->sctpi_overall_error
)
2470 out(" overerr:%d", s
->sctpi_overall_error
);
2471 if (s
->sctpi_max_burst
)
2472 out(" maxburst:%d", s
->sctpi_max_burst
);
2473 if (s
->sctpi_maxseg
)
2474 out(" maxseg:%d", s
->sctpi_maxseg
);
2475 if (s
->sctpi_peer_rwnd
)
2476 out(" prwnd:%d", s
->sctpi_peer_rwnd
);
2477 if (s
->sctpi_peer_tag
)
2478 out(" ptag:%x", s
->sctpi_peer_tag
);
2479 if (s
->sctpi_peer_capable
)
2480 out(" pcapable:%d", s
->sctpi_peer_capable
);
2481 if (s
->sctpi_peer_sack
)
2482 out(" psack:%d", s
->sctpi_peer_sack
);
2483 if (s
->sctpi_s_autoclose
)
2484 out(" autoclose:%d", s
->sctpi_s_autoclose
);
2485 if (s
->sctpi_s_adaptation_ind
)
2486 out(" adapind:%d", s
->sctpi_s_adaptation_ind
);
2487 if (s
->sctpi_s_pd_point
)
2488 out(" pdpoint:%d", s
->sctpi_s_pd_point
);
2489 if (s
->sctpi_s_nodelay
)
2490 out(" nodelay:%d", s
->sctpi_s_nodelay
);
2491 if (s
->sctpi_s_disable_fragments
)
2492 out(" nofrag:%d", s
->sctpi_s_disable_fragments
);
2493 if (s
->sctpi_s_v4mapped
)
2494 out(" v4mapped:%d", s
->sctpi_s_v4mapped
);
2495 if (s
->sctpi_s_frag_interleave
)
2496 out(" fraginl:%d", s
->sctpi_s_frag_interleave
);
2499 static void tcp_stats_print(struct tcpstat
*s
)
2505 if (s
->has_sack_opt
)
2509 if (s
->has_ecnseen_opt
)
2511 if (s
->has_fastopen_opt
)
2514 out(" %s", s
->cong_alg
);
2515 if (s
->has_wscale_opt
)
2516 out(" wscale:%d,%d", s
->snd_wscale
, s
->rcv_wscale
);
2518 out(" rto:%g", s
->rto
);
2520 out(" backoff:%u", s
->backoff
);
2522 out(" rtt:%g/%g", s
->rtt
, s
->rttvar
);
2524 out(" ato:%g", s
->ato
);
2527 out(" qack:%d", s
->qack
);
2532 out(" mss:%d", s
->mss
);
2534 out(" pmtu:%u", s
->pmtu
);
2536 out(" rcvmss:%d", s
->rcv_mss
);
2538 out(" advmss:%d", s
->advmss
);
2540 out(" cwnd:%u", s
->cwnd
);
2542 out(" ssthresh:%d", s
->ssthresh
);
2545 out(" bytes_sent:%llu", s
->bytes_sent
);
2546 if (s
->bytes_retrans
)
2547 out(" bytes_retrans:%llu", s
->bytes_retrans
);
2549 out(" bytes_acked:%llu", s
->bytes_acked
);
2550 if (s
->bytes_received
)
2551 out(" bytes_received:%llu", s
->bytes_received
);
2553 out(" segs_out:%u", s
->segs_out
);
2555 out(" segs_in:%u", s
->segs_in
);
2556 if (s
->data_segs_out
)
2557 out(" data_segs_out:%u", s
->data_segs_out
);
2558 if (s
->data_segs_in
)
2559 out(" data_segs_in:%u", s
->data_segs_in
);
2561 if (s
->dctcp
&& s
->dctcp
->enabled
) {
2562 struct dctcpstat
*dctcp
= s
->dctcp
;
2564 out(" dctcp:(ce_state:%u,alpha:%u,ab_ecn:%u,ab_tot:%u)",
2565 dctcp
->ce_state
, dctcp
->alpha
, dctcp
->ab_ecn
,
2567 } else if (s
->dctcp
) {
2568 out(" dctcp:fallback_mode");
2574 bw
= s
->bbr_info
->bbr_bw_hi
;
2576 bw
|= s
->bbr_info
->bbr_bw_lo
;
2578 out(" bbr:(bw:%sbps,mrtt:%g",
2579 sprint_bw(b1
, bw
* 8.0),
2580 (double)s
->bbr_info
->bbr_min_rtt
/ 1000.0);
2581 if (s
->bbr_info
->bbr_pacing_gain
)
2582 out(",pacing_gain:%g",
2583 (double)s
->bbr_info
->bbr_pacing_gain
/ 256.0);
2584 if (s
->bbr_info
->bbr_cwnd_gain
)
2585 out(",cwnd_gain:%g",
2586 (double)s
->bbr_info
->bbr_cwnd_gain
/ 256.0);
2591 out(" send %sbps", sprint_bw(b1
, s
->send_bps
));
2593 out(" lastsnd:%u", s
->lastsnd
);
2595 out(" lastrcv:%u", s
->lastrcv
);
2597 out(" lastack:%u", s
->lastack
);
2599 if (s
->pacing_rate
) {
2600 out(" pacing_rate %sbps", sprint_bw(b1
, s
->pacing_rate
));
2601 if (s
->pacing_rate_max
)
2602 out("/%sbps", sprint_bw(b1
, s
->pacing_rate_max
));
2605 if (s
->delivery_rate
)
2606 out(" delivery_rate %sbps", sprint_bw(b1
, s
->delivery_rate
));
2608 out(" delivered:%u", s
->delivered
);
2609 if (s
->delivered_ce
)
2610 out(" delivered_ce:%u", s
->delivered_ce
);
2612 out(" app_limited");
2615 out(" busy:%llums", s
->busy_time
/ 1000);
2616 if (s
->rwnd_limited
)
2617 out(" rwnd_limited:%llums(%.1f%%)",
2618 s
->rwnd_limited
/ 1000,
2619 100.0 * s
->rwnd_limited
/ s
->busy_time
);
2620 if (s
->sndbuf_limited
)
2621 out(" sndbuf_limited:%llums(%.1f%%)",
2622 s
->sndbuf_limited
/ 1000,
2623 100.0 * s
->sndbuf_limited
/ s
->busy_time
);
2627 out(" unacked:%u", s
->unacked
);
2628 if (s
->retrans
|| s
->retrans_total
)
2629 out(" retrans:%u/%u", s
->retrans
, s
->retrans_total
);
2631 out(" lost:%u", s
->lost
);
2632 if (s
->sacked
&& s
->ss
.state
!= SS_LISTEN
)
2633 out(" sacked:%u", s
->sacked
);
2635 out(" dsack_dups:%u", s
->dsack_dups
);
2637 out(" fackets:%u", s
->fackets
);
2638 if (s
->reordering
!= 3)
2639 out(" reordering:%d", s
->reordering
);
2641 out(" reord_seen:%d", s
->reord_seen
);
2643 out(" rcv_rtt:%g", s
->rcv_rtt
);
2645 out(" rcv_space:%d", s
->rcv_space
);
2646 if (s
->rcv_ssthresh
)
2647 out(" rcv_ssthresh:%u", s
->rcv_ssthresh
);
2649 out(" notsent:%u", s
->not_sent
);
2651 out(" minrtt:%g", s
->min_rtt
);
2654 static void tcp_timer_print(struct tcpstat
*s
)
2656 static const char * const tmr_name
[] = {
2668 out(" timer:(%s,%s,%d)",
2670 print_ms_timer(s
->timeout
),
2675 static void sctp_timer_print(struct tcpstat
*s
)
2678 out(" timer:(T3_RTX,%s,%d)",
2679 print_ms_timer(s
->timeout
), s
->retrans
);
2682 static int tcp_show_line(char *line
, const struct filter
*f
, int family
)
2684 int rto
= 0, ato
= 0;
2685 struct tcpstat s
= {};
2686 char *loc
, *rem
, *data
;
2689 int hz
= get_user_hz();
2691 if (proc_inet_split_line(line
, &loc
, &rem
, &data
))
2694 int state
= (data
[1] >= 'A') ? (data
[1] - 'A' + 10) : (data
[1] - '0');
2696 if (!(f
->states
& (1 << state
)))
2699 proc_parse_inet_addr(loc
, rem
, family
, &s
.ss
);
2701 if (f
->f
&& run_ssfilter(f
->f
, &s
.ss
) == 0)
2705 n
= sscanf(data
, "%x %x:%x %x:%x %x %d %d %u %d %llx %d %d %d %u %d %[^\n]\n",
2706 &s
.ss
.state
, &s
.ss
.wq
, &s
.ss
.rq
,
2707 &s
.timer
, &s
.timeout
, &s
.retrans
, &s
.ss
.uid
, &s
.probes
,
2708 &s
.ss
.ino
, &s
.ss
.refcnt
, &s
.ss
.sk
, &rto
, &ato
, &s
.qack
, &s
.cwnd
,
2721 s
.retrans
= s
.timer
!= 1 ? s
.probes
: s
.retrans
;
2722 s
.timeout
= (s
.timeout
* 1000 + hz
- 1) / hz
;
2723 s
.ato
= (double)ato
/ hz
;
2725 s
.rto
= (double)rto
;
2726 s
.ssthresh
= s
.ssthresh
== -1 ? 0 : s
.ssthresh
;
2727 s
.rto
= s
.rto
!= 3 * hz
? s
.rto
/ hz
: 0;
2728 s
.ss
.type
= IPPROTO_TCP
;
2730 inet_stats_print(&s
.ss
, false);
2733 tcp_timer_print(&s
);
2736 sock_details_print(&s
.ss
);
2738 out(" opt:\"%s\"", opt
);
2742 tcp_stats_print(&s
);
2747 static int generic_record_read(FILE *fp
,
2748 int (*worker
)(char*, const struct filter
*, int),
2749 const struct filter
*f
, int fam
)
2754 if (fgets(line
, sizeof(line
), fp
) == NULL
)
2757 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
2758 int n
= strlen(line
);
2760 if (n
== 0 || line
[n
-1] != '\n') {
2766 if (worker(line
, f
, fam
) < 0)
2771 return ferror(fp
) ? -1 : 0;
2774 static void print_skmeminfo(struct rtattr
*tb
[], int attrtype
)
2776 const __u32
*skmeminfo
;
2778 if (!tb
[attrtype
]) {
2779 if (attrtype
== INET_DIAG_SKMEMINFO
) {
2780 if (!tb
[INET_DIAG_MEMINFO
])
2783 const struct inet_diag_meminfo
*minfo
=
2784 RTA_DATA(tb
[INET_DIAG_MEMINFO
]);
2786 out(" mem:(r%u,w%u,f%u,t%u)",
2795 skmeminfo
= RTA_DATA(tb
[attrtype
]);
2797 out(" skmem:(r%u,rb%u,t%u,tb%u,f%u,w%u,o%u",
2798 skmeminfo
[SK_MEMINFO_RMEM_ALLOC
],
2799 skmeminfo
[SK_MEMINFO_RCVBUF
],
2800 skmeminfo
[SK_MEMINFO_WMEM_ALLOC
],
2801 skmeminfo
[SK_MEMINFO_SNDBUF
],
2802 skmeminfo
[SK_MEMINFO_FWD_ALLOC
],
2803 skmeminfo
[SK_MEMINFO_WMEM_QUEUED
],
2804 skmeminfo
[SK_MEMINFO_OPTMEM
]);
2806 if (RTA_PAYLOAD(tb
[attrtype
]) >=
2807 (SK_MEMINFO_BACKLOG
+ 1) * sizeof(__u32
))
2808 out(",bl%u", skmeminfo
[SK_MEMINFO_BACKLOG
]);
2810 if (RTA_PAYLOAD(tb
[attrtype
]) >=
2811 (SK_MEMINFO_DROPS
+ 1) * sizeof(__u32
))
2812 out(",d%u", skmeminfo
[SK_MEMINFO_DROPS
]);
2817 static void print_md5sig(struct tcp_diag_md5sig
*sig
)
2820 format_host(sig
->tcpm_family
,
2821 sig
->tcpm_family
== AF_INET6
? 16 : 4,
2823 sig
->tcpm_prefixlen
);
2824 print_escape_buf(sig
->tcpm_key
, sig
->tcpm_keylen
, " ,");
2827 static void tcp_tls_version(struct rtattr
*attr
)
2833 val
= rta_getattr_u16(attr
);
2836 case TLS_1_2_VERSION
:
2837 out(" version: 1.2");
2839 case TLS_1_3_VERSION
:
2840 out(" version: 1.3");
2843 out(" version: unknown(%hu)", val
);
2848 static void tcp_tls_cipher(struct rtattr
*attr
)
2854 val
= rta_getattr_u16(attr
);
2857 case TLS_CIPHER_AES_GCM_128
:
2858 out(" cipher: aes-gcm-128");
2860 case TLS_CIPHER_AES_GCM_256
:
2861 out(" cipher: aes-gcm-256");
2866 static void tcp_tls_conf(const char *name
, struct rtattr
*attr
)
2872 val
= rta_getattr_u16(attr
);
2876 out(" %s: none", name
);
2879 out(" %s: sw", name
);
2882 out(" %s: hw", name
);
2884 case TLS_CONF_HW_RECORD
:
2885 out(" %s: hw-record", name
);
2888 out(" %s: unknown(%hu)", name
, val
);
2893 static void mptcp_subflow_info(struct rtattr
*tb
[])
2895 u_int32_t flags
= 0;
2897 if (tb
[MPTCP_SUBFLOW_ATTR_FLAGS
]) {
2898 char caps
[32 + 1] = { 0 }, *cap
= &caps
[0];
2900 flags
= rta_getattr_u32(tb
[MPTCP_SUBFLOW_ATTR_FLAGS
]);
2902 if (flags
& MPTCP_SUBFLOW_FLAG_MCAP_REM
)
2904 if (flags
& MPTCP_SUBFLOW_FLAG_MCAP_LOC
)
2906 if (flags
& MPTCP_SUBFLOW_FLAG_JOIN_REM
)
2908 if (flags
& MPTCP_SUBFLOW_FLAG_JOIN_LOC
)
2910 if (flags
& MPTCP_SUBFLOW_FLAG_BKUP_REM
)
2912 if (flags
& MPTCP_SUBFLOW_FLAG_BKUP_LOC
)
2914 if (flags
& MPTCP_SUBFLOW_FLAG_FULLY_ESTABLISHED
)
2916 if (flags
& MPTCP_SUBFLOW_FLAG_CONNECTED
)
2918 if (flags
& MPTCP_SUBFLOW_FLAG_MAPVALID
)
2921 out(" flags:%s", caps
);
2923 if (tb
[MPTCP_SUBFLOW_ATTR_TOKEN_REM
] &&
2924 tb
[MPTCP_SUBFLOW_ATTR_TOKEN_LOC
] &&
2925 tb
[MPTCP_SUBFLOW_ATTR_ID_REM
] &&
2926 tb
[MPTCP_SUBFLOW_ATTR_ID_LOC
])
2927 out(" token:%04x(id:%hhu)/%04x(id:%hhu)",
2928 rta_getattr_u32(tb
[MPTCP_SUBFLOW_ATTR_TOKEN_REM
]),
2929 rta_getattr_u8(tb
[MPTCP_SUBFLOW_ATTR_ID_REM
]),
2930 rta_getattr_u32(tb
[MPTCP_SUBFLOW_ATTR_TOKEN_LOC
]),
2931 rta_getattr_u8(tb
[MPTCP_SUBFLOW_ATTR_ID_LOC
]));
2932 if (tb
[MPTCP_SUBFLOW_ATTR_MAP_SEQ
])
2934 rta_getattr_u64(tb
[MPTCP_SUBFLOW_ATTR_MAP_SEQ
]));
2935 if (tb
[MPTCP_SUBFLOW_ATTR_MAP_SFSEQ
])
2937 rta_getattr_u32(tb
[MPTCP_SUBFLOW_ATTR_MAP_SFSEQ
]));
2938 if (tb
[MPTCP_SUBFLOW_ATTR_SSN_OFFSET
])
2940 rta_getattr_u32(tb
[MPTCP_SUBFLOW_ATTR_SSN_OFFSET
]));
2941 if (tb
[MPTCP_SUBFLOW_ATTR_MAP_DATALEN
])
2943 rta_getattr_u32(tb
[MPTCP_SUBFLOW_ATTR_MAP_DATALEN
]));
2946 #define TCPI_HAS_OPT(info, opt) !!(info->tcpi_options & (opt))
2948 static void tcp_show_info(const struct nlmsghdr
*nlh
, struct inet_diag_msg
*r
,
2949 struct rtattr
*tb
[])
2952 struct tcpstat s
= {};
2954 s
.ss
.state
= r
->idiag_state
;
2956 print_skmeminfo(tb
, INET_DIAG_SKMEMINFO
);
2958 if (tb
[INET_DIAG_INFO
]) {
2959 struct tcp_info
*info
;
2960 int len
= RTA_PAYLOAD(tb
[INET_DIAG_INFO
]);
2962 /* workaround for older kernels with less fields */
2963 if (len
< sizeof(*info
)) {
2964 info
= alloca(sizeof(*info
));
2965 memcpy(info
, RTA_DATA(tb
[INET_DIAG_INFO
]), len
);
2966 memset((char *)info
+ len
, 0, sizeof(*info
) - len
);
2968 info
= RTA_DATA(tb
[INET_DIAG_INFO
]);
2971 s
.has_ts_opt
= TCPI_HAS_OPT(info
, TCPI_OPT_TIMESTAMPS
);
2972 s
.has_sack_opt
= TCPI_HAS_OPT(info
, TCPI_OPT_SACK
);
2973 s
.has_ecn_opt
= TCPI_HAS_OPT(info
, TCPI_OPT_ECN
);
2974 s
.has_ecnseen_opt
= TCPI_HAS_OPT(info
, TCPI_OPT_ECN_SEEN
);
2975 s
.has_fastopen_opt
= TCPI_HAS_OPT(info
, TCPI_OPT_SYN_DATA
);
2978 if (tb
[INET_DIAG_CONG
])
2980 rta_getattr_str(tb
[INET_DIAG_CONG
]),
2981 sizeof(s
.cong_alg
) - 1);
2983 if (TCPI_HAS_OPT(info
, TCPI_OPT_WSCALE
)) {
2984 s
.has_wscale_opt
= true;
2985 s
.snd_wscale
= info
->tcpi_snd_wscale
;
2986 s
.rcv_wscale
= info
->tcpi_rcv_wscale
;
2989 if (info
->tcpi_rto
&& info
->tcpi_rto
!= 3000000)
2990 s
.rto
= (double)info
->tcpi_rto
/ 1000;
2992 s
.backoff
= info
->tcpi_backoff
;
2993 s
.rtt
= (double)info
->tcpi_rtt
/ 1000;
2994 s
.rttvar
= (double)info
->tcpi_rttvar
/ 1000;
2995 s
.ato
= (double)info
->tcpi_ato
/ 1000;
2996 s
.mss
= info
->tcpi_snd_mss
;
2997 s
.rcv_mss
= info
->tcpi_rcv_mss
;
2998 s
.advmss
= info
->tcpi_advmss
;
2999 s
.rcv_space
= info
->tcpi_rcv_space
;
3000 s
.rcv_rtt
= (double)info
->tcpi_rcv_rtt
/ 1000;
3001 s
.lastsnd
= info
->tcpi_last_data_sent
;
3002 s
.lastrcv
= info
->tcpi_last_data_recv
;
3003 s
.lastack
= info
->tcpi_last_ack_recv
;
3004 s
.unacked
= info
->tcpi_unacked
;
3005 s
.retrans
= info
->tcpi_retrans
;
3006 s
.retrans_total
= info
->tcpi_total_retrans
;
3007 s
.lost
= info
->tcpi_lost
;
3008 s
.sacked
= info
->tcpi_sacked
;
3009 s
.fackets
= info
->tcpi_fackets
;
3010 s
.reordering
= info
->tcpi_reordering
;
3011 s
.rcv_ssthresh
= info
->tcpi_rcv_ssthresh
;
3012 s
.cwnd
= info
->tcpi_snd_cwnd
;
3013 s
.pmtu
= info
->tcpi_pmtu
;
3015 if (info
->tcpi_snd_ssthresh
< 0xFFFF)
3016 s
.ssthresh
= info
->tcpi_snd_ssthresh
;
3018 rtt
= (double) info
->tcpi_rtt
;
3019 if (tb
[INET_DIAG_VEGASINFO
]) {
3020 const struct tcpvegas_info
*vinfo
3021 = RTA_DATA(tb
[INET_DIAG_VEGASINFO
]);
3023 if (vinfo
->tcpv_enabled
&&
3024 vinfo
->tcpv_rtt
&& vinfo
->tcpv_rtt
!= 0x7fffffff)
3025 rtt
= vinfo
->tcpv_rtt
;
3028 if (tb
[INET_DIAG_DCTCPINFO
]) {
3029 struct dctcpstat
*dctcp
= malloc(sizeof(struct
3032 const struct tcp_dctcp_info
*dinfo
3033 = RTA_DATA(tb
[INET_DIAG_DCTCPINFO
]);
3035 dctcp
->enabled
= !!dinfo
->dctcp_enabled
;
3036 dctcp
->ce_state
= dinfo
->dctcp_ce_state
;
3037 dctcp
->alpha
= dinfo
->dctcp_alpha
;
3038 dctcp
->ab_ecn
= dinfo
->dctcp_ab_ecn
;
3039 dctcp
->ab_tot
= dinfo
->dctcp_ab_tot
;
3043 if (tb
[INET_DIAG_BBRINFO
]) {
3044 const void *bbr_info
= RTA_DATA(tb
[INET_DIAG_BBRINFO
]);
3045 int len
= min(RTA_PAYLOAD(tb
[INET_DIAG_BBRINFO
]),
3046 sizeof(*s
.bbr_info
));
3048 s
.bbr_info
= calloc(1, sizeof(*s
.bbr_info
));
3049 if (s
.bbr_info
&& bbr_info
)
3050 memcpy(s
.bbr_info
, bbr_info
, len
);
3053 if (rtt
> 0 && info
->tcpi_snd_mss
&& info
->tcpi_snd_cwnd
) {
3054 s
.send_bps
= (double) info
->tcpi_snd_cwnd
*
3055 (double)info
->tcpi_snd_mss
* 8000000. / rtt
;
3058 if (info
->tcpi_pacing_rate
&&
3059 info
->tcpi_pacing_rate
!= ~0ULL) {
3060 s
.pacing_rate
= info
->tcpi_pacing_rate
* 8.;
3062 if (info
->tcpi_max_pacing_rate
&&
3063 info
->tcpi_max_pacing_rate
!= ~0ULL)
3064 s
.pacing_rate_max
= info
->tcpi_max_pacing_rate
* 8.;
3066 s
.bytes_acked
= info
->tcpi_bytes_acked
;
3067 s
.bytes_received
= info
->tcpi_bytes_received
;
3068 s
.segs_out
= info
->tcpi_segs_out
;
3069 s
.segs_in
= info
->tcpi_segs_in
;
3070 s
.data_segs_out
= info
->tcpi_data_segs_out
;
3071 s
.data_segs_in
= info
->tcpi_data_segs_in
;
3072 s
.not_sent
= info
->tcpi_notsent_bytes
;
3073 if (info
->tcpi_min_rtt
&& info
->tcpi_min_rtt
!= ~0U)
3074 s
.min_rtt
= (double) info
->tcpi_min_rtt
/ 1000;
3075 s
.delivery_rate
= info
->tcpi_delivery_rate
* 8.;
3076 s
.app_limited
= info
->tcpi_delivery_rate_app_limited
;
3077 s
.busy_time
= info
->tcpi_busy_time
;
3078 s
.rwnd_limited
= info
->tcpi_rwnd_limited
;
3079 s
.sndbuf_limited
= info
->tcpi_sndbuf_limited
;
3080 s
.delivered
= info
->tcpi_delivered
;
3081 s
.delivered_ce
= info
->tcpi_delivered_ce
;
3082 s
.dsack_dups
= info
->tcpi_dsack_dups
;
3083 s
.reord_seen
= info
->tcpi_reord_seen
;
3084 s
.bytes_sent
= info
->tcpi_bytes_sent
;
3085 s
.bytes_retrans
= info
->tcpi_bytes_retrans
;
3086 tcp_stats_print(&s
);
3090 if (tb
[INET_DIAG_MD5SIG
]) {
3091 struct tcp_diag_md5sig
*sig
= RTA_DATA(tb
[INET_DIAG_MD5SIG
]);
3092 int len
= RTA_PAYLOAD(tb
[INET_DIAG_MD5SIG
]);
3095 print_md5sig(sig
++);
3096 for (len
-= sizeof(*sig
); len
> 0; len
-= sizeof(*sig
)) {
3098 print_md5sig(sig
++);
3101 if (tb
[INET_DIAG_ULP_INFO
]) {
3102 struct rtattr
*ulpinfo
[INET_ULP_INFO_MAX
+ 1] = { 0 };
3104 parse_rtattr_nested(ulpinfo
, INET_ULP_INFO_MAX
,
3105 tb
[INET_DIAG_ULP_INFO
]);
3107 if (ulpinfo
[INET_ULP_INFO_NAME
])
3109 rta_getattr_str(ulpinfo
[INET_ULP_INFO_NAME
]));
3111 if (ulpinfo
[INET_ULP_INFO_TLS
]) {
3112 struct rtattr
*tlsinfo
[TLS_INFO_MAX
+ 1] = { 0 };
3114 parse_rtattr_nested(tlsinfo
, TLS_INFO_MAX
,
3115 ulpinfo
[INET_ULP_INFO_TLS
]);
3117 tcp_tls_version(tlsinfo
[TLS_INFO_VERSION
]);
3118 tcp_tls_cipher(tlsinfo
[TLS_INFO_CIPHER
]);
3119 tcp_tls_conf("rxconf", tlsinfo
[TLS_INFO_RXCONF
]);
3120 tcp_tls_conf("txconf", tlsinfo
[TLS_INFO_TXCONF
]);
3122 if (ulpinfo
[INET_ULP_INFO_MPTCP
]) {
3123 struct rtattr
*sfinfo
[MPTCP_SUBFLOW_ATTR_MAX
+ 1] =
3126 parse_rtattr_nested(sfinfo
, MPTCP_SUBFLOW_ATTR_MAX
,
3127 ulpinfo
[INET_ULP_INFO_MPTCP
]);
3128 mptcp_subflow_info(sfinfo
);
3133 static void mptcp_stats_print(struct mptcp_info
*s
)
3135 if (s
->mptcpi_subflows
)
3136 out(" subflows:%d", s
->mptcpi_subflows
);
3137 if (s
->mptcpi_add_addr_signal
)
3138 out(" add_addr_signal:%d", s
->mptcpi_add_addr_signal
);
3139 if (s
->mptcpi_add_addr_signal
)
3140 out(" add_addr_accepted:%d", s
->mptcpi_add_addr_accepted
);
3141 if (s
->mptcpi_subflows_max
)
3142 out(" subflows_max:%d", s
->mptcpi_subflows_max
);
3143 if (s
->mptcpi_add_addr_signal_max
)
3144 out(" add_addr_signal_max:%d", s
->mptcpi_add_addr_signal_max
);
3145 if (s
->mptcpi_add_addr_accepted_max
)
3146 out(" add_addr_accepted_max:%d", s
->mptcpi_add_addr_accepted_max
);
3147 if (s
->mptcpi_flags
& MPTCP_INFO_FLAG_FALLBACK
)
3149 if (s
->mptcpi_flags
& MPTCP_INFO_FLAG_REMOTE_KEY_RECEIVED
)
3151 if (s
->mptcpi_token
)
3152 out(" token:%x", s
->mptcpi_token
);
3153 if (s
->mptcpi_write_seq
)
3154 out(" write_seq:%llx", s
->mptcpi_write_seq
);
3155 if (s
->mptcpi_snd_una
)
3156 out(" snd_una:%llx", s
->mptcpi_snd_una
);
3157 if (s
->mptcpi_rcv_nxt
)
3158 out(" rcv_nxt:%llx", s
->mptcpi_rcv_nxt
);
3161 static void mptcp_show_info(const struct nlmsghdr
*nlh
, struct inet_diag_msg
*r
,
3162 struct rtattr
*tb
[])
3164 print_skmeminfo(tb
, INET_DIAG_SKMEMINFO
);
3166 if (tb
[INET_DIAG_INFO
]) {
3167 struct mptcp_info
*info
;
3168 int len
= RTA_PAYLOAD(tb
[INET_DIAG_INFO
]);
3170 /* workaround for older kernels with less fields */
3171 if (len
< sizeof(*info
)) {
3172 info
= alloca(sizeof(*info
));
3173 memcpy(info
, RTA_DATA(tb
[INET_DIAG_INFO
]), len
);
3174 memset((char *)info
+ len
, 0, sizeof(*info
) - len
);
3176 info
= RTA_DATA(tb
[INET_DIAG_INFO
]);
3178 mptcp_stats_print(info
);
3182 static const char *format_host_sa(struct sockaddr_storage
*sa
)
3185 struct sockaddr_in sin
;
3186 struct sockaddr_in6 sin6
;
3187 } *saddr
= (void *)sa
;
3189 switch (sa
->ss_family
) {
3191 return format_host(AF_INET
, 4, &saddr
->sin
.sin_addr
);
3193 return format_host(AF_INET6
, 16, &saddr
->sin6
.sin6_addr
);
3199 static void sctp_show_info(const struct nlmsghdr
*nlh
, struct inet_diag_msg
*r
,
3200 struct rtattr
*tb
[])
3202 struct sockaddr_storage
*sa
;
3205 print_skmeminfo(tb
, INET_DIAG_SKMEMINFO
);
3207 if (tb
[INET_DIAG_LOCALS
]) {
3208 len
= RTA_PAYLOAD(tb
[INET_DIAG_LOCALS
]);
3209 sa
= RTA_DATA(tb
[INET_DIAG_LOCALS
]);
3211 out(" locals:%s", format_host_sa(sa
));
3212 for (sa
++, len
-= sizeof(*sa
); len
> 0; sa
++, len
-= sizeof(*sa
))
3213 out(",%s", format_host_sa(sa
));
3216 if (tb
[INET_DIAG_PEERS
]) {
3217 len
= RTA_PAYLOAD(tb
[INET_DIAG_PEERS
]);
3218 sa
= RTA_DATA(tb
[INET_DIAG_PEERS
]);
3220 out(" peers:%s", format_host_sa(sa
));
3221 for (sa
++, len
-= sizeof(*sa
); len
> 0; sa
++, len
-= sizeof(*sa
))
3222 out(",%s", format_host_sa(sa
));
3224 if (tb
[INET_DIAG_INFO
]) {
3225 struct sctp_info
*info
;
3226 len
= RTA_PAYLOAD(tb
[INET_DIAG_INFO
]);
3228 /* workaround for older kernels with less fields */
3229 if (len
< sizeof(*info
)) {
3230 info
= alloca(sizeof(*info
));
3231 memcpy(info
, RTA_DATA(tb
[INET_DIAG_INFO
]), len
);
3232 memset((char *)info
+ len
, 0, sizeof(*info
) - len
);
3234 info
= RTA_DATA(tb
[INET_DIAG_INFO
]);
3236 sctp_stats_print(info
);
3240 static void parse_diag_msg(struct nlmsghdr
*nlh
, struct sockstat
*s
)
3242 struct rtattr
*tb
[INET_DIAG_MAX
+1];
3243 struct inet_diag_msg
*r
= NLMSG_DATA(nlh
);
3245 parse_rtattr(tb
, INET_DIAG_MAX
, (struct rtattr
*)(r
+1),
3246 nlh
->nlmsg_len
- NLMSG_LENGTH(sizeof(*r
)));
3248 s
->state
= r
->idiag_state
;
3249 s
->local
.family
= s
->remote
.family
= r
->idiag_family
;
3250 s
->lport
= ntohs(r
->id
.idiag_sport
);
3251 s
->rport
= ntohs(r
->id
.idiag_dport
);
3252 s
->wq
= r
->idiag_wqueue
;
3253 s
->rq
= r
->idiag_rqueue
;
3254 s
->ino
= r
->idiag_inode
;
3255 s
->uid
= r
->idiag_uid
;
3256 s
->iface
= r
->id
.idiag_if
;
3257 s
->sk
= cookie_sk_get(&r
->id
.idiag_cookie
[0]);
3260 if (tb
[INET_DIAG_MARK
])
3261 s
->mark
= rta_getattr_u32(tb
[INET_DIAG_MARK
]);
3263 if (tb
[INET_DIAG_CGROUP_ID
])
3264 s
->cgroup_id
= rta_getattr_u64(tb
[INET_DIAG_CGROUP_ID
]);
3265 if (tb
[INET_DIAG_PROTOCOL
])
3266 s
->raw_prot
= rta_getattr_u8(tb
[INET_DIAG_PROTOCOL
]);
3270 if (s
->local
.family
== AF_INET
)
3271 s
->local
.bytelen
= s
->remote
.bytelen
= 4;
3273 s
->local
.bytelen
= s
->remote
.bytelen
= 16;
3275 memcpy(s
->local
.data
, r
->id
.idiag_src
, s
->local
.bytelen
);
3276 memcpy(s
->remote
.data
, r
->id
.idiag_dst
, s
->local
.bytelen
);
3279 static int inet_show_sock(struct nlmsghdr
*nlh
,
3282 struct rtattr
*tb
[INET_DIAG_MAX
+1];
3283 struct inet_diag_msg
*r
= NLMSG_DATA(nlh
);
3284 unsigned char v6only
= 0;
3286 parse_rtattr(tb
, INET_DIAG_MAX
, (struct rtattr
*)(r
+1),
3287 nlh
->nlmsg_len
- NLMSG_LENGTH(sizeof(*r
)));
3289 if (tb
[INET_DIAG_PROTOCOL
])
3290 s
->type
= rta_getattr_u8(tb
[INET_DIAG_PROTOCOL
]);
3292 if (s
->local
.family
== AF_INET6
&& tb
[INET_DIAG_SKV6ONLY
])
3293 v6only
= rta_getattr_u8(tb
[INET_DIAG_SKV6ONLY
]);
3295 inet_stats_print(s
, v6only
);
3298 struct tcpstat t
= {};
3300 t
.timer
= r
->idiag_timer
;
3301 t
.timeout
= r
->idiag_expires
;
3302 t
.retrans
= r
->idiag_retrans
;
3303 if (s
->type
== IPPROTO_SCTP
)
3304 sctp_timer_print(&t
);
3306 tcp_timer_print(&t
);
3310 sock_details_print(s
);
3311 if (s
->local
.family
== AF_INET6
&& tb
[INET_DIAG_SKV6ONLY
])
3312 out(" v6only:%u", v6only
);
3314 if (tb
[INET_DIAG_SHUTDOWN
]) {
3317 mask
= rta_getattr_u8(tb
[INET_DIAG_SHUTDOWN
]);
3319 mask
& 1 ? '-' : '<', mask
& 2 ? '-' : '>');
3324 if (tb
[INET_DIAG_TOS
])
3325 out(" tos:%#x", rta_getattr_u8(tb
[INET_DIAG_TOS
]));
3326 if (tb
[INET_DIAG_TCLASS
])
3327 out(" tclass:%#x", rta_getattr_u8(tb
[INET_DIAG_TCLASS
]));
3328 if (tb
[INET_DIAG_CLASS_ID
])
3329 out(" class_id:%#x", rta_getattr_u32(tb
[INET_DIAG_CLASS_ID
]));
3333 if (tb
[INET_DIAG_CGROUP_ID
])
3334 out(" cgroup:%s", cg_id_to_path(rta_getattr_u64(tb
[INET_DIAG_CGROUP_ID
])));
3337 if (show_inet_sockopt
) {
3338 if (tb
[INET_DIAG_SOCKOPT
] && RTA_PAYLOAD(tb
[INET_DIAG_SOCKOPT
]) >=
3339 sizeof(struct inet_diag_sockopt
)) {
3340 const struct inet_diag_sockopt
*sockopt
=
3341 RTA_DATA(tb
[INET_DIAG_SOCKOPT
]);
3343 out("\n\tinet-sockopt: (");
3345 out(" inet-sockopt: (");
3346 if (sockopt
->recverr
)
3348 if (sockopt
->is_icsk
)
3350 if (sockopt
->freebind
)
3352 if (sockopt
->hdrincl
)
3354 if (sockopt
->mc_loop
)
3356 if (sockopt
->transparent
)
3357 out(" transparent");
3358 if (sockopt
->mc_all
)
3360 if (sockopt
->nodefrag
)
3362 if (sockopt
->bind_address_no_port
)
3363 out(" bind_addr_no_port");
3364 if (sockopt
->recverr_rfc4884
)
3365 out(" recverr_rfc4884");
3366 if (sockopt
->defer_connect
)
3367 out(" defer_connect");
3372 if (show_mem
|| (show_tcpinfo
&& s
->type
!= IPPROTO_UDP
)) {
3375 if (s
->type
== IPPROTO_SCTP
)
3376 sctp_show_info(nlh
, r
, tb
);
3377 else if (s
->type
== IPPROTO_MPTCP
)
3378 mptcp_show_info(nlh
, r
, tb
);
3380 tcp_show_info(nlh
, r
, tb
);
3387 static int tcpdiag_send(int fd
, int protocol
, struct filter
*f
)
3389 struct sockaddr_nl nladdr
= { .nl_family
= AF_NETLINK
};
3391 struct nlmsghdr nlh
;
3392 struct inet_diag_req r
;
3394 .nlh
.nlmsg_len
= sizeof(req
),
3395 .nlh
.nlmsg_flags
= NLM_F_ROOT
| NLM_F_MATCH
| NLM_F_REQUEST
,
3396 .nlh
.nlmsg_seq
= MAGIC_SEQ
,
3397 .r
.idiag_family
= AF_INET
,
3398 .r
.idiag_states
= f
->states
,
3404 struct iovec iov
[3];
3407 if (protocol
== IPPROTO_UDP
)
3410 if (protocol
== IPPROTO_TCP
)
3411 req
.nlh
.nlmsg_type
= TCPDIAG_GETSOCK
;
3413 req
.nlh
.nlmsg_type
= DCCPDIAG_GETSOCK
;
3415 req
.r
.idiag_ext
|= (1<<(INET_DIAG_MEMINFO
-1));
3416 req
.r
.idiag_ext
|= (1<<(INET_DIAG_SKMEMINFO
-1));
3420 req
.r
.idiag_ext
|= (1<<(INET_DIAG_INFO
-1));
3421 req
.r
.idiag_ext
|= (1<<(INET_DIAG_VEGASINFO
-1));
3422 req
.r
.idiag_ext
|= (1<<(INET_DIAG_CONG
-1));
3426 req
.r
.idiag_ext
|= (1<<(INET_DIAG_TOS
-1));
3427 req
.r
.idiag_ext
|= (1<<(INET_DIAG_TCLASS
-1));
3430 iov
[0] = (struct iovec
){
3432 .iov_len
= sizeof(req
)
3435 bclen
= ssfilter_bytecompile(f
->f
, &bc
);
3437 rta
.rta_type
= INET_DIAG_REQ_BYTECODE
;
3438 rta
.rta_len
= RTA_LENGTH(bclen
);
3439 iov
[1] = (struct iovec
){ &rta
, sizeof(rta
) };
3440 iov
[2] = (struct iovec
){ bc
, bclen
};
3441 req
.nlh
.nlmsg_len
+= RTA_LENGTH(bclen
);
3446 msg
= (struct msghdr
) {
3447 .msg_name
= (void *)&nladdr
,
3448 .msg_namelen
= sizeof(nladdr
),
3450 .msg_iovlen
= iovlen
,
3453 if (sendmsg(fd
, &msg
, 0) < 0) {
3461 static int sockdiag_send(int family
, int fd
, int protocol
, struct filter
*f
)
3463 struct sockaddr_nl nladdr
= { .nl_family
= AF_NETLINK
};
3464 DIAG_REQUEST(req
, struct inet_diag_req_v2 r
);
3469 struct rtattr rta_bc
;
3470 struct rtattr rta_proto
;
3471 struct iovec iov
[5];
3474 if (family
== PF_UNSPEC
)
3475 return tcpdiag_send(fd
, protocol
, f
);
3477 memset(&req
.r
, 0, sizeof(req
.r
));
3478 req
.r
.sdiag_family
= family
;
3479 req
.r
.sdiag_protocol
= protocol
;
3480 req
.r
.idiag_states
= f
->states
;
3482 req
.r
.idiag_ext
|= (1<<(INET_DIAG_MEMINFO
-1));
3483 req
.r
.idiag_ext
|= (1<<(INET_DIAG_SKMEMINFO
-1));
3487 req
.r
.idiag_ext
|= (1<<(INET_DIAG_INFO
-1));
3488 req
.r
.idiag_ext
|= (1<<(INET_DIAG_VEGASINFO
-1));
3489 req
.r
.idiag_ext
|= (1<<(INET_DIAG_CONG
-1));
3493 req
.r
.idiag_ext
|= (1<<(INET_DIAG_TOS
-1));
3494 req
.r
.idiag_ext
|= (1<<(INET_DIAG_TCLASS
-1));
3497 iov
[0] = (struct iovec
){
3499 .iov_len
= sizeof(req
)
3502 bclen
= ssfilter_bytecompile(f
->f
, &bc
);
3504 rta_bc
.rta_type
= INET_DIAG_REQ_BYTECODE
;
3505 rta_bc
.rta_len
= RTA_LENGTH(bclen
);
3506 iov
[1] = (struct iovec
){ &rta_bc
, sizeof(rta_bc
) };
3507 iov
[2] = (struct iovec
){ bc
, bclen
};
3508 req
.nlh
.nlmsg_len
+= RTA_LENGTH(bclen
);
3513 /* put extended protocol attribute, if required */
3514 if (protocol
> 255) {
3515 rta_proto
.rta_type
= INET_DIAG_REQ_PROTOCOL
;
3516 rta_proto
.rta_len
= RTA_LENGTH(sizeof(proto
));
3518 iov
[iovlen
] = (struct iovec
){ &rta_proto
, sizeof(rta_proto
) };
3519 iov
[iovlen
+ 1] = (struct iovec
){ &proto
, sizeof(proto
) };
3520 req
.nlh
.nlmsg_len
+= RTA_LENGTH(sizeof(proto
));
3524 msg
= (struct msghdr
) {
3525 .msg_name
= (void *)&nladdr
,
3526 .msg_namelen
= sizeof(nladdr
),
3528 .msg_iovlen
= iovlen
,
3531 if (sendmsg(fd
, &msg
, 0) < 0) {
3539 struct inet_diag_arg
{
3542 struct rtnl_handle
*rth
;
3545 static int kill_inet_sock(struct nlmsghdr
*h
, void *arg
, struct sockstat
*s
)
3547 struct inet_diag_msg
*d
= NLMSG_DATA(h
);
3548 struct inet_diag_arg
*diag_arg
= arg
;
3549 struct rtnl_handle
*rth
= diag_arg
->rth
;
3551 DIAG_REQUEST(req
, struct inet_diag_req_v2 r
);
3553 req
.nlh
.nlmsg_type
= SOCK_DESTROY
;
3554 req
.nlh
.nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
;
3555 req
.nlh
.nlmsg_seq
= ++rth
->seq
;
3556 req
.r
.sdiag_family
= d
->idiag_family
;
3557 req
.r
.sdiag_protocol
= diag_arg
->protocol
;
3560 if (diag_arg
->protocol
== IPPROTO_RAW
) {
3561 struct inet_diag_req_raw
*raw
= (void *)&req
.r
;
3563 BUILD_BUG_ON(sizeof(req
.r
) != sizeof(*raw
));
3564 raw
->sdiag_raw_protocol
= s
->raw_prot
;
3567 return rtnl_talk(rth
, &req
.nlh
, NULL
);
3570 static int show_one_inet_sock(struct nlmsghdr
*h
, void *arg
)
3573 struct inet_diag_arg
*diag_arg
= arg
;
3574 struct inet_diag_msg
*r
= NLMSG_DATA(h
);
3575 struct sockstat s
= {};
3577 if (!(diag_arg
->f
->families
& FAMILY_MASK(r
->idiag_family
)))
3580 parse_diag_msg(h
, &s
);
3581 s
.type
= diag_arg
->protocol
;
3583 if (diag_arg
->f
->f
&& run_ssfilter(diag_arg
->f
->f
, &s
) == 0)
3586 if (diag_arg
->f
->kill
&& kill_inet_sock(h
, arg
, &s
) != 0) {
3587 if (errno
== EOPNOTSUPP
|| errno
== ENOENT
) {
3588 /* Socket can't be closed, or is already closed. */
3591 perror("SOCK_DESTROY answers");
3596 err
= inet_show_sock(h
, &s
);
3603 static int inet_show_netlink(struct filter
*f
, FILE *dump_fp
, int protocol
)
3606 struct rtnl_handle rth
, rth2
;
3607 int family
= PF_INET
;
3608 struct inet_diag_arg arg
= { .f
= f
, .protocol
= protocol
};
3610 if (rtnl_open_byproto(&rth
, 0, NETLINK_SOCK_DIAG
))
3614 if (rtnl_open_byproto(&rth2
, 0, NETLINK_SOCK_DIAG
)) {
3621 rth
.dump
= MAGIC_SEQ
;
3622 rth
.dump_fp
= dump_fp
;
3623 if (preferred_family
== PF_INET6
)
3627 if ((err
= sockdiag_send(family
, rth
.fd
, protocol
, f
)))
3630 if ((err
= rtnl_dump_filter(&rth
, show_one_inet_sock
, &arg
))) {
3631 if (family
!= PF_UNSPEC
) {
3637 if (family
== PF_INET
&& preferred_family
!= PF_INET
) {
3645 rtnl_close(arg
.rth
);
3649 static int tcp_show_netlink_file(struct filter
*f
)
3655 if ((fp
= fopen(getenv("TCPDIAG_FILE"), "r")) == NULL
) {
3656 perror("fopen($TCPDIAG_FILE)");
3662 size_t status
, nitems
;
3663 struct nlmsghdr
*h
= (struct nlmsghdr
*)buf
;
3664 struct sockstat s
= {};
3666 status
= fread(buf
, 1, sizeof(*h
), fp
);
3667 if (status
!= sizeof(*h
)) {
3669 perror("Reading header from $TCPDIAG_FILE");
3671 fprintf(stderr
, "Unexpected EOF reading $TCPDIAG_FILE");
3675 nitems
= NLMSG_ALIGN(h
->nlmsg_len
- sizeof(*h
));
3676 status
= fread(h
+1, 1, nitems
, fp
);
3678 if (status
!= nitems
) {
3680 perror("Reading $TCPDIAG_FILE");
3682 fprintf(stderr
, "Unexpected EOF reading $TCPDIAG_FILE");
3686 /* The only legal exit point */
3687 if (h
->nlmsg_type
== NLMSG_DONE
) {
3692 if (h
->nlmsg_type
== NLMSG_ERROR
) {
3693 struct nlmsgerr
*err
= (struct nlmsgerr
*)NLMSG_DATA(h
);
3695 if (h
->nlmsg_len
< NLMSG_LENGTH(sizeof(struct nlmsgerr
))) {
3696 fprintf(stderr
, "ERROR truncated\n");
3698 errno
= -err
->error
;
3699 perror("TCPDIAG answered");
3704 parse_diag_msg(h
, &s
);
3705 s
.type
= IPPROTO_TCP
;
3707 if (f
&& f
->f
&& run_ssfilter(f
->f
, &s
) == 0)
3710 err2
= inet_show_sock(h
, &s
);
3721 static int tcp_show(struct filter
*f
)
3725 int bufsize
= 1024*1024;
3727 if (!filter_af_get(f
, AF_INET
) && !filter_af_get(f
, AF_INET6
))
3730 dg_proto
= TCP_PROTO
;
3732 if (getenv("TCPDIAG_FILE"))
3733 return tcp_show_netlink_file(f
);
3735 if (!getenv("PROC_NET_TCP") && !getenv("PROC_ROOT")
3736 && inet_show_netlink(f
, NULL
, IPPROTO_TCP
) == 0)
3739 /* Sigh... We have to parse /proc/net/tcp... */
3740 while (bufsize
>= 64*1024) {
3741 if ((buf
= malloc(bufsize
)) != NULL
)
3750 if (f
->families
& FAMILY_MASK(AF_INET
)) {
3751 if ((fp
= net_tcp_open()) == NULL
)
3754 setbuffer(fp
, buf
, bufsize
);
3755 if (generic_record_read(fp
, tcp_show_line
, f
, AF_INET
))
3760 if ((f
->families
& FAMILY_MASK(AF_INET6
)) &&
3761 (fp
= net_tcp6_open()) != NULL
) {
3762 setbuffer(fp
, buf
, bufsize
);
3763 if (generic_record_read(fp
, tcp_show_line
, f
, AF_INET6
))
3773 int saved_errno
= errno
;
3778 errno
= saved_errno
;
3783 static int mptcp_show(struct filter
*f
)
3785 if (!filter_af_get(f
, AF_INET
) && !filter_af_get(f
, AF_INET6
))
3788 if (!getenv("PROC_NET_MPTCP") && !getenv("PROC_ROOT")
3789 && inet_show_netlink(f
, NULL
, IPPROTO_MPTCP
) == 0)
3795 static int dccp_show(struct filter
*f
)
3797 if (!filter_af_get(f
, AF_INET
) && !filter_af_get(f
, AF_INET6
))
3800 if (!getenv("PROC_NET_DCCP") && !getenv("PROC_ROOT")
3801 && inet_show_netlink(f
, NULL
, IPPROTO_DCCP
) == 0)
3807 static int sctp_show(struct filter
*f
)
3809 if (!filter_af_get(f
, AF_INET
) && !filter_af_get(f
, AF_INET6
))
3812 if (!getenv("PROC_NET_SCTP") && !getenv("PROC_ROOT")
3813 && inet_show_netlink(f
, NULL
, IPPROTO_SCTP
) == 0)
3819 static int dgram_show_line(char *line
, const struct filter
*f
, int family
)
3821 struct sockstat s
= {};
3822 char *loc
, *rem
, *data
;
3826 if (proc_inet_split_line(line
, &loc
, &rem
, &data
))
3829 int state
= (data
[1] >= 'A') ? (data
[1] - 'A' + 10) : (data
[1] - '0');
3831 if (!(f
->states
& (1 << state
)))
3834 proc_parse_inet_addr(loc
, rem
, family
, &s
);
3836 if (f
->f
&& run_ssfilter(f
->f
, &s
) == 0)
3840 n
= sscanf(data
, "%x %x:%x %*x:%*x %*x %d %*d %u %d %llx %[^\n]\n",
3841 &s
.state
, &s
.wq
, &s
.rq
,
3843 &s
.refcnt
, &s
.sk
, opt
);
3848 s
.type
= dg_proto
== UDP_PROTO
? IPPROTO_UDP
: 0;
3849 inet_stats_print(&s
, false);
3851 if (show_details
&& opt
[0])
3852 out(" opt:\"%s\"", opt
);
3857 static int udp_show(struct filter
*f
)
3861 if (!filter_af_get(f
, AF_INET
) && !filter_af_get(f
, AF_INET6
))
3864 dg_proto
= UDP_PROTO
;
3866 if (!getenv("PROC_NET_UDP") && !getenv("PROC_ROOT")
3867 && inet_show_netlink(f
, NULL
, IPPROTO_UDP
) == 0)
3870 if (f
->families
&FAMILY_MASK(AF_INET
)) {
3871 if ((fp
= net_udp_open()) == NULL
)
3873 if (generic_record_read(fp
, dgram_show_line
, f
, AF_INET
))
3878 if ((f
->families
&FAMILY_MASK(AF_INET6
)) &&
3879 (fp
= net_udp6_open()) != NULL
) {
3880 if (generic_record_read(fp
, dgram_show_line
, f
, AF_INET6
))
3888 int saved_errno
= errno
;
3892 errno
= saved_errno
;
3897 static int raw_show(struct filter
*f
)
3901 if (!filter_af_get(f
, AF_INET
) && !filter_af_get(f
, AF_INET6
))
3904 dg_proto
= RAW_PROTO
;
3906 if (!getenv("PROC_NET_RAW") && !getenv("PROC_ROOT") &&
3907 inet_show_netlink(f
, NULL
, IPPROTO_RAW
) == 0)
3910 if (f
->families
&FAMILY_MASK(AF_INET
)) {
3911 if ((fp
= net_raw_open()) == NULL
)
3913 if (generic_record_read(fp
, dgram_show_line
, f
, AF_INET
))
3918 if ((f
->families
&FAMILY_MASK(AF_INET6
)) &&
3919 (fp
= net_raw6_open()) != NULL
) {
3920 if (generic_record_read(fp
, dgram_show_line
, f
, AF_INET6
))
3928 int saved_errno
= errno
;
3932 errno
= saved_errno
;
3937 #define MAX_UNIX_REMEMBER (1024*1024/sizeof(struct sockstat))
3939 static void unix_list_drop_first(struct sockstat
**list
)
3941 struct sockstat
*s
= *list
;
3943 (*list
) = (*list
)->next
;
3948 static bool unix_type_skip(struct sockstat
*s
, struct filter
*f
)
3950 if (s
->type
== SOCK_STREAM
&& !(f
->dbs
&(1<<UNIX_ST_DB
)))
3952 if (s
->type
== SOCK_DGRAM
&& !(f
->dbs
&(1<<UNIX_DG_DB
)))
3954 if (s
->type
== SOCK_SEQPACKET
&& !(f
->dbs
&(1<<UNIX_SQ_DB
)))
3959 static void unix_stats_print(struct sockstat
*s
, struct filter
*f
)
3961 char port_name
[30] = {};
3963 sock_state_print(s
);
3965 sock_addr_print(s
->name
?: "*", " ",
3966 int_to_str(s
->lport
, port_name
), NULL
);
3967 sock_addr_print(s
->peer_name
?: "*", " ",
3968 int_to_str(s
->rport
, port_name
), NULL
);
3973 static int unix_show_sock(struct nlmsghdr
*nlh
, void *arg
)
3975 struct filter
*f
= (struct filter
*)arg
;
3976 struct unix_diag_msg
*r
= NLMSG_DATA(nlh
);
3977 struct rtattr
*tb
[UNIX_DIAG_MAX
+1];
3979 struct sockstat stat
= { .name
= "*", .peer_name
= "*" };
3981 parse_rtattr(tb
, UNIX_DIAG_MAX
, (struct rtattr
*)(r
+1),
3982 nlh
->nlmsg_len
- NLMSG_LENGTH(sizeof(*r
)));
3984 stat
.type
= r
->udiag_type
;
3985 stat
.state
= r
->udiag_state
;
3986 stat
.ino
= stat
.lport
= r
->udiag_ino
;
3987 stat
.local
.family
= stat
.remote
.family
= AF_UNIX
;
3989 if (unix_type_skip(&stat
, f
))
3992 if (tb
[UNIX_DIAG_RQLEN
]) {
3993 struct unix_diag_rqlen
*rql
= RTA_DATA(tb
[UNIX_DIAG_RQLEN
]);
3995 stat
.rq
= rql
->udiag_rqueue
;
3996 stat
.wq
= rql
->udiag_wqueue
;
3998 if (tb
[UNIX_DIAG_NAME
]) {
3999 int len
= RTA_PAYLOAD(tb
[UNIX_DIAG_NAME
]);
4001 memcpy(name
, RTA_DATA(tb
[UNIX_DIAG_NAME
]), len
);
4003 if (name
[0] == '\0') {
4005 for (i
= 0; i
< len
; i
++)
4006 if (name
[i
] == '\0')
4009 stat
.name
= &name
[0];
4010 memcpy(stat
.local
.data
, &stat
.name
, sizeof(stat
.name
));
4012 if (tb
[UNIX_DIAG_PEER
])
4013 stat
.rport
= rta_getattr_u32(tb
[UNIX_DIAG_PEER
]);
4015 if (f
->f
&& run_ssfilter(f
->f
, &stat
) == 0)
4018 unix_stats_print(&stat
, f
);
4021 print_skmeminfo(tb
, UNIX_DIAG_MEMINFO
);
4023 if (tb
[UNIX_DIAG_SHUTDOWN
]) {
4026 mask
= rta_getattr_u8(tb
[UNIX_DIAG_SHUTDOWN
]);
4028 mask
& 1 ? '-' : '<', mask
& 2 ? '-' : '>');
4030 if (tb
[UNIX_DIAG_VFS
]) {
4031 struct unix_diag_vfs
*uv
= RTA_DATA(tb
[UNIX_DIAG_VFS
]);
4033 out(" ino:%u dev:%u/%u", uv
->udiag_vfs_ino
, major(uv
->udiag_vfs_dev
),
4034 minor(uv
->udiag_vfs_dev
));
4036 if (tb
[UNIX_DIAG_ICONS
]) {
4037 int len
= RTA_PAYLOAD(tb
[UNIX_DIAG_ICONS
]);
4038 __u32
*peers
= RTA_DATA(tb
[UNIX_DIAG_ICONS
]);
4042 for (i
= 0; i
< len
/ sizeof(__u32
); i
++)
4043 out(" %u", peers
[i
]);
4050 static int handle_netlink_request(struct filter
*f
, struct nlmsghdr
*req
,
4051 size_t size
, rtnl_filter_t show_one_sock
)
4054 struct rtnl_handle rth
;
4056 if (rtnl_open_byproto(&rth
, 0, NETLINK_SOCK_DIAG
))
4059 rth
.dump
= MAGIC_SEQ
;
4061 if (rtnl_send(&rth
, req
, size
) < 0)
4064 if (rtnl_dump_filter(&rth
, show_one_sock
, f
))
4073 static int unix_show_netlink(struct filter
*f
)
4075 DIAG_REQUEST(req
, struct unix_diag_req r
);
4077 req
.r
.sdiag_family
= AF_UNIX
;
4078 req
.r
.udiag_states
= f
->states
;
4079 req
.r
.udiag_show
= UDIAG_SHOW_NAME
| UDIAG_SHOW_PEER
| UDIAG_SHOW_RQLEN
;
4081 req
.r
.udiag_show
|= UDIAG_SHOW_MEMINFO
;
4083 req
.r
.udiag_show
|= UDIAG_SHOW_VFS
| UDIAG_SHOW_ICONS
;
4085 return handle_netlink_request(f
, &req
.nlh
, sizeof(req
), unix_show_sock
);
4088 static int unix_show(struct filter
*f
)
4095 struct sockstat
*list
= NULL
;
4096 const int unix_state_map
[] = { SS_CLOSE
, SS_SYN_SENT
,
4097 SS_ESTABLISHED
, SS_CLOSING
};
4099 if (!filter_af_get(f
, AF_UNIX
))
4102 if (!getenv("PROC_NET_UNIX") && !getenv("PROC_ROOT")
4103 && unix_show_netlink(f
) == 0)
4106 if ((fp
= net_unix_open()) == NULL
)
4108 if (!fgets(buf
, sizeof(buf
), fp
)) {
4113 if (memcmp(buf
, "Peer", 4) == 0)
4117 while (fgets(buf
, sizeof(buf
), fp
)) {
4118 struct sockstat
*u
, **insp
;
4121 if (!(u
= calloc(1, sizeof(*u
))))
4124 if (sscanf(buf
, "%x: %x %x %x %x %x %d %s",
4125 &u
->rport
, &u
->rq
, &u
->wq
, &flags
, &u
->type
,
4126 &u
->state
, &u
->ino
, name
) < 8)
4130 u
->local
.family
= u
->remote
.family
= AF_UNIX
;
4132 if (flags
& (1 << 16)) {
4133 u
->state
= SS_LISTEN
;
4134 } else if (u
->state
> 0 &&
4135 u
->state
<= ARRAY_SIZE(unix_state_map
)) {
4136 u
->state
= unix_state_map
[u
->state
-1];
4137 if (u
->type
== SOCK_DGRAM
&& u
->state
== SS_CLOSE
&& u
->rport
)
4138 u
->state
= SS_ESTABLISHED
;
4140 if (unix_type_skip(u
, f
) ||
4141 !(f
->states
& (1 << u
->state
))) {
4153 u
->name
= strdup(name
);
4163 for (p
= list
; p
; p
= p
->next
) {
4164 if (u
->rport
== p
->lport
)
4170 u
->peer_name
= p
->name
? : "*";
4174 struct sockstat st
= {
4175 .local
.family
= AF_UNIX
,
4176 .remote
.family
= AF_UNIX
,
4179 memcpy(st
.local
.data
, &u
->name
, sizeof(u
->name
));
4180 /* when parsing the old format rport is set to 0 and
4181 * therefore peer_name remains NULL
4183 if (u
->peer_name
&& strcmp(u
->peer_name
, "*"))
4184 memcpy(st
.remote
.data
, &u
->peer_name
,
4185 sizeof(u
->peer_name
));
4186 if (run_ssfilter(f
->f
, &st
) == 0) {
4195 if (u
->type
< (*insp
)->type
||
4196 (u
->type
== (*insp
)->type
&&
4197 u
->ino
< (*insp
)->ino
))
4199 insp
= &(*insp
)->next
;
4204 if (++cnt
> MAX_UNIX_REMEMBER
) {
4206 unix_stats_print(list
, f
);
4207 unix_list_drop_first(&list
);
4214 unix_stats_print(list
, f
);
4215 unix_list_drop_first(&list
);
4221 static int packet_stats_print(struct sockstat
*s
, const struct filter
*f
)
4223 const char *addr
, *port
;
4226 s
->local
.family
= s
->remote
.family
= AF_PACKET
;
4229 s
->local
.data
[0] = s
->prot
;
4230 if (run_ssfilter(f
->f
, s
) == 0)
4234 sock_state_print(s
);
4239 addr
= ll_proto_n2a(htons(s
->prot
), ll_name
, sizeof(ll_name
));
4244 port
= xll_index_to_name(s
->iface
);
4246 sock_addr_print(addr
, ":", port
, NULL
);
4247 sock_addr_print("", "*", "", NULL
);
4252 sock_details_print(s
);
4257 static void packet_show_ring(struct packet_diag_ring
*ring
)
4259 out("blk_size:%d", ring
->pdr_block_size
);
4260 out(",blk_nr:%d", ring
->pdr_block_nr
);
4261 out(",frm_size:%d", ring
->pdr_frame_size
);
4262 out(",frm_nr:%d", ring
->pdr_frame_nr
);
4263 out(",tmo:%d", ring
->pdr_retire_tmo
);
4264 out(",features:0x%x", ring
->pdr_features
);
4267 static int packet_show_sock(struct nlmsghdr
*nlh
, void *arg
)
4269 const struct filter
*f
= arg
;
4270 struct packet_diag_msg
*r
= NLMSG_DATA(nlh
);
4271 struct packet_diag_info
*pinfo
= NULL
;
4272 struct packet_diag_ring
*ring_rx
= NULL
, *ring_tx
= NULL
;
4273 struct rtattr
*tb
[PACKET_DIAG_MAX
+1];
4274 struct sockstat stat
= {};
4275 uint32_t fanout
= 0;
4276 bool has_fanout
= false;
4278 parse_rtattr(tb
, PACKET_DIAG_MAX
, (struct rtattr
*)(r
+1),
4279 nlh
->nlmsg_len
- NLMSG_LENGTH(sizeof(*r
)));
4281 /* use /proc/net/packet if all info are not available */
4282 if (!tb
[PACKET_DIAG_MEMINFO
])
4285 stat
.type
= r
->pdiag_type
;
4286 stat
.prot
= r
->pdiag_num
;
4287 stat
.ino
= r
->pdiag_ino
;
4288 stat
.state
= SS_CLOSE
;
4289 stat
.sk
= cookie_sk_get(&r
->pdiag_cookie
[0]);
4291 if (tb
[PACKET_DIAG_MEMINFO
]) {
4292 __u32
*skmeminfo
= RTA_DATA(tb
[PACKET_DIAG_MEMINFO
]);
4294 stat
.rq
= skmeminfo
[SK_MEMINFO_RMEM_ALLOC
];
4297 if (tb
[PACKET_DIAG_INFO
]) {
4298 pinfo
= RTA_DATA(tb
[PACKET_DIAG_INFO
]);
4299 stat
.lport
= stat
.iface
= pinfo
->pdi_index
;
4302 if (tb
[PACKET_DIAG_UID
])
4303 stat
.uid
= rta_getattr_u32(tb
[PACKET_DIAG_UID
]);
4305 if (tb
[PACKET_DIAG_RX_RING
])
4306 ring_rx
= RTA_DATA(tb
[PACKET_DIAG_RX_RING
]);
4308 if (tb
[PACKET_DIAG_TX_RING
])
4309 ring_tx
= RTA_DATA(tb
[PACKET_DIAG_TX_RING
]);
4311 if (tb
[PACKET_DIAG_FANOUT
]) {
4313 fanout
= rta_getattr_u32(tb
[PACKET_DIAG_FANOUT
]);
4316 if (packet_stats_print(&stat
, f
))
4322 out(" ver:%d", pinfo
->pdi_version
);
4324 out("\n\tver:%d", pinfo
->pdi_version
);
4325 out(" cpy_thresh:%d", pinfo
->pdi_copy_thresh
);
4327 if (pinfo
->pdi_flags
& PDI_RUNNING
)
4329 if (pinfo
->pdi_flags
& PDI_AUXDATA
)
4331 if (pinfo
->pdi_flags
& PDI_ORIGDEV
)
4333 if (pinfo
->pdi_flags
& PDI_VNETHDR
)
4335 if (pinfo
->pdi_flags
& PDI_LOSS
)
4337 if (!pinfo
->pdi_flags
)
4345 out("\n\tring_rx(");
4346 packet_show_ring(ring_rx
);
4353 out("\n\tring_tx(");
4354 packet_show_ring(ring_tx
);
4358 uint16_t type
= (fanout
>> 16) & 0xffff;
4364 out("id:%d,", fanout
& 0xffff);
4386 if (show_bpf
&& tb
[PACKET_DIAG_FILTER
]) {
4387 struct sock_filter
*fil
=
4388 RTA_DATA(tb
[PACKET_DIAG_FILTER
]);
4389 int num
= RTA_PAYLOAD(tb
[PACKET_DIAG_FILTER
]) /
4390 sizeof(struct sock_filter
);
4393 out(" bpf filter (%d): ", num
);
4395 out("\n\tbpf filter (%d): ", num
);
4397 out(" 0x%02x %u %u %u,",
4398 fil
->code
, fil
->jt
, fil
->jf
, fil
->k
);
4405 print_skmeminfo(tb
, PACKET_DIAG_MEMINFO
);
4409 static int packet_show_netlink(struct filter
*f
)
4411 DIAG_REQUEST(req
, struct packet_diag_req r
);
4413 req
.r
.sdiag_family
= AF_PACKET
;
4414 req
.r
.pdiag_show
= PACKET_SHOW_INFO
| PACKET_SHOW_MEMINFO
|
4415 PACKET_SHOW_FILTER
| PACKET_SHOW_RING_CFG
| PACKET_SHOW_FANOUT
;
4417 return handle_netlink_request(f
, &req
.nlh
, sizeof(req
), packet_show_sock
);
4420 static int packet_show_line(char *buf
, const struct filter
*f
, int fam
)
4422 unsigned long long sk
;
4423 struct sockstat stat
= {};
4424 int type
, prot
, iface
, state
, rq
, uid
, ino
;
4426 sscanf(buf
, "%llx %*d %d %x %d %d %u %u %u",
4428 &type
, &prot
, &iface
, &state
,
4431 if (stat
.type
== SOCK_RAW
&& !(f
->dbs
&(1<<PACKET_R_DB
)))
4433 if (stat
.type
== SOCK_DGRAM
&& !(f
->dbs
&(1<<PACKET_DG_DB
)))
4438 stat
.lport
= stat
.iface
= iface
;
4443 stat
.state
= SS_CLOSE
;
4445 if (packet_stats_print(&stat
, f
))
4451 static int packet_show(struct filter
*f
)
4456 if (!filter_af_get(f
, AF_PACKET
) || !(f
->states
& (1 << SS_CLOSE
)))
4459 if (!getenv("PROC_NET_PACKET") && !getenv("PROC_ROOT") &&
4460 packet_show_netlink(f
) == 0)
4463 if ((fp
= net_packet_open()) == NULL
)
4465 if (generic_record_read(fp
, packet_show_line
, f
, AF_PACKET
))
4472 static int xdp_stats_print(struct sockstat
*s
, const struct filter
*f
)
4474 const char *addr
, *port
;
4477 s
->local
.family
= s
->remote
.family
= AF_XDP
;
4480 if (run_ssfilter(f
->f
, s
) == 0)
4484 sock_state_print(s
);
4487 addr
= xll_index_to_name(s
->iface
);
4488 snprintf(q_str
, sizeof(q_str
), "q%d", s
->lport
);
4490 sock_addr_print(addr
, ":", port
, NULL
);
4492 sock_addr_print("", "*", "", NULL
);
4495 sock_addr_print("", "*", "", NULL
);
4500 sock_details_print(s
);
4505 static void xdp_show_ring(const char *name
, struct xdp_diag_ring
*ring
)
4510 out("\n\t%s(", name
);
4511 out("entries:%u", ring
->entries
);
4515 static void xdp_show_umem(struct xdp_diag_umem
*umem
, struct xdp_diag_ring
*fr
,
4516 struct xdp_diag_ring
*cr
)
4522 out("id:%u", umem
->id
);
4523 out(",size:%llu", umem
->size
);
4524 out(",num_pages:%u", umem
->num_pages
);
4525 out(",chunk_size:%u", umem
->chunk_size
);
4526 out(",headroom:%u", umem
->headroom
);
4527 out(",ifindex:%u", umem
->ifindex
);
4528 out(",qid:%u", umem
->queue_id
);
4529 out(",zc:%u", umem
->flags
& XDP_DU_F_ZEROCOPY
);
4530 out(",refs:%u", umem
->refs
);
4534 xdp_show_ring("fr", fr
);
4536 xdp_show_ring("cr", cr
);
4539 static void xdp_show_stats(struct xdp_diag_stats
*stats
)
4545 out("rx dropped:%llu", stats
->n_rx_dropped
);
4546 out(",rx invalid:%llu", stats
->n_rx_invalid
);
4547 out(",rx queue full:%llu", stats
->n_rx_full
);
4548 out(",rx fill ring empty:%llu", stats
->n_fill_ring_empty
);
4549 out(",tx invalid:%llu", stats
->n_tx_invalid
);
4550 out(",tx ring empty:%llu", stats
->n_tx_ring_empty
);
4554 static int xdp_show_sock(struct nlmsghdr
*nlh
, void *arg
)
4556 struct xdp_diag_ring
*rx
= NULL
, *tx
= NULL
, *fr
= NULL
, *cr
= NULL
;
4557 struct xdp_diag_msg
*msg
= NLMSG_DATA(nlh
);
4558 struct rtattr
*tb
[XDP_DIAG_MAX
+ 1];
4559 struct xdp_diag_info
*info
= NULL
;
4560 struct xdp_diag_umem
*umem
= NULL
;
4561 struct xdp_diag_stats
*stats
= NULL
;
4562 const struct filter
*f
= arg
;
4563 struct sockstat stat
= {};
4565 parse_rtattr(tb
, XDP_DIAG_MAX
, (struct rtattr
*)(msg
+ 1),
4566 nlh
->nlmsg_len
- NLMSG_LENGTH(sizeof(*msg
)));
4568 stat
.type
= msg
->xdiag_type
;
4569 stat
.ino
= msg
->xdiag_ino
;
4570 stat
.state
= SS_CLOSE
;
4571 stat
.sk
= cookie_sk_get(&msg
->xdiag_cookie
[0]);
4573 if (tb
[XDP_DIAG_INFO
]) {
4574 info
= RTA_DATA(tb
[XDP_DIAG_INFO
]);
4575 stat
.iface
= info
->ifindex
;
4576 stat
.lport
= info
->queue_id
;
4579 if (tb
[XDP_DIAG_UID
])
4580 stat
.uid
= rta_getattr_u32(tb
[XDP_DIAG_UID
]);
4581 if (tb
[XDP_DIAG_RX_RING
])
4582 rx
= RTA_DATA(tb
[XDP_DIAG_RX_RING
]);
4583 if (tb
[XDP_DIAG_TX_RING
])
4584 tx
= RTA_DATA(tb
[XDP_DIAG_TX_RING
]);
4585 if (tb
[XDP_DIAG_UMEM
])
4586 umem
= RTA_DATA(tb
[XDP_DIAG_UMEM
]);
4587 if (tb
[XDP_DIAG_UMEM_FILL_RING
])
4588 fr
= RTA_DATA(tb
[XDP_DIAG_UMEM_FILL_RING
]);
4589 if (tb
[XDP_DIAG_UMEM_COMPLETION_RING
])
4590 cr
= RTA_DATA(tb
[XDP_DIAG_UMEM_COMPLETION_RING
]);
4591 if (tb
[XDP_DIAG_MEMINFO
]) {
4592 __u32
*skmeminfo
= RTA_DATA(tb
[XDP_DIAG_MEMINFO
]);
4594 stat
.rq
= skmeminfo
[SK_MEMINFO_RMEM_ALLOC
];
4596 if (tb
[XDP_DIAG_STATS
])
4597 stats
= RTA_DATA(tb
[XDP_DIAG_STATS
]);
4599 if (xdp_stats_print(&stat
, f
))
4604 xdp_show_ring("rx", rx
);
4606 xdp_show_ring("tx", tx
);
4608 xdp_show_umem(umem
, fr
, cr
);
4610 xdp_show_stats(stats
);
4614 print_skmeminfo(tb
, XDP_DIAG_MEMINFO
); // really?
4620 static int xdp_show(struct filter
*f
)
4622 DIAG_REQUEST(req
, struct xdp_diag_req r
);
4624 if (!filter_af_get(f
, AF_XDP
) || !(f
->states
& (1 << SS_CLOSE
)))
4627 req
.r
.sdiag_family
= AF_XDP
;
4628 req
.r
.xdiag_show
= XDP_SHOW_INFO
| XDP_SHOW_RING_CFG
| XDP_SHOW_UMEM
|
4629 XDP_SHOW_MEMINFO
| XDP_SHOW_STATS
;
4631 return handle_netlink_request(f
, &req
.nlh
, sizeof(req
), xdp_show_sock
);
4634 static int netlink_show_one(struct filter
*f
,
4635 int prot
, int pid
, unsigned int groups
,
4636 int state
, int dst_pid
, unsigned int dst_group
,
4638 unsigned long long sk
, unsigned long long cb
)
4640 struct sockstat st
= {
4644 .local
.family
= AF_NETLINK
,
4645 .remote
.family
= AF_NETLINK
,
4648 SPRINT_BUF(prot_buf
) = {};
4649 const char *prot_name
;
4650 char procname
[64] = {};
4655 st
.local
.data
[0] = prot
;
4656 if (run_ssfilter(f
->f
, &st
) == 0)
4660 sock_state_print(&st
);
4662 prot_name
= nl_proto_n2a(prot
, prot_buf
, sizeof(prot_buf
));
4666 } else if (!numeric
) {
4671 strncpy(procname
, "kernel", 7);
4672 } else if (pid
> 0) {
4675 snprintf(procname
, sizeof(procname
), "%s/%d/stat",
4676 getenv("PROC_ROOT") ? : "/proc", pid
);
4677 if ((fp
= fopen(procname
, "r")) != NULL
) {
4678 if (fscanf(fp
, "%*d (%[^)])", procname
) == 1) {
4679 snprintf(procname
+strlen(procname
),
4680 sizeof(procname
)-strlen(procname
),
4688 int_to_str(pid
, procname
);
4690 int_to_str(pid
, procname
);
4693 sock_addr_print(prot_name
, ":", procname
, NULL
);
4695 if (state
== NETLINK_CONNECTED
) {
4696 char dst_group_buf
[30];
4697 char dst_pid_buf
[30];
4699 sock_addr_print(int_to_str(dst_group
, dst_group_buf
), ":",
4700 int_to_str(dst_pid
, dst_pid_buf
), NULL
);
4702 sock_addr_print("", "*", "", NULL
);
4705 char *pid_context
= NULL
;
4707 if (show_proc_ctx
) {
4708 /* The pid value will either be:
4709 * 0 if destination kernel - show kernel initial context.
4710 * A valid process pid - use getpidcon.
4711 * A unique value allocated by the kernel or netlink user
4712 * to the process - show context as "not available".
4715 security_get_initial_context("kernel", &pid_context
);
4717 getpidcon(pid
, &pid_context
);
4719 out(" proc_ctx=%s", pid_context
? : "unavailable");
4724 out(" sk=%llx cb=%llx groups=0x%08x", sk
, cb
, groups
);
4730 static int netlink_show_sock(struct nlmsghdr
*nlh
, void *arg
)
4732 struct filter
*f
= (struct filter
*)arg
;
4733 struct netlink_diag_msg
*r
= NLMSG_DATA(nlh
);
4734 struct rtattr
*tb
[NETLINK_DIAG_MAX
+1];
4736 unsigned long groups
= 0;
4738 parse_rtattr(tb
, NETLINK_DIAG_MAX
, (struct rtattr
*)(r
+1),
4739 nlh
->nlmsg_len
- NLMSG_LENGTH(sizeof(*r
)));
4741 if (tb
[NETLINK_DIAG_GROUPS
] && RTA_PAYLOAD(tb
[NETLINK_DIAG_GROUPS
]))
4742 groups
= *(unsigned long *) RTA_DATA(tb
[NETLINK_DIAG_GROUPS
]);
4744 if (tb
[NETLINK_DIAG_MEMINFO
]) {
4745 const __u32
*skmeminfo
;
4747 skmeminfo
= RTA_DATA(tb
[NETLINK_DIAG_MEMINFO
]);
4749 rq
= skmeminfo
[SK_MEMINFO_RMEM_ALLOC
];
4750 wq
= skmeminfo
[SK_MEMINFO_WMEM_ALLOC
];
4753 if (netlink_show_one(f
, r
->ndiag_protocol
, r
->ndiag_portid
, groups
,
4754 r
->ndiag_state
, r
->ndiag_dst_portid
, r
->ndiag_dst_group
,
4761 print_skmeminfo(tb
, NETLINK_DIAG_MEMINFO
);
4767 static int netlink_show_netlink(struct filter
*f
)
4769 DIAG_REQUEST(req
, struct netlink_diag_req r
);
4771 req
.r
.sdiag_family
= AF_NETLINK
;
4772 req
.r
.sdiag_protocol
= NDIAG_PROTO_ALL
;
4773 req
.r
.ndiag_show
= NDIAG_SHOW_GROUPS
| NDIAG_SHOW_MEMINFO
;
4775 return handle_netlink_request(f
, &req
.nlh
, sizeof(req
), netlink_show_sock
);
4778 static int netlink_show(struct filter
*f
)
4783 unsigned int groups
;
4785 unsigned long long sk
, cb
;
4787 if (!filter_af_get(f
, AF_NETLINK
) || !(f
->states
& (1 << SS_CLOSE
)))
4790 if (!getenv("PROC_NET_NETLINK") && !getenv("PROC_ROOT") &&
4791 netlink_show_netlink(f
) == 0)
4794 if ((fp
= net_netlink_open()) == NULL
)
4796 if (!fgets(buf
, sizeof(buf
), fp
)) {
4801 while (fgets(buf
, sizeof(buf
), fp
)) {
4802 sscanf(buf
, "%llx %d %d %x %d %d %llx %d",
4804 &prot
, &pid
, &groups
, &rq
, &wq
, &cb
, &rc
);
4806 netlink_show_one(f
, prot
, pid
, groups
, 0, 0, 0, rq
, wq
, sk
, cb
);
4813 static bool vsock_type_skip(struct sockstat
*s
, struct filter
*f
)
4815 if (s
->type
== SOCK_STREAM
&& !(f
->dbs
& (1 << VSOCK_ST_DB
)))
4817 if (s
->type
== SOCK_DGRAM
&& !(f
->dbs
& (1 << VSOCK_DG_DB
)))
4822 static void vsock_addr_print(inet_prefix
*a
, __u32 port
)
4824 char cid_str
[sizeof("4294967295")];
4825 char port_str
[sizeof("4294967295")];
4828 memcpy(&cid
, a
->data
, sizeof(cid
));
4830 if (cid
== ~(__u32
)0)
4831 snprintf(cid_str
, sizeof(cid_str
), "*");
4833 snprintf(cid_str
, sizeof(cid_str
), "%u", cid
);
4835 if (port
== ~(__u32
)0)
4836 snprintf(port_str
, sizeof(port_str
), "*");
4838 snprintf(port_str
, sizeof(port_str
), "%u", port
);
4840 sock_addr_print(cid_str
, ":", port_str
, NULL
);
4843 static void vsock_stats_print(struct sockstat
*s
, struct filter
*f
)
4845 sock_state_print(s
);
4847 vsock_addr_print(&s
->local
, s
->lport
);
4848 vsock_addr_print(&s
->remote
, s
->rport
);
4853 static int vsock_show_sock(struct nlmsghdr
*nlh
, void *arg
)
4855 struct filter
*f
= (struct filter
*)arg
;
4856 struct vsock_diag_msg
*r
= NLMSG_DATA(nlh
);
4857 struct sockstat stat
= {
4858 .type
= r
->vdiag_type
,
4859 .lport
= r
->vdiag_src_port
,
4860 .rport
= r
->vdiag_dst_port
,
4861 .state
= r
->vdiag_state
,
4862 .ino
= r
->vdiag_ino
,
4865 vsock_set_inet_prefix(&stat
.local
, r
->vdiag_src_cid
);
4866 vsock_set_inet_prefix(&stat
.remote
, r
->vdiag_dst_cid
);
4868 if (vsock_type_skip(&stat
, f
))
4871 if (f
->f
&& run_ssfilter(f
->f
, &stat
) == 0)
4874 vsock_stats_print(&stat
, f
);
4879 static int vsock_show(struct filter
*f
)
4881 DIAG_REQUEST(req
, struct vsock_diag_req r
);
4883 if (!filter_af_get(f
, AF_VSOCK
))
4886 req
.r
.sdiag_family
= AF_VSOCK
;
4887 req
.r
.vdiag_states
= f
->states
;
4889 return handle_netlink_request(f
, &req
.nlh
, sizeof(req
), vsock_show_sock
);
4892 static void tipc_sock_addr_print(struct rtattr
*net_addr
, struct rtattr
*id
)
4894 uint32_t node
= rta_getattr_u32(net_addr
);
4895 uint32_t identity
= rta_getattr_u32(id
);
4897 SPRINT_BUF(addr
) = {};
4898 SPRINT_BUF(port
) = {};
4900 sprintf(addr
, "%u", node
);
4901 sprintf(port
, "%u", identity
);
4902 sock_addr_print(addr
, ":", port
, NULL
);
4906 static int tipc_show_sock(struct nlmsghdr
*nlh
, void *arg
)
4908 struct rtattr
*stat
[TIPC_NLA_SOCK_STAT_MAX
+ 1] = {};
4909 struct rtattr
*attrs
[TIPC_NLA_SOCK_MAX
+ 1] = {};
4910 struct rtattr
*con
[TIPC_NLA_CON_MAX
+ 1] = {};
4911 struct rtattr
*info
[TIPC_NLA_MAX
+ 1] = {};
4912 struct rtattr
*msg_ref
;
4913 struct sockstat ss
= {};
4915 parse_rtattr(info
, TIPC_NLA_MAX
, NLMSG_DATA(nlh
),
4916 NLMSG_PAYLOAD(nlh
, 0));
4918 if (!info
[TIPC_NLA_SOCK
])
4921 msg_ref
= info
[TIPC_NLA_SOCK
];
4922 parse_rtattr(attrs
, TIPC_NLA_SOCK_MAX
, RTA_DATA(msg_ref
),
4923 RTA_PAYLOAD(msg_ref
));
4925 msg_ref
= attrs
[TIPC_NLA_SOCK_STAT
];
4926 parse_rtattr(stat
, TIPC_NLA_SOCK_STAT_MAX
,
4927 RTA_DATA(msg_ref
), RTA_PAYLOAD(msg_ref
));
4930 ss
.local
.family
= AF_TIPC
;
4931 ss
.type
= rta_getattr_u32(attrs
[TIPC_NLA_SOCK_TYPE
]);
4932 ss
.state
= rta_getattr_u32(attrs
[TIPC_NLA_SOCK_TIPC_STATE
]);
4933 ss
.uid
= rta_getattr_u32(attrs
[TIPC_NLA_SOCK_UID
]);
4934 ss
.ino
= rta_getattr_u32(attrs
[TIPC_NLA_SOCK_INO
]);
4935 ss
.rq
= rta_getattr_u32(stat
[TIPC_NLA_SOCK_STAT_RCVQ
]);
4936 ss
.wq
= rta_getattr_u32(stat
[TIPC_NLA_SOCK_STAT_SENDQ
]);
4937 ss
.sk
= rta_getattr_u64(attrs
[TIPC_NLA_SOCK_COOKIE
]);
4939 sock_state_print (&ss
);
4941 tipc_sock_addr_print(attrs
[TIPC_NLA_SOCK_ADDR
],
4942 attrs
[TIPC_NLA_SOCK_REF
]);
4944 msg_ref
= attrs
[TIPC_NLA_SOCK_CON
];
4946 parse_rtattr(con
, TIPC_NLA_CON_MAX
,
4947 RTA_DATA(msg_ref
), RTA_PAYLOAD(msg_ref
));
4949 tipc_sock_addr_print(con
[TIPC_NLA_CON_NODE
],
4950 con
[TIPC_NLA_CON_SOCK
]);
4952 sock_addr_print("", "-", "", NULL
);
4955 sock_details_print(&ss
);
4957 proc_ctx_print(&ss
);
4959 if (show_tipcinfo
) {
4961 out(" type:%s", stype_nameg
[ss
.type
]);
4963 out("\n type:%s", stype_nameg
[ss
.type
]);
4965 stat
[TIPC_NLA_SOCK_STAT_LINK_CONG
] ? "link" :
4966 stat
[TIPC_NLA_SOCK_STAT_CONN_CONG
] ? "conn" : "none");
4968 rta_getattr_u32(stat
[TIPC_NLA_SOCK_STAT_DROP
]));
4970 if (attrs
[TIPC_NLA_SOCK_HAS_PUBL
])
4973 if (con
[TIPC_NLA_CON_FLAG
])
4974 out(" via {%u,%u} ",
4975 rta_getattr_u32(con
[TIPC_NLA_CON_TYPE
]),
4976 rta_getattr_u32(con
[TIPC_NLA_CON_INST
]));
4982 static int tipc_show(struct filter
*f
)
4984 DIAG_REQUEST(req
, struct tipc_sock_diag_req r
);
4986 memset(&req
.r
, 0, sizeof(req
.r
));
4987 req
.r
.sdiag_family
= AF_TIPC
;
4988 req
.r
.tidiag_states
= f
->states
;
4990 return handle_netlink_request(f
, &req
.nlh
, sizeof(req
), tipc_show_sock
);
4993 struct sock_diag_msg
{
4997 static int generic_show_sock(struct nlmsghdr
*nlh
, void *arg
)
4999 struct sock_diag_msg
*r
= NLMSG_DATA(nlh
);
5000 struct inet_diag_arg inet_arg
= { .f
= arg
, .protocol
= IPPROTO_MAX
};
5003 switch (r
->sdiag_family
) {
5006 inet_arg
.rth
= inet_arg
.f
->rth_for_killing
;
5007 ret
= show_one_inet_sock(nlh
, &inet_arg
);
5010 ret
= unix_show_sock(nlh
, arg
);
5013 ret
= packet_show_sock(nlh
, arg
);
5016 ret
= netlink_show_sock(nlh
, arg
);
5019 ret
= vsock_show_sock(nlh
, arg
);
5022 ret
= xdp_show_sock(nlh
, arg
);
5033 static int handle_follow_request(struct filter
*f
)
5037 struct rtnl_handle rth
, rth2
;
5039 if (f
->families
& FAMILY_MASK(AF_INET
) && f
->dbs
& (1 << TCP_DB
))
5040 groups
|= 1 << (SKNLGRP_INET_TCP_DESTROY
- 1);
5041 if (f
->families
& FAMILY_MASK(AF_INET
) && f
->dbs
& (1 << UDP_DB
))
5042 groups
|= 1 << (SKNLGRP_INET_UDP_DESTROY
- 1);
5043 if (f
->families
& FAMILY_MASK(AF_INET6
) && f
->dbs
& (1 << TCP_DB
))
5044 groups
|= 1 << (SKNLGRP_INET6_TCP_DESTROY
- 1);
5045 if (f
->families
& FAMILY_MASK(AF_INET6
) && f
->dbs
& (1 << UDP_DB
))
5046 groups
|= 1 << (SKNLGRP_INET6_UDP_DESTROY
- 1);
5051 if (rtnl_open_byproto(&rth
, groups
, NETLINK_SOCK_DIAG
))
5055 rth
.local
.nl_pid
= 0;
5058 if (rtnl_open_byproto(&rth2
, groups
, NETLINK_SOCK_DIAG
)) {
5062 f
->rth_for_killing
= &rth2
;
5065 if (rtnl_dump_filter(&rth
, generic_show_sock
, f
))
5069 if (f
->rth_for_killing
)
5070 rtnl_close(f
->rth_for_killing
);
5074 static int get_snmp_int(char *proto
, char *key
, int *result
)
5078 int protolen
= strlen(proto
);
5079 int keylen
= strlen(key
);
5083 if ((fp
= net_snmp_open()) == NULL
)
5086 while (fgets(buf
, sizeof(buf
), fp
) != NULL
) {
5090 if (memcmp(buf
, proto
, protolen
))
5092 while ((p
= strchr(p
, ' ')) != NULL
) {
5095 if (memcmp(p
, key
, keylen
) == 0 &&
5096 (p
[keylen
] == ' ' || p
[keylen
] == '\n'))
5099 if (fgets(buf
, sizeof(buf
), fp
) == NULL
)
5101 if (memcmp(buf
, proto
, protolen
))
5104 while ((p
= strchr(p
, ' ')) != NULL
) {
5107 sscanf(p
, "%d", result
);
5120 /* Get stats from sockstat */
5140 static void get_sockstat_line(char *line
, struct ssummary
*s
)
5142 char id
[256], rem
[256];
5144 if (sscanf(line
, "%[^ ] %[^\n]\n", id
, rem
) != 2)
5147 if (strcmp(id
, "sockets:") == 0)
5148 sscanf(rem
, "%*s%d", &s
->socks
);
5149 else if (strcmp(id
, "UDP:") == 0)
5150 sscanf(rem
, "%*s%d", &s
->udp4
);
5151 else if (strcmp(id
, "UDP6:") == 0)
5152 sscanf(rem
, "%*s%d", &s
->udp6
);
5153 else if (strcmp(id
, "RAW:") == 0)
5154 sscanf(rem
, "%*s%d", &s
->raw4
);
5155 else if (strcmp(id
, "RAW6:") == 0)
5156 sscanf(rem
, "%*s%d", &s
->raw6
);
5157 else if (strcmp(id
, "TCP6:") == 0)
5158 sscanf(rem
, "%*s%d", &s
->tcp6_hashed
);
5159 else if (strcmp(id
, "FRAG:") == 0)
5160 sscanf(rem
, "%*s%d%*s%d", &s
->frag4
, &s
->frag4_mem
);
5161 else if (strcmp(id
, "FRAG6:") == 0)
5162 sscanf(rem
, "%*s%d%*s%d", &s
->frag6
, &s
->frag6_mem
);
5163 else if (strcmp(id
, "TCP:") == 0)
5164 sscanf(rem
, "%*s%d%*s%d%*s%d%*s%d%*s%d",
5166 &s
->tcp_orphans
, &s
->tcp_tws
, &s
->tcp_total
, &s
->tcp_mem
);
5169 static int get_sockstat(struct ssummary
*s
)
5174 memset(s
, 0, sizeof(*s
));
5176 if ((fp
= net_sockstat_open()) == NULL
)
5178 while (fgets(buf
, sizeof(buf
), fp
) != NULL
)
5179 get_sockstat_line(buf
, s
);
5182 if ((fp
= net_sockstat6_open()) == NULL
)
5184 while (fgets(buf
, sizeof(buf
), fp
) != NULL
)
5185 get_sockstat_line(buf
, s
);
5191 static int print_summary(void)
5196 if (get_sockstat(&s
) < 0)
5197 perror("ss: get_sockstat");
5198 if (get_snmp_int("Tcp:", "CurrEstab", &tcp_estab
) < 0)
5199 perror("ss: get_snmpstat");
5201 printf("Total: %d\n", s
.socks
);
5203 printf("TCP: %d (estab %d, closed %d, orphaned %d, timewait %d)\n",
5204 s
.tcp_total
+ s
.tcp_tws
, tcp_estab
,
5205 s
.tcp_total
- (s
.tcp4_hashed
+ s
.tcp6_hashed
- s
.tcp_tws
),
5206 s
.tcp_orphans
, s
.tcp_tws
);
5209 printf("Transport Total IP IPv6\n");
5210 printf("RAW %-9d %-9d %-9d\n", s
.raw4
+s
.raw6
, s
.raw4
, s
.raw6
);
5211 printf("UDP %-9d %-9d %-9d\n", s
.udp4
+s
.udp6
, s
.udp4
, s
.udp6
);
5212 printf("TCP %-9d %-9d %-9d\n", s
.tcp4_hashed
+s
.tcp6_hashed
, s
.tcp4_hashed
, s
.tcp6_hashed
);
5213 printf("INET %-9d %-9d %-9d\n",
5214 s
.raw4
+s
.udp4
+s
.tcp4_hashed
+
5215 s
.raw6
+s
.udp6
+s
.tcp6_hashed
,
5216 s
.raw4
+s
.udp4
+s
.tcp4_hashed
,
5217 s
.raw6
+s
.udp6
+s
.tcp6_hashed
);
5218 printf("FRAG %-9d %-9d %-9d\n", s
.frag4
+s
.frag6
, s
.frag4
, s
.frag6
);
5225 static void _usage(FILE *dest
)
5228 "Usage: ss [ OPTIONS ]\n"
5229 " ss [ OPTIONS ] [ FILTER ]\n"
5230 " -h, --help this message\n"
5231 " -V, --version output version information\n"
5232 " -n, --numeric don't resolve service names\n"
5233 " -r, --resolve resolve host names\n"
5234 " -a, --all display all sockets\n"
5235 " -l, --listening display listening sockets\n"
5236 " -o, --options show timer information\n"
5237 " -e, --extended show detailed socket information\n"
5238 " -m, --memory show socket memory usage\n"
5239 " -p, --processes show process using socket\n"
5240 " -i, --info show internal TCP information\n"
5241 " --tipcinfo show internal tipc socket information\n"
5242 " -s, --summary show socket usage summary\n"
5243 " --tos show tos and priority information\n"
5244 " --cgroup show cgroup information\n"
5245 " -b, --bpf show bpf filter socket information\n"
5246 " -E, --events continually display sockets as they are destroyed\n"
5247 " -Z, --context display process SELinux security contexts\n"
5248 " -z, --contexts display process and socket SELinux security contexts\n"
5249 " -N, --net switch to the specified network namespace name\n"
5251 " -4, --ipv4 display only IP version 4 sockets\n"
5252 " -6, --ipv6 display only IP version 6 sockets\n"
5253 " -0, --packet display PACKET sockets\n"
5254 " -t, --tcp display only TCP sockets\n"
5255 " -M, --mptcp display only MPTCP sockets\n"
5256 " -S, --sctp display only SCTP sockets\n"
5257 " -u, --udp display only UDP sockets\n"
5258 " -d, --dccp display only DCCP sockets\n"
5259 " -w, --raw display only RAW sockets\n"
5260 " -x, --unix display only Unix domain sockets\n"
5261 " --tipc display only TIPC sockets\n"
5262 " --vsock display only vsock sockets\n"
5263 " -f, --family=FAMILY display sockets of type FAMILY\n"
5264 " FAMILY := {inet|inet6|link|unix|netlink|vsock|tipc|xdp|help}\n"
5266 " -K, --kill forcibly close sockets, display what was closed\n"
5267 " -H, --no-header Suppress header line\n"
5268 " -O, --oneline socket's data printed on a single line\n"
5269 " --inet-sockopt show various inet socket options\n"
5271 " -A, --query=QUERY, --socket=QUERY\n"
5272 " QUERY := {all|inet|tcp|mptcp|udp|raw|unix|unix_dgram|unix_stream|unix_seqpacket|packet|netlink|vsock_stream|vsock_dgram|tipc}[,QUERY]\n"
5274 " -D, --diag=FILE Dump raw information about TCP sockets to FILE\n"
5275 " -F, --filter=FILE read filter information from FILE\n"
5276 " FILTER := [ state STATE-FILTER ] [ EXPRESSION ]\n"
5277 " STATE-FILTER := {all|connected|synchronized|bucket|big|TCP-STATES}\n"
5278 " TCP-STATES := {established|syn-sent|syn-recv|fin-wait-{1,2}|time-wait|closed|close-wait|last-ack|listening|closing}\n"
5279 " connected := {established|syn-sent|syn-recv|fin-wait-{1,2}|time-wait|close-wait|last-ack|closing}\n"
5280 " synchronized := {established|syn-recv|fin-wait-{1,2}|time-wait|close-wait|last-ack|closing}\n"
5281 " bucket := {syn-recv|time-wait}\n"
5282 " big := {established|syn-sent|fin-wait-{1,2}|closed|close-wait|last-ack|listening|closing}\n"
5286 static void help(void) __attribute__((noreturn
));
5287 static void help(void)
5293 static void usage(void) __attribute__((noreturn
));
5294 static void usage(void)
5301 static int scan_state(const char *state
)
5303 static const char * const sstate_namel
[] = {
5305 [SS_ESTABLISHED
] = "established",
5306 [SS_SYN_SENT
] = "syn-sent",
5307 [SS_SYN_RECV
] = "syn-recv",
5308 [SS_FIN_WAIT1
] = "fin-wait-1",
5309 [SS_FIN_WAIT2
] = "fin-wait-2",
5310 [SS_TIME_WAIT
] = "time-wait",
5311 [SS_CLOSE
] = "unconnected",
5312 [SS_CLOSE_WAIT
] = "close-wait",
5313 [SS_LAST_ACK
] = "last-ack",
5314 [SS_LISTEN
] = "listening",
5315 [SS_CLOSING
] = "closing",
5319 if (strcasecmp(state
, "close") == 0 ||
5320 strcasecmp(state
, "closed") == 0)
5321 return (1<<SS_CLOSE
);
5322 if (strcasecmp(state
, "syn-rcv") == 0)
5323 return (1<<SS_SYN_RECV
);
5324 if (strcasecmp(state
, "established") == 0)
5325 return (1<<SS_ESTABLISHED
);
5326 if (strcasecmp(state
, "all") == 0)
5328 if (strcasecmp(state
, "connected") == 0)
5329 return SS_ALL
& ~((1<<SS_CLOSE
)|(1<<SS_LISTEN
));
5330 if (strcasecmp(state
, "synchronized") == 0)
5331 return SS_ALL
& ~((1<<SS_CLOSE
)|(1<<SS_LISTEN
)|(1<<SS_SYN_SENT
));
5332 if (strcasecmp(state
, "bucket") == 0)
5333 return (1<<SS_SYN_RECV
)|(1<<SS_TIME_WAIT
);
5334 if (strcasecmp(state
, "big") == 0)
5335 return SS_ALL
& ~((1<<SS_SYN_RECV
)|(1<<SS_TIME_WAIT
));
5336 for (i
= 0; i
< SS_MAX
; i
++) {
5337 if (strcasecmp(state
, sstate_namel
[i
]) == 0)
5341 fprintf(stderr
, "ss: wrong state name: %s\n", state
);
5345 /* Values 'v' and 'V' are already used so a non-character is used */
5346 #define OPT_VSOCK 256
5348 /* Values of 't' are already used so a non-character is used */
5349 #define OPT_TIPCSOCK 257
5350 #define OPT_TIPCINFO 258
5354 /* Values of 'x' are already used so a non-character is used */
5355 #define OPT_XDPSOCK 260
5357 #define OPT_CGROUP 261
5359 #define OPT_INET_SOCKOPT 262
5361 static const struct option long_opts
[] = {
5362 { "numeric", 0, 0, 'n' },
5363 { "resolve", 0, 0, 'r' },
5364 { "options", 0, 0, 'o' },
5365 { "extended", 0, 0, 'e' },
5366 { "memory", 0, 0, 'm' },
5367 { "info", 0, 0, 'i' },
5368 { "processes", 0, 0, 'p' },
5369 { "bpf", 0, 0, 'b' },
5370 { "events", 0, 0, 'E' },
5371 { "dccp", 0, 0, 'd' },
5372 { "tcp", 0, 0, 't' },
5373 { "sctp", 0, 0, 'S' },
5374 { "udp", 0, 0, 'u' },
5375 { "raw", 0, 0, 'w' },
5376 { "unix", 0, 0, 'x' },
5377 { "tipc", 0, 0, OPT_TIPCSOCK
},
5378 { "vsock", 0, 0, OPT_VSOCK
},
5379 { "all", 0, 0, 'a' },
5380 { "listening", 0, 0, 'l' },
5381 { "ipv4", 0, 0, '4' },
5382 { "ipv6", 0, 0, '6' },
5383 { "packet", 0, 0, '0' },
5384 { "family", 1, 0, 'f' },
5385 { "socket", 1, 0, 'A' },
5386 { "query", 1, 0, 'A' },
5387 { "summary", 0, 0, 's' },
5388 { "diag", 1, 0, 'D' },
5389 { "filter", 1, 0, 'F' },
5390 { "version", 0, 0, 'V' },
5391 { "help", 0, 0, 'h' },
5392 { "context", 0, 0, 'Z' },
5393 { "contexts", 0, 0, 'z' },
5394 { "net", 1, 0, 'N' },
5395 { "tipcinfo", 0, 0, OPT_TIPCINFO
},
5396 { "tos", 0, 0, OPT_TOS
},
5397 { "cgroup", 0, 0, OPT_CGROUP
},
5398 { "kill", 0, 0, 'K' },
5399 { "no-header", 0, 0, 'H' },
5400 { "xdp", 0, 0, OPT_XDPSOCK
},
5401 { "mptcp", 0, 0, 'M' },
5402 { "oneline", 0, 0, 'O' },
5403 { "inet-sockopt", 0, 0, OPT_INET_SOCKOPT
},
5408 int main(int argc
, char *argv
[])
5413 const char *dump_tcpdiag
= NULL
;
5414 FILE *filter_fp
= NULL
;
5416 int state_filter
= 0;
5418 while ((ch
= getopt_long(argc
, argv
,
5419 "dhaletuwxnro460spbEf:mMiA:D:F:vVzZN:KHSO",
5420 long_opts
, NULL
)) != EOF
) {
5443 user_ent_hash_build();
5453 filter_db_set(¤t_filter
, DCCP_DB
, true);
5456 filter_db_set(¤t_filter
, TCP_DB
, true);
5459 filter_db_set(¤t_filter
, SCTP_DB
, true);
5462 filter_db_set(¤t_filter
, UDP_DB
, true);
5465 filter_db_set(¤t_filter
, RAW_DB
, true);
5468 filter_af_set(¤t_filter
, AF_UNIX
);
5471 filter_af_set(¤t_filter
, AF_VSOCK
);
5474 filter_af_set(¤t_filter
, AF_TIPC
);
5477 state_filter
= SS_ALL
;
5480 state_filter
= (1 << SS_LISTEN
) | (1 << SS_CLOSE
);
5483 filter_af_set(¤t_filter
, AF_INET
);
5486 filter_af_set(¤t_filter
, AF_INET6
);
5489 filter_af_set(¤t_filter
, AF_PACKET
);
5492 filter_af_set(¤t_filter
, AF_XDP
);
5495 filter_db_set(¤t_filter
, MPTCP_DB
, true);
5498 if (strcmp(optarg
, "inet") == 0)
5499 filter_af_set(¤t_filter
, AF_INET
);
5500 else if (strcmp(optarg
, "inet6") == 0)
5501 filter_af_set(¤t_filter
, AF_INET6
);
5502 else if (strcmp(optarg
, "link") == 0)
5503 filter_af_set(¤t_filter
, AF_PACKET
);
5504 else if (strcmp(optarg
, "unix") == 0)
5505 filter_af_set(¤t_filter
, AF_UNIX
);
5506 else if (strcmp(optarg
, "netlink") == 0)
5507 filter_af_set(¤t_filter
, AF_NETLINK
);
5508 else if (strcmp(optarg
, "tipc") == 0)
5509 filter_af_set(¤t_filter
, AF_TIPC
);
5510 else if (strcmp(optarg
, "vsock") == 0)
5511 filter_af_set(¤t_filter
, AF_VSOCK
);
5512 else if (strcmp(optarg
, "xdp") == 0)
5513 filter_af_set(¤t_filter
, AF_XDP
);
5514 else if (strcmp(optarg
, "help") == 0)
5517 fprintf(stderr
, "ss: \"%s\" is invalid family\n",
5527 current_filter
.dbs
= 0;
5528 state_filter
= state_filter
?
5529 state_filter
: SS_CONN
;
5535 if ((p1
= strchr(p
, ',')) != NULL
)
5537 if (filter_db_parse(¤t_filter
, p
)) {
5538 fprintf(stderr
, "ss: \"%s\" is illegal socket table id\n", p
);
5549 dump_tcpdiag
= optarg
;
5553 fprintf(stderr
, "More than one filter file\n");
5556 if (optarg
[0] == '-')
5559 filter_fp
= fopen(optarg
, "r");
5561 perror("fopen filter file");
5567 printf("ss utility, iproute2-%s\n", version
);
5573 if (is_selinux_enabled() <= 0) {
5574 fprintf(stderr
, "ss: SELinux is not enabled.\n");
5578 user_ent_hash_build();
5581 if (netns_switch(optarg
))
5594 current_filter
.kill
= 1;
5602 case OPT_INET_SOCKOPT
:
5603 show_inet_sockopt
= 1;
5618 if (do_default
&& argc
== 0)
5623 if (strcmp(*argv
, "state") == 0) {
5627 state_filter
|= scan_state(*argv
);
5629 } else if (strcmp(*argv
, "exclude") == 0 ||
5630 strcmp(*argv
, "excl") == 0) {
5633 state_filter
= SS_ALL
;
5634 state_filter
&= ~scan_state(*argv
);
5643 state_filter
= state_filter
? state_filter
: SS_CONN
;
5644 filter_db_parse(¤t_filter
, "all");
5647 filter_states_set(¤t_filter
, state_filter
);
5648 filter_merge_defaults(¤t_filter
);
5650 if (!numeric
&& resolve_hosts
&&
5651 (current_filter
.dbs
& (UNIX_DBM
|INET_L4_DBM
)))
5652 init_service_resolver();
5654 if (current_filter
.dbs
== 0) {
5655 fprintf(stderr
, "ss: no socket tables to show with such filter.\n");
5658 if (current_filter
.families
== 0) {
5659 fprintf(stderr
, "ss: no families to show with such filter.\n");
5662 if (current_filter
.states
== 0) {
5663 fprintf(stderr
, "ss: no socket states to show with such filter.\n");
5668 FILE *dump_fp
= stdout
;
5670 if (!(current_filter
.dbs
& (1<<TCP_DB
))) {
5671 fprintf(stderr
, "ss: tcpdiag dump requested and no tcp in filter.\n");
5674 if (dump_tcpdiag
[0] != '-') {
5675 dump_fp
= fopen(dump_tcpdiag
, "w");
5676 if (!dump_tcpdiag
) {
5677 perror("fopen dump file");
5681 inet_show_netlink(¤t_filter
, dump_fp
, IPPROTO_TCP
);
5686 if (ssfilter_parse(¤t_filter
.f
, argc
, argv
, filter_fp
))
5689 if (!(current_filter
.dbs
& (current_filter
.dbs
- 1)))
5690 columns
[COL_NETID
].disabled
= 1;
5692 if (!(current_filter
.states
& (current_filter
.states
- 1)))
5693 columns
[COL_STATE
].disabled
= 1;
5701 exit(handle_follow_request(¤t_filter
));
5703 if (current_filter
.dbs
& (1<<NETLINK_DB
))
5704 netlink_show(¤t_filter
);
5705 if (current_filter
.dbs
& PACKET_DBM
)
5706 packet_show(¤t_filter
);
5707 if (current_filter
.dbs
& UNIX_DBM
)
5708 unix_show(¤t_filter
);
5709 if (current_filter
.dbs
& (1<<RAW_DB
))
5710 raw_show(¤t_filter
);
5711 if (current_filter
.dbs
& (1<<UDP_DB
))
5712 udp_show(¤t_filter
);
5713 if (current_filter
.dbs
& (1<<TCP_DB
))
5714 tcp_show(¤t_filter
);
5715 if (current_filter
.dbs
& (1<<DCCP_DB
))
5716 dccp_show(¤t_filter
);
5717 if (current_filter
.dbs
& (1<<SCTP_DB
))
5718 sctp_show(¤t_filter
);
5719 if (current_filter
.dbs
& VSOCK_DBM
)
5720 vsock_show(¤t_filter
);
5721 if (current_filter
.dbs
& (1<<TIPC_DB
))
5722 tipc_show(¤t_filter
);
5723 if (current_filter
.dbs
& (1<<XDP_DB
))
5724 xdp_show(¤t_filter
);
5725 if (current_filter
.dbs
& (1<<MPTCP_DB
))
5726 mptcp_show(¤t_filter
);
5728 if (show_users
|| show_proc_ctx
|| show_sock_ctx
)