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 <netinet/in.h>
23 #include <arpa/inet.h>
34 #include "libnetlink.h"
35 #include "namespace.h"
38 #include <linux/tcp.h>
39 #include <linux/sock_diag.h>
40 #include <linux/inet_diag.h>
41 #include <linux/unix_diag.h>
42 #include <linux/netdevice.h> /* for MAX_ADDR_LEN */
43 #include <linux/filter.h>
44 #include <linux/packet_diag.h>
45 #include <linux/netlink_diag.h>
46 #include <linux/sctp.h>
47 #include <linux/vm_sockets_diag.h>
49 #define MAGIC_SEQ 123456
50 #define BUF_CHUNK (1024 * 1024)
51 #define LEN_ALIGN(x) (((x) + 1) & ~1)
53 #define DIAG_REQUEST(_req, _r) \
55 struct nlmsghdr nlh; \
59 .nlmsg_type = SOCK_DIAG_BY_FAMILY, \
60 .nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST,\
61 .nlmsg_seq = MAGIC_SEQ, \
62 .nlmsg_len = sizeof(_req), \
67 #include <selinux/selinux.h>
69 /* Stubs for SELinux functions */
70 static int is_selinux_enabled(void)
75 static int getpidcon(pid_t pid
, char **context
)
81 static int getfilecon(char *path
, char **context
)
87 static int security_get_initial_context(char *name
, char **context
)
94 int resolve_services
= 1;
95 int preferred_family
= AF_UNSPEC
;
128 const enum col_align align
;
132 int width
; /* Calculated, including additional layout spacing */
133 int max_len
; /* Measured maximum field length in this column */
136 static struct column columns
[] = {
137 { ALIGN_LEFT
, "Netid", "", 0, 0, 0 },
138 { ALIGN_LEFT
, "State", " ", 0, 0, 0 },
139 { ALIGN_LEFT
, "Recv-Q", " ", 0, 0, 0 },
140 { ALIGN_LEFT
, "Send-Q", " ", 0, 0, 0 },
141 { ALIGN_RIGHT
, "Local Address:", " ", 0, 0, 0 },
142 { ALIGN_LEFT
, "Port", "", 0, 0, 0 },
143 { ALIGN_RIGHT
, "Peer Address:", " ", 0, 0, 0 },
144 { ALIGN_LEFT
, "Port", "", 0, 0, 0 },
145 { ALIGN_LEFT
, "", "", 0, 0, 0 },
148 static struct column
*current_field
= columns
;
150 /* Output buffer: chained chunks of BUF_CHUNK bytes. Each field is written to
151 * the buffer as a variable size token. A token consists of a 16 bits length
152 * field, followed by a string which is not NULL-terminated.
154 * A new chunk is allocated and linked when the current chunk doesn't have
155 * enough room to store the current token as a whole.
158 struct buf_chunk
*next
; /* Next chained chunk */
159 char *end
; /* Current end of content */
164 uint16_t len
; /* Data length, excluding length descriptor */
169 struct buf_token
*cur
; /* Position of current token in chunk */
170 struct buf_chunk
*head
; /* First chunk */
171 struct buf_chunk
*tail
; /* Current chunk */
174 static const char *TCP_PROTO
= "tcp";
175 static const char *SCTP_PROTO
= "sctp";
176 static const char *UDP_PROTO
= "udp";
177 static const char *RAW_PROTO
= "raw";
178 static const char *dg_proto
;
197 #define PACKET_DBM ((1<<PACKET_DG_DB)|(1<<PACKET_R_DB))
198 #define UNIX_DBM ((1<<UNIX_DG_DB)|(1<<UNIX_ST_DB)|(1<<UNIX_SQ_DB))
199 #define ALL_DB ((1<<MAX_DB)-1)
200 #define INET_L4_DBM ((1<<TCP_DB)|(1<<UDP_DB)|(1<<DCCP_DB)|(1<<SCTP_DB))
201 #define INET_DBM (INET_L4_DBM | (1<<RAW_DB))
202 #define VSOCK_DBM ((1<<VSOCK_ST_DB)|(1<<VSOCK_DG_DB))
221 SCTP_STATE_CLOSED
= 0,
222 SCTP_STATE_COOKIE_WAIT
= 1,
223 SCTP_STATE_COOKIE_ECHOED
= 2,
224 SCTP_STATE_ESTABLISHED
= 3,
225 SCTP_STATE_SHUTDOWN_PENDING
= 4,
226 SCTP_STATE_SHUTDOWN_SENT
= 5,
227 SCTP_STATE_SHUTDOWN_RECEIVED
= 6,
228 SCTP_STATE_SHUTDOWN_ACK_SENT
= 7,
231 #define SS_ALL ((1 << SS_MAX) - 1)
232 #define SS_CONN (SS_ALL & ~((1<<SS_LISTEN)|(1<<SS_CLOSE)|(1<<SS_TIME_WAIT)|(1<<SS_SYN_RECV)))
234 #include "ssfilter.h"
242 struct rtnl_handle
*rth_for_killing
;
245 #define FAMILY_MASK(family) ((uint64_t)1 << (family))
247 static const struct filter default_dbs
[MAX_DB
] = {
250 .families
= FAMILY_MASK(AF_INET
) | FAMILY_MASK(AF_INET6
),
254 .families
= FAMILY_MASK(AF_INET
) | FAMILY_MASK(AF_INET6
),
257 .states
= (1 << SS_ESTABLISHED
),
258 .families
= FAMILY_MASK(AF_INET
) | FAMILY_MASK(AF_INET6
),
261 .states
= (1 << SS_ESTABLISHED
),
262 .families
= FAMILY_MASK(AF_INET
) | FAMILY_MASK(AF_INET6
),
265 .states
= (1 << SS_CLOSE
),
266 .families
= FAMILY_MASK(AF_UNIX
),
270 .families
= FAMILY_MASK(AF_UNIX
),
274 .families
= FAMILY_MASK(AF_UNIX
),
277 .states
= (1 << SS_CLOSE
),
278 .families
= FAMILY_MASK(AF_PACKET
),
281 .states
= (1 << SS_CLOSE
),
282 .families
= FAMILY_MASK(AF_PACKET
),
285 .states
= (1 << SS_CLOSE
),
286 .families
= FAMILY_MASK(AF_NETLINK
),
290 .families
= FAMILY_MASK(AF_INET
) | FAMILY_MASK(AF_INET6
),
294 .families
= FAMILY_MASK(AF_VSOCK
),
298 .families
= FAMILY_MASK(AF_VSOCK
),
302 static const struct filter default_afs
[AF_MAX
] = {
317 .states
= (1 << SS_CLOSE
),
320 .dbs
= (1 << NETLINK_DB
),
321 .states
= (1 << SS_CLOSE
),
329 static int do_default
= 1;
330 static struct filter current_filter
;
332 static void filter_db_set(struct filter
*f
, int db
)
334 f
->states
|= default_dbs
[db
].states
;
339 static void filter_af_set(struct filter
*f
, int af
)
341 f
->states
|= default_afs
[af
].states
;
342 f
->families
|= FAMILY_MASK(af
);
344 preferred_family
= af
;
347 static int filter_af_get(struct filter
*f
, int af
)
349 return !!(f
->families
& FAMILY_MASK(af
));
352 static void filter_default_dbs(struct filter
*f
)
354 filter_db_set(f
, UDP_DB
);
355 filter_db_set(f
, DCCP_DB
);
356 filter_db_set(f
, TCP_DB
);
357 filter_db_set(f
, RAW_DB
);
358 filter_db_set(f
, UNIX_ST_DB
);
359 filter_db_set(f
, UNIX_DG_DB
);
360 filter_db_set(f
, UNIX_SQ_DB
);
361 filter_db_set(f
, PACKET_R_DB
);
362 filter_db_set(f
, PACKET_DG_DB
);
363 filter_db_set(f
, NETLINK_DB
);
364 filter_db_set(f
, SCTP_DB
);
365 filter_db_set(f
, VSOCK_ST_DB
);
366 filter_db_set(f
, VSOCK_DG_DB
);
369 static void filter_states_set(struct filter
*f
, int states
)
375 static void filter_merge_defaults(struct filter
*f
)
380 for (db
= 0; db
< MAX_DB
; db
++) {
381 if (!(f
->dbs
& (1 << db
)))
384 if (!(default_dbs
[db
].families
& f
->families
))
385 f
->families
|= default_dbs
[db
].families
;
387 for (af
= 0; af
< AF_MAX
; af
++) {
388 if (!(f
->families
& FAMILY_MASK(af
)))
391 if (!(default_afs
[af
].dbs
& f
->dbs
))
392 f
->dbs
|= default_afs
[af
].dbs
;
396 static FILE *generic_proc_open(const char *env
, const char *name
)
398 const char *p
= getenv(env
);
402 p
= getenv("PROC_ROOT") ? : "/proc";
403 snprintf(store
, sizeof(store
)-1, "%s/%s", p
, name
);
407 return fopen(p
, "r");
409 #define net_tcp_open() generic_proc_open("PROC_NET_TCP", "net/tcp")
410 #define net_tcp6_open() generic_proc_open("PROC_NET_TCP6", "net/tcp6")
411 #define net_udp_open() generic_proc_open("PROC_NET_UDP", "net/udp")
412 #define net_udp6_open() generic_proc_open("PROC_NET_UDP6", "net/udp6")
413 #define net_raw_open() generic_proc_open("PROC_NET_RAW", "net/raw")
414 #define net_raw6_open() generic_proc_open("PROC_NET_RAW6", "net/raw6")
415 #define net_unix_open() generic_proc_open("PROC_NET_UNIX", "net/unix")
416 #define net_packet_open() generic_proc_open("PROC_NET_PACKET", \
418 #define net_netlink_open() generic_proc_open("PROC_NET_NETLINK", \
420 #define slabinfo_open() generic_proc_open("PROC_SLABINFO", "slabinfo")
421 #define net_sockstat_open() generic_proc_open("PROC_NET_SOCKSTAT", \
423 #define net_sockstat6_open() generic_proc_open("PROC_NET_SOCKSTAT6", \
425 #define net_snmp_open() generic_proc_open("PROC_NET_SNMP", "net/snmp")
426 #define ephemeral_ports_open() generic_proc_open("PROC_IP_LOCAL_PORT_RANGE", \
427 "sys/net/ipv4/ip_local_port_range")
430 struct user_ent
*next
;
439 #define USER_ENT_HASH_SIZE 256
440 struct user_ent
*user_ent_hash
[USER_ENT_HASH_SIZE
];
442 static int user_ent_hashfn(unsigned int ino
)
444 int val
= (ino
>> 24) ^ (ino
>> 16) ^ (ino
>> 8) ^ ino
;
446 return val
& (USER_ENT_HASH_SIZE
- 1);
449 static void user_ent_add(unsigned int ino
, char *process
,
454 struct user_ent
*p
, **pp
;
456 p
= malloc(sizeof(struct user_ent
));
458 fprintf(stderr
, "ss: failed to malloc buffer\n");
465 p
->process
= strdup(process
);
466 p
->process_ctx
= strdup(proc_ctx
);
467 p
->socket_ctx
= strdup(sock_ctx
);
469 pp
= &user_ent_hash
[user_ent_hashfn(ino
)];
474 static void user_ent_destroy(void)
476 struct user_ent
*p
, *p_next
;
479 while (cnt
!= USER_ENT_HASH_SIZE
) {
480 p
= user_ent_hash
[cnt
];
483 free(p
->process_ctx
);
493 static void user_ent_hash_build(void)
495 const char *root
= getenv("PROC_ROOT") ? : "/proc/";
502 const char *no_ctx
= "unavailable";
503 static int user_ent_hash_build_init
;
505 /* If show_users & show_proc_ctx set only do this once */
506 if (user_ent_hash_build_init
!= 0)
509 user_ent_hash_build_init
= 1;
511 strlcpy(name
, root
, sizeof(name
));
513 if (strlen(name
) == 0 || name
[strlen(name
)-1] != '/')
516 nameoff
= strlen(name
);
522 while ((d
= readdir(dir
)) != NULL
) {
530 if (sscanf(d
->d_name
, "%d%c", &pid
, &crap
) != 1)
533 if (getpidcon(pid
, &pid_context
) != 0)
534 pid_context
= strdup(no_ctx
);
536 snprintf(name
+ nameoff
, sizeof(name
) - nameoff
, "%d/fd/", pid
);
538 if ((dir1
= opendir(name
)) == NULL
) {
546 while ((d1
= readdir(dir1
)) != NULL
) {
547 const char *pattern
= "socket:[";
554 if (sscanf(d1
->d_name
, "%d%c", &fd
, &crap
) != 1)
557 snprintf(name
+pos
, sizeof(name
) - pos
, "%d", fd
);
559 link_len
= readlink(name
, lnk
, sizeof(lnk
)-1);
562 lnk
[link_len
] = '\0';
564 if (strncmp(lnk
, pattern
, strlen(pattern
)))
567 sscanf(lnk
, "socket:[%u]", &ino
);
569 snprintf(tmp
, sizeof(tmp
), "%s/%d/fd/%s",
570 root
, pid
, d1
->d_name
);
572 if (getfilecon(tmp
, &sock_context
) <= 0)
573 sock_context
= strdup(no_ctx
);
578 snprintf(tmp
, sizeof(tmp
), "%s/%d/stat",
580 if ((fp
= fopen(tmp
, "r")) != NULL
) {
581 if (fscanf(fp
, "%*d (%[^)])", p
) < 1)
586 user_ent_add(ino
, p
, pid
, fd
,
587 pid_context
, sock_context
);
602 #define ENTRY_BUF_SIZE 512
603 static int find_entry(unsigned int ino
, char **buf
, int type
)
609 int len
, new_buf_len
;
616 p
= user_ent_hash
[user_ent_hashfn(ino
)];
623 ptr
= *buf
+ buf_used
;
626 len
= snprintf(ptr
, buf_len
- buf_used
,
627 "(\"%s\",pid=%d,fd=%d),",
628 p
->process
, p
->pid
, p
->fd
);
631 len
= snprintf(ptr
, buf_len
- buf_used
,
632 "(\"%s\",pid=%d,proc_ctx=%s,fd=%d),",
634 p
->process_ctx
, p
->fd
);
637 len
= snprintf(ptr
, buf_len
- buf_used
,
638 "(\"%s\",pid=%d,proc_ctx=%s,fd=%d,sock_ctx=%s),",
640 p
->process_ctx
, p
->fd
,
644 fprintf(stderr
, "ss: invalid type: %d\n", type
);
648 if (len
< 0 || len
>= buf_len
- buf_used
) {
649 new_buf_len
= buf_len
+ ENTRY_BUF_SIZE
;
650 new_buf
= realloc(*buf
, new_buf_len
);
652 fprintf(stderr
, "ss: failed to malloc buffer\n");
656 buf_len
= new_buf_len
;
668 ptr
= *buf
+ buf_used
;
674 /* Get stats from slab */
684 static struct slabstat slabstat
;
686 static int get_slabstat(struct slabstat
*s
)
691 static int slabstat_valid
;
692 static const char * const slabstat_ids
[] = {
703 memset(s
, 0, sizeof(*s
));
705 fp
= slabinfo_open();
709 cnt
= sizeof(*s
)/sizeof(int);
711 if (!fgets(buf
, sizeof(buf
), fp
)) {
715 while (fgets(buf
, sizeof(buf
), fp
) != NULL
) {
718 for (i
= 0; i
< ARRAY_SIZE(slabstat_ids
); i
++) {
719 if (memcmp(buf
, slabstat_ids
[i
], strlen(slabstat_ids
[i
])) == 0) {
720 sscanf(buf
, "%*s%d", ((int *)s
) + i
);
735 static unsigned long long cookie_sk_get(const uint32_t *cookie
)
737 return (((unsigned long long)cookie
[1] << 31) << 1) | cookie
[0];
740 static const char *sctp_sstate_name
[] = {
741 [SCTP_STATE_CLOSED
] = "CLOSED",
742 [SCTP_STATE_COOKIE_WAIT
] = "COOKIE_WAIT",
743 [SCTP_STATE_COOKIE_ECHOED
] = "COOKIE_ECHOED",
744 [SCTP_STATE_ESTABLISHED
] = "ESTAB",
745 [SCTP_STATE_SHUTDOWN_PENDING
] = "SHUTDOWN_PENDING",
746 [SCTP_STATE_SHUTDOWN_SENT
] = "SHUTDOWN_SENT",
747 [SCTP_STATE_SHUTDOWN_RECEIVED
] = "SHUTDOWN_RECEIVED",
748 [SCTP_STATE_SHUTDOWN_ACK_SENT
] = "ACK_SENT",
752 struct sockstat
*next
;
766 unsigned long long sk
;
773 unsigned int ce_state
;
783 unsigned int timeout
;
786 double rto
, ato
, rtt
, rttvar
;
787 int qack
, ssthresh
, backoff
;
796 unsigned int lastsnd
;
797 unsigned int lastrcv
;
798 unsigned int lastack
;
800 double pacing_rate_max
;
801 double delivery_rate
;
802 unsigned long long bytes_acked
;
803 unsigned long long bytes_received
;
804 unsigned int segs_out
;
805 unsigned int segs_in
;
806 unsigned int data_segs_out
;
807 unsigned int data_segs_in
;
808 unsigned int unacked
;
809 unsigned int retrans
;
810 unsigned int retrans_total
;
813 unsigned int fackets
;
814 unsigned int reordering
;
815 unsigned int not_sent
;
819 unsigned int rcv_ssthresh
;
820 unsigned long long busy_time
;
821 unsigned long long rwnd_limited
;
822 unsigned long long sndbuf_limited
;
826 bool has_ecnseen_opt
;
827 bool has_fastopen_opt
;
830 struct dctcpstat
*dctcp
;
831 struct tcp_bbr_info
*bbr_info
;
834 /* SCTP assocs share the same inode number with their parent endpoint. So if we
835 * have seen the inode number before, it must be an assoc instead of the next
837 static bool is_sctp_assoc(struct sockstat
*s
, const char *sock_name
)
839 if (strcmp(sock_name
, "sctp"))
841 if (!sctp_ino
|| sctp_ino
!= s
->ino
)
846 static const char *unix_netid_name(int type
)
859 static const char *proto_name(int protocol
)
879 static const char *vsock_netid_name(int type
)
891 /* Allocate and initialize a new buffer chunk */
892 static struct buf_chunk
*buf_chunk_new(void)
894 struct buf_chunk
*new = malloc(BUF_CHUNK
);
901 /* This is also the last block */
904 /* Next token will be stored at the beginning of chunk data area, and
905 * its initial length is zero.
907 buffer
.cur
= (struct buf_token
*)new->data
;
910 new->end
= buffer
.cur
->data
;
915 /* Return available tail room in given chunk */
916 static int buf_chunk_avail(struct buf_chunk
*chunk
)
918 return BUF_CHUNK
- offsetof(struct buf_chunk
, data
) -
919 (chunk
->end
- chunk
->data
);
922 /* Update end pointer and token length, link new chunk if we hit the end of the
923 * current one. Return -EAGAIN if we got a new chunk, caller has to print again.
925 static int buf_update(int len
)
927 struct buf_chunk
*chunk
= buffer
.tail
;
928 struct buf_token
*t
= buffer
.cur
;
930 /* Claim success if new content fits in the current chunk, and anyway
931 * if this is the first token in the chunk: in the latter case,
932 * allocating a new chunk won't help, so we'll just cut the output.
934 if ((len
< buf_chunk_avail(chunk
) && len
!= -1 /* glibc < 2.0.6 */) ||
935 t
== (struct buf_token
*)chunk
->data
) {
936 len
= min(len
, buf_chunk_avail(chunk
));
938 /* Total field length can't exceed 2^16 bytes, cut as needed */
939 len
= min(len
, USHRT_MAX
- t
->len
);
946 /* Content truncated, time to allocate more */
947 chunk
->next
= buf_chunk_new();
949 /* Copy current token over to new chunk, including length descriptor */
950 memcpy(chunk
->next
->data
, t
, sizeof(t
->len
) + t
->len
);
951 chunk
->next
->end
+= t
->len
;
953 /* Discard partially written field in old chunk */
954 chunk
->end
-= t
->len
+ sizeof(t
->len
);
959 /* Append content to buffer as part of the current field */
960 static void out(const char *fmt
, ...)
962 struct column
*f
= current_field
;
971 buffer
.head
= buf_chunk_new();
973 again
: /* Append to buffer: if we have a new chunk, print again */
975 pos
= buffer
.cur
->data
+ buffer
.cur
->len
;
978 /* Limit to tail room. If we hit the limit, buf_update() will tell us */
979 len
= vsnprintf(pos
, buf_chunk_avail(buffer
.tail
), fmt
, args
);
986 static int print_left_spacing(struct column
*f
, int stored
, int printed
)
990 if (!f
->width
|| f
->align
== ALIGN_LEFT
)
993 s
= f
->width
- stored
- printed
;
994 if (f
->align
== ALIGN_CENTER
)
995 /* If count of total spacing is odd, shift right by one */
999 return printf("%*c", s
, ' ');
1004 static void print_right_spacing(struct column
*f
, int printed
)
1008 if (!f
->width
|| f
->align
== ALIGN_RIGHT
)
1011 s
= f
->width
- printed
;
1012 if (f
->align
== ALIGN_CENTER
)
1016 printf("%*c", s
, ' ');
1019 /* Done with field: update buffer pointer, start new token after current one */
1020 static void field_flush(struct column
*f
)
1022 struct buf_chunk
*chunk
;
1028 chunk
= buffer
.tail
;
1029 pad
= buffer
.cur
->len
% 2;
1031 if (buffer
.cur
->len
> f
->max_len
)
1032 f
->max_len
= buffer
.cur
->len
;
1034 /* We need a new chunk if we can't store the next length descriptor.
1035 * Mind the gap between end of previous token and next aligned position
1036 * for length descriptor.
1038 if (buf_chunk_avail(chunk
) - pad
< sizeof(buffer
.cur
->len
)) {
1040 chunk
->next
= buf_chunk_new();
1044 buffer
.cur
= (struct buf_token
*)(buffer
.cur
->data
+
1045 LEN_ALIGN(buffer
.cur
->len
));
1046 buffer
.cur
->len
= 0;
1047 buffer
.tail
->end
= buffer
.cur
->data
;
1050 static int field_is_last(struct column
*f
)
1052 return f
- columns
== COL_MAX
- 1;
1055 static void field_next(void)
1057 field_flush(current_field
);
1059 if (field_is_last(current_field
))
1060 current_field
= columns
;
1065 /* Walk through fields and flush them until we reach the desired one */
1066 static void field_set(enum col_id id
)
1068 while (id
!= current_field
- columns
)
1072 /* Print header for all non-empty columns */
1073 static void print_header(void)
1075 while (!field_is_last(current_field
)) {
1076 if (!current_field
->disabled
)
1077 out(current_field
->header
);
1082 /* Get the next available token in the buffer starting from the current token */
1083 static struct buf_token
*buf_token_next(struct buf_token
*cur
)
1085 struct buf_chunk
*chunk
= buffer
.tail
;
1087 /* If we reached the end of chunk contents, get token from next chunk */
1088 if (cur
->data
+ LEN_ALIGN(cur
->len
) == chunk
->end
) {
1089 buffer
.tail
= chunk
= chunk
->next
;
1090 return chunk
? (struct buf_token
*)chunk
->data
: NULL
;
1093 return (struct buf_token
*)(cur
->data
+ LEN_ALIGN(cur
->len
));
1096 /* Free up all allocated buffer chunks */
1097 static void buf_free_all(void)
1099 struct buf_chunk
*tmp
;
1101 for (buffer
.tail
= buffer
.head
; buffer
.tail
; ) {
1103 buffer
.tail
= buffer
.tail
->next
;
1109 /* Get current screen width, default to 80 columns if TIOCGWINSZ fails */
1110 static int render_screen_width(void)
1114 if (isatty(STDOUT_FILENO
)) {
1117 if (ioctl(STDOUT_FILENO
, TIOCGWINSZ
, &w
) != -1) {
1126 /* Calculate column width from contents length. If columns don't fit on one
1127 * line, break them into the least possible amount of lines and keep them
1128 * aligned across lines. Available screen space is equally spread between fields
1129 * as additional spacing.
1131 static void render_calc_width(void)
1133 int screen_width
= render_screen_width();
1134 struct column
*c
, *eol
= columns
- 1;
1135 int first
, len
= 0, linecols
= 0;
1137 /* First pass: set width for each column to measured content length */
1138 for (first
= 1, c
= columns
; c
- columns
< COL_MAX
; c
++) {
1142 if (!first
&& c
->max_len
)
1143 c
->width
= c
->max_len
+ strlen(c
->ldelim
);
1145 c
->width
= c
->max_len
;
1147 /* But don't exceed screen size. If we exceed the screen size
1148 * for even a single field, it will just start on a line of its
1149 * own and then naturally wrap.
1151 c
->width
= min(c
->width
, screen_width
);
1157 /* Second pass: find out newlines and distribute available spacing */
1158 for (c
= columns
; c
- columns
< COL_MAX
; c
++) {
1159 int pad
, spacing
, rem
, last
;
1168 for (last
= 1, tmp
= c
+ 1; tmp
- columns
< COL_MAX
; tmp
++) {
1175 if (!last
&& len
< screen_width
) {
1176 /* Columns fit on screen so far, nothing to do yet */
1180 if (len
== screen_width
) {
1181 /* Exact fit, just start with new line */
1185 if (len
> screen_width
) {
1186 /* Screen width exceeded: go back one column */
1192 /* Distribute remaining space to columns on this line */
1193 pad
= screen_width
- len
;
1194 spacing
= pad
/ linecols
;
1195 rem
= pad
% linecols
;
1196 for (tmp
= c
; tmp
> eol
; tmp
--) {
1200 tmp
->width
+= spacing
;
1208 /* Line break: reset line counters, mark end-of-line */
1215 /* Render buffered output with spacing and delimiters, then free up buffers */
1216 static void render(void)
1218 struct buf_token
*token
;
1219 int printed
, line_started
= 0;
1225 token
= (struct buf_token
*)buffer
.head
->data
;
1227 /* Ensure end alignment of last token, it wasn't necessarily flushed */
1228 buffer
.tail
->end
+= buffer
.cur
->len
% 2;
1230 render_calc_width();
1232 /* Rewind and replay */
1233 buffer
.tail
= buffer
.head
;
1240 /* Print left delimiter only if we already started a line */
1242 printed
= printf("%s", current_field
->ldelim
);
1246 /* Print field content from token data with spacing */
1247 printed
+= print_left_spacing(f
, token
->len
, printed
);
1248 printed
+= fwrite(token
->data
, 1, token
->len
, stdout
);
1249 print_right_spacing(f
, printed
);
1251 /* Go to next non-empty field, deal with end-of-line */
1253 if (field_is_last(f
)) {
1260 } while (f
->disabled
);
1262 token
= buf_token_next(token
);
1266 current_field
= columns
;
1269 static void sock_state_print(struct sockstat
*s
)
1271 const char *sock_name
;
1272 static const char * const sstate_name
[] = {
1274 [SS_ESTABLISHED
] = "ESTAB",
1275 [SS_SYN_SENT
] = "SYN-SENT",
1276 [SS_SYN_RECV
] = "SYN-RECV",
1277 [SS_FIN_WAIT1
] = "FIN-WAIT-1",
1278 [SS_FIN_WAIT2
] = "FIN-WAIT-2",
1279 [SS_TIME_WAIT
] = "TIME-WAIT",
1280 [SS_CLOSE
] = "UNCONN",
1281 [SS_CLOSE_WAIT
] = "CLOSE-WAIT",
1282 [SS_LAST_ACK
] = "LAST-ACK",
1283 [SS_LISTEN
] = "LISTEN",
1284 [SS_CLOSING
] = "CLOSING",
1287 switch (s
->local
.family
) {
1289 sock_name
= unix_netid_name(s
->type
);
1293 sock_name
= proto_name(s
->type
);
1296 sock_name
= s
->type
== SOCK_RAW
? "p_raw" : "p_dgr";
1302 sock_name
= vsock_netid_name(s
->type
);
1305 sock_name
= "unknown";
1308 if (is_sctp_assoc(s
, sock_name
)) {
1309 field_set(COL_STATE
); /* Empty Netid field */
1310 out("`- %s", sctp_sstate_name
[s
->state
]);
1312 field_set(COL_NETID
);
1313 out("%s", sock_name
);
1314 field_set(COL_STATE
);
1315 out("%s", sstate_name
[s
->state
]);
1318 field_set(COL_RECVQ
);
1320 field_set(COL_SENDQ
);
1322 field_set(COL_ADDR
);
1325 static void sock_details_print(struct sockstat
*s
)
1328 out(" uid:%u", s
->uid
);
1330 out(" ino:%u", s
->ino
);
1331 out(" sk:%llx", s
->sk
);
1334 out(" fwmark:0x%x", s
->mark
);
1337 static void sock_addr_print(const char *addr
, char *delim
, const char *port
,
1341 out("%s" "%%" "%s%s", addr
, ifname
, delim
);
1343 out("%s%s", addr
, delim
);
1350 static const char *print_ms_timer(unsigned int timeout
)
1352 static char buf
[64];
1353 int secs
, msecs
, minutes
;
1355 secs
= timeout
/1000;
1358 msecs
= timeout
%1000;
1362 snprintf(buf
, sizeof(buf
)-16, "%dmin", minutes
);
1369 sprintf(buf
+strlen(buf
), "%d%s", secs
, msecs
? "." : "sec");
1372 sprintf(buf
+strlen(buf
), "%03dms", msecs
);
1377 struct scache
*next
;
1383 struct scache
*rlist
;
1385 static void init_service_resolver(void)
1388 FILE *fp
= popen("/usr/sbin/rpcinfo -p 2>/dev/null", "r");
1393 if (!fgets(buf
, sizeof(buf
), fp
)) {
1397 while (fgets(buf
, sizeof(buf
), fp
) != NULL
) {
1398 unsigned int progn
, port
;
1399 char proto
[128], prog
[128] = "rpc.";
1402 if (sscanf(buf
, "%u %*d %s %u %s",
1403 &progn
, proto
, &port
, prog
+4) != 4)
1406 if (!(c
= malloc(sizeof(*c
))))
1410 c
->name
= strdup(prog
);
1411 if (strcmp(proto
, TCP_PROTO
) == 0)
1412 c
->proto
= TCP_PROTO
;
1413 else if (strcmp(proto
, UDP_PROTO
) == 0)
1414 c
->proto
= UDP_PROTO
;
1415 else if (strcmp(proto
, SCTP_PROTO
) == 0)
1416 c
->proto
= SCTP_PROTO
;
1425 /* Even do not try default linux ephemeral port ranges:
1426 * default /etc/services contains so much of useless crap
1427 * wouldbe "allocated" to this area that resolution
1428 * is really harmful. I shrug each time when seeing
1429 * "socks" or "cfinger" in dumps.
1431 static int is_ephemeral(int port
)
1433 static int min
= 0, max
;
1436 FILE *f
= ephemeral_ports_open();
1438 if (!f
|| fscanf(f
, "%d %d", &min
, &max
) < 2) {
1445 return port
>= min
&& port
<= max
;
1449 static const char *__resolve_service(int port
)
1453 for (c
= rlist
; c
; c
= c
->next
) {
1454 if (c
->port
== port
&& c
->proto
== dg_proto
)
1458 if (!is_ephemeral(port
)) {
1459 static int notfirst
;
1466 se
= getservbyport(htons(port
), dg_proto
);
1474 #define SCACHE_BUCKETS 1024
1475 static struct scache
*cache_htab
[SCACHE_BUCKETS
];
1477 static const char *resolve_service(int port
)
1479 static char buf
[128];
1490 if (!resolve_services
)
1493 if (dg_proto
== RAW_PROTO
)
1494 return inet_proto_n2a(port
, buf
, sizeof(buf
));
1497 hash
= (port
^(((unsigned long)dg_proto
)>>2)) % SCACHE_BUCKETS
;
1499 for (c
= cache_htab
[hash
]; c
; c
= c
->next
) {
1500 if (c
->port
== port
&& c
->proto
== dg_proto
)
1504 c
= malloc(sizeof(*c
));
1507 res
= __resolve_service(port
);
1509 c
->name
= res
? strdup(res
) : NULL
;
1510 c
->proto
= dg_proto
;
1511 c
->next
= cache_htab
[hash
];
1512 cache_htab
[hash
] = c
;
1519 sprintf(buf
, "%u", port
);
1523 static void inet_addr_print(const inet_prefix
*a
, int port
,
1524 unsigned int ifindex
, bool v6only
)
1527 const char *ap
= buf
;
1528 const char *ifname
= NULL
;
1530 if (a
->family
== AF_INET
) {
1531 ap
= format_host(AF_INET
, 4, a
->data
);
1534 !memcmp(a
->data
, &in6addr_any
, sizeof(in6addr_any
))) {
1538 ap
= format_host(a
->family
, 16, a
->data
);
1540 /* Numeric IPv6 addresses should be bracketed */
1541 if (strchr(ap
, ':')) {
1542 snprintf(buf
, sizeof(buf
),
1550 ifname
= ll_index_to_name(ifindex
);
1552 sock_addr_print(ap
, ":", resolve_service(port
), ifname
);
1561 struct aafilter
*next
;
1564 static int inet2_addr_match(const inet_prefix
*a
, const inet_prefix
*p
,
1567 if (!inet_addr_match(a
, p
, plen
))
1570 /* Cursed "v4 mapped" addresses: v4 mapped socket matches
1571 * pure IPv4 rule, but v4-mapped rule selects only v4-mapped
1573 if (p
->family
== AF_INET
&& a
->family
== AF_INET6
) {
1574 if (a
->data
[0] == 0 && a
->data
[1] == 0 &&
1575 a
->data
[2] == htonl(0xffff)) {
1576 inet_prefix tmp
= *a
;
1578 tmp
.data
[0] = a
->data
[3];
1579 return inet_addr_match(&tmp
, p
, plen
);
1585 static int unix_match(const inet_prefix
*a
, const inet_prefix
*p
)
1587 char *addr
, *pattern
;
1589 memcpy(&addr
, a
->data
, sizeof(addr
));
1590 memcpy(&pattern
, p
->data
, sizeof(pattern
));
1591 if (pattern
== NULL
)
1595 return !fnmatch(pattern
, addr
, 0);
1598 static int run_ssfilter(struct ssfilter
*f
, struct sockstat
*s
)
1603 if (s
->local
.family
== AF_UNIX
) {
1606 memcpy(&p
, s
->local
.data
, sizeof(p
));
1607 return p
== NULL
|| (p
[0] == '@' && strlen(p
) == 6 &&
1608 strspn(p
+1, "0123456789abcdef") == 5);
1610 if (s
->local
.family
== AF_PACKET
)
1611 return s
->lport
== 0 && s
->local
.data
[0] == 0;
1612 if (s
->local
.family
== AF_NETLINK
)
1613 return s
->lport
< 0;
1614 if (s
->local
.family
== AF_VSOCK
)
1615 return s
->lport
> 1023;
1617 return is_ephemeral(s
->lport
);
1621 struct aafilter
*a
= (void *)f
->pred
;
1623 if (a
->addr
.family
== AF_UNIX
)
1624 return unix_match(&s
->remote
, &a
->addr
);
1625 if (a
->port
!= -1 && a
->port
!= s
->rport
)
1627 if (a
->addr
.bitlen
) {
1629 if (!inet2_addr_match(&s
->remote
, &a
->addr
, a
->addr
.bitlen
))
1631 } while ((a
= a
->next
) != NULL
);
1638 struct aafilter
*a
= (void *)f
->pred
;
1640 if (a
->addr
.family
== AF_UNIX
)
1641 return unix_match(&s
->local
, &a
->addr
);
1642 if (a
->port
!= -1 && a
->port
!= s
->lport
)
1644 if (a
->addr
.bitlen
) {
1646 if (!inet2_addr_match(&s
->local
, &a
->addr
, a
->addr
.bitlen
))
1648 } while ((a
= a
->next
) != NULL
);
1655 struct aafilter
*a
= (void *)f
->pred
;
1657 return s
->rport
>= a
->port
;
1661 struct aafilter
*a
= (void *)f
->pred
;
1663 return s
->rport
<= a
->port
;
1667 struct aafilter
*a
= (void *)f
->pred
;
1669 return s
->lport
>= a
->port
;
1673 struct aafilter
*a
= (void *)f
->pred
;
1675 return s
->lport
<= a
->port
;
1679 struct aafilter
*a
= (void *)f
->pred
;
1681 return s
->iface
== a
->iface
;
1685 struct aafilter
*a
= (void *)f
->pred
;
1687 return (s
->mark
& a
->mask
) == a
->mark
;
1689 /* Yup. It is recursion. Sorry. */
1691 return run_ssfilter(f
->pred
, s
) && run_ssfilter(f
->post
, s
);
1693 return run_ssfilter(f
->pred
, s
) || run_ssfilter(f
->post
, s
);
1695 return !run_ssfilter(f
->pred
, s
);
1701 /* Relocate external jumps by reloc. */
1702 static void ssfilter_patch(char *a
, int len
, int reloc
)
1705 struct inet_diag_bc_op
*op
= (struct inet_diag_bc_op
*)a
;
1707 if (op
->no
== len
+4)
1716 static int ssfilter_bytecompile(struct ssfilter
*f
, char **bytecode
)
1721 if (!(*bytecode
= malloc(4))) abort();
1722 ((struct inet_diag_bc_op
*)*bytecode
)[0] = (struct inet_diag_bc_op
){ INET_DIAG_BC_AUTO
, 4, 8 };
1728 struct aafilter
*a
= (void *)f
->pred
;
1731 int code
= (f
->type
== SSF_DCOND
? INET_DIAG_BC_D_COND
: INET_DIAG_BC_S_COND
);
1734 for (b
= a
; b
; b
= b
->next
) {
1735 len
+= 4 + sizeof(struct inet_diag_hostcond
);
1736 if (a
->addr
.family
== AF_INET6
)
1743 if (!(ptr
= malloc(len
))) abort();
1745 for (b
= a
; b
; b
= b
->next
) {
1746 struct inet_diag_bc_op
*op
= (struct inet_diag_bc_op
*)ptr
;
1747 int alen
= (a
->addr
.family
== AF_INET6
? 16 : 4);
1748 int oplen
= alen
+ 4 + sizeof(struct inet_diag_hostcond
);
1749 struct inet_diag_hostcond
*cond
= (struct inet_diag_hostcond
*)(ptr
+4);
1751 *op
= (struct inet_diag_bc_op
){ code
, oplen
, oplen
+4 };
1752 cond
->family
= a
->addr
.family
;
1753 cond
->port
= a
->port
;
1754 cond
->prefix_len
= a
->addr
.bitlen
;
1755 memcpy(cond
->addr
, a
->addr
.data
, alen
);
1758 op
= (struct inet_diag_bc_op
*)ptr
;
1759 *op
= (struct inet_diag_bc_op
){ INET_DIAG_BC_JMP
, 4, len
- (ptr
-*bytecode
)};
1763 return ptr
- *bytecode
;
1767 struct aafilter
*x
= (void *)f
->pred
;
1769 if (!(*bytecode
= malloc(8))) abort();
1770 ((struct inet_diag_bc_op
*)*bytecode
)[0] = (struct inet_diag_bc_op
){ INET_DIAG_BC_D_GE
, 8, 12 };
1771 ((struct inet_diag_bc_op
*)*bytecode
)[1] = (struct inet_diag_bc_op
){ 0, 0, x
->port
};
1776 struct aafilter
*x
= (void *)f
->pred
;
1778 if (!(*bytecode
= malloc(8))) abort();
1779 ((struct inet_diag_bc_op
*)*bytecode
)[0] = (struct inet_diag_bc_op
){ INET_DIAG_BC_D_LE
, 8, 12 };
1780 ((struct inet_diag_bc_op
*)*bytecode
)[1] = (struct inet_diag_bc_op
){ 0, 0, x
->port
};
1785 struct aafilter
*x
= (void *)f
->pred
;
1787 if (!(*bytecode
= malloc(8))) abort();
1788 ((struct inet_diag_bc_op
*)*bytecode
)[0] = (struct inet_diag_bc_op
){ INET_DIAG_BC_S_GE
, 8, 12 };
1789 ((struct inet_diag_bc_op
*)*bytecode
)[1] = (struct inet_diag_bc_op
){ 0, 0, x
->port
};
1794 struct aafilter
*x
= (void *)f
->pred
;
1796 if (!(*bytecode
= malloc(8))) abort();
1797 ((struct inet_diag_bc_op
*)*bytecode
)[0] = (struct inet_diag_bc_op
){ INET_DIAG_BC_S_LE
, 8, 12 };
1798 ((struct inet_diag_bc_op
*)*bytecode
)[1] = (struct inet_diag_bc_op
){ 0, 0, x
->port
};
1804 char *a1
= NULL
, *a2
= NULL
, *a
;
1807 l1
= ssfilter_bytecompile(f
->pred
, &a1
);
1808 l2
= ssfilter_bytecompile(f
->post
, &a2
);
1814 if (!(a
= malloc(l1
+l2
))) abort();
1816 memcpy(a
+l1
, a2
, l2
);
1818 ssfilter_patch(a
, l1
, l2
);
1824 char *a1
= NULL
, *a2
= NULL
, *a
;
1827 l1
= ssfilter_bytecompile(f
->pred
, &a1
);
1828 l2
= ssfilter_bytecompile(f
->post
, &a2
);
1834 if (!(a
= malloc(l1
+l2
+4))) abort();
1836 memcpy(a
+l1
+4, a2
, l2
);
1838 *(struct inet_diag_bc_op
*)(a
+l1
) = (struct inet_diag_bc_op
){ INET_DIAG_BC_JMP
, 4, l2
+4 };
1844 char *a1
= NULL
, *a
;
1847 l1
= ssfilter_bytecompile(f
->pred
, &a1
);
1852 if (!(a
= malloc(l1
+4))) abort();
1855 *(struct inet_diag_bc_op
*)(a
+l1
) = (struct inet_diag_bc_op
){ INET_DIAG_BC_JMP
, 4, 8 };
1861 /* bytecompile for SSF_DEVCOND not supported yet */
1866 struct aafilter
*a
= (void *)f
->pred
;
1868 struct inet_diag_bc_op op
;
1869 struct inet_diag_markcond cond
;
1871 int inslen
= sizeof(struct instr
);
1873 if (!(*bytecode
= malloc(inslen
))) abort();
1874 ((struct instr
*)*bytecode
)[0] = (struct instr
) {
1875 { INET_DIAG_BC_MARK_COND
, inslen
, inslen
+ 4 },
1876 { a
->mark
, a
->mask
},
1886 static int remember_he(struct aafilter
*a
, struct hostent
*he
)
1888 char **ptr
= he
->h_addr_list
;
1892 if (he
->h_addrtype
== AF_INET
)
1894 else if (he
->h_addrtype
== AF_INET6
)
1900 struct aafilter
*b
= a
;
1902 if (a
->addr
.bitlen
) {
1903 if ((b
= malloc(sizeof(*b
))) == NULL
)
1908 memcpy(b
->addr
.data
, *ptr
, len
);
1909 b
->addr
.bytelen
= len
;
1910 b
->addr
.bitlen
= len
*8;
1911 b
->addr
.family
= he
->h_addrtype
;
1918 static int get_dns_host(struct aafilter
*a
, const char *addr
, int fam
)
1920 static int notfirst
;
1929 he
= gethostbyname2(addr
, fam
== AF_UNSPEC
? AF_INET
: fam
);
1931 cnt
= remember_he(a
, he
);
1932 if (fam
== AF_UNSPEC
) {
1933 he
= gethostbyname2(addr
, AF_INET6
);
1935 cnt
+= remember_he(a
, he
);
1940 static int xll_initted
;
1942 static void xll_init(void)
1944 struct rtnl_handle rth
;
1946 if (rtnl_open(&rth
, 0) < 0)
1954 static const char *xll_index_to_name(int index
)
1958 return ll_index_to_name(index
);
1961 static int xll_name_to_index(const char *dev
)
1965 return ll_name_to_index(dev
);
1968 void *parse_devcond(char *name
)
1970 struct aafilter a
= { .iface
= 0 };
1971 struct aafilter
*res
;
1973 a
.iface
= xll_name_to_index(name
);
1978 n
= strtoul(name
, &end
, 0);
1979 if (!end
|| end
== name
|| *end
|| n
> UINT_MAX
)
1985 res
= malloc(sizeof(*res
));
1991 static void vsock_set_inet_prefix(inet_prefix
*a
, __u32 cid
)
1994 .bytelen
= sizeof(cid
),
1997 memcpy(a
->data
, &cid
, sizeof(cid
));
2000 void *parse_hostcond(char *addr
, bool is_port
)
2003 struct aafilter a
= { .port
= -1 };
2004 struct aafilter
*res
;
2005 int fam
= preferred_family
;
2006 struct filter
*f
= ¤t_filter
;
2008 if (fam
== AF_UNIX
|| strncmp(addr
, "unix:", 5) == 0) {
2011 a
.addr
.family
= AF_UNIX
;
2012 if (strncmp(addr
, "unix:", 5) == 0)
2015 a
.addr
.bitlen
= 8*strlen(p
);
2016 memcpy(a
.addr
.data
, &p
, sizeof(p
));
2021 if (fam
== AF_PACKET
|| strncmp(addr
, "link:", 5) == 0) {
2022 a
.addr
.family
= AF_PACKET
;
2024 if (strncmp(addr
, "link:", 5) == 0)
2026 port
= strchr(addr
, ':');
2029 if (port
[1] && strcmp(port
+1, "*")) {
2030 if (get_integer(&a
.port
, port
+1, 0)) {
2031 if ((a
.port
= xll_name_to_index(port
+1)) <= 0)
2036 if (addr
[0] && strcmp(addr
, "*")) {
2040 if (ll_proto_a2n(&tmp
, addr
))
2042 a
.addr
.data
[0] = ntohs(tmp
);
2048 if (fam
== AF_NETLINK
|| strncmp(addr
, "netlink:", 8) == 0) {
2049 a
.addr
.family
= AF_NETLINK
;
2051 if (strncmp(addr
, "netlink:", 8) == 0)
2053 port
= strchr(addr
, ':');
2056 if (port
[1] && strcmp(port
+1, "*")) {
2057 if (get_integer(&a
.port
, port
+1, 0)) {
2058 if (strcmp(port
+1, "kernel") == 0)
2065 if (addr
[0] && strcmp(addr
, "*")) {
2067 if (nl_proto_a2n(&a
.addr
.data
[0], addr
) == -1)
2074 if (fam
== AF_VSOCK
|| strncmp(addr
, "vsock:", 6) == 0) {
2075 __u32 cid
= ~(__u32
)0;
2077 a
.addr
.family
= AF_VSOCK
;
2078 if (strncmp(addr
, "vsock:", 6) == 0)
2084 port
= strchr(addr
, ':');
2091 if (port
&& strcmp(port
, "*") &&
2092 get_u32((__u32
*)&a
.port
, port
, 0))
2095 if (addr
[0] && strcmp(addr
, "*")) {
2097 if (get_u32(&cid
, addr
, 0))
2100 vsock_set_inet_prefix(&a
.addr
, cid
);
2105 if (fam
== AF_INET
|| !strncmp(addr
, "inet:", 5)) {
2107 if (!strncmp(addr
, "inet:", 5))
2109 } else if (fam
== AF_INET6
|| !strncmp(addr
, "inet6:", 6)) {
2111 if (!strncmp(addr
, "inet6:", 6))
2115 /* URL-like literal [] */
2116 if (addr
[0] == '[') {
2118 if ((port
= strchr(addr
, ']')) == NULL
)
2121 } else if (addr
[0] == '*') {
2124 port
= strrchr(strchr(addr
, '/') ? : addr
, ':');
2130 if (port
&& *port
) {
2134 if (*port
&& *port
!= '*') {
2135 if (get_integer(&a
.port
, port
, 0)) {
2136 struct servent
*se1
= NULL
;
2137 struct servent
*se2
= NULL
;
2139 if (current_filter
.dbs
&(1<<UDP_DB
))
2140 se1
= getservbyname(port
, UDP_PROTO
);
2141 if (current_filter
.dbs
&(1<<TCP_DB
))
2142 se2
= getservbyname(port
, TCP_PROTO
);
2143 if (se1
&& se2
&& se1
->s_port
!= se2
->s_port
) {
2144 fprintf(stderr
, "Error: ambiguous port \"%s\".\n", port
);
2150 a
.port
= ntohs(se1
->s_port
);
2154 for (s
= rlist
; s
; s
= s
->next
) {
2155 if ((s
->proto
== UDP_PROTO
&&
2156 (current_filter
.dbs
&(1<<UDP_DB
))) ||
2157 (s
->proto
== TCP_PROTO
&&
2158 (current_filter
.dbs
&(1<<TCP_DB
)))) {
2159 if (s
->name
&& strcmp(s
->name
, port
) == 0) {
2160 if (a
.port
> 0 && a
.port
!= s
->port
) {
2161 fprintf(stderr
, "Error: ambiguous port \"%s\".\n", port
);
2169 fprintf(stderr
, "Error: \"%s\" does not look like a port.\n", port
);
2176 if (!is_port
&& *addr
&& *addr
!= '*') {
2177 if (get_prefix_1(&a
.addr
, addr
, fam
)) {
2178 if (get_dns_host(&a
, addr
, fam
)) {
2179 fprintf(stderr
, "Error: an inet prefix is expected rather than \"%s\".\n", addr
);
2186 if (fam
!= AF_UNSPEC
) {
2187 int states
= f
->states
;
2189 filter_af_set(f
, fam
);
2190 filter_states_set(f
, states
);
2193 res
= malloc(sizeof(*res
));
2195 memcpy(res
, &a
, sizeof(a
));
2199 void *parse_markmask(const char *markmask
)
2201 struct aafilter a
, *res
;
2203 if (strchr(markmask
, '/')) {
2204 if (sscanf(markmask
, "%i/%i", &a
.mark
, &a
.mask
) != 2)
2207 a
.mask
= 0xffffffff;
2208 if (sscanf(markmask
, "%i", &a
.mark
) != 1)
2212 res
= malloc(sizeof(*res
));
2214 memcpy(res
, &a
, sizeof(a
));
2218 static void proc_ctx_print(struct sockstat
*s
)
2222 if (show_proc_ctx
|| show_sock_ctx
) {
2223 if (find_entry(s
->ino
, &buf
,
2224 (show_proc_ctx
& show_sock_ctx
) ?
2225 PROC_SOCK_CTX
: PROC_CTX
) > 0) {
2226 out(" users:(%s)", buf
);
2229 } else if (show_users
) {
2230 if (find_entry(s
->ino
, &buf
, USERS
) > 0) {
2231 out(" users:(%s)", buf
);
2237 static void inet_stats_print(struct sockstat
*s
, bool v6only
)
2239 sock_state_print(s
);
2241 inet_addr_print(&s
->local
, s
->lport
, s
->iface
, v6only
);
2242 inet_addr_print(&s
->remote
, s
->rport
, 0, v6only
);
2247 static int proc_parse_inet_addr(char *loc
, char *rem
, int family
, struct
2250 s
->local
.family
= s
->remote
.family
= family
;
2251 if (family
== AF_INET
) {
2252 sscanf(loc
, "%x:%x", s
->local
.data
, (unsigned *)&s
->lport
);
2253 sscanf(rem
, "%x:%x", s
->remote
.data
, (unsigned *)&s
->rport
);
2254 s
->local
.bytelen
= s
->remote
.bytelen
= 4;
2257 sscanf(loc
, "%08x%08x%08x%08x:%x",
2263 sscanf(rem
, "%08x%08x%08x%08x:%x",
2269 s
->local
.bytelen
= s
->remote
.bytelen
= 16;
2275 static int proc_inet_split_line(char *line
, char **loc
, char **rem
, char **data
)
2279 if ((p
= strchr(line
, ':')) == NULL
)
2283 if ((p
= strchr(*loc
, ':')) == NULL
)
2288 if ((p
= strchr(*rem
, ':')) == NULL
)
2296 static char *sprint_bw(char *buf
, double bw
)
2299 sprintf(buf
, "%.1fM", bw
/ 1000000.);
2300 else if (bw
> 1000.)
2301 sprintf(buf
, "%.1fK", bw
/ 1000.);
2303 sprintf(buf
, "%g", bw
);
2308 static void sctp_stats_print(struct sctp_info
*s
)
2311 out(" tag:%x", s
->sctpi_tag
);
2313 out(" state:%s", sctp_sstate_name
[s
->sctpi_state
]);
2315 out(" rwnd:%d", s
->sctpi_rwnd
);
2316 if (s
->sctpi_unackdata
)
2317 out(" unackdata:%d", s
->sctpi_unackdata
);
2318 if (s
->sctpi_penddata
)
2319 out(" penddata:%d", s
->sctpi_penddata
);
2320 if (s
->sctpi_instrms
)
2321 out(" instrms:%d", s
->sctpi_instrms
);
2322 if (s
->sctpi_outstrms
)
2323 out(" outstrms:%d", s
->sctpi_outstrms
);
2324 if (s
->sctpi_inqueue
)
2325 out(" inqueue:%d", s
->sctpi_inqueue
);
2326 if (s
->sctpi_outqueue
)
2327 out(" outqueue:%d", s
->sctpi_outqueue
);
2328 if (s
->sctpi_overall_error
)
2329 out(" overerr:%d", s
->sctpi_overall_error
);
2330 if (s
->sctpi_max_burst
)
2331 out(" maxburst:%d", s
->sctpi_max_burst
);
2332 if (s
->sctpi_maxseg
)
2333 out(" maxseg:%d", s
->sctpi_maxseg
);
2334 if (s
->sctpi_peer_rwnd
)
2335 out(" prwnd:%d", s
->sctpi_peer_rwnd
);
2336 if (s
->sctpi_peer_tag
)
2337 out(" ptag:%x", s
->sctpi_peer_tag
);
2338 if (s
->sctpi_peer_capable
)
2339 out(" pcapable:%d", s
->sctpi_peer_capable
);
2340 if (s
->sctpi_peer_sack
)
2341 out(" psack:%d", s
->sctpi_peer_sack
);
2342 if (s
->sctpi_s_autoclose
)
2343 out(" autoclose:%d", s
->sctpi_s_autoclose
);
2344 if (s
->sctpi_s_adaptation_ind
)
2345 out(" adapind:%d", s
->sctpi_s_adaptation_ind
);
2346 if (s
->sctpi_s_pd_point
)
2347 out(" pdpoint:%d", s
->sctpi_s_pd_point
);
2348 if (s
->sctpi_s_nodelay
)
2349 out(" nodealy:%d", s
->sctpi_s_nodelay
);
2350 if (s
->sctpi_s_disable_fragments
)
2351 out(" nofrag:%d", s
->sctpi_s_disable_fragments
);
2352 if (s
->sctpi_s_v4mapped
)
2353 out(" v4mapped:%d", s
->sctpi_s_v4mapped
);
2354 if (s
->sctpi_s_frag_interleave
)
2355 out(" fraginl:%d", s
->sctpi_s_frag_interleave
);
2358 static void tcp_stats_print(struct tcpstat
*s
)
2364 if (s
->has_sack_opt
)
2368 if (s
->has_ecnseen_opt
)
2370 if (s
->has_fastopen_opt
)
2373 out(" %s", s
->cong_alg
);
2374 if (s
->has_wscale_opt
)
2375 out(" wscale:%d,%d", s
->snd_wscale
, s
->rcv_wscale
);
2377 out(" rto:%g", s
->rto
);
2379 out(" backoff:%u", s
->backoff
);
2381 out(" rtt:%g/%g", s
->rtt
, s
->rttvar
);
2383 out(" ato:%g", s
->ato
);
2386 out(" qack:%d", s
->qack
);
2391 out(" mss:%d", s
->mss
);
2393 out(" pmtu:%u", s
->pmtu
);
2395 out(" rcvmss:%d", s
->rcv_mss
);
2397 out(" advmss:%d", s
->advmss
);
2399 out(" cwnd:%u", s
->cwnd
);
2401 out(" ssthresh:%d", s
->ssthresh
);
2404 out(" bytes_acked:%llu", s
->bytes_acked
);
2405 if (s
->bytes_received
)
2406 out(" bytes_received:%llu", s
->bytes_received
);
2408 out(" segs_out:%u", s
->segs_out
);
2410 out(" segs_in:%u", s
->segs_in
);
2411 if (s
->data_segs_out
)
2412 out(" data_segs_out:%u", s
->data_segs_out
);
2413 if (s
->data_segs_in
)
2414 out(" data_segs_in:%u", s
->data_segs_in
);
2416 if (s
->dctcp
&& s
->dctcp
->enabled
) {
2417 struct dctcpstat
*dctcp
= s
->dctcp
;
2419 out(" dctcp:(ce_state:%u,alpha:%u,ab_ecn:%u,ab_tot:%u)",
2420 dctcp
->ce_state
, dctcp
->alpha
, dctcp
->ab_ecn
,
2422 } else if (s
->dctcp
) {
2423 out(" dctcp:fallback_mode");
2429 bw
= s
->bbr_info
->bbr_bw_hi
;
2431 bw
|= s
->bbr_info
->bbr_bw_lo
;
2433 out(" bbr:(bw:%sbps,mrtt:%g",
2434 sprint_bw(b1
, bw
* 8.0),
2435 (double)s
->bbr_info
->bbr_min_rtt
/ 1000.0);
2436 if (s
->bbr_info
->bbr_pacing_gain
)
2437 out(",pacing_gain:%g",
2438 (double)s
->bbr_info
->bbr_pacing_gain
/ 256.0);
2439 if (s
->bbr_info
->bbr_cwnd_gain
)
2440 out(",cwnd_gain:%g",
2441 (double)s
->bbr_info
->bbr_cwnd_gain
/ 256.0);
2446 out(" send %sbps", sprint_bw(b1
, s
->send_bps
));
2448 out(" lastsnd:%u", s
->lastsnd
);
2450 out(" lastrcv:%u", s
->lastrcv
);
2452 out(" lastack:%u", s
->lastack
);
2454 if (s
->pacing_rate
) {
2455 out(" pacing_rate %sbps", sprint_bw(b1
, s
->pacing_rate
));
2456 if (s
->pacing_rate_max
)
2457 out("/%sbps", sprint_bw(b1
, s
->pacing_rate_max
));
2460 if (s
->delivery_rate
)
2461 out(" delivery_rate %sbps", sprint_bw(b1
, s
->delivery_rate
));
2463 out(" app_limited");
2466 out(" busy:%llums", s
->busy_time
/ 1000);
2467 if (s
->rwnd_limited
)
2468 out(" rwnd_limited:%llums(%.1f%%)",
2469 s
->rwnd_limited
/ 1000,
2470 100.0 * s
->rwnd_limited
/ s
->busy_time
);
2471 if (s
->sndbuf_limited
)
2472 out(" sndbuf_limited:%llums(%.1f%%)",
2473 s
->sndbuf_limited
/ 1000,
2474 100.0 * s
->sndbuf_limited
/ s
->busy_time
);
2478 out(" unacked:%u", s
->unacked
);
2479 if (s
->retrans
|| s
->retrans_total
)
2480 out(" retrans:%u/%u", s
->retrans
, s
->retrans_total
);
2482 out(" lost:%u", s
->lost
);
2483 if (s
->sacked
&& s
->ss
.state
!= SS_LISTEN
)
2484 out(" sacked:%u", s
->sacked
);
2486 out(" fackets:%u", s
->fackets
);
2487 if (s
->reordering
!= 3)
2488 out(" reordering:%d", s
->reordering
);
2490 out(" rcv_rtt:%g", s
->rcv_rtt
);
2492 out(" rcv_space:%d", s
->rcv_space
);
2493 if (s
->rcv_ssthresh
)
2494 out(" rcv_ssthresh:%u", s
->rcv_ssthresh
);
2496 out(" notsent:%u", s
->not_sent
);
2498 out(" minrtt:%g", s
->min_rtt
);
2501 static void tcp_timer_print(struct tcpstat
*s
)
2503 static const char * const tmr_name
[] = {
2515 out(" timer:(%s,%s,%d)",
2517 print_ms_timer(s
->timeout
),
2522 static void sctp_timer_print(struct tcpstat
*s
)
2525 out(" timer:(T3_RTX,%s,%d)",
2526 print_ms_timer(s
->timeout
), s
->retrans
);
2529 static int tcp_show_line(char *line
, const struct filter
*f
, int family
)
2531 int rto
= 0, ato
= 0;
2532 struct tcpstat s
= {};
2533 char *loc
, *rem
, *data
;
2536 int hz
= get_user_hz();
2538 if (proc_inet_split_line(line
, &loc
, &rem
, &data
))
2541 int state
= (data
[1] >= 'A') ? (data
[1] - 'A' + 10) : (data
[1] - '0');
2543 if (!(f
->states
& (1 << state
)))
2546 proc_parse_inet_addr(loc
, rem
, family
, &s
.ss
);
2548 if (f
->f
&& run_ssfilter(f
->f
, &s
.ss
) == 0)
2552 n
= sscanf(data
, "%x %x:%x %x:%x %x %d %d %u %d %llx %d %d %d %u %d %[^\n]\n",
2553 &s
.ss
.state
, &s
.ss
.wq
, &s
.ss
.rq
,
2554 &s
.timer
, &s
.timeout
, &s
.retrans
, &s
.ss
.uid
, &s
.probes
,
2555 &s
.ss
.ino
, &s
.ss
.refcnt
, &s
.ss
.sk
, &rto
, &ato
, &s
.qack
, &s
.cwnd
,
2568 s
.retrans
= s
.timer
!= 1 ? s
.probes
: s
.retrans
;
2569 s
.timeout
= (s
.timeout
* 1000 + hz
- 1) / hz
;
2570 s
.ato
= (double)ato
/ hz
;
2572 s
.rto
= (double)rto
;
2573 s
.ssthresh
= s
.ssthresh
== -1 ? 0 : s
.ssthresh
;
2574 s
.rto
= s
.rto
!= 3 * hz
? s
.rto
/ hz
: 0;
2575 s
.ss
.type
= IPPROTO_TCP
;
2577 inet_stats_print(&s
.ss
, false);
2580 tcp_timer_print(&s
);
2583 sock_details_print(&s
.ss
);
2585 out(" opt:\"%s\"", opt
);
2589 tcp_stats_print(&s
);
2594 static int generic_record_read(FILE *fp
,
2595 int (*worker
)(char*, const struct filter
*, int),
2596 const struct filter
*f
, int fam
)
2601 if (fgets(line
, sizeof(line
), fp
) == NULL
)
2604 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
2605 int n
= strlen(line
);
2607 if (n
== 0 || line
[n
-1] != '\n') {
2613 if (worker(line
, f
, fam
) < 0)
2618 return ferror(fp
) ? -1 : 0;
2621 static void print_skmeminfo(struct rtattr
*tb
[], int attrtype
)
2623 const __u32
*skmeminfo
;
2625 if (!tb
[attrtype
]) {
2626 if (attrtype
== INET_DIAG_SKMEMINFO
) {
2627 if (!tb
[INET_DIAG_MEMINFO
])
2630 const struct inet_diag_meminfo
*minfo
=
2631 RTA_DATA(tb
[INET_DIAG_MEMINFO
]);
2633 out(" mem:(r%u,w%u,f%u,t%u)",
2642 skmeminfo
= RTA_DATA(tb
[attrtype
]);
2644 out(" skmem:(r%u,rb%u,t%u,tb%u,f%u,w%u,o%u",
2645 skmeminfo
[SK_MEMINFO_RMEM_ALLOC
],
2646 skmeminfo
[SK_MEMINFO_RCVBUF
],
2647 skmeminfo
[SK_MEMINFO_WMEM_ALLOC
],
2648 skmeminfo
[SK_MEMINFO_SNDBUF
],
2649 skmeminfo
[SK_MEMINFO_FWD_ALLOC
],
2650 skmeminfo
[SK_MEMINFO_WMEM_QUEUED
],
2651 skmeminfo
[SK_MEMINFO_OPTMEM
]);
2653 if (RTA_PAYLOAD(tb
[attrtype
]) >=
2654 (SK_MEMINFO_BACKLOG
+ 1) * sizeof(__u32
))
2655 out(",bl%u", skmeminfo
[SK_MEMINFO_BACKLOG
]);
2657 if (RTA_PAYLOAD(tb
[attrtype
]) >=
2658 (SK_MEMINFO_DROPS
+ 1) * sizeof(__u32
))
2659 out(",d%u", skmeminfo
[SK_MEMINFO_DROPS
]);
2664 static void print_md5sig(struct tcp_diag_md5sig
*sig
)
2667 format_host(sig
->tcpm_family
,
2668 sig
->tcpm_family
== AF_INET6
? 16 : 4,
2670 sig
->tcpm_prefixlen
);
2671 print_escape_buf(sig
->tcpm_key
, sig
->tcpm_keylen
, " ,");
2674 #define TCPI_HAS_OPT(info, opt) !!(info->tcpi_options & (opt))
2676 static void tcp_show_info(const struct nlmsghdr
*nlh
, struct inet_diag_msg
*r
,
2677 struct rtattr
*tb
[])
2680 struct tcpstat s
= {};
2682 s
.ss
.state
= r
->idiag_state
;
2684 print_skmeminfo(tb
, INET_DIAG_SKMEMINFO
);
2686 if (tb
[INET_DIAG_INFO
]) {
2687 struct tcp_info
*info
;
2688 int len
= RTA_PAYLOAD(tb
[INET_DIAG_INFO
]);
2690 /* workaround for older kernels with less fields */
2691 if (len
< sizeof(*info
)) {
2692 info
= alloca(sizeof(*info
));
2693 memcpy(info
, RTA_DATA(tb
[INET_DIAG_INFO
]), len
);
2694 memset((char *)info
+ len
, 0, sizeof(*info
) - len
);
2696 info
= RTA_DATA(tb
[INET_DIAG_INFO
]);
2699 s
.has_ts_opt
= TCPI_HAS_OPT(info
, TCPI_OPT_TIMESTAMPS
);
2700 s
.has_sack_opt
= TCPI_HAS_OPT(info
, TCPI_OPT_SACK
);
2701 s
.has_ecn_opt
= TCPI_HAS_OPT(info
, TCPI_OPT_ECN
);
2702 s
.has_ecnseen_opt
= TCPI_HAS_OPT(info
, TCPI_OPT_ECN_SEEN
);
2703 s
.has_fastopen_opt
= TCPI_HAS_OPT(info
, TCPI_OPT_SYN_DATA
);
2706 if (tb
[INET_DIAG_CONG
])
2708 rta_getattr_str(tb
[INET_DIAG_CONG
]),
2709 sizeof(s
.cong_alg
) - 1);
2711 if (TCPI_HAS_OPT(info
, TCPI_OPT_WSCALE
)) {
2712 s
.has_wscale_opt
= true;
2713 s
.snd_wscale
= info
->tcpi_snd_wscale
;
2714 s
.rcv_wscale
= info
->tcpi_rcv_wscale
;
2717 if (info
->tcpi_rto
&& info
->tcpi_rto
!= 3000000)
2718 s
.rto
= (double)info
->tcpi_rto
/ 1000;
2720 s
.backoff
= info
->tcpi_backoff
;
2721 s
.rtt
= (double)info
->tcpi_rtt
/ 1000;
2722 s
.rttvar
= (double)info
->tcpi_rttvar
/ 1000;
2723 s
.ato
= (double)info
->tcpi_ato
/ 1000;
2724 s
.mss
= info
->tcpi_snd_mss
;
2725 s
.rcv_mss
= info
->tcpi_rcv_mss
;
2726 s
.advmss
= info
->tcpi_advmss
;
2727 s
.rcv_space
= info
->tcpi_rcv_space
;
2728 s
.rcv_rtt
= (double)info
->tcpi_rcv_rtt
/ 1000;
2729 s
.lastsnd
= info
->tcpi_last_data_sent
;
2730 s
.lastrcv
= info
->tcpi_last_data_recv
;
2731 s
.lastack
= info
->tcpi_last_ack_recv
;
2732 s
.unacked
= info
->tcpi_unacked
;
2733 s
.retrans
= info
->tcpi_retrans
;
2734 s
.retrans_total
= info
->tcpi_total_retrans
;
2735 s
.lost
= info
->tcpi_lost
;
2736 s
.sacked
= info
->tcpi_sacked
;
2737 s
.fackets
= info
->tcpi_fackets
;
2738 s
.reordering
= info
->tcpi_reordering
;
2739 s
.rcv_ssthresh
= info
->tcpi_rcv_ssthresh
;
2740 s
.cwnd
= info
->tcpi_snd_cwnd
;
2741 s
.pmtu
= info
->tcpi_pmtu
;
2743 if (info
->tcpi_snd_ssthresh
< 0xFFFF)
2744 s
.ssthresh
= info
->tcpi_snd_ssthresh
;
2746 rtt
= (double) info
->tcpi_rtt
;
2747 if (tb
[INET_DIAG_VEGASINFO
]) {
2748 const struct tcpvegas_info
*vinfo
2749 = RTA_DATA(tb
[INET_DIAG_VEGASINFO
]);
2751 if (vinfo
->tcpv_enabled
&&
2752 vinfo
->tcpv_rtt
&& vinfo
->tcpv_rtt
!= 0x7fffffff)
2753 rtt
= vinfo
->tcpv_rtt
;
2756 if (tb
[INET_DIAG_DCTCPINFO
]) {
2757 struct dctcpstat
*dctcp
= malloc(sizeof(struct
2760 const struct tcp_dctcp_info
*dinfo
2761 = RTA_DATA(tb
[INET_DIAG_DCTCPINFO
]);
2763 dctcp
->enabled
= !!dinfo
->dctcp_enabled
;
2764 dctcp
->ce_state
= dinfo
->dctcp_ce_state
;
2765 dctcp
->alpha
= dinfo
->dctcp_alpha
;
2766 dctcp
->ab_ecn
= dinfo
->dctcp_ab_ecn
;
2767 dctcp
->ab_tot
= dinfo
->dctcp_ab_tot
;
2771 if (tb
[INET_DIAG_BBRINFO
]) {
2772 const void *bbr_info
= RTA_DATA(tb
[INET_DIAG_BBRINFO
]);
2773 int len
= min(RTA_PAYLOAD(tb
[INET_DIAG_BBRINFO
]),
2774 sizeof(*s
.bbr_info
));
2776 s
.bbr_info
= calloc(1, sizeof(*s
.bbr_info
));
2777 if (s
.bbr_info
&& bbr_info
)
2778 memcpy(s
.bbr_info
, bbr_info
, len
);
2781 if (rtt
> 0 && info
->tcpi_snd_mss
&& info
->tcpi_snd_cwnd
) {
2782 s
.send_bps
= (double) info
->tcpi_snd_cwnd
*
2783 (double)info
->tcpi_snd_mss
* 8000000. / rtt
;
2786 if (info
->tcpi_pacing_rate
&&
2787 info
->tcpi_pacing_rate
!= ~0ULL) {
2788 s
.pacing_rate
= info
->tcpi_pacing_rate
* 8.;
2790 if (info
->tcpi_max_pacing_rate
&&
2791 info
->tcpi_max_pacing_rate
!= ~0ULL)
2792 s
.pacing_rate_max
= info
->tcpi_max_pacing_rate
* 8.;
2794 s
.bytes_acked
= info
->tcpi_bytes_acked
;
2795 s
.bytes_received
= info
->tcpi_bytes_received
;
2796 s
.segs_out
= info
->tcpi_segs_out
;
2797 s
.segs_in
= info
->tcpi_segs_in
;
2798 s
.data_segs_out
= info
->tcpi_data_segs_out
;
2799 s
.data_segs_in
= info
->tcpi_data_segs_in
;
2800 s
.not_sent
= info
->tcpi_notsent_bytes
;
2801 if (info
->tcpi_min_rtt
&& info
->tcpi_min_rtt
!= ~0U)
2802 s
.min_rtt
= (double) info
->tcpi_min_rtt
/ 1000;
2803 s
.delivery_rate
= info
->tcpi_delivery_rate
* 8.;
2804 s
.app_limited
= info
->tcpi_delivery_rate_app_limited
;
2805 s
.busy_time
= info
->tcpi_busy_time
;
2806 s
.rwnd_limited
= info
->tcpi_rwnd_limited
;
2807 s
.sndbuf_limited
= info
->tcpi_sndbuf_limited
;
2808 tcp_stats_print(&s
);
2812 if (tb
[INET_DIAG_MD5SIG
]) {
2813 struct tcp_diag_md5sig
*sig
= RTA_DATA(tb
[INET_DIAG_MD5SIG
]);
2814 int len
= RTA_PAYLOAD(tb
[INET_DIAG_MD5SIG
]);
2817 print_md5sig(sig
++);
2818 for (len
-= sizeof(*sig
); len
> 0; len
-= sizeof(*sig
)) {
2820 print_md5sig(sig
++);
2825 static const char *format_host_sa(struct sockaddr_storage
*sa
)
2828 struct sockaddr_in sin
;
2829 struct sockaddr_in6 sin6
;
2830 } *saddr
= (void *)sa
;
2832 switch (sa
->ss_family
) {
2834 return format_host(AF_INET
, 4, &saddr
->sin
.sin_addr
);
2836 return format_host(AF_INET6
, 16, &saddr
->sin6
.sin6_addr
);
2842 static void sctp_show_info(const struct nlmsghdr
*nlh
, struct inet_diag_msg
*r
,
2843 struct rtattr
*tb
[])
2845 struct sockaddr_storage
*sa
;
2848 print_skmeminfo(tb
, INET_DIAG_SKMEMINFO
);
2850 if (tb
[INET_DIAG_LOCALS
]) {
2851 len
= RTA_PAYLOAD(tb
[INET_DIAG_LOCALS
]);
2852 sa
= RTA_DATA(tb
[INET_DIAG_LOCALS
]);
2854 out("locals:%s", format_host_sa(sa
));
2855 for (sa
++, len
-= sizeof(*sa
); len
> 0; sa
++, len
-= sizeof(*sa
))
2856 out(",%s", format_host_sa(sa
));
2859 if (tb
[INET_DIAG_PEERS
]) {
2860 len
= RTA_PAYLOAD(tb
[INET_DIAG_PEERS
]);
2861 sa
= RTA_DATA(tb
[INET_DIAG_PEERS
]);
2863 out(" peers:%s", format_host_sa(sa
));
2864 for (sa
++, len
-= sizeof(*sa
); len
> 0; sa
++, len
-= sizeof(*sa
))
2865 out(",%s", format_host_sa(sa
));
2867 if (tb
[INET_DIAG_INFO
]) {
2868 struct sctp_info
*info
;
2869 len
= RTA_PAYLOAD(tb
[INET_DIAG_INFO
]);
2871 /* workaround for older kernels with less fields */
2872 if (len
< sizeof(*info
)) {
2873 info
= alloca(sizeof(*info
));
2874 memcpy(info
, RTA_DATA(tb
[INET_DIAG_INFO
]), len
);
2875 memset((char *)info
+ len
, 0, sizeof(*info
) - len
);
2877 info
= RTA_DATA(tb
[INET_DIAG_INFO
]);
2879 sctp_stats_print(info
);
2883 static void parse_diag_msg(struct nlmsghdr
*nlh
, struct sockstat
*s
)
2885 struct rtattr
*tb
[INET_DIAG_MAX
+1];
2886 struct inet_diag_msg
*r
= NLMSG_DATA(nlh
);
2888 parse_rtattr(tb
, INET_DIAG_MAX
, (struct rtattr
*)(r
+1),
2889 nlh
->nlmsg_len
- NLMSG_LENGTH(sizeof(*r
)));
2891 s
->state
= r
->idiag_state
;
2892 s
->local
.family
= s
->remote
.family
= r
->idiag_family
;
2893 s
->lport
= ntohs(r
->id
.idiag_sport
);
2894 s
->rport
= ntohs(r
->id
.idiag_dport
);
2895 s
->wq
= r
->idiag_wqueue
;
2896 s
->rq
= r
->idiag_rqueue
;
2897 s
->ino
= r
->idiag_inode
;
2898 s
->uid
= r
->idiag_uid
;
2899 s
->iface
= r
->id
.idiag_if
;
2900 s
->sk
= cookie_sk_get(&r
->id
.idiag_cookie
[0]);
2903 if (tb
[INET_DIAG_MARK
])
2904 s
->mark
= rta_getattr_u32(tb
[INET_DIAG_MARK
]);
2905 if (tb
[INET_DIAG_PROTOCOL
])
2906 s
->raw_prot
= rta_getattr_u8(tb
[INET_DIAG_PROTOCOL
]);
2910 if (s
->local
.family
== AF_INET
)
2911 s
->local
.bytelen
= s
->remote
.bytelen
= 4;
2913 s
->local
.bytelen
= s
->remote
.bytelen
= 16;
2915 memcpy(s
->local
.data
, r
->id
.idiag_src
, s
->local
.bytelen
);
2916 memcpy(s
->remote
.data
, r
->id
.idiag_dst
, s
->local
.bytelen
);
2919 static int inet_show_sock(struct nlmsghdr
*nlh
,
2922 struct rtattr
*tb
[INET_DIAG_MAX
+1];
2923 struct inet_diag_msg
*r
= NLMSG_DATA(nlh
);
2924 unsigned char v6only
= 0;
2926 parse_rtattr(tb
, INET_DIAG_MAX
, (struct rtattr
*)(r
+1),
2927 nlh
->nlmsg_len
- NLMSG_LENGTH(sizeof(*r
)));
2929 if (tb
[INET_DIAG_PROTOCOL
])
2930 s
->type
= rta_getattr_u8(tb
[INET_DIAG_PROTOCOL
]);
2932 if (s
->local
.family
== AF_INET6
&& tb
[INET_DIAG_SKV6ONLY
])
2933 v6only
= rta_getattr_u8(tb
[INET_DIAG_SKV6ONLY
]);
2935 inet_stats_print(s
, v6only
);
2938 struct tcpstat t
= {};
2940 t
.timer
= r
->idiag_timer
;
2941 t
.timeout
= r
->idiag_expires
;
2942 t
.retrans
= r
->idiag_retrans
;
2943 if (s
->type
== IPPROTO_SCTP
)
2944 sctp_timer_print(&t
);
2946 tcp_timer_print(&t
);
2950 sock_details_print(s
);
2951 if (s
->local
.family
== AF_INET6
&& tb
[INET_DIAG_SKV6ONLY
])
2952 out(" v6only:%u", v6only
);
2954 if (tb
[INET_DIAG_SHUTDOWN
]) {
2957 mask
= rta_getattr_u8(tb
[INET_DIAG_SHUTDOWN
]);
2959 mask
& 1 ? '-' : '<', mask
& 2 ? '-' : '>');
2963 if (show_mem
|| (show_tcpinfo
&& s
->type
!= IPPROTO_UDP
)) {
2965 if (s
->type
== IPPROTO_SCTP
)
2966 sctp_show_info(nlh
, r
, tb
);
2968 tcp_show_info(nlh
, r
, tb
);
2975 static int tcpdiag_send(int fd
, int protocol
, struct filter
*f
)
2977 struct sockaddr_nl nladdr
= { .nl_family
= AF_NETLINK
};
2979 struct nlmsghdr nlh
;
2980 struct inet_diag_req r
;
2982 .nlh
.nlmsg_len
= sizeof(req
),
2983 .nlh
.nlmsg_flags
= NLM_F_ROOT
| NLM_F_MATCH
| NLM_F_REQUEST
,
2984 .nlh
.nlmsg_seq
= MAGIC_SEQ
,
2985 .r
.idiag_family
= AF_INET
,
2986 .r
.idiag_states
= f
->states
,
2992 struct iovec iov
[3];
2995 if (protocol
== IPPROTO_UDP
)
2998 if (protocol
== IPPROTO_TCP
)
2999 req
.nlh
.nlmsg_type
= TCPDIAG_GETSOCK
;
3001 req
.nlh
.nlmsg_type
= DCCPDIAG_GETSOCK
;
3003 req
.r
.idiag_ext
|= (1<<(INET_DIAG_MEMINFO
-1));
3004 req
.r
.idiag_ext
|= (1<<(INET_DIAG_SKMEMINFO
-1));
3008 req
.r
.idiag_ext
|= (1<<(INET_DIAG_INFO
-1));
3009 req
.r
.idiag_ext
|= (1<<(INET_DIAG_VEGASINFO
-1));
3010 req
.r
.idiag_ext
|= (1<<(INET_DIAG_CONG
-1));
3013 iov
[0] = (struct iovec
){
3015 .iov_len
= sizeof(req
)
3018 bclen
= ssfilter_bytecompile(f
->f
, &bc
);
3020 rta
.rta_type
= INET_DIAG_REQ_BYTECODE
;
3021 rta
.rta_len
= RTA_LENGTH(bclen
);
3022 iov
[1] = (struct iovec
){ &rta
, sizeof(rta
) };
3023 iov
[2] = (struct iovec
){ bc
, bclen
};
3024 req
.nlh
.nlmsg_len
+= RTA_LENGTH(bclen
);
3029 msg
= (struct msghdr
) {
3030 .msg_name
= (void *)&nladdr
,
3031 .msg_namelen
= sizeof(nladdr
),
3033 .msg_iovlen
= iovlen
,
3036 if (sendmsg(fd
, &msg
, 0) < 0) {
3044 static int sockdiag_send(int family
, int fd
, int protocol
, struct filter
*f
)
3046 struct sockaddr_nl nladdr
= { .nl_family
= AF_NETLINK
};
3047 DIAG_REQUEST(req
, struct inet_diag_req_v2 r
);
3052 struct iovec iov
[3];
3055 if (family
== PF_UNSPEC
)
3056 return tcpdiag_send(fd
, protocol
, f
);
3058 memset(&req
.r
, 0, sizeof(req
.r
));
3059 req
.r
.sdiag_family
= family
;
3060 req
.r
.sdiag_protocol
= protocol
;
3061 req
.r
.idiag_states
= f
->states
;
3063 req
.r
.idiag_ext
|= (1<<(INET_DIAG_MEMINFO
-1));
3064 req
.r
.idiag_ext
|= (1<<(INET_DIAG_SKMEMINFO
-1));
3068 req
.r
.idiag_ext
|= (1<<(INET_DIAG_INFO
-1));
3069 req
.r
.idiag_ext
|= (1<<(INET_DIAG_VEGASINFO
-1));
3070 req
.r
.idiag_ext
|= (1<<(INET_DIAG_CONG
-1));
3073 iov
[0] = (struct iovec
){
3075 .iov_len
= sizeof(req
)
3078 bclen
= ssfilter_bytecompile(f
->f
, &bc
);
3080 rta
.rta_type
= INET_DIAG_REQ_BYTECODE
;
3081 rta
.rta_len
= RTA_LENGTH(bclen
);
3082 iov
[1] = (struct iovec
){ &rta
, sizeof(rta
) };
3083 iov
[2] = (struct iovec
){ bc
, bclen
};
3084 req
.nlh
.nlmsg_len
+= RTA_LENGTH(bclen
);
3089 msg
= (struct msghdr
) {
3090 .msg_name
= (void *)&nladdr
,
3091 .msg_namelen
= sizeof(nladdr
),
3093 .msg_iovlen
= iovlen
,
3096 if (sendmsg(fd
, &msg
, 0) < 0) {
3104 struct inet_diag_arg
{
3107 struct rtnl_handle
*rth
;
3110 static int kill_inet_sock(struct nlmsghdr
*h
, void *arg
, struct sockstat
*s
)
3112 struct inet_diag_msg
*d
= NLMSG_DATA(h
);
3113 struct inet_diag_arg
*diag_arg
= arg
;
3114 struct rtnl_handle
*rth
= diag_arg
->rth
;
3116 DIAG_REQUEST(req
, struct inet_diag_req_v2 r
);
3118 req
.nlh
.nlmsg_type
= SOCK_DESTROY
;
3119 req
.nlh
.nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
;
3120 req
.nlh
.nlmsg_seq
= ++rth
->seq
;
3121 req
.r
.sdiag_family
= d
->idiag_family
;
3122 req
.r
.sdiag_protocol
= diag_arg
->protocol
;
3125 if (diag_arg
->protocol
== IPPROTO_RAW
) {
3126 struct inet_diag_req_raw
*raw
= (void *)&req
.r
;
3128 BUILD_BUG_ON(sizeof(req
.r
) != sizeof(*raw
));
3129 raw
->sdiag_raw_protocol
= s
->raw_prot
;
3132 return rtnl_talk(rth
, &req
.nlh
, NULL
);
3135 static int show_one_inet_sock(const struct sockaddr_nl
*addr
,
3136 struct nlmsghdr
*h
, void *arg
)
3139 struct inet_diag_arg
*diag_arg
= arg
;
3140 struct inet_diag_msg
*r
= NLMSG_DATA(h
);
3141 struct sockstat s
= {};
3143 if (!(diag_arg
->f
->families
& FAMILY_MASK(r
->idiag_family
)))
3146 parse_diag_msg(h
, &s
);
3147 s
.type
= diag_arg
->protocol
;
3149 if (diag_arg
->f
->f
&& run_ssfilter(diag_arg
->f
->f
, &s
) == 0)
3152 if (diag_arg
->f
->kill
&& kill_inet_sock(h
, arg
, &s
) != 0) {
3153 if (errno
== EOPNOTSUPP
|| errno
== ENOENT
) {
3154 /* Socket can't be closed, or is already closed. */
3157 perror("SOCK_DESTROY answers");
3162 err
= inet_show_sock(h
, &s
);
3169 static int inet_show_netlink(struct filter
*f
, FILE *dump_fp
, int protocol
)
3172 struct rtnl_handle rth
, rth2
;
3173 int family
= PF_INET
;
3174 struct inet_diag_arg arg
= { .f
= f
, .protocol
= protocol
};
3176 if (rtnl_open_byproto(&rth
, 0, NETLINK_SOCK_DIAG
))
3180 if (rtnl_open_byproto(&rth2
, 0, NETLINK_SOCK_DIAG
)) {
3187 rth
.dump
= MAGIC_SEQ
;
3188 rth
.dump_fp
= dump_fp
;
3189 if (preferred_family
== PF_INET6
)
3193 if ((err
= sockdiag_send(family
, rth
.fd
, protocol
, f
)))
3196 if ((err
= rtnl_dump_filter(&rth
, show_one_inet_sock
, &arg
))) {
3197 if (family
!= PF_UNSPEC
) {
3203 if (family
== PF_INET
&& preferred_family
!= PF_INET
) {
3211 rtnl_close(arg
.rth
);
3215 static int tcp_show_netlink_file(struct filter
*f
)
3221 if ((fp
= fopen(getenv("TCPDIAG_FILE"), "r")) == NULL
) {
3222 perror("fopen($TCPDIAG_FILE)");
3228 struct nlmsghdr
*h
= (struct nlmsghdr
*)buf
;
3229 struct sockstat s
= {};
3231 status
= fread(buf
, 1, sizeof(*h
), fp
);
3233 perror("Reading header from $TCPDIAG_FILE");
3236 if (status
!= sizeof(*h
)) {
3237 perror("Unexpected EOF reading $TCPDIAG_FILE");
3241 status
= fread(h
+1, 1, NLMSG_ALIGN(h
->nlmsg_len
-sizeof(*h
)), fp
);
3244 perror("Reading $TCPDIAG_FILE");
3247 if (status
+ sizeof(*h
) < h
->nlmsg_len
) {
3248 perror("Unexpected EOF reading $TCPDIAG_FILE");
3252 /* The only legal exit point */
3253 if (h
->nlmsg_type
== NLMSG_DONE
) {
3258 if (h
->nlmsg_type
== NLMSG_ERROR
) {
3259 struct nlmsgerr
*err
= (struct nlmsgerr
*)NLMSG_DATA(h
);
3261 if (h
->nlmsg_len
< NLMSG_LENGTH(sizeof(struct nlmsgerr
))) {
3262 fprintf(stderr
, "ERROR truncated\n");
3264 errno
= -err
->error
;
3265 perror("TCPDIAG answered");
3270 parse_diag_msg(h
, &s
);
3271 s
.type
= IPPROTO_TCP
;
3273 if (f
&& f
->f
&& run_ssfilter(f
->f
, &s
) == 0)
3276 err2
= inet_show_sock(h
, &s
);
3287 static int tcp_show(struct filter
*f
)
3291 int bufsize
= 64*1024;
3293 if (!filter_af_get(f
, AF_INET
) && !filter_af_get(f
, AF_INET6
))
3296 dg_proto
= TCP_PROTO
;
3298 if (getenv("TCPDIAG_FILE"))
3299 return tcp_show_netlink_file(f
);
3301 if (!getenv("PROC_NET_TCP") && !getenv("PROC_ROOT")
3302 && inet_show_netlink(f
, NULL
, IPPROTO_TCP
) == 0)
3305 /* Sigh... We have to parse /proc/net/tcp... */
3308 /* Estimate amount of sockets and try to allocate
3309 * huge buffer to read all the table at one read.
3310 * Limit it by 16MB though. The assumption is: as soon as
3311 * kernel was able to hold information about N connections,
3312 * it is able to give us some memory for snapshot.
3315 get_slabstat(&slabstat
);
3317 int guess
= slabstat
.socks
+slabstat
.tcp_syns
;
3319 if (f
->states
&(1<<SS_TIME_WAIT
))
3320 guess
+= slabstat
.tcp_tws
;
3321 if (guess
> (16*1024*1024)/128)
3322 guess
= (16*1024*1024)/128;
3324 if (guess
> bufsize
)
3327 while (bufsize
>= 64*1024) {
3328 if ((buf
= malloc(bufsize
)) != NULL
)
3337 if (f
->families
& FAMILY_MASK(AF_INET
)) {
3338 if ((fp
= net_tcp_open()) == NULL
)
3341 setbuffer(fp
, buf
, bufsize
);
3342 if (generic_record_read(fp
, tcp_show_line
, f
, AF_INET
))
3347 if ((f
->families
& FAMILY_MASK(AF_INET6
)) &&
3348 (fp
= net_tcp6_open()) != NULL
) {
3349 setbuffer(fp
, buf
, bufsize
);
3350 if (generic_record_read(fp
, tcp_show_line
, f
, AF_INET6
))
3360 int saved_errno
= errno
;
3365 errno
= saved_errno
;
3370 static int dccp_show(struct filter
*f
)
3372 if (!filter_af_get(f
, AF_INET
) && !filter_af_get(f
, AF_INET6
))
3375 if (!getenv("PROC_NET_DCCP") && !getenv("PROC_ROOT")
3376 && inet_show_netlink(f
, NULL
, IPPROTO_DCCP
) == 0)
3382 static int sctp_show(struct filter
*f
)
3384 if (!filter_af_get(f
, AF_INET
) && !filter_af_get(f
, AF_INET6
))
3387 if (!getenv("PROC_NET_SCTP") && !getenv("PROC_ROOT")
3388 && inet_show_netlink(f
, NULL
, IPPROTO_SCTP
) == 0)
3394 static int dgram_show_line(char *line
, const struct filter
*f
, int family
)
3396 struct sockstat s
= {};
3397 char *loc
, *rem
, *data
;
3401 if (proc_inet_split_line(line
, &loc
, &rem
, &data
))
3404 int state
= (data
[1] >= 'A') ? (data
[1] - 'A' + 10) : (data
[1] - '0');
3406 if (!(f
->states
& (1 << state
)))
3409 proc_parse_inet_addr(loc
, rem
, family
, &s
);
3411 if (f
->f
&& run_ssfilter(f
->f
, &s
) == 0)
3415 n
= sscanf(data
, "%x %x:%x %*x:%*x %*x %d %*d %u %d %llx %[^\n]\n",
3416 &s
.state
, &s
.wq
, &s
.rq
,
3418 &s
.refcnt
, &s
.sk
, opt
);
3423 s
.type
= dg_proto
== UDP_PROTO
? IPPROTO_UDP
: 0;
3424 inet_stats_print(&s
, false);
3426 if (show_details
&& opt
[0])
3427 out(" opt:\"%s\"", opt
);
3432 static int udp_show(struct filter
*f
)
3436 if (!filter_af_get(f
, AF_INET
) && !filter_af_get(f
, AF_INET6
))
3439 dg_proto
= UDP_PROTO
;
3441 if (!getenv("PROC_NET_UDP") && !getenv("PROC_ROOT")
3442 && inet_show_netlink(f
, NULL
, IPPROTO_UDP
) == 0)
3445 if (f
->families
&FAMILY_MASK(AF_INET
)) {
3446 if ((fp
= net_udp_open()) == NULL
)
3448 if (generic_record_read(fp
, dgram_show_line
, f
, AF_INET
))
3453 if ((f
->families
&FAMILY_MASK(AF_INET6
)) &&
3454 (fp
= net_udp6_open()) != NULL
) {
3455 if (generic_record_read(fp
, dgram_show_line
, f
, AF_INET6
))
3463 int saved_errno
= errno
;
3467 errno
= saved_errno
;
3472 static int raw_show(struct filter
*f
)
3476 if (!filter_af_get(f
, AF_INET
) && !filter_af_get(f
, AF_INET6
))
3479 dg_proto
= RAW_PROTO
;
3481 if (!getenv("PROC_NET_RAW") && !getenv("PROC_ROOT") &&
3482 inet_show_netlink(f
, NULL
, IPPROTO_RAW
) == 0)
3485 if (f
->families
&FAMILY_MASK(AF_INET
)) {
3486 if ((fp
= net_raw_open()) == NULL
)
3488 if (generic_record_read(fp
, dgram_show_line
, f
, AF_INET
))
3493 if ((f
->families
&FAMILY_MASK(AF_INET6
)) &&
3494 (fp
= net_raw6_open()) != NULL
) {
3495 if (generic_record_read(fp
, dgram_show_line
, f
, AF_INET6
))
3503 int saved_errno
= errno
;
3507 errno
= saved_errno
;
3512 #define MAX_UNIX_REMEMBER (1024*1024/sizeof(struct sockstat))
3514 static void unix_list_drop_first(struct sockstat
**list
)
3516 struct sockstat
*s
= *list
;
3518 (*list
) = (*list
)->next
;
3523 static bool unix_type_skip(struct sockstat
*s
, struct filter
*f
)
3525 if (s
->type
== SOCK_STREAM
&& !(f
->dbs
&(1<<UNIX_ST_DB
)))
3527 if (s
->type
== SOCK_DGRAM
&& !(f
->dbs
&(1<<UNIX_DG_DB
)))
3529 if (s
->type
== SOCK_SEQPACKET
&& !(f
->dbs
&(1<<UNIX_SQ_DB
)))
3534 static void unix_stats_print(struct sockstat
*s
, struct filter
*f
)
3536 char port_name
[30] = {};
3538 sock_state_print(s
);
3540 sock_addr_print(s
->name
?: "*", " ",
3541 int_to_str(s
->lport
, port_name
), NULL
);
3542 sock_addr_print(s
->peer_name
?: "*", " ",
3543 int_to_str(s
->rport
, port_name
), NULL
);
3548 static int unix_show_sock(const struct sockaddr_nl
*addr
, struct nlmsghdr
*nlh
,
3551 struct filter
*f
= (struct filter
*)arg
;
3552 struct unix_diag_msg
*r
= NLMSG_DATA(nlh
);
3553 struct rtattr
*tb
[UNIX_DIAG_MAX
+1];
3555 struct sockstat stat
= { .name
= "*", .peer_name
= "*" };
3557 parse_rtattr(tb
, UNIX_DIAG_MAX
, (struct rtattr
*)(r
+1),
3558 nlh
->nlmsg_len
- NLMSG_LENGTH(sizeof(*r
)));
3560 stat
.type
= r
->udiag_type
;
3561 stat
.state
= r
->udiag_state
;
3562 stat
.ino
= stat
.lport
= r
->udiag_ino
;
3563 stat
.local
.family
= stat
.remote
.family
= AF_UNIX
;
3565 if (unix_type_skip(&stat
, f
))
3568 if (tb
[UNIX_DIAG_RQLEN
]) {
3569 struct unix_diag_rqlen
*rql
= RTA_DATA(tb
[UNIX_DIAG_RQLEN
]);
3571 stat
.rq
= rql
->udiag_rqueue
;
3572 stat
.wq
= rql
->udiag_wqueue
;
3574 if (tb
[UNIX_DIAG_NAME
]) {
3575 int len
= RTA_PAYLOAD(tb
[UNIX_DIAG_NAME
]);
3577 memcpy(name
, RTA_DATA(tb
[UNIX_DIAG_NAME
]), len
);
3579 if (name
[0] == '\0') {
3581 for (i
= 0; i
< len
; i
++)
3582 if (name
[i
] == '\0')
3585 stat
.name
= &name
[0];
3586 memcpy(stat
.local
.data
, &stat
.name
, sizeof(stat
.name
));
3588 if (tb
[UNIX_DIAG_PEER
])
3589 stat
.rport
= rta_getattr_u32(tb
[UNIX_DIAG_PEER
]);
3591 if (f
->f
&& run_ssfilter(f
->f
, &stat
) == 0)
3594 unix_stats_print(&stat
, f
);
3597 print_skmeminfo(tb
, UNIX_DIAG_MEMINFO
);
3599 if (tb
[UNIX_DIAG_SHUTDOWN
]) {
3602 mask
= rta_getattr_u8(tb
[UNIX_DIAG_SHUTDOWN
]);
3604 mask
& 1 ? '-' : '<', mask
& 2 ? '-' : '>');
3611 static int handle_netlink_request(struct filter
*f
, struct nlmsghdr
*req
,
3612 size_t size
, rtnl_filter_t show_one_sock
)
3615 struct rtnl_handle rth
;
3617 if (rtnl_open_byproto(&rth
, 0, NETLINK_SOCK_DIAG
))
3620 rth
.dump
= MAGIC_SEQ
;
3622 if (rtnl_send(&rth
, req
, size
) < 0)
3625 if (rtnl_dump_filter(&rth
, show_one_sock
, f
))
3634 static int unix_show_netlink(struct filter
*f
)
3636 DIAG_REQUEST(req
, struct unix_diag_req r
);
3638 req
.r
.sdiag_family
= AF_UNIX
;
3639 req
.r
.udiag_states
= f
->states
;
3640 req
.r
.udiag_show
= UDIAG_SHOW_NAME
| UDIAG_SHOW_PEER
| UDIAG_SHOW_RQLEN
;
3642 req
.r
.udiag_show
|= UDIAG_SHOW_MEMINFO
;
3644 return handle_netlink_request(f
, &req
.nlh
, sizeof(req
), unix_show_sock
);
3647 static int unix_show(struct filter
*f
)
3654 struct sockstat
*list
= NULL
;
3655 const int unix_state_map
[] = { SS_CLOSE
, SS_SYN_SENT
,
3656 SS_ESTABLISHED
, SS_CLOSING
};
3658 if (!filter_af_get(f
, AF_UNIX
))
3661 if (!getenv("PROC_NET_UNIX") && !getenv("PROC_ROOT")
3662 && unix_show_netlink(f
) == 0)
3665 if ((fp
= net_unix_open()) == NULL
)
3667 if (!fgets(buf
, sizeof(buf
), fp
)) {
3672 if (memcmp(buf
, "Peer", 4) == 0)
3676 while (fgets(buf
, sizeof(buf
), fp
)) {
3677 struct sockstat
*u
, **insp
;
3680 if (!(u
= calloc(1, sizeof(*u
))))
3683 if (sscanf(buf
, "%x: %x %x %x %x %x %d %s",
3684 &u
->rport
, &u
->rq
, &u
->wq
, &flags
, &u
->type
,
3685 &u
->state
, &u
->ino
, name
) < 8)
3689 u
->local
.family
= u
->remote
.family
= AF_UNIX
;
3691 if (flags
& (1 << 16)) {
3692 u
->state
= SS_LISTEN
;
3693 } else if (u
->state
> 0 &&
3694 u
->state
<= ARRAY_SIZE(unix_state_map
)) {
3695 u
->state
= unix_state_map
[u
->state
-1];
3696 if (u
->type
== SOCK_DGRAM
&& u
->state
== SS_CLOSE
&& u
->rport
)
3697 u
->state
= SS_ESTABLISHED
;
3699 if (unix_type_skip(u
, f
) ||
3700 !(f
->states
& (1 << u
->state
))) {
3712 u
->name
= strdup(name
);
3722 for (p
= list
; p
; p
= p
->next
) {
3723 if (u
->rport
== p
->lport
)
3729 u
->peer_name
= p
->name
? : "*";
3733 struct sockstat st
= {
3734 .local
.family
= AF_UNIX
,
3735 .remote
.family
= AF_UNIX
,
3738 memcpy(st
.local
.data
, &u
->name
, sizeof(u
->name
));
3739 /* when parsing the old format rport is set to 0 and
3740 * therefore peer_name remains NULL
3742 if (u
->peer_name
&& strcmp(u
->peer_name
, "*"))
3743 memcpy(st
.remote
.data
, &u
->peer_name
,
3744 sizeof(u
->peer_name
));
3745 if (run_ssfilter(f
->f
, &st
) == 0) {
3754 if (u
->type
< (*insp
)->type
||
3755 (u
->type
== (*insp
)->type
&&
3756 u
->ino
< (*insp
)->ino
))
3758 insp
= &(*insp
)->next
;
3763 if (++cnt
> MAX_UNIX_REMEMBER
) {
3765 unix_stats_print(list
, f
);
3766 unix_list_drop_first(&list
);
3773 unix_stats_print(list
, f
);
3774 unix_list_drop_first(&list
);
3780 static int packet_stats_print(struct sockstat
*s
, const struct filter
*f
)
3782 const char *addr
, *port
;
3785 s
->local
.family
= s
->remote
.family
= AF_PACKET
;
3788 s
->local
.data
[0] = s
->prot
;
3789 if (run_ssfilter(f
->f
, s
) == 0)
3793 sock_state_print(s
);
3798 addr
= ll_proto_n2a(htons(s
->prot
), ll_name
, sizeof(ll_name
));
3803 port
= xll_index_to_name(s
->iface
);
3805 sock_addr_print(addr
, ":", port
, NULL
);
3806 sock_addr_print("", "*", "", NULL
);
3811 sock_details_print(s
);
3816 static void packet_show_ring(struct packet_diag_ring
*ring
)
3818 out("blk_size:%d", ring
->pdr_block_size
);
3819 out(",blk_nr:%d", ring
->pdr_block_nr
);
3820 out(",frm_size:%d", ring
->pdr_frame_size
);
3821 out(",frm_nr:%d", ring
->pdr_frame_nr
);
3822 out(",tmo:%d", ring
->pdr_retire_tmo
);
3823 out(",features:0x%x", ring
->pdr_features
);
3826 static int packet_show_sock(const struct sockaddr_nl
*addr
,
3827 struct nlmsghdr
*nlh
, void *arg
)
3829 const struct filter
*f
= arg
;
3830 struct packet_diag_msg
*r
= NLMSG_DATA(nlh
);
3831 struct packet_diag_info
*pinfo
= NULL
;
3832 struct packet_diag_ring
*ring_rx
= NULL
, *ring_tx
= NULL
;
3833 struct rtattr
*tb
[PACKET_DIAG_MAX
+1];
3834 struct sockstat stat
= {};
3835 uint32_t fanout
= 0;
3836 bool has_fanout
= false;
3838 parse_rtattr(tb
, PACKET_DIAG_MAX
, (struct rtattr
*)(r
+1),
3839 nlh
->nlmsg_len
- NLMSG_LENGTH(sizeof(*r
)));
3841 /* use /proc/net/packet if all info are not available */
3842 if (!tb
[PACKET_DIAG_MEMINFO
])
3845 stat
.type
= r
->pdiag_type
;
3846 stat
.prot
= r
->pdiag_num
;
3847 stat
.ino
= r
->pdiag_ino
;
3848 stat
.state
= SS_CLOSE
;
3849 stat
.sk
= cookie_sk_get(&r
->pdiag_cookie
[0]);
3851 if (tb
[PACKET_DIAG_MEMINFO
]) {
3852 __u32
*skmeminfo
= RTA_DATA(tb
[PACKET_DIAG_MEMINFO
]);
3854 stat
.rq
= skmeminfo
[SK_MEMINFO_RMEM_ALLOC
];
3857 if (tb
[PACKET_DIAG_INFO
]) {
3858 pinfo
= RTA_DATA(tb
[PACKET_DIAG_INFO
]);
3859 stat
.lport
= stat
.iface
= pinfo
->pdi_index
;
3862 if (tb
[PACKET_DIAG_UID
])
3863 stat
.uid
= rta_getattr_u32(tb
[PACKET_DIAG_UID
]);
3865 if (tb
[PACKET_DIAG_RX_RING
])
3866 ring_rx
= RTA_DATA(tb
[PACKET_DIAG_RX_RING
]);
3868 if (tb
[PACKET_DIAG_TX_RING
])
3869 ring_tx
= RTA_DATA(tb
[PACKET_DIAG_TX_RING
]);
3871 if (tb
[PACKET_DIAG_FANOUT
]) {
3873 fanout
= rta_getattr_u32(tb
[PACKET_DIAG_FANOUT
]);
3876 if (packet_stats_print(&stat
, f
))
3881 out("\n\tver:%d", pinfo
->pdi_version
);
3882 out(" cpy_thresh:%d", pinfo
->pdi_copy_thresh
);
3884 if (pinfo
->pdi_flags
& PDI_RUNNING
)
3886 if (pinfo
->pdi_flags
& PDI_AUXDATA
)
3888 if (pinfo
->pdi_flags
& PDI_ORIGDEV
)
3890 if (pinfo
->pdi_flags
& PDI_VNETHDR
)
3892 if (pinfo
->pdi_flags
& PDI_LOSS
)
3894 if (!pinfo
->pdi_flags
)
3899 out("\n\tring_rx(");
3900 packet_show_ring(ring_rx
);
3904 out("\n\tring_tx(");
3905 packet_show_ring(ring_tx
);
3909 uint16_t type
= (fanout
>> 16) & 0xffff;
3912 out("id:%d,", fanout
& 0xffff);
3934 if (show_bpf
&& tb
[PACKET_DIAG_FILTER
]) {
3935 struct sock_filter
*fil
=
3936 RTA_DATA(tb
[PACKET_DIAG_FILTER
]);
3937 int num
= RTA_PAYLOAD(tb
[PACKET_DIAG_FILTER
]) /
3938 sizeof(struct sock_filter
);
3940 out("\n\tbpf filter (%d): ", num
);
3942 out(" 0x%02x %u %u %u,",
3943 fil
->code
, fil
->jt
, fil
->jf
, fil
->k
);
3951 static int packet_show_netlink(struct filter
*f
)
3953 DIAG_REQUEST(req
, struct packet_diag_req r
);
3955 req
.r
.sdiag_family
= AF_PACKET
;
3956 req
.r
.pdiag_show
= PACKET_SHOW_INFO
| PACKET_SHOW_MEMINFO
|
3957 PACKET_SHOW_FILTER
| PACKET_SHOW_RING_CFG
| PACKET_SHOW_FANOUT
;
3959 return handle_netlink_request(f
, &req
.nlh
, sizeof(req
), packet_show_sock
);
3962 static int packet_show_line(char *buf
, const struct filter
*f
, int fam
)
3964 unsigned long long sk
;
3965 struct sockstat stat
= {};
3966 int type
, prot
, iface
, state
, rq
, uid
, ino
;
3968 sscanf(buf
, "%llx %*d %d %x %d %d %u %u %u",
3970 &type
, &prot
, &iface
, &state
,
3973 if (stat
.type
== SOCK_RAW
&& !(f
->dbs
&(1<<PACKET_R_DB
)))
3975 if (stat
.type
== SOCK_DGRAM
&& !(f
->dbs
&(1<<PACKET_DG_DB
)))
3980 stat
.lport
= stat
.iface
= iface
;
3985 stat
.state
= SS_CLOSE
;
3987 if (packet_stats_print(&stat
, f
))
3993 static int packet_show(struct filter
*f
)
3998 if (!filter_af_get(f
, AF_PACKET
) || !(f
->states
& (1 << SS_CLOSE
)))
4001 if (!getenv("PROC_NET_PACKET") && !getenv("PROC_ROOT") &&
4002 packet_show_netlink(f
) == 0)
4005 if ((fp
= net_packet_open()) == NULL
)
4007 if (generic_record_read(fp
, packet_show_line
, f
, AF_PACKET
))
4014 static int netlink_show_one(struct filter
*f
,
4015 int prot
, int pid
, unsigned int groups
,
4016 int state
, int dst_pid
, unsigned int dst_group
,
4018 unsigned long long sk
, unsigned long long cb
)
4020 struct sockstat st
= {
4024 .local
.family
= AF_NETLINK
,
4025 .remote
.family
= AF_NETLINK
,
4028 SPRINT_BUF(prot_buf
) = {};
4029 const char *prot_name
;
4030 char procname
[64] = {};
4035 st
.local
.data
[0] = prot
;
4036 if (run_ssfilter(f
->f
, &st
) == 0)
4040 sock_state_print(&st
);
4042 if (resolve_services
)
4043 prot_name
= nl_proto_n2a(prot
, prot_buf
, sizeof(prot_buf
));
4045 prot_name
= int_to_str(prot
, prot_buf
);
4049 } else if (resolve_services
) {
4054 strncpy(procname
, "kernel", 6);
4055 } else if (pid
> 0) {
4058 snprintf(procname
, sizeof(procname
), "%s/%d/stat",
4059 getenv("PROC_ROOT") ? : "/proc", pid
);
4060 if ((fp
= fopen(procname
, "r")) != NULL
) {
4061 if (fscanf(fp
, "%*d (%[^)])", procname
) == 1) {
4062 snprintf(procname
+strlen(procname
),
4063 sizeof(procname
)-strlen(procname
),
4071 int_to_str(pid
, procname
);
4073 int_to_str(pid
, procname
);
4076 sock_addr_print(prot_name
, ":", procname
, NULL
);
4078 if (state
== NETLINK_CONNECTED
) {
4079 char dst_group_buf
[30];
4080 char dst_pid_buf
[30];
4082 sock_addr_print(int_to_str(dst_group
, dst_group_buf
), ":",
4083 int_to_str(dst_pid
, dst_pid_buf
), NULL
);
4085 sock_addr_print("", "*", "", NULL
);
4088 char *pid_context
= NULL
;
4090 if (show_proc_ctx
) {
4091 /* The pid value will either be:
4092 * 0 if destination kernel - show kernel initial context.
4093 * A valid process pid - use getpidcon.
4094 * A unique value allocated by the kernel or netlink user
4095 * to the process - show context as "not available".
4098 security_get_initial_context("kernel", &pid_context
);
4100 getpidcon(pid
, &pid_context
);
4102 out(" proc_ctx=%s", pid_context
? : "unavailable");
4107 out(" sk=%llx cb=%llx groups=0x%08x", sk
, cb
, groups
);
4113 static int netlink_show_sock(const struct sockaddr_nl
*addr
,
4114 struct nlmsghdr
*nlh
, void *arg
)
4116 struct filter
*f
= (struct filter
*)arg
;
4117 struct netlink_diag_msg
*r
= NLMSG_DATA(nlh
);
4118 struct rtattr
*tb
[NETLINK_DIAG_MAX
+1];
4120 unsigned long groups
= 0;
4122 parse_rtattr(tb
, NETLINK_DIAG_MAX
, (struct rtattr
*)(r
+1),
4123 nlh
->nlmsg_len
- NLMSG_LENGTH(sizeof(*r
)));
4125 if (tb
[NETLINK_DIAG_GROUPS
] && RTA_PAYLOAD(tb
[NETLINK_DIAG_GROUPS
]))
4126 groups
= *(unsigned long *) RTA_DATA(tb
[NETLINK_DIAG_GROUPS
]);
4128 if (tb
[NETLINK_DIAG_MEMINFO
]) {
4129 const __u32
*skmeminfo
;
4131 skmeminfo
= RTA_DATA(tb
[NETLINK_DIAG_MEMINFO
]);
4133 rq
= skmeminfo
[SK_MEMINFO_RMEM_ALLOC
];
4134 wq
= skmeminfo
[SK_MEMINFO_WMEM_ALLOC
];
4137 if (netlink_show_one(f
, r
->ndiag_protocol
, r
->ndiag_portid
, groups
,
4138 r
->ndiag_state
, r
->ndiag_dst_portid
, r
->ndiag_dst_group
,
4145 print_skmeminfo(tb
, NETLINK_DIAG_MEMINFO
);
4151 static int netlink_show_netlink(struct filter
*f
)
4153 DIAG_REQUEST(req
, struct netlink_diag_req r
);
4155 req
.r
.sdiag_family
= AF_NETLINK
;
4156 req
.r
.sdiag_protocol
= NDIAG_PROTO_ALL
;
4157 req
.r
.ndiag_show
= NDIAG_SHOW_GROUPS
| NDIAG_SHOW_MEMINFO
;
4159 return handle_netlink_request(f
, &req
.nlh
, sizeof(req
), netlink_show_sock
);
4162 static int netlink_show(struct filter
*f
)
4167 unsigned int groups
;
4169 unsigned long long sk
, cb
;
4171 if (!filter_af_get(f
, AF_NETLINK
) || !(f
->states
& (1 << SS_CLOSE
)))
4174 if (!getenv("PROC_NET_NETLINK") && !getenv("PROC_ROOT") &&
4175 netlink_show_netlink(f
) == 0)
4178 if ((fp
= net_netlink_open()) == NULL
)
4180 if (!fgets(buf
, sizeof(buf
), fp
)) {
4185 while (fgets(buf
, sizeof(buf
), fp
)) {
4186 sscanf(buf
, "%llx %d %d %x %d %d %llx %d",
4188 &prot
, &pid
, &groups
, &rq
, &wq
, &cb
, &rc
);
4190 netlink_show_one(f
, prot
, pid
, groups
, 0, 0, 0, rq
, wq
, sk
, cb
);
4197 static bool vsock_type_skip(struct sockstat
*s
, struct filter
*f
)
4199 if (s
->type
== SOCK_STREAM
&& !(f
->dbs
& (1 << VSOCK_ST_DB
)))
4201 if (s
->type
== SOCK_DGRAM
&& !(f
->dbs
& (1 << VSOCK_DG_DB
)))
4206 static void vsock_addr_print(inet_prefix
*a
, __u32 port
)
4208 char cid_str
[sizeof("4294967295")];
4209 char port_str
[sizeof("4294967295")];
4212 memcpy(&cid
, a
->data
, sizeof(cid
));
4214 if (cid
== ~(__u32
)0)
4215 snprintf(cid_str
, sizeof(cid_str
), "*");
4217 snprintf(cid_str
, sizeof(cid_str
), "%u", cid
);
4219 if (port
== ~(__u32
)0)
4220 snprintf(port_str
, sizeof(port_str
), "*");
4222 snprintf(port_str
, sizeof(port_str
), "%u", port
);
4224 sock_addr_print(cid_str
, ":", port_str
, NULL
);
4227 static void vsock_stats_print(struct sockstat
*s
, struct filter
*f
)
4229 sock_state_print(s
);
4231 vsock_addr_print(&s
->local
, s
->lport
);
4232 vsock_addr_print(&s
->remote
, s
->rport
);
4237 static int vsock_show_sock(const struct sockaddr_nl
*addr
,
4238 struct nlmsghdr
*nlh
, void *arg
)
4240 struct filter
*f
= (struct filter
*)arg
;
4241 struct vsock_diag_msg
*r
= NLMSG_DATA(nlh
);
4242 struct sockstat stat
= {
4243 .type
= r
->vdiag_type
,
4244 .lport
= r
->vdiag_src_port
,
4245 .rport
= r
->vdiag_dst_port
,
4246 .state
= r
->vdiag_state
,
4247 .ino
= r
->vdiag_ino
,
4250 vsock_set_inet_prefix(&stat
.local
, r
->vdiag_src_cid
);
4251 vsock_set_inet_prefix(&stat
.remote
, r
->vdiag_dst_cid
);
4253 if (vsock_type_skip(&stat
, f
))
4256 if (f
->f
&& run_ssfilter(f
->f
, &stat
) == 0)
4259 vsock_stats_print(&stat
, f
);
4264 static int vsock_show(struct filter
*f
)
4266 DIAG_REQUEST(req
, struct vsock_diag_req r
);
4268 if (!filter_af_get(f
, AF_VSOCK
))
4271 req
.r
.sdiag_family
= AF_VSOCK
;
4272 req
.r
.vdiag_states
= f
->states
;
4274 return handle_netlink_request(f
, &req
.nlh
, sizeof(req
), vsock_show_sock
);
4277 struct sock_diag_msg
{
4281 static int generic_show_sock(const struct sockaddr_nl
*addr
,
4282 struct nlmsghdr
*nlh
, void *arg
)
4284 struct sock_diag_msg
*r
= NLMSG_DATA(nlh
);
4285 struct inet_diag_arg inet_arg
= { .f
= arg
, .protocol
= IPPROTO_MAX
};
4288 switch (r
->sdiag_family
) {
4291 inet_arg
.rth
= inet_arg
.f
->rth_for_killing
;
4292 ret
= show_one_inet_sock(addr
, nlh
, &inet_arg
);
4295 ret
= unix_show_sock(addr
, nlh
, arg
);
4298 ret
= packet_show_sock(addr
, nlh
, arg
);
4301 ret
= netlink_show_sock(addr
, nlh
, arg
);
4304 ret
= vsock_show_sock(addr
, nlh
, arg
);
4315 static int handle_follow_request(struct filter
*f
)
4319 struct rtnl_handle rth
, rth2
;
4321 if (f
->families
& FAMILY_MASK(AF_INET
) && f
->dbs
& (1 << TCP_DB
))
4322 groups
|= 1 << (SKNLGRP_INET_TCP_DESTROY
- 1);
4323 if (f
->families
& FAMILY_MASK(AF_INET
) && f
->dbs
& (1 << UDP_DB
))
4324 groups
|= 1 << (SKNLGRP_INET_UDP_DESTROY
- 1);
4325 if (f
->families
& FAMILY_MASK(AF_INET6
) && f
->dbs
& (1 << TCP_DB
))
4326 groups
|= 1 << (SKNLGRP_INET6_TCP_DESTROY
- 1);
4327 if (f
->families
& FAMILY_MASK(AF_INET6
) && f
->dbs
& (1 << UDP_DB
))
4328 groups
|= 1 << (SKNLGRP_INET6_UDP_DESTROY
- 1);
4333 if (rtnl_open_byproto(&rth
, groups
, NETLINK_SOCK_DIAG
))
4337 rth
.local
.nl_pid
= 0;
4340 if (rtnl_open_byproto(&rth2
, groups
, NETLINK_SOCK_DIAG
)) {
4344 f
->rth_for_killing
= &rth2
;
4347 if (rtnl_dump_filter(&rth
, generic_show_sock
, f
))
4351 if (f
->rth_for_killing
)
4352 rtnl_close(f
->rth_for_killing
);
4356 static int get_snmp_int(char *proto
, char *key
, int *result
)
4360 int protolen
= strlen(proto
);
4361 int keylen
= strlen(key
);
4365 if ((fp
= net_snmp_open()) == NULL
)
4368 while (fgets(buf
, sizeof(buf
), fp
) != NULL
) {
4372 if (memcmp(buf
, proto
, protolen
))
4374 while ((p
= strchr(p
, ' ')) != NULL
) {
4377 if (memcmp(p
, key
, keylen
) == 0 &&
4378 (p
[keylen
] == ' ' || p
[keylen
] == '\n'))
4381 if (fgets(buf
, sizeof(buf
), fp
) == NULL
)
4383 if (memcmp(buf
, proto
, protolen
))
4386 while ((p
= strchr(p
, ' ')) != NULL
) {
4389 sscanf(p
, "%d", result
);
4402 /* Get stats from sockstat */
4422 static void get_sockstat_line(char *line
, struct ssummary
*s
)
4424 char id
[256], rem
[256];
4426 if (sscanf(line
, "%[^ ] %[^\n]\n", id
, rem
) != 2)
4429 if (strcmp(id
, "sockets:") == 0)
4430 sscanf(rem
, "%*s%d", &s
->socks
);
4431 else if (strcmp(id
, "UDP:") == 0)
4432 sscanf(rem
, "%*s%d", &s
->udp4
);
4433 else if (strcmp(id
, "UDP6:") == 0)
4434 sscanf(rem
, "%*s%d", &s
->udp6
);
4435 else if (strcmp(id
, "RAW:") == 0)
4436 sscanf(rem
, "%*s%d", &s
->raw4
);
4437 else if (strcmp(id
, "RAW6:") == 0)
4438 sscanf(rem
, "%*s%d", &s
->raw6
);
4439 else if (strcmp(id
, "TCP6:") == 0)
4440 sscanf(rem
, "%*s%d", &s
->tcp6_hashed
);
4441 else if (strcmp(id
, "FRAG:") == 0)
4442 sscanf(rem
, "%*s%d%*s%d", &s
->frag4
, &s
->frag4_mem
);
4443 else if (strcmp(id
, "FRAG6:") == 0)
4444 sscanf(rem
, "%*s%d%*s%d", &s
->frag6
, &s
->frag6_mem
);
4445 else if (strcmp(id
, "TCP:") == 0)
4446 sscanf(rem
, "%*s%d%*s%d%*s%d%*s%d%*s%d",
4448 &s
->tcp_orphans
, &s
->tcp_tws
, &s
->tcp_total
, &s
->tcp_mem
);
4451 static int get_sockstat(struct ssummary
*s
)
4456 memset(s
, 0, sizeof(*s
));
4458 if ((fp
= net_sockstat_open()) == NULL
)
4460 while (fgets(buf
, sizeof(buf
), fp
) != NULL
)
4461 get_sockstat_line(buf
, s
);
4464 if ((fp
= net_sockstat6_open()) == NULL
)
4466 while (fgets(buf
, sizeof(buf
), fp
) != NULL
)
4467 get_sockstat_line(buf
, s
);
4473 static int print_summary(void)
4478 if (get_sockstat(&s
) < 0)
4479 perror("ss: get_sockstat");
4480 if (get_snmp_int("Tcp:", "CurrEstab", &tcp_estab
) < 0)
4481 perror("ss: get_snmpstat");
4483 get_slabstat(&slabstat
);
4485 printf("Total: %d (kernel %d)\n", s
.socks
, slabstat
.socks
);
4487 printf("TCP: %d (estab %d, closed %d, orphaned %d, synrecv %d, timewait %d/%d), ports %d\n",
4488 s
.tcp_total
+ slabstat
.tcp_syns
+ s
.tcp_tws
,
4490 s
.tcp_total
- (s
.tcp4_hashed
+s
.tcp6_hashed
-s
.tcp_tws
),
4493 s
.tcp_tws
, slabstat
.tcp_tws
,
4498 printf("Transport Total IP IPv6\n");
4499 printf("* %-9d %-9s %-9s\n", slabstat
.socks
, "-", "-");
4500 printf("RAW %-9d %-9d %-9d\n", s
.raw4
+s
.raw6
, s
.raw4
, s
.raw6
);
4501 printf("UDP %-9d %-9d %-9d\n", s
.udp4
+s
.udp6
, s
.udp4
, s
.udp6
);
4502 printf("TCP %-9d %-9d %-9d\n", s
.tcp4_hashed
+s
.tcp6_hashed
, s
.tcp4_hashed
, s
.tcp6_hashed
);
4503 printf("INET %-9d %-9d %-9d\n",
4504 s
.raw4
+s
.udp4
+s
.tcp4_hashed
+
4505 s
.raw6
+s
.udp6
+s
.tcp6_hashed
,
4506 s
.raw4
+s
.udp4
+s
.tcp4_hashed
,
4507 s
.raw6
+s
.udp6
+s
.tcp6_hashed
);
4508 printf("FRAG %-9d %-9d %-9d\n", s
.frag4
+s
.frag6
, s
.frag4
, s
.frag6
);
4515 static void _usage(FILE *dest
)
4518 "Usage: ss [ OPTIONS ]\n"
4519 " ss [ OPTIONS ] [ FILTER ]\n"
4520 " -h, --help this message\n"
4521 " -V, --version output version information\n"
4522 " -n, --numeric don't resolve service names\n"
4523 " -r, --resolve resolve host names\n"
4524 " -a, --all display all sockets\n"
4525 " -l, --listening display listening sockets\n"
4526 " -o, --options show timer information\n"
4527 " -e, --extended show detailed socket information\n"
4528 " -m, --memory show socket memory usage\n"
4529 " -p, --processes show process using socket\n"
4530 " -i, --info show internal TCP information\n"
4531 " -s, --summary show socket usage summary\n"
4532 " -b, --bpf show bpf filter socket information\n"
4533 " -E, --events continually display sockets as they are destroyed\n"
4534 " -Z, --context display process SELinux security contexts\n"
4535 " -z, --contexts display process and socket SELinux security contexts\n"
4536 " -N, --net switch to the specified network namespace name\n"
4538 " -4, --ipv4 display only IP version 4 sockets\n"
4539 " -6, --ipv6 display only IP version 6 sockets\n"
4540 " -0, --packet display PACKET sockets\n"
4541 " -t, --tcp display only TCP sockets\n"
4542 " -S, --sctp display only SCTP sockets\n"
4543 " -u, --udp display only UDP sockets\n"
4544 " -d, --dccp display only DCCP sockets\n"
4545 " -w, --raw display only RAW sockets\n"
4546 " -x, --unix display only Unix domain sockets\n"
4547 " --vsock display only vsock sockets\n"
4548 " -f, --family=FAMILY display sockets of type FAMILY\n"
4549 " FAMILY := {inet|inet6|link|unix|netlink|vsock|help}\n"
4551 " -K, --kill forcibly close sockets, display what was closed\n"
4552 " -H, --no-header Suppress header line\n"
4554 " -A, --query=QUERY, --socket=QUERY\n"
4555 " QUERY := {all|inet|tcp|udp|raw|unix|unix_dgram|unix_stream|unix_seqpacket|packet|netlink|vsock_stream|vsock_dgram}[,QUERY]\n"
4557 " -D, --diag=FILE Dump raw information about TCP sockets to FILE\n"
4558 " -F, --filter=FILE read filter information from FILE\n"
4559 " FILTER := [ state STATE-FILTER ] [ EXPRESSION ]\n"
4560 " STATE-FILTER := {all|connected|synchronized|bucket|big|TCP-STATES}\n"
4561 " TCP-STATES := {established|syn-sent|syn-recv|fin-wait-{1,2}|time-wait|closed|close-wait|last-ack|listening|closing}\n"
4562 " connected := {established|syn-sent|syn-recv|fin-wait-{1,2}|time-wait|close-wait|last-ack|closing}\n"
4563 " synchronized := {established|syn-recv|fin-wait-{1,2}|time-wait|close-wait|last-ack|closing}\n"
4564 " bucket := {syn-recv|time-wait}\n"
4565 " big := {established|syn-sent|fin-wait-{1,2}|closed|close-wait|last-ack|listening|closing}\n"
4569 static void help(void) __attribute__((noreturn
));
4570 static void help(void)
4576 static void usage(void) __attribute__((noreturn
));
4577 static void usage(void)
4584 static int scan_state(const char *state
)
4586 static const char * const sstate_namel
[] = {
4588 [SS_ESTABLISHED
] = "established",
4589 [SS_SYN_SENT
] = "syn-sent",
4590 [SS_SYN_RECV
] = "syn-recv",
4591 [SS_FIN_WAIT1
] = "fin-wait-1",
4592 [SS_FIN_WAIT2
] = "fin-wait-2",
4593 [SS_TIME_WAIT
] = "time-wait",
4594 [SS_CLOSE
] = "unconnected",
4595 [SS_CLOSE_WAIT
] = "close-wait",
4596 [SS_LAST_ACK
] = "last-ack",
4597 [SS_LISTEN
] = "listening",
4598 [SS_CLOSING
] = "closing",
4602 if (strcasecmp(state
, "close") == 0 ||
4603 strcasecmp(state
, "closed") == 0)
4604 return (1<<SS_CLOSE
);
4605 if (strcasecmp(state
, "syn-rcv") == 0)
4606 return (1<<SS_SYN_RECV
);
4607 if (strcasecmp(state
, "established") == 0)
4608 return (1<<SS_ESTABLISHED
);
4609 if (strcasecmp(state
, "all") == 0)
4611 if (strcasecmp(state
, "connected") == 0)
4612 return SS_ALL
& ~((1<<SS_CLOSE
)|(1<<SS_LISTEN
));
4613 if (strcasecmp(state
, "synchronized") == 0)
4614 return SS_ALL
& ~((1<<SS_CLOSE
)|(1<<SS_LISTEN
)|(1<<SS_SYN_SENT
));
4615 if (strcasecmp(state
, "bucket") == 0)
4616 return (1<<SS_SYN_RECV
)|(1<<SS_TIME_WAIT
);
4617 if (strcasecmp(state
, "big") == 0)
4618 return SS_ALL
& ~((1<<SS_SYN_RECV
)|(1<<SS_TIME_WAIT
));
4619 for (i
= 0; i
< SS_MAX
; i
++) {
4620 if (strcasecmp(state
, sstate_namel
[i
]) == 0)
4624 fprintf(stderr
, "ss: wrong state name: %s\n", state
);
4628 /* Values 'v' and 'V' are already used so a non-character is used */
4629 #define OPT_VSOCK 256
4631 static const struct option long_opts
[] = {
4632 { "numeric", 0, 0, 'n' },
4633 { "resolve", 0, 0, 'r' },
4634 { "options", 0, 0, 'o' },
4635 { "extended", 0, 0, 'e' },
4636 { "memory", 0, 0, 'm' },
4637 { "info", 0, 0, 'i' },
4638 { "processes", 0, 0, 'p' },
4639 { "bpf", 0, 0, 'b' },
4640 { "events", 0, 0, 'E' },
4641 { "dccp", 0, 0, 'd' },
4642 { "tcp", 0, 0, 't' },
4643 { "sctp", 0, 0, 'S' },
4644 { "udp", 0, 0, 'u' },
4645 { "raw", 0, 0, 'w' },
4646 { "unix", 0, 0, 'x' },
4647 { "vsock", 0, 0, OPT_VSOCK
},
4648 { "all", 0, 0, 'a' },
4649 { "listening", 0, 0, 'l' },
4650 { "ipv4", 0, 0, '4' },
4651 { "ipv6", 0, 0, '6' },
4652 { "packet", 0, 0, '0' },
4653 { "family", 1, 0, 'f' },
4654 { "socket", 1, 0, 'A' },
4655 { "query", 1, 0, 'A' },
4656 { "summary", 0, 0, 's' },
4657 { "diag", 1, 0, 'D' },
4658 { "filter", 1, 0, 'F' },
4659 { "version", 0, 0, 'V' },
4660 { "help", 0, 0, 'h' },
4661 { "context", 0, 0, 'Z' },
4662 { "contexts", 0, 0, 'z' },
4663 { "net", 1, 0, 'N' },
4664 { "kill", 0, 0, 'K' },
4665 { "no-header", 0, 0, 'H' },
4670 int main(int argc
, char *argv
[])
4675 const char *dump_tcpdiag
= NULL
;
4676 FILE *filter_fp
= NULL
;
4678 int state_filter
= 0;
4680 while ((ch
= getopt_long(argc
, argv
,
4681 "dhaletuwxnro460spbEf:miA:D:F:vVzZN:KHS",
4682 long_opts
, NULL
)) != EOF
) {
4685 resolve_services
= 0;
4705 user_ent_hash_build();
4715 filter_db_set(¤t_filter
, DCCP_DB
);
4718 filter_db_set(¤t_filter
, TCP_DB
);
4721 filter_db_set(¤t_filter
, SCTP_DB
);
4724 filter_db_set(¤t_filter
, UDP_DB
);
4727 filter_db_set(¤t_filter
, RAW_DB
);
4730 filter_af_set(¤t_filter
, AF_UNIX
);
4733 filter_af_set(¤t_filter
, AF_VSOCK
);
4736 state_filter
= SS_ALL
;
4739 state_filter
= (1 << SS_LISTEN
) | (1 << SS_CLOSE
);
4742 filter_af_set(¤t_filter
, AF_INET
);
4745 filter_af_set(¤t_filter
, AF_INET6
);
4748 filter_af_set(¤t_filter
, AF_PACKET
);
4751 if (strcmp(optarg
, "inet") == 0)
4752 filter_af_set(¤t_filter
, AF_INET
);
4753 else if (strcmp(optarg
, "inet6") == 0)
4754 filter_af_set(¤t_filter
, AF_INET6
);
4755 else if (strcmp(optarg
, "link") == 0)
4756 filter_af_set(¤t_filter
, AF_PACKET
);
4757 else if (strcmp(optarg
, "unix") == 0)
4758 filter_af_set(¤t_filter
, AF_UNIX
);
4759 else if (strcmp(optarg
, "netlink") == 0)
4760 filter_af_set(¤t_filter
, AF_NETLINK
);
4761 else if (strcmp(optarg
, "vsock") == 0)
4762 filter_af_set(¤t_filter
, AF_VSOCK
);
4763 else if (strcmp(optarg
, "help") == 0)
4766 fprintf(stderr
, "ss: \"%s\" is invalid family\n",
4776 current_filter
.dbs
= 0;
4777 state_filter
= state_filter
?
4778 state_filter
: SS_CONN
;
4784 if ((p1
= strchr(p
, ',')) != NULL
)
4786 if (strcmp(p
, "all") == 0) {
4787 filter_default_dbs(¤t_filter
);
4788 } else if (strcmp(p
, "inet") == 0) {
4789 filter_db_set(¤t_filter
, UDP_DB
);
4790 filter_db_set(¤t_filter
, DCCP_DB
);
4791 filter_db_set(¤t_filter
, TCP_DB
);
4792 filter_db_set(¤t_filter
, SCTP_DB
);
4793 filter_db_set(¤t_filter
, RAW_DB
);
4794 } else if (strcmp(p
, "udp") == 0) {
4795 filter_db_set(¤t_filter
, UDP_DB
);
4796 } else if (strcmp(p
, "dccp") == 0) {
4797 filter_db_set(¤t_filter
, DCCP_DB
);
4798 } else if (strcmp(p
, "tcp") == 0) {
4799 filter_db_set(¤t_filter
, TCP_DB
);
4800 } else if (strcmp(p
, "sctp") == 0) {
4801 filter_db_set(¤t_filter
, SCTP_DB
);
4802 } else if (strcmp(p
, "raw") == 0) {
4803 filter_db_set(¤t_filter
, RAW_DB
);
4804 } else if (strcmp(p
, "unix") == 0) {
4805 filter_db_set(¤t_filter
, UNIX_ST_DB
);
4806 filter_db_set(¤t_filter
, UNIX_DG_DB
);
4807 filter_db_set(¤t_filter
, UNIX_SQ_DB
);
4808 } else if (strcasecmp(p
, "unix_stream") == 0 ||
4809 strcmp(p
, "u_str") == 0) {
4810 filter_db_set(¤t_filter
, UNIX_ST_DB
);
4811 } else if (strcasecmp(p
, "unix_dgram") == 0 ||
4812 strcmp(p
, "u_dgr") == 0) {
4813 filter_db_set(¤t_filter
, UNIX_DG_DB
);
4814 } else if (strcasecmp(p
, "unix_seqpacket") == 0 ||
4815 strcmp(p
, "u_seq") == 0) {
4816 filter_db_set(¤t_filter
, UNIX_SQ_DB
);
4817 } else if (strcmp(p
, "packet") == 0) {
4818 filter_db_set(¤t_filter
, PACKET_R_DB
);
4819 filter_db_set(¤t_filter
, PACKET_DG_DB
);
4820 } else if (strcmp(p
, "packet_raw") == 0 ||
4821 strcmp(p
, "p_raw") == 0) {
4822 filter_db_set(¤t_filter
, PACKET_R_DB
);
4823 } else if (strcmp(p
, "packet_dgram") == 0 ||
4824 strcmp(p
, "p_dgr") == 0) {
4825 filter_db_set(¤t_filter
, PACKET_DG_DB
);
4826 } else if (strcmp(p
, "netlink") == 0) {
4827 filter_db_set(¤t_filter
, NETLINK_DB
);
4828 } else if (strcmp(p
, "vsock") == 0) {
4829 filter_db_set(¤t_filter
, VSOCK_ST_DB
);
4830 filter_db_set(¤t_filter
, VSOCK_DG_DB
);
4831 } else if (strcmp(p
, "vsock_stream") == 0 ||
4832 strcmp(p
, "v_str") == 0) {
4833 filter_db_set(¤t_filter
, VSOCK_ST_DB
);
4834 } else if (strcmp(p
, "vsock_dgram") == 0 ||
4835 strcmp(p
, "v_dgr") == 0) {
4836 filter_db_set(¤t_filter
, VSOCK_DG_DB
);
4838 fprintf(stderr
, "ss: \"%s\" is illegal socket table id\n", p
);
4849 dump_tcpdiag
= optarg
;
4853 fprintf(stderr
, "More than one filter file\n");
4856 if (optarg
[0] == '-')
4859 filter_fp
= fopen(optarg
, "r");
4861 perror("fopen filter file");
4867 printf("ss utility, iproute2-ss%s\n", SNAPSHOT
);
4873 if (is_selinux_enabled() <= 0) {
4874 fprintf(stderr
, "ss: SELinux is not enabled.\n");
4878 user_ent_hash_build();
4881 if (netns_switch(optarg
))
4885 current_filter
.kill
= 1;
4903 if (do_default
&& argc
== 0)
4908 if (strcmp(*argv
, "state") == 0) {
4912 state_filter
|= scan_state(*argv
);
4914 } else if (strcmp(*argv
, "exclude") == 0 ||
4915 strcmp(*argv
, "excl") == 0) {
4918 state_filter
= SS_ALL
;
4919 state_filter
&= ~scan_state(*argv
);
4928 state_filter
= state_filter
? state_filter
: SS_CONN
;
4929 filter_default_dbs(¤t_filter
);
4932 filter_states_set(¤t_filter
, state_filter
);
4933 filter_merge_defaults(¤t_filter
);
4935 if (resolve_services
&& resolve_hosts
&&
4936 (current_filter
.dbs
& (UNIX_DBM
|INET_L4_DBM
)))
4937 init_service_resolver();
4939 if (current_filter
.dbs
== 0) {
4940 fprintf(stderr
, "ss: no socket tables to show with such filter.\n");
4943 if (current_filter
.families
== 0) {
4944 fprintf(stderr
, "ss: no families to show with such filter.\n");
4947 if (current_filter
.states
== 0) {
4948 fprintf(stderr
, "ss: no socket states to show with such filter.\n");
4953 FILE *dump_fp
= stdout
;
4955 if (!(current_filter
.dbs
& (1<<TCP_DB
))) {
4956 fprintf(stderr
, "ss: tcpdiag dump requested and no tcp in filter.\n");
4959 if (dump_tcpdiag
[0] != '-') {
4960 dump_fp
= fopen(dump_tcpdiag
, "w");
4961 if (!dump_tcpdiag
) {
4962 perror("fopen dump file");
4966 inet_show_netlink(¤t_filter
, dump_fp
, IPPROTO_TCP
);
4971 if (ssfilter_parse(¤t_filter
.f
, argc
, argv
, filter_fp
))
4974 if (!(current_filter
.dbs
& (current_filter
.dbs
- 1)))
4975 columns
[COL_NETID
].disabled
= 1;
4977 if (!(current_filter
.states
& (current_filter
.states
- 1)))
4978 columns
[COL_STATE
].disabled
= 1;
4986 exit(handle_follow_request(¤t_filter
));
4988 if (current_filter
.dbs
& (1<<NETLINK_DB
))
4989 netlink_show(¤t_filter
);
4990 if (current_filter
.dbs
& PACKET_DBM
)
4991 packet_show(¤t_filter
);
4992 if (current_filter
.dbs
& UNIX_DBM
)
4993 unix_show(¤t_filter
);
4994 if (current_filter
.dbs
& (1<<RAW_DB
))
4995 raw_show(¤t_filter
);
4996 if (current_filter
.dbs
& (1<<UDP_DB
))
4997 udp_show(¤t_filter
);
4998 if (current_filter
.dbs
& (1<<TCP_DB
))
4999 tcp_show(¤t_filter
);
5000 if (current_filter
.dbs
& (1<<DCCP_DB
))
5001 dccp_show(¤t_filter
);
5002 if (current_filter
.dbs
& (1<<SCTP_DB
))
5003 sctp_show(¤t_filter
);
5004 if (current_filter
.dbs
& VSOCK_DBM
)
5005 vsock_show(¤t_filter
);
5007 if (show_users
|| show_proc_ctx
|| show_sock_ctx
)