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>
17 #include <sys/ioctl.h>
18 #include <sys/socket.h>
20 #include <netinet/in.h>
24 #include <arpa/inet.h>
33 #include "libnetlink.h"
34 #include "namespace.h"
37 #include <linux/tcp.h>
38 #include <linux/sock_diag.h>
39 #include <linux/inet_diag.h>
40 #include <linux/unix_diag.h>
41 #include <linux/netdevice.h> /* for MAX_ADDR_LEN */
42 #include <linux/filter.h>
43 #include <linux/packet_diag.h>
44 #include <linux/netlink_diag.h>
46 #define MAGIC_SEQ 123456
48 #define DIAG_REQUEST(_req, _r) \
50 struct nlmsghdr nlh; \
54 .nlmsg_type = SOCK_DIAG_BY_FAMILY, \
55 .nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST,\
56 .nlmsg_seq = MAGIC_SEQ, \
57 .nlmsg_len = sizeof(_req), \
62 #include <selinux/selinux.h>
64 /* Stubs for SELinux functions */
65 static int is_selinux_enabled(void)
70 static int getpidcon(pid_t pid
, char **context
)
76 static int getfilecon(char *path
, char **context
)
82 static int security_get_initial_context(char *name
, char **context
)
89 int resolve_hosts
= 0;
90 int resolve_services
= 1;
91 int preferred_family
= AF_UNSPEC
;
98 int show_proc_ctx
= 0;
99 int show_sock_ctx
= 0;
100 /* If show_users & show_proc_ctx only do user_ent_hash_build() once */
101 int user_ent_hash_build_init
= 0;
110 static const char *TCP_PROTO
= "tcp";
111 static const char *UDP_PROTO
= "udp";
112 static const char *RAW_PROTO
= "raw";
113 static const char *dg_proto
= NULL
;
130 #define PACKET_DBM ((1<<PACKET_DG_DB)|(1<<PACKET_R_DB))
131 #define UNIX_DBM ((1<<UNIX_DG_DB)|(1<<UNIX_ST_DB)|(1<<UNIX_SQ_DB))
132 #define ALL_DB ((1<<MAX_DB)-1)
133 #define INET_DBM ((1<<TCP_DB)|(1<<UDP_DB)|(1<<DCCP_DB)|(1<<RAW_DB))
151 #define SS_ALL ((1 << SS_MAX) - 1)
152 #define SS_CONN (SS_ALL & ~((1<<SS_LISTEN)|(1<<SS_CLOSE)|(1<<SS_TIME_WAIT)|(1<<SS_SYN_RECV)))
154 #include "ssfilter.h"
164 static const struct filter default_dbs
[MAX_DB
] = {
167 .families
= (1 << AF_INET
) | (1 << AF_INET6
),
171 .families
= (1 << AF_INET
) | (1 << AF_INET6
),
174 .states
= (1 << SS_ESTABLISHED
),
175 .families
= (1 << AF_INET
) | (1 << AF_INET6
),
178 .states
= (1 << SS_ESTABLISHED
),
179 .families
= (1 << AF_INET
) | (1 << AF_INET6
),
182 .states
= (1 << SS_CLOSE
),
183 .families
= (1 << AF_UNIX
),
187 .families
= (1 << AF_UNIX
),
191 .families
= (1 << AF_UNIX
),
194 .states
= (1 << SS_CLOSE
),
195 .families
= (1 << AF_PACKET
),
198 .states
= (1 << SS_CLOSE
),
199 .families
= (1 << AF_PACKET
),
202 .states
= (1 << SS_CLOSE
),
203 .families
= (1 << AF_NETLINK
),
207 static const struct filter default_afs
[AF_MAX
] = {
222 .states
= (1 << SS_CLOSE
),
225 .dbs
= (1 << NETLINK_DB
),
226 .states
= (1 << SS_CLOSE
),
230 static int do_default
= 1;
231 static struct filter current_filter
;
233 static void filter_db_set(struct filter
*f
, int db
)
235 f
->states
|= default_dbs
[db
].states
;
240 static void filter_af_set(struct filter
*f
, int af
)
242 f
->states
|= default_afs
[af
].states
;
243 f
->families
|= 1 << af
;
245 preferred_family
= af
;
248 static int filter_af_get(struct filter
*f
, int af
)
250 return f
->families
& (1 << af
);
253 static void filter_default_dbs(struct filter
*f
)
255 filter_db_set(f
, UDP_DB
);
256 filter_db_set(f
, DCCP_DB
);
257 filter_db_set(f
, TCP_DB
);
258 filter_db_set(f
, RAW_DB
);
259 filter_db_set(f
, UNIX_ST_DB
);
260 filter_db_set(f
, UNIX_DG_DB
);
261 filter_db_set(f
, UNIX_SQ_DB
);
262 filter_db_set(f
, PACKET_R_DB
);
263 filter_db_set(f
, PACKET_DG_DB
);
264 filter_db_set(f
, NETLINK_DB
);
267 static void filter_states_set(struct filter
*f
, int states
)
270 f
->states
= (f
->states
| states
) & states
;
273 static void filter_merge_defaults(struct filter
*f
)
278 for (db
= 0; db
< MAX_DB
; db
++) {
279 if (!(f
->dbs
& (1 << db
)))
282 if (!(default_dbs
[db
].families
& f
->families
))
283 f
->families
|= default_dbs
[db
].families
;
285 for (af
= 0; af
< AF_MAX
; af
++) {
286 if (!(f
->families
& (1 << af
)))
289 if (!(default_afs
[af
].dbs
& f
->dbs
))
290 f
->dbs
|= default_afs
[af
].dbs
;
294 static FILE *generic_proc_open(const char *env
, const char *name
)
296 const char *p
= getenv(env
);
300 p
= getenv("PROC_ROOT") ? : "/proc";
301 snprintf(store
, sizeof(store
)-1, "%s/%s", p
, name
);
305 return fopen(p
, "r");
308 static FILE *net_tcp_open(void)
310 return generic_proc_open("PROC_NET_TCP", "net/tcp");
313 static FILE *net_tcp6_open(void)
315 return generic_proc_open("PROC_NET_TCP6", "net/tcp6");
318 static FILE *net_udp_open(void)
320 return generic_proc_open("PROC_NET_UDP", "net/udp");
323 static FILE *net_udp6_open(void)
325 return generic_proc_open("PROC_NET_UDP6", "net/udp6");
328 static FILE *net_raw_open(void)
330 return generic_proc_open("PROC_NET_RAW", "net/raw");
333 static FILE *net_raw6_open(void)
335 return generic_proc_open("PROC_NET_RAW6", "net/raw6");
338 static FILE *net_unix_open(void)
340 return generic_proc_open("PROC_NET_UNIX", "net/unix");
343 static FILE *net_packet_open(void)
345 return generic_proc_open("PROC_NET_PACKET", "net/packet");
348 static FILE *net_netlink_open(void)
350 return generic_proc_open("PROC_NET_NETLINK", "net/netlink");
353 static FILE *slabinfo_open(void)
355 return generic_proc_open("PROC_SLABINFO", "slabinfo");
358 static FILE *net_sockstat_open(void)
360 return generic_proc_open("PROC_NET_SOCKSTAT", "net/sockstat");
363 static FILE *net_sockstat6_open(void)
365 return generic_proc_open("PROC_NET_SOCKSTAT6", "net/sockstat6");
368 static FILE *net_snmp_open(void)
370 return generic_proc_open("PROC_NET_SNMP", "net/snmp");
373 static FILE *ephemeral_ports_open(void)
375 return generic_proc_open("PROC_IP_LOCAL_PORT_RANGE", "sys/net/ipv4/ip_local_port_range");
379 struct user_ent
*next
;
388 #define USER_ENT_HASH_SIZE 256
389 struct user_ent
*user_ent_hash
[USER_ENT_HASH_SIZE
];
391 static int user_ent_hashfn(unsigned int ino
)
393 int val
= (ino
>> 24) ^ (ino
>> 16) ^ (ino
>> 8) ^ ino
;
395 return val
& (USER_ENT_HASH_SIZE
- 1);
398 static void user_ent_add(unsigned int ino
, char *process
,
403 struct user_ent
*p
, **pp
;
405 p
= malloc(sizeof(struct user_ent
));
407 fprintf(stderr
, "ss: failed to malloc buffer\n");
414 p
->process
= strdup(process
);
415 p
->process_ctx
= strdup(proc_ctx
);
416 p
->socket_ctx
= strdup(sock_ctx
);
418 pp
= &user_ent_hash
[user_ent_hashfn(ino
)];
423 static void user_ent_destroy(void)
425 struct user_ent
*p
, *p_next
;
428 while (cnt
!= USER_ENT_HASH_SIZE
) {
429 p
= user_ent_hash
[cnt
];
432 free(p
->process_ctx
);
442 static void user_ent_hash_build(void)
444 const char *root
= getenv("PROC_ROOT") ? : "/proc/";
451 const char *no_ctx
= "unavailable";
453 /* If show_users & show_proc_ctx set only do this once */
454 if (user_ent_hash_build_init
!= 0)
457 user_ent_hash_build_init
= 1;
460 if (strlen(name
) == 0 || name
[strlen(name
)-1] != '/')
463 nameoff
= strlen(name
);
469 while ((d
= readdir(dir
)) != NULL
) {
477 if (sscanf(d
->d_name
, "%d%c", &pid
, &crap
) != 1)
480 if (getpidcon(pid
, &pid_context
) != 0)
481 pid_context
= strdup(no_ctx
);
483 sprintf(name
+ nameoff
, "%d/fd/", pid
);
485 if ((dir1
= opendir(name
)) == NULL
)
491 while ((d1
= readdir(dir1
)) != NULL
) {
492 const char *pattern
= "socket:[";
499 if (sscanf(d1
->d_name
, "%d%c", &fd
, &crap
) != 1)
502 sprintf(name
+pos
, "%d", fd
);
504 link_len
= readlink(name
, lnk
, sizeof(lnk
)-1);
507 lnk
[link_len
] = '\0';
509 if (strncmp(lnk
, pattern
, strlen(pattern
)))
512 sscanf(lnk
, "socket:[%u]", &ino
);
514 snprintf(tmp
, sizeof(tmp
), "%s/%d/fd/%s",
515 root
, pid
, d1
->d_name
);
517 if (getfilecon(tmp
, &sock_context
) <= 0)
518 sock_context
= strdup(no_ctx
);
523 snprintf(tmp
, sizeof(tmp
), "%s/%d/stat",
525 if ((fp
= fopen(tmp
, "r")) != NULL
) {
526 fscanf(fp
, "%*d (%[^)])", p
);
530 user_ent_add(ino
, p
, pid
, fd
,
531 pid_context
, sock_context
);
546 #define ENTRY_BUF_SIZE 512
547 static int find_entry(unsigned ino
, char **buf
, int type
)
552 char **new_buf
= buf
;
553 int len
, new_buf_len
;
560 p
= user_ent_hash
[user_ent_hashfn(ino
)];
567 ptr
= *buf
+ buf_used
;
570 len
= snprintf(ptr
, buf_len
- buf_used
,
571 "(\"%s\",pid=%d,fd=%d),",
572 p
->process
, p
->pid
, p
->fd
);
575 len
= snprintf(ptr
, buf_len
- buf_used
,
576 "(\"%s\",pid=%d,proc_ctx=%s,fd=%d),",
578 p
->process_ctx
, p
->fd
);
581 len
= snprintf(ptr
, buf_len
- buf_used
,
582 "(\"%s\",pid=%d,proc_ctx=%s,fd=%d,sock_ctx=%s),",
584 p
->process_ctx
, p
->fd
,
588 fprintf(stderr
, "ss: invalid type: %d\n", type
);
592 if (len
< 0 || len
>= buf_len
- buf_used
) {
593 new_buf_len
= buf_len
+ ENTRY_BUF_SIZE
;
594 *new_buf
= realloc(*buf
, new_buf_len
);
596 fprintf(stderr
, "ss: failed to malloc buffer\n");
600 buf_len
= new_buf_len
;
612 ptr
= *buf
+ buf_used
;
618 /* Get stats from slab */
629 static struct slabstat slabstat
;
631 static const char *slabstat_ids
[] =
640 static int get_slabstat(struct slabstat
*s
)
645 static int slabstat_valid
;
650 memset(s
, 0, sizeof(*s
));
652 fp
= slabinfo_open();
656 cnt
= sizeof(*s
)/sizeof(int);
658 fgets(buf
, sizeof(buf
), fp
);
659 while(fgets(buf
, sizeof(buf
), fp
) != NULL
) {
661 for (i
=0; i
<sizeof(slabstat_ids
)/sizeof(slabstat_ids
[0]); i
++) {
662 if (memcmp(buf
, slabstat_ids
[i
], strlen(slabstat_ids
[i
])) == 0) {
663 sscanf(buf
, "%*s%d", ((int *)s
) + i
);
678 static inline void sock_addr_set_str(inet_prefix
*prefix
, char **ptr
)
680 memcpy(prefix
->data
, ptr
, sizeof(char *));
683 static inline char *sock_addr_get_str(const inet_prefix
*prefix
)
686 memcpy(&tmp
, prefix
->data
, sizeof(char *));
690 static unsigned long long cookie_sk_get(const uint32_t *cookie
)
692 return (((unsigned long long)cookie
[1] << 31) << 1) | cookie
[0];
695 static const char *sstate_name
[] = {
697 [SS_ESTABLISHED
] = "ESTAB",
698 [SS_SYN_SENT
] = "SYN-SENT",
699 [SS_SYN_RECV
] = "SYN-RECV",
700 [SS_FIN_WAIT1
] = "FIN-WAIT-1",
701 [SS_FIN_WAIT2
] = "FIN-WAIT-2",
702 [SS_TIME_WAIT
] = "TIME-WAIT",
703 [SS_CLOSE
] = "UNCONN",
704 [SS_CLOSE_WAIT
] = "CLOSE-WAIT",
705 [SS_LAST_ACK
] = "LAST-ACK",
706 [SS_LISTEN
] = "LISTEN",
707 [SS_CLOSING
] = "CLOSING",
710 static const char *sstate_namel
[] = {
712 [SS_ESTABLISHED
] = "established",
713 [SS_SYN_SENT
] = "syn-sent",
714 [SS_SYN_RECV
] = "syn-recv",
715 [SS_FIN_WAIT1
] = "fin-wait-1",
716 [SS_FIN_WAIT2
] = "fin-wait-2",
717 [SS_TIME_WAIT
] = "time-wait",
718 [SS_CLOSE
] = "unconnected",
719 [SS_CLOSE_WAIT
] = "close-wait",
720 [SS_LAST_ACK
] = "last-ack",
721 [SS_LISTEN
] = "listening",
722 [SS_CLOSING
] = "closing",
727 struct sockstat
*next
;
740 unsigned long long sk
;
745 unsigned int ce_state
;
759 double rto
, ato
, rtt
, rttvar
;
760 int qack
, cwnd
, ssthresh
, backoff
;
765 unsigned int lastsnd
;
766 unsigned int lastrcv
;
767 unsigned int lastack
;
769 double pacing_rate_max
;
770 unsigned long long bytes_acked
;
771 unsigned long long bytes_received
;
772 unsigned int segs_out
;
773 unsigned int segs_in
;
774 unsigned int unacked
;
775 unsigned int retrans
;
776 unsigned int retrans_total
;
779 unsigned int fackets
;
780 unsigned int reordering
;
786 bool has_ecnseen_opt
;
787 bool has_fastopen_opt
;
789 struct dctcpstat
*dctcp
;
792 static void sock_state_print(struct sockstat
*s
, const char *sock_name
)
795 printf("%-*s ", netid_width
, sock_name
);
797 printf("%-*s ", state_width
, sstate_name
[s
->state
]);
799 printf("%-6d %-6d ", s
->rq
, s
->wq
);
802 static void sock_details_print(struct sockstat
*s
)
805 printf(" uid:%u", s
->uid
);
807 printf(" ino:%u", s
->ino
);
808 printf(" sk:%llx", s
->sk
);
811 static void sock_addr_print_width(int addr_len
, const char *addr
, char *delim
,
812 int port_len
, const char *port
, const char *ifname
)
815 printf("%*s%%%s%s%-*s ", addr_len
, addr
, ifname
, delim
,
819 printf("%*s%s%-*s ", addr_len
, addr
, delim
, port_len
, port
);
823 static void sock_addr_print(const char *addr
, char *delim
, const char *port
,
826 sock_addr_print_width(addr_width
, addr
, delim
, serv_width
, port
, ifname
);
829 static const char *tmr_name
[] = {
838 static const char *print_ms_timer(int timeout
)
841 int secs
, msecs
, minutes
;
847 msecs
= timeout
%1000;
851 snprintf(buf
, sizeof(buf
)-16, "%dmin", minutes
);
858 sprintf(buf
+strlen(buf
), "%d%s", secs
, msecs
? "." : "sec");
861 sprintf(buf
+strlen(buf
), "%03dms", msecs
);
872 struct scache
*rlist
;
874 static void init_service_resolver(void)
877 FILE *fp
= popen("/usr/sbin/rpcinfo -p 2>/dev/null", "r");
879 fgets(buf
, sizeof(buf
), fp
);
880 while (fgets(buf
, sizeof(buf
), fp
) != NULL
) {
881 unsigned int progn
, port
;
882 char proto
[128], prog
[128];
883 if (sscanf(buf
, "%u %*d %s %u %s", &progn
, proto
,
884 &port
, prog
+4) == 4) {
885 struct scache
*c
= malloc(sizeof(*c
));
888 memcpy(prog
, "rpc.", 4);
889 c
->name
= strdup(prog
);
890 if (strcmp(proto
, TCP_PROTO
) == 0)
891 c
->proto
= TCP_PROTO
;
892 else if (strcmp(proto
, UDP_PROTO
) == 0)
893 c
->proto
= UDP_PROTO
;
905 static int ip_local_port_min
, ip_local_port_max
;
907 /* Even do not try default linux ephemeral port ranges:
908 * default /etc/services contains so much of useless crap
909 * wouldbe "allocated" to this area that resolution
910 * is really harmful. I shrug each time when seeing
911 * "socks" or "cfinger" in dumps.
913 static int is_ephemeral(int port
)
915 if (!ip_local_port_min
) {
916 FILE *f
= ephemeral_ports_open();
919 &ip_local_port_min
, &ip_local_port_max
);
922 ip_local_port_min
= 1024;
923 ip_local_port_max
= 4999;
927 return (port
>= ip_local_port_min
&& port
<= ip_local_port_max
);
931 static const char *__resolve_service(int port
)
935 for (c
= rlist
; c
; c
= c
->next
) {
936 if (c
->port
== port
&& c
->proto
== dg_proto
)
940 if (!is_ephemeral(port
)) {
947 se
= getservbyport(htons(port
), dg_proto
);
955 #define SCACHE_BUCKETS 1024
956 static struct scache
*cache_htab
[SCACHE_BUCKETS
];
958 static const char *resolve_service(int port
)
960 static char buf
[128];
971 if (!resolve_services
)
974 if (dg_proto
== RAW_PROTO
)
975 return inet_proto_n2a(port
, buf
, sizeof(buf
));
978 hash
= (port
^(((unsigned long)dg_proto
)>>2)) % SCACHE_BUCKETS
;
980 for (c
= cache_htab
[hash
]; c
; c
= c
->next
) {
981 if (c
->port
== port
&& c
->proto
== dg_proto
)
985 c
= malloc(sizeof(*c
));
988 res
= __resolve_service(port
);
990 c
->name
= res
? strdup(res
) : NULL
;
992 c
->next
= cache_htab
[hash
];
993 cache_htab
[hash
] = c
;
1000 sprintf(buf
, "%u", port
);
1004 static void inet_addr_print(const inet_prefix
*a
, int port
, unsigned int ifindex
)
1007 const char *ap
= buf
;
1008 int est_len
= addr_width
;
1009 const char *ifname
= NULL
;
1011 if (a
->family
== AF_INET
) {
1012 if (a
->data
[0] == 0) {
1016 ap
= format_host(AF_INET
, 4, a
->data
, buf
, sizeof(buf
));
1019 ap
= format_host(a
->family
, 16, a
->data
, buf
, sizeof(buf
));
1020 est_len
= strlen(ap
);
1021 if (est_len
<= addr_width
)
1022 est_len
= addr_width
;
1024 est_len
= addr_width
+ ((est_len
-addr_width
+3)/4)*4;
1028 ifname
= ll_index_to_name(ifindex
);
1029 est_len
-= strlen(ifname
) + 1; /* +1 for percent char */
1032 sock_addr_print_width(est_len
, ap
, ":", serv_width
, resolve_service(port
),
1040 struct aafilter
*next
;
1043 static int inet2_addr_match(const inet_prefix
*a
, const inet_prefix
*p
,
1046 if (!inet_addr_match(a
, p
, plen
))
1049 /* Cursed "v4 mapped" addresses: v4 mapped socket matches
1050 * pure IPv4 rule, but v4-mapped rule selects only v4-mapped
1052 if (p
->family
== AF_INET
&& a
->family
== AF_INET6
) {
1053 if (a
->data
[0] == 0 && a
->data
[1] == 0 &&
1054 a
->data
[2] == htonl(0xffff)) {
1055 inet_prefix tmp
= *a
;
1056 tmp
.data
[0] = a
->data
[3];
1057 return inet_addr_match(&tmp
, p
, plen
);
1063 static int unix_match(const inet_prefix
*a
, const inet_prefix
*p
)
1065 char *addr
= sock_addr_get_str(a
);
1066 char *pattern
= sock_addr_get_str(p
);
1068 if (pattern
== NULL
)
1072 return !fnmatch(pattern
, addr
, 0);
1075 static int run_ssfilter(struct ssfilter
*f
, struct sockstat
*s
)
1080 static int low
, high
=65535;
1082 if (s
->local
.family
== AF_UNIX
) {
1083 char *p
= sock_addr_get_str(&s
->local
);
1084 return p
== NULL
|| (p
[0] == '@' && strlen(p
) == 6 &&
1085 strspn(p
+1, "0123456789abcdef") == 5);
1087 if (s
->local
.family
== AF_PACKET
)
1088 return s
->lport
== 0 && s
->local
.data
[0] == 0;
1089 if (s
->local
.family
== AF_NETLINK
)
1090 return s
->lport
< 0;
1093 FILE *fp
= ephemeral_ports_open();
1095 fscanf(fp
, "%d%d", &low
, &high
);
1099 return s
->lport
>= low
&& s
->lport
<= high
;
1103 struct aafilter
*a
= (void*)f
->pred
;
1104 if (a
->addr
.family
== AF_UNIX
)
1105 return unix_match(&s
->remote
, &a
->addr
);
1106 if (a
->port
!= -1 && a
->port
!= s
->rport
)
1108 if (a
->addr
.bitlen
) {
1110 if (!inet2_addr_match(&s
->remote
, &a
->addr
, a
->addr
.bitlen
))
1112 } while ((a
= a
->next
) != NULL
);
1119 struct aafilter
*a
= (void*)f
->pred
;
1120 if (a
->addr
.family
== AF_UNIX
)
1121 return unix_match(&s
->local
, &a
->addr
);
1122 if (a
->port
!= -1 && a
->port
!= s
->lport
)
1124 if (a
->addr
.bitlen
) {
1126 if (!inet2_addr_match(&s
->local
, &a
->addr
, a
->addr
.bitlen
))
1128 } while ((a
= a
->next
) != NULL
);
1135 struct aafilter
*a
= (void*)f
->pred
;
1136 return s
->rport
>= a
->port
;
1140 struct aafilter
*a
= (void*)f
->pred
;
1141 return s
->rport
<= a
->port
;
1145 struct aafilter
*a
= (void*)f
->pred
;
1146 return s
->lport
>= a
->port
;
1150 struct aafilter
*a
= (void*)f
->pred
;
1151 return s
->lport
<= a
->port
;
1154 /* Yup. It is recursion. Sorry. */
1156 return run_ssfilter(f
->pred
, s
) && run_ssfilter(f
->post
, s
);
1158 return run_ssfilter(f
->pred
, s
) || run_ssfilter(f
->post
, s
);
1160 return !run_ssfilter(f
->pred
, s
);
1166 /* Relocate external jumps by reloc. */
1167 static void ssfilter_patch(char *a
, int len
, int reloc
)
1170 struct inet_diag_bc_op
*op
= (struct inet_diag_bc_op
*)a
;
1171 if (op
->no
== len
+4)
1180 static int ssfilter_bytecompile(struct ssfilter
*f
, char **bytecode
)
1185 if (!(*bytecode
=malloc(4))) abort();
1186 ((struct inet_diag_bc_op
*)*bytecode
)[0] = (struct inet_diag_bc_op
){ INET_DIAG_BC_AUTO
, 4, 8 };
1192 struct aafilter
*a
= (void*)f
->pred
;
1195 int code
= (f
->type
== SSF_DCOND
? INET_DIAG_BC_D_COND
: INET_DIAG_BC_S_COND
);
1198 for (b
=a
; b
; b
=b
->next
) {
1199 len
+= 4 + sizeof(struct inet_diag_hostcond
);
1200 if (a
->addr
.family
== AF_INET6
)
1207 if (!(ptr
= malloc(len
))) abort();
1209 for (b
=a
; b
; b
=b
->next
) {
1210 struct inet_diag_bc_op
*op
= (struct inet_diag_bc_op
*)ptr
;
1211 int alen
= (a
->addr
.family
== AF_INET6
? 16 : 4);
1212 int oplen
= alen
+ 4 + sizeof(struct inet_diag_hostcond
);
1213 struct inet_diag_hostcond
*cond
= (struct inet_diag_hostcond
*)(ptr
+4);
1215 *op
= (struct inet_diag_bc_op
){ code
, oplen
, oplen
+4 };
1216 cond
->family
= a
->addr
.family
;
1217 cond
->port
= a
->port
;
1218 cond
->prefix_len
= a
->addr
.bitlen
;
1219 memcpy(cond
->addr
, a
->addr
.data
, alen
);
1222 op
= (struct inet_diag_bc_op
*)ptr
;
1223 *op
= (struct inet_diag_bc_op
){ INET_DIAG_BC_JMP
, 4, len
- (ptr
-*bytecode
)};
1227 return ptr
- *bytecode
;
1231 struct aafilter
*x
= (void*)f
->pred
;
1232 if (!(*bytecode
=malloc(8))) abort();
1233 ((struct inet_diag_bc_op
*)*bytecode
)[0] = (struct inet_diag_bc_op
){ INET_DIAG_BC_D_GE
, 8, 12 };
1234 ((struct inet_diag_bc_op
*)*bytecode
)[1] = (struct inet_diag_bc_op
){ 0, 0, x
->port
};
1239 struct aafilter
*x
= (void*)f
->pred
;
1240 if (!(*bytecode
=malloc(8))) abort();
1241 ((struct inet_diag_bc_op
*)*bytecode
)[0] = (struct inet_diag_bc_op
){ INET_DIAG_BC_D_LE
, 8, 12 };
1242 ((struct inet_diag_bc_op
*)*bytecode
)[1] = (struct inet_diag_bc_op
){ 0, 0, x
->port
};
1247 struct aafilter
*x
= (void*)f
->pred
;
1248 if (!(*bytecode
=malloc(8))) abort();
1249 ((struct inet_diag_bc_op
*)*bytecode
)[0] = (struct inet_diag_bc_op
){ INET_DIAG_BC_S_GE
, 8, 12 };
1250 ((struct inet_diag_bc_op
*)*bytecode
)[1] = (struct inet_diag_bc_op
){ 0, 0, x
->port
};
1255 struct aafilter
*x
= (void*)f
->pred
;
1256 if (!(*bytecode
=malloc(8))) abort();
1257 ((struct inet_diag_bc_op
*)*bytecode
)[0] = (struct inet_diag_bc_op
){ INET_DIAG_BC_S_LE
, 8, 12 };
1258 ((struct inet_diag_bc_op
*)*bytecode
)[1] = (struct inet_diag_bc_op
){ 0, 0, x
->port
};
1266 l1
= ssfilter_bytecompile(f
->pred
, &a1
);
1267 l2
= ssfilter_bytecompile(f
->post
, &a2
);
1268 if (!(a
= malloc(l1
+l2
))) abort();
1270 memcpy(a
+l1
, a2
, l2
);
1272 ssfilter_patch(a
, l1
, l2
);
1280 l1
= ssfilter_bytecompile(f
->pred
, &a1
);
1281 l2
= ssfilter_bytecompile(f
->post
, &a2
);
1282 if (!(a
= malloc(l1
+l2
+4))) abort();
1284 memcpy(a
+l1
+4, a2
, l2
);
1286 *(struct inet_diag_bc_op
*)(a
+l1
) = (struct inet_diag_bc_op
){ INET_DIAG_BC_JMP
, 4, l2
+4 };
1294 l1
= ssfilter_bytecompile(f
->pred
, &a1
);
1295 if (!(a
= malloc(l1
+4))) abort();
1298 *(struct inet_diag_bc_op
*)(a
+l1
) = (struct inet_diag_bc_op
){ INET_DIAG_BC_JMP
, 4, 8 };
1307 static int remember_he(struct aafilter
*a
, struct hostent
*he
)
1309 char **ptr
= he
->h_addr_list
;
1313 if (he
->h_addrtype
== AF_INET
)
1315 else if (he
->h_addrtype
== AF_INET6
)
1321 struct aafilter
*b
= a
;
1322 if (a
->addr
.bitlen
) {
1323 if ((b
= malloc(sizeof(*b
))) == NULL
)
1329 memcpy(b
->addr
.data
, *ptr
, len
);
1330 b
->addr
.bytelen
= len
;
1331 b
->addr
.bitlen
= len
*8;
1332 b
->addr
.family
= he
->h_addrtype
;
1339 static int get_dns_host(struct aafilter
*a
, const char *addr
, int fam
)
1341 static int notfirst
;
1350 he
= gethostbyname2(addr
, fam
== AF_UNSPEC
? AF_INET
: fam
);
1352 cnt
= remember_he(a
, he
);
1353 if (fam
== AF_UNSPEC
) {
1354 he
= gethostbyname2(addr
, AF_INET6
);
1356 cnt
+= remember_he(a
, he
);
1361 static int xll_initted
= 0;
1363 static void xll_init(void)
1365 struct rtnl_handle rth
;
1366 if (rtnl_open(&rth
, 0) < 0)
1374 static const char *xll_index_to_name(int index
)
1378 return ll_index_to_name(index
);
1381 static int xll_name_to_index(const char *dev
)
1385 return ll_name_to_index(dev
);
1388 void *parse_hostcond(char *addr
, bool is_port
)
1391 struct aafilter a
= { .port
= -1 };
1392 struct aafilter
*res
;
1393 int fam
= preferred_family
;
1394 struct filter
*f
= ¤t_filter
;
1396 if (fam
== AF_UNIX
|| strncmp(addr
, "unix:", 5) == 0) {
1398 a
.addr
.family
= AF_UNIX
;
1399 if (strncmp(addr
, "unix:", 5) == 0)
1402 a
.addr
.bitlen
= 8*strlen(p
);
1403 sock_addr_set_str(&a
.addr
, &p
);
1408 if (fam
== AF_PACKET
|| strncmp(addr
, "link:", 5) == 0) {
1409 a
.addr
.family
= AF_PACKET
;
1411 if (strncmp(addr
, "link:", 5) == 0)
1413 port
= strchr(addr
, ':');
1416 if (port
[1] && strcmp(port
+1, "*")) {
1417 if (get_integer(&a
.port
, port
+1, 0)) {
1418 if ((a
.port
= xll_name_to_index(port
+1)) <= 0)
1423 if (addr
[0] && strcmp(addr
, "*")) {
1426 if (ll_proto_a2n(&tmp
, addr
))
1428 a
.addr
.data
[0] = ntohs(tmp
);
1434 if (fam
== AF_NETLINK
|| strncmp(addr
, "netlink:", 8) == 0) {
1435 a
.addr
.family
= AF_NETLINK
;
1437 if (strncmp(addr
, "netlink:", 8) == 0)
1439 port
= strchr(addr
, ':');
1442 if (port
[1] && strcmp(port
+1, "*")) {
1443 if (get_integer(&a
.port
, port
+1, 0)) {
1444 if (strcmp(port
+1, "kernel") == 0)
1451 if (addr
[0] && strcmp(addr
, "*")) {
1453 if (nl_proto_a2n(&a
.addr
.data
[0], addr
) == -1)
1460 if (fam
== AF_INET
|| !strncmp(addr
, "inet:", 5)) {
1462 if (!strncmp(addr
, "inet:", 5))
1464 } else if (fam
== AF_INET6
|| !strncmp(addr
, "inet6:", 6)) {
1466 if (!strncmp(addr
, "inet6:", 6))
1470 /* URL-like literal [] */
1471 if (addr
[0] == '[') {
1473 if ((port
= strchr(addr
, ']')) == NULL
)
1476 } else if (addr
[0] == '*') {
1479 port
= strrchr(strchr(addr
, '/') ? : addr
, ':');
1485 if (port
&& *port
) {
1489 if (*port
&& *port
!= '*') {
1490 if (get_integer(&a
.port
, port
, 0)) {
1491 struct servent
*se1
= NULL
;
1492 struct servent
*se2
= NULL
;
1493 if (current_filter
.dbs
&(1<<UDP_DB
))
1494 se1
= getservbyname(port
, UDP_PROTO
);
1495 if (current_filter
.dbs
&(1<<TCP_DB
))
1496 se2
= getservbyname(port
, TCP_PROTO
);
1497 if (se1
&& se2
&& se1
->s_port
!= se2
->s_port
) {
1498 fprintf(stderr
, "Error: ambiguous port \"%s\".\n", port
);
1504 a
.port
= ntohs(se1
->s_port
);
1507 for (s
= rlist
; s
; s
= s
->next
) {
1508 if ((s
->proto
== UDP_PROTO
&&
1509 (current_filter
.dbs
&(1<<UDP_DB
))) ||
1510 (s
->proto
== TCP_PROTO
&&
1511 (current_filter
.dbs
&(1<<TCP_DB
)))) {
1512 if (s
->name
&& strcmp(s
->name
, port
) == 0) {
1513 if (a
.port
> 0 && a
.port
!= s
->port
) {
1514 fprintf(stderr
, "Error: ambiguous port \"%s\".\n", port
);
1522 fprintf(stderr
, "Error: \"%s\" does not look like a port.\n", port
);
1529 if (!is_port
&& addr
&& *addr
&& *addr
!= '*') {
1530 if (get_prefix_1(&a
.addr
, addr
, fam
)) {
1531 if (get_dns_host(&a
, addr
, fam
)) {
1532 fprintf(stderr
, "Error: an inet prefix is expected rather than \"%s\".\n", addr
);
1539 if (fam
!= AF_UNSPEC
) {
1541 filter_af_set(f
, fam
);
1542 filter_states_set(f
, 0);
1545 res
= malloc(sizeof(*res
));
1547 memcpy(res
, &a
, sizeof(a
));
1551 static char *proto_name(int protocol
)
1565 static void inet_stats_print(struct sockstat
*s
, int protocol
)
1569 sock_state_print(s
, proto_name(protocol
));
1571 inet_addr_print(&s
->local
, s
->lport
, s
->iface
);
1572 inet_addr_print(&s
->remote
, s
->rport
, 0);
1574 if (show_proc_ctx
|| show_sock_ctx
) {
1575 if (find_entry(s
->ino
, &buf
,
1576 (show_proc_ctx
& show_sock_ctx
) ?
1577 PROC_SOCK_CTX
: PROC_CTX
) > 0) {
1578 printf(" users:(%s)", buf
);
1581 } else if (show_users
) {
1582 if (find_entry(s
->ino
, &buf
, USERS
) > 0) {
1583 printf(" users:(%s)", buf
);
1589 static int proc_parse_inet_addr(char *loc
, char *rem
, int family
, struct
1592 s
->local
.family
= s
->remote
.family
= family
;
1593 if (family
== AF_INET
) {
1594 sscanf(loc
, "%x:%x", s
->local
.data
, (unsigned*)&s
->lport
);
1595 sscanf(rem
, "%x:%x", s
->remote
.data
, (unsigned*)&s
->rport
);
1596 s
->local
.bytelen
= s
->remote
.bytelen
= 4;
1599 sscanf(loc
, "%08x%08x%08x%08x:%x",
1605 sscanf(rem
, "%08x%08x%08x%08x:%x",
1611 s
->local
.bytelen
= s
->remote
.bytelen
= 16;
1617 static int proc_inet_split_line(char *line
, char **loc
, char **rem
, char **data
)
1621 if ((p
= strchr(line
, ':')) == NULL
)
1625 if ((p
= strchr(*loc
, ':')) == NULL
)
1630 if ((p
= strchr(*rem
, ':')) == NULL
)
1638 static char *sprint_bw(char *buf
, double bw
)
1641 sprintf(buf
,"%.1fM", bw
/ 1000000.);
1642 else if (bw
> 1000.)
1643 sprintf(buf
,"%.1fK", bw
/ 1000.);
1645 sprintf(buf
, "%g", bw
);
1650 static void tcp_stats_print(struct tcpstat
*s
)
1656 if (s
->has_sack_opt
)
1660 if (s
->has_ecnseen_opt
)
1662 if (s
->has_fastopen_opt
)
1663 printf(" fastopen");
1665 printf(" %s", s
->cong_alg
);
1666 if (s
->has_wscale_opt
)
1667 printf(" wscale:%d,%d", s
->snd_wscale
, s
->rcv_wscale
);
1669 printf(" rto:%g", s
->rto
);
1671 printf(" backoff:%u", s
->backoff
);
1673 printf(" rtt:%g/%g", s
->rtt
, s
->rttvar
);
1675 printf(" ato:%g", s
->ato
);
1678 printf(" qack:%d", s
->qack
);
1683 printf(" mss:%d", s
->mss
);
1685 printf(" cwnd:%d", s
->cwnd
);
1687 printf(" ssthresh:%d", s
->ssthresh
);
1690 printf(" bytes_acked:%llu", s
->bytes_acked
);
1691 if (s
->bytes_received
)
1692 printf(" bytes_received:%llu", s
->bytes_received
);
1694 printf(" segs_out:%u", s
->segs_out
);
1696 printf(" segs_in:%u", s
->segs_in
);
1698 if (s
->dctcp
&& s
->dctcp
->enabled
) {
1699 struct dctcpstat
*dctcp
= s
->dctcp
;
1701 printf(" dctcp:(ce_state:%u,alpha:%u,ab_ecn:%u,ab_tot:%u)",
1702 dctcp
->ce_state
, dctcp
->alpha
, dctcp
->ab_ecn
,
1704 } else if (s
->dctcp
) {
1705 printf(" dctcp:fallback_mode");
1709 printf(" send %sbps", sprint_bw(b1
, s
->send_bps
));
1711 printf(" lastsnd:%u", s
->lastsnd
);
1713 printf(" lastrcv:%u", s
->lastrcv
);
1715 printf(" lastack:%u", s
->lastack
);
1717 if (s
->pacing_rate
) {
1718 printf(" pacing_rate %sbps", sprint_bw(b1
, s
->pacing_rate
));
1719 if (s
->pacing_rate_max
)
1720 printf("/%sbps", sprint_bw(b1
,
1721 s
->pacing_rate_max
));
1725 printf(" unacked:%u", s
->unacked
);
1726 if (s
->retrans
|| s
->retrans_total
)
1727 printf(" retrans:%u/%u", s
->retrans
, s
->retrans_total
);
1729 printf(" lost:%u", s
->lost
);
1730 if (s
->sacked
&& s
->ss
.state
!= SS_LISTEN
)
1731 printf(" sacked:%u", s
->sacked
);
1733 printf(" fackets:%u", s
->fackets
);
1734 if (s
->reordering
!= 3)
1735 printf(" reordering:%d", s
->reordering
);
1737 printf(" rcv_rtt:%g", s
->rcv_rtt
);
1739 printf(" rcv_space:%d", s
->rcv_space
);
1742 static void tcp_timer_print(struct tcpstat
*s
)
1747 printf(" timer:(%s,%s,%d)",
1749 print_ms_timer(s
->timeout
),
1754 static int tcp_show_line(char *line
, const struct filter
*f
, int family
)
1756 int rto
= 0, ato
= 0;
1757 struct tcpstat s
= {};
1758 char *loc
, *rem
, *data
;
1761 int hz
= get_user_hz();
1763 if (proc_inet_split_line(line
, &loc
, &rem
, &data
))
1766 int state
= (data
[1] >= 'A') ? (data
[1] - 'A' + 10) : (data
[1] - '0');
1767 if (!(f
->states
& (1 << state
)))
1770 proc_parse_inet_addr(loc
, rem
, family
, &s
.ss
);
1772 if (f
->f
&& run_ssfilter(f
->f
, &s
.ss
) == 0)
1776 n
= sscanf(data
, "%x %x:%x %x:%x %x %d %d %u %d %llx %d %d %d %d %d %[^\n]\n",
1777 &s
.ss
.state
, &s
.ss
.wq
, &s
.ss
.rq
,
1778 &s
.timer
, &s
.timeout
, &s
.retrans
, &s
.ss
.uid
, &s
.probes
,
1779 &s
.ss
.ino
, &s
.ss
.refcnt
, &s
.ss
.sk
, &rto
, &ato
, &s
.qack
, &s
.cwnd
,
1792 s
.retrans
= s
.timer
!= 1 ? s
.probes
: s
.retrans
;
1793 s
.timeout
= (s
.timeout
* 1000 + hz
- 1) / hz
;
1794 s
.ato
= (double)ato
/ hz
;
1796 s
.rto
= (double)rto
;
1797 s
.ssthresh
= s
.ssthresh
== -1 ? 0 : s
.ssthresh
;
1798 s
.rto
= s
.rto
!= 3 * hz
? s
.rto
/ hz
: 0;
1800 inet_stats_print(&s
.ss
, IPPROTO_TCP
);
1803 tcp_timer_print(&s
);
1806 sock_details_print(&s
.ss
);
1808 printf(" opt:\"%s\"", opt
);
1812 tcp_stats_print(&s
);
1818 static int generic_record_read(FILE *fp
,
1819 int (*worker
)(char*, const struct filter
*, int),
1820 const struct filter
*f
, int fam
)
1825 if (fgets(line
, sizeof(line
), fp
) == NULL
)
1828 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
1829 int n
= strlen(line
);
1830 if (n
== 0 || line
[n
-1] != '\n') {
1836 if (worker(line
, f
, fam
) < 0)
1841 return ferror(fp
) ? -1 : 0;
1844 static void print_skmeminfo(struct rtattr
*tb
[], int attrtype
)
1846 const __u32
*skmeminfo
;
1848 if (!tb
[attrtype
]) {
1849 if (attrtype
== INET_DIAG_SKMEMINFO
) {
1850 if (!tb
[INET_DIAG_MEMINFO
])
1853 const struct inet_diag_meminfo
*minfo
=
1854 RTA_DATA(tb
[INET_DIAG_MEMINFO
]);
1856 printf(" mem:(r%u,w%u,f%u,t%u)",
1865 skmeminfo
= RTA_DATA(tb
[attrtype
]);
1867 printf(" skmem:(r%u,rb%u,t%u,tb%u,f%u,w%u,o%u",
1868 skmeminfo
[SK_MEMINFO_RMEM_ALLOC
],
1869 skmeminfo
[SK_MEMINFO_RCVBUF
],
1870 skmeminfo
[SK_MEMINFO_WMEM_ALLOC
],
1871 skmeminfo
[SK_MEMINFO_SNDBUF
],
1872 skmeminfo
[SK_MEMINFO_FWD_ALLOC
],
1873 skmeminfo
[SK_MEMINFO_WMEM_QUEUED
],
1874 skmeminfo
[SK_MEMINFO_OPTMEM
]);
1876 if (RTA_PAYLOAD(tb
[attrtype
]) >=
1877 (SK_MEMINFO_BACKLOG
+ 1) * sizeof(__u32
))
1878 printf(",bl%u", skmeminfo
[SK_MEMINFO_BACKLOG
]);
1883 #define TCPI_HAS_OPT(info, opt) !!(info->tcpi_options & (opt))
1885 static void tcp_show_info(const struct nlmsghdr
*nlh
, struct inet_diag_msg
*r
,
1886 struct rtattr
*tb
[])
1889 struct tcpstat s
= {};
1891 s
.ss
.state
= r
->idiag_state
;
1893 print_skmeminfo(tb
, INET_DIAG_SKMEMINFO
);
1895 if (tb
[INET_DIAG_INFO
]) {
1896 struct tcp_info
*info
;
1897 int len
= RTA_PAYLOAD(tb
[INET_DIAG_INFO
]);
1899 /* workaround for older kernels with less fields */
1900 if (len
< sizeof(*info
)) {
1901 info
= alloca(sizeof(*info
));
1902 memcpy(info
, RTA_DATA(tb
[INET_DIAG_INFO
]), len
);
1903 memset((char *)info
+ len
, 0, sizeof(*info
) - len
);
1905 info
= RTA_DATA(tb
[INET_DIAG_INFO
]);
1908 s
.has_ts_opt
= TCPI_HAS_OPT(info
, TCPI_OPT_TIMESTAMPS
);
1909 s
.has_sack_opt
= TCPI_HAS_OPT(info
, TCPI_OPT_SACK
);
1910 s
.has_ecn_opt
= TCPI_HAS_OPT(info
, TCPI_OPT_ECN
);
1911 s
.has_ecnseen_opt
= TCPI_HAS_OPT(info
, TCPI_OPT_ECN_SEEN
);
1912 s
.has_fastopen_opt
= TCPI_HAS_OPT(info
, TCPI_OPT_SYN_DATA
);
1915 if (tb
[INET_DIAG_CONG
])
1917 rta_getattr_str(tb
[INET_DIAG_CONG
]),
1918 sizeof(s
.cong_alg
) - 1);
1920 if (TCPI_HAS_OPT(info
, TCPI_OPT_WSCALE
)) {
1921 s
.has_wscale_opt
= true;
1922 s
.snd_wscale
= info
->tcpi_snd_wscale
;
1923 s
.rcv_wscale
= info
->tcpi_rcv_wscale
;
1926 if (info
->tcpi_rto
&& info
->tcpi_rto
!= 3000000)
1927 s
.rto
= (double)info
->tcpi_rto
/ 1000;
1929 s
.backoff
= info
->tcpi_backoff
;
1930 s
.rtt
= (double)info
->tcpi_rtt
/ 1000;
1931 s
.rttvar
= (double)info
->tcpi_rttvar
/ 1000;
1932 s
.ato
= (double)info
->tcpi_ato
/ 1000;
1933 s
.mss
= info
->tcpi_snd_mss
;
1934 s
.rcv_space
= info
->tcpi_rcv_space
;
1935 s
.rcv_rtt
= (double)info
->tcpi_rcv_rtt
/ 1000;
1936 s
.lastsnd
= info
->tcpi_last_data_sent
;
1937 s
.lastrcv
= info
->tcpi_last_data_recv
;
1938 s
.lastack
= info
->tcpi_last_ack_recv
;
1939 s
.unacked
= info
->tcpi_unacked
;
1940 s
.retrans
= info
->tcpi_retrans
;
1941 s
.retrans_total
= info
->tcpi_total_retrans
;
1942 s
.lost
= info
->tcpi_lost
;
1943 s
.sacked
= info
->tcpi_sacked
;
1944 s
.reordering
= info
->tcpi_reordering
;
1945 s
.rcv_space
= info
->tcpi_rcv_space
;
1946 s
.cwnd
= info
->tcpi_snd_cwnd
;
1948 if (info
->tcpi_snd_ssthresh
< 0xFFFF)
1949 s
.ssthresh
= info
->tcpi_snd_ssthresh
;
1951 rtt
= (double) info
->tcpi_rtt
;
1952 if (tb
[INET_DIAG_VEGASINFO
]) {
1953 const struct tcpvegas_info
*vinfo
1954 = RTA_DATA(tb
[INET_DIAG_VEGASINFO
]);
1956 if (vinfo
->tcpv_enabled
&&
1957 vinfo
->tcpv_rtt
&& vinfo
->tcpv_rtt
!= 0x7fffffff)
1958 rtt
= vinfo
->tcpv_rtt
;
1961 if (tb
[INET_DIAG_DCTCPINFO
]) {
1962 struct dctcpstat
*dctcp
= malloc(sizeof(struct
1965 const struct tcp_dctcp_info
*dinfo
1966 = RTA_DATA(tb
[INET_DIAG_DCTCPINFO
]);
1968 dctcp
->enabled
= !!dinfo
->dctcp_enabled
;
1969 dctcp
->ce_state
= dinfo
->dctcp_ce_state
;
1970 dctcp
->alpha
= dinfo
->dctcp_alpha
;
1971 dctcp
->ab_ecn
= dinfo
->dctcp_ab_ecn
;
1972 dctcp
->ab_tot
= dinfo
->dctcp_ab_tot
;
1976 if (rtt
> 0 && info
->tcpi_snd_mss
&& info
->tcpi_snd_cwnd
) {
1977 s
.send_bps
= (double) info
->tcpi_snd_cwnd
*
1978 (double)info
->tcpi_snd_mss
* 8000000. / rtt
;
1981 if (info
->tcpi_pacing_rate
&&
1982 info
->tcpi_pacing_rate
!= ~0ULL) {
1983 s
.pacing_rate
= info
->tcpi_pacing_rate
* 8.;
1985 if (info
->tcpi_max_pacing_rate
&&
1986 info
->tcpi_max_pacing_rate
!= ~0ULL)
1987 s
.pacing_rate_max
= info
->tcpi_max_pacing_rate
* 8.;
1989 s
.bytes_acked
= info
->tcpi_bytes_acked
;
1990 s
.bytes_received
= info
->tcpi_bytes_received
;
1991 s
.segs_out
= info
->tcpi_segs_out
;
1992 s
.segs_in
= info
->tcpi_segs_in
;
1993 tcp_stats_print(&s
);
1999 static int inet_show_sock(struct nlmsghdr
*nlh
, struct filter
*f
, int protocol
)
2001 struct rtattr
* tb
[INET_DIAG_MAX
+1];
2002 struct inet_diag_msg
*r
= NLMSG_DATA(nlh
);
2003 struct sockstat s
= {};
2005 parse_rtattr(tb
, INET_DIAG_MAX
, (struct rtattr
*)(r
+1),
2006 nlh
->nlmsg_len
- NLMSG_LENGTH(sizeof(*r
)));
2008 s
.state
= r
->idiag_state
;
2009 s
.local
.family
= s
.remote
.family
= r
->idiag_family
;
2010 s
.lport
= ntohs(r
->id
.idiag_sport
);
2011 s
.rport
= ntohs(r
->id
.idiag_dport
);
2012 s
.wq
= r
->idiag_wqueue
;
2013 s
.rq
= r
->idiag_rqueue
;
2014 s
.ino
= r
->idiag_inode
;
2015 s
.uid
= r
->idiag_uid
;
2016 s
.iface
= r
->id
.idiag_if
;
2017 s
.sk
= cookie_sk_get(&r
->id
.idiag_cookie
[0]);
2019 if (s
.local
.family
== AF_INET
) {
2020 s
.local
.bytelen
= s
.remote
.bytelen
= 4;
2022 s
.local
.bytelen
= s
.remote
.bytelen
= 16;
2025 memcpy(s
.local
.data
, r
->id
.idiag_src
, s
.local
.bytelen
);
2026 memcpy(s
.remote
.data
, r
->id
.idiag_dst
, s
.local
.bytelen
);
2028 if (f
&& f
->f
&& run_ssfilter(f
->f
, &s
) == 0)
2031 inet_stats_print(&s
, protocol
);
2034 struct tcpstat t
= {};
2036 t
.timer
= r
->idiag_timer
;
2037 t
.timeout
= r
->idiag_expires
;
2038 t
.retrans
= r
->idiag_retrans
;
2039 tcp_timer_print(&t
);
2043 sock_details_print(&s
);
2044 if (tb
[INET_DIAG_SHUTDOWN
]) {
2046 mask
= *(__u8
*)RTA_DATA(tb
[INET_DIAG_SHUTDOWN
]);
2047 printf(" %c-%c", mask
& 1 ? '-' : '<', mask
& 2 ? '-' : '>');
2051 if (show_mem
|| show_tcpinfo
) {
2053 tcp_show_info(nlh
, r
, tb
);
2060 static int tcpdiag_send(int fd
, int protocol
, struct filter
*f
)
2062 struct sockaddr_nl nladdr
;
2064 struct nlmsghdr nlh
;
2065 struct inet_diag_req r
;
2071 struct iovec iov
[3];
2073 if (protocol
== IPPROTO_UDP
)
2076 memset(&nladdr
, 0, sizeof(nladdr
));
2077 nladdr
.nl_family
= AF_NETLINK
;
2079 req
.nlh
.nlmsg_len
= sizeof(req
);
2080 if (protocol
== IPPROTO_TCP
)
2081 req
.nlh
.nlmsg_type
= TCPDIAG_GETSOCK
;
2083 req
.nlh
.nlmsg_type
= DCCPDIAG_GETSOCK
;
2084 req
.nlh
.nlmsg_flags
= NLM_F_ROOT
|NLM_F_MATCH
|NLM_F_REQUEST
;
2085 req
.nlh
.nlmsg_pid
= 0;
2086 req
.nlh
.nlmsg_seq
= MAGIC_SEQ
;
2087 memset(&req
.r
, 0, sizeof(req
.r
));
2088 req
.r
.idiag_family
= AF_INET
;
2089 req
.r
.idiag_states
= f
->states
;
2091 req
.r
.idiag_ext
|= (1<<(INET_DIAG_MEMINFO
-1));
2092 req
.r
.idiag_ext
|= (1<<(INET_DIAG_SKMEMINFO
-1));
2096 req
.r
.idiag_ext
|= (1<<(INET_DIAG_INFO
-1));
2097 req
.r
.idiag_ext
|= (1<<(INET_DIAG_VEGASINFO
-1));
2098 req
.r
.idiag_ext
|= (1<<(INET_DIAG_CONG
-1));
2101 iov
[0] = (struct iovec
){
2103 .iov_len
= sizeof(req
)
2106 bclen
= ssfilter_bytecompile(f
->f
, &bc
);
2107 rta
.rta_type
= INET_DIAG_REQ_BYTECODE
;
2108 rta
.rta_len
= RTA_LENGTH(bclen
);
2109 iov
[1] = (struct iovec
){ &rta
, sizeof(rta
) };
2110 iov
[2] = (struct iovec
){ bc
, bclen
};
2111 req
.nlh
.nlmsg_len
+= RTA_LENGTH(bclen
);
2114 msg
= (struct msghdr
) {
2115 .msg_name
= (void*)&nladdr
,
2116 .msg_namelen
= sizeof(nladdr
),
2118 .msg_iovlen
= f
->f
? 3 : 1,
2121 if (sendmsg(fd
, &msg
, 0) < 0) {
2129 static int sockdiag_send(int family
, int fd
, int protocol
, struct filter
*f
)
2131 struct sockaddr_nl nladdr
;
2132 DIAG_REQUEST(req
, struct inet_diag_req_v2 r
);
2137 struct iovec iov
[3];
2139 if (family
== PF_UNSPEC
)
2140 return tcpdiag_send(fd
, protocol
, f
);
2142 memset(&nladdr
, 0, sizeof(nladdr
));
2143 nladdr
.nl_family
= AF_NETLINK
;
2145 memset(&req
.r
, 0, sizeof(req
.r
));
2146 req
.r
.sdiag_family
= family
;
2147 req
.r
.sdiag_protocol
= protocol
;
2148 req
.r
.idiag_states
= f
->states
;
2150 req
.r
.idiag_ext
|= (1<<(INET_DIAG_MEMINFO
-1));
2151 req
.r
.idiag_ext
|= (1<<(INET_DIAG_SKMEMINFO
-1));
2155 req
.r
.idiag_ext
|= (1<<(INET_DIAG_INFO
-1));
2156 req
.r
.idiag_ext
|= (1<<(INET_DIAG_VEGASINFO
-1));
2157 req
.r
.idiag_ext
|= (1<<(INET_DIAG_CONG
-1));
2160 iov
[0] = (struct iovec
){
2162 .iov_len
= sizeof(req
)
2165 bclen
= ssfilter_bytecompile(f
->f
, &bc
);
2166 rta
.rta_type
= INET_DIAG_REQ_BYTECODE
;
2167 rta
.rta_len
= RTA_LENGTH(bclen
);
2168 iov
[1] = (struct iovec
){ &rta
, sizeof(rta
) };
2169 iov
[2] = (struct iovec
){ bc
, bclen
};
2170 req
.nlh
.nlmsg_len
+= RTA_LENGTH(bclen
);
2173 msg
= (struct msghdr
) {
2174 .msg_name
= (void*)&nladdr
,
2175 .msg_namelen
= sizeof(nladdr
),
2177 .msg_iovlen
= f
->f
? 3 : 1,
2180 if (sendmsg(fd
, &msg
, 0) < 0) {
2188 struct inet_diag_arg
{
2193 static int show_one_inet_sock(const struct sockaddr_nl
*addr
,
2194 struct nlmsghdr
*h
, void *arg
)
2197 struct inet_diag_arg
*diag_arg
= arg
;
2198 struct inet_diag_msg
*r
= NLMSG_DATA(h
);
2200 if (!(diag_arg
->f
->families
& (1 << r
->idiag_family
)))
2202 if ((err
= inet_show_sock(h
, NULL
, diag_arg
->protocol
)) < 0)
2208 static int inet_show_netlink(struct filter
*f
, FILE *dump_fp
, int protocol
)
2211 struct rtnl_handle rth
;
2212 int family
= PF_INET
;
2213 struct inet_diag_arg arg
= { .f
= f
, .protocol
= protocol
};
2215 if (rtnl_open_byproto(&rth
, 0, NETLINK_SOCK_DIAG
))
2217 rth
.dump
= MAGIC_SEQ
;
2218 rth
.dump_fp
= dump_fp
;
2219 if (preferred_family
== PF_INET6
)
2223 if ((err
= sockdiag_send(family
, rth
.fd
, protocol
, f
)))
2226 if ((err
= rtnl_dump_filter(&rth
, show_one_inet_sock
, &arg
))) {
2227 if (family
!= PF_UNSPEC
) {
2233 if (family
== PF_INET
&& preferred_family
!= PF_INET
) {
2243 static int tcp_show_netlink_file(struct filter
*f
)
2248 if ((fp
= fopen(getenv("TCPDIAG_FILE"), "r")) == NULL
) {
2249 perror("fopen($TCPDIAG_FILE)");
2255 struct nlmsghdr
*h
= (struct nlmsghdr
*)buf
;
2257 status
= fread(buf
, 1, sizeof(*h
), fp
);
2259 perror("Reading header from $TCPDIAG_FILE");
2262 if (status
!= sizeof(*h
)) {
2263 perror("Unexpected EOF reading $TCPDIAG_FILE");
2267 status
= fread(h
+1, 1, NLMSG_ALIGN(h
->nlmsg_len
-sizeof(*h
)), fp
);
2270 perror("Reading $TCPDIAG_FILE");
2273 if (status
+ sizeof(*h
) < h
->nlmsg_len
) {
2274 perror("Unexpected EOF reading $TCPDIAG_FILE");
2278 /* The only legal exit point */
2279 if (h
->nlmsg_type
== NLMSG_DONE
)
2282 if (h
->nlmsg_type
== NLMSG_ERROR
) {
2283 struct nlmsgerr
*err
= (struct nlmsgerr
*)NLMSG_DATA(h
);
2284 if (h
->nlmsg_len
< NLMSG_LENGTH(sizeof(struct nlmsgerr
))) {
2285 fprintf(stderr
, "ERROR truncated\n");
2287 errno
= -err
->error
;
2288 perror("TCPDIAG answered");
2293 err
= inet_show_sock(h
, f
, IPPROTO_TCP
);
2299 static int tcp_show(struct filter
*f
, int socktype
)
2303 int bufsize
= 64*1024;
2305 if (!filter_af_get(f
, AF_INET
) && !filter_af_get(f
, AF_INET6
))
2308 dg_proto
= TCP_PROTO
;
2310 if (getenv("TCPDIAG_FILE"))
2311 return tcp_show_netlink_file(f
);
2313 if (!getenv("PROC_NET_TCP") && !getenv("PROC_ROOT")
2314 && inet_show_netlink(f
, NULL
, socktype
) == 0)
2317 /* Sigh... We have to parse /proc/net/tcp... */
2320 /* Estimate amount of sockets and try to allocate
2321 * huge buffer to read all the table at one read.
2322 * Limit it by 16MB though. The assumption is: as soon as
2323 * kernel was able to hold information about N connections,
2324 * it is able to give us some memory for snapshot.
2327 get_slabstat(&slabstat
);
2329 int guess
= slabstat
.socks
+slabstat
.tcp_syns
;
2330 if (f
->states
&(1<<SS_TIME_WAIT
))
2331 guess
+= slabstat
.tcp_tws
;
2332 if (guess
> (16*1024*1024)/128)
2333 guess
= (16*1024*1024)/128;
2335 if (guess
> bufsize
)
2338 while (bufsize
>= 64*1024) {
2339 if ((buf
= malloc(bufsize
)) != NULL
)
2348 if (f
->families
& (1<<AF_INET
)) {
2349 if ((fp
= net_tcp_open()) == NULL
)
2352 setbuffer(fp
, buf
, bufsize
);
2353 if (generic_record_read(fp
, tcp_show_line
, f
, AF_INET
))
2358 if ((f
->families
& (1<<AF_INET6
)) &&
2359 (fp
= net_tcp6_open()) != NULL
) {
2360 setbuffer(fp
, buf
, bufsize
);
2361 if (generic_record_read(fp
, tcp_show_line
, f
, AF_INET6
))
2371 int saved_errno
= errno
;
2376 errno
= saved_errno
;
2382 static int dgram_show_line(char *line
, const struct filter
*f
, int family
)
2384 struct sockstat s
= {};
2385 char *loc
, *rem
, *data
;
2389 if (proc_inet_split_line(line
, &loc
, &rem
, &data
))
2392 int state
= (data
[1] >= 'A') ? (data
[1] - 'A' + 10) : (data
[1] - '0');
2393 if (!(f
->states
& (1 << state
)))
2396 proc_parse_inet_addr(loc
, rem
, family
, &s
);
2398 if (f
->f
&& run_ssfilter(f
->f
, &s
) == 0)
2402 n
= sscanf(data
, "%x %x:%x %*x:%*x %*x %d %*d %u %d %llx %[^\n]\n",
2403 &s
.state
, &s
.wq
, &s
.rq
,
2405 &s
.refcnt
, &s
.sk
, opt
);
2410 inet_stats_print(&s
, IPPROTO_UDP
);
2412 if (show_details
&& opt
[0])
2413 printf(" opt:\"%s\"", opt
);
2419 static int udp_show(struct filter
*f
)
2423 if (!filter_af_get(f
, AF_INET
) && !filter_af_get(f
, AF_INET6
))
2426 dg_proto
= UDP_PROTO
;
2428 if (!getenv("PROC_NET_UDP") && !getenv("PROC_ROOT")
2429 && inet_show_netlink(f
, NULL
, IPPROTO_UDP
) == 0)
2432 if (f
->families
&(1<<AF_INET
)) {
2433 if ((fp
= net_udp_open()) == NULL
)
2435 if (generic_record_read(fp
, dgram_show_line
, f
, AF_INET
))
2440 if ((f
->families
&(1<<AF_INET6
)) &&
2441 (fp
= net_udp6_open()) != NULL
) {
2442 if (generic_record_read(fp
, dgram_show_line
, f
, AF_INET6
))
2450 int saved_errno
= errno
;
2453 errno
= saved_errno
;
2458 static int raw_show(struct filter
*f
)
2462 if (!filter_af_get(f
, AF_INET
) && !filter_af_get(f
, AF_INET6
))
2465 dg_proto
= RAW_PROTO
;
2467 if (f
->families
&(1<<AF_INET
)) {
2468 if ((fp
= net_raw_open()) == NULL
)
2470 if (generic_record_read(fp
, dgram_show_line
, f
, AF_INET
))
2475 if ((f
->families
&(1<<AF_INET6
)) &&
2476 (fp
= net_raw6_open()) != NULL
) {
2477 if (generic_record_read(fp
, dgram_show_line
, f
, AF_INET6
))
2485 int saved_errno
= errno
;
2488 errno
= saved_errno
;
2493 int unix_state_map
[] = { SS_CLOSE
, SS_SYN_SENT
,
2494 SS_ESTABLISHED
, SS_CLOSING
};
2496 #define MAX_UNIX_REMEMBER (1024*1024/sizeof(struct sockstat))
2498 static void unix_list_free(struct sockstat
*list
)
2501 struct sockstat
*s
= list
;
2502 char *name
= sock_addr_get_str(&s
->local
);
2512 static const char *unix_netid_name(int type
)
2520 case SOCK_SEQPACKET
:
2531 static bool unix_type_skip(struct sockstat
*s
, struct filter
*f
)
2533 if (s
->type
== SOCK_STREAM
&& !(f
->dbs
&(1<<UNIX_ST_DB
)))
2535 if (s
->type
== SOCK_DGRAM
&& !(f
->dbs
&(1<<UNIX_DG_DB
)))
2537 if (s
->type
== SOCK_SEQPACKET
&& !(f
->dbs
&(1<<UNIX_SQ_DB
)))
2542 static bool unix_use_proc(void)
2544 return getenv("PROC_NET_UNIX") || getenv("PROC_ROOT");
2547 static void unix_stats_print(struct sockstat
*list
, struct filter
*f
)
2551 char *ctx_buf
= NULL
;
2552 bool use_proc
= unix_use_proc();
2553 char port_name
[30] = {};
2555 for (s
= list
; s
; s
= s
->next
) {
2556 if (!(f
->states
& (1 << s
->state
)))
2558 if (unix_type_skip(s
, f
))
2561 local
= sock_addr_get_str(&s
->local
);
2564 if (s
->rport
&& use_proc
) {
2567 for (p
= list
; p
; p
= p
->next
) {
2568 if (s
->rport
== p
->lport
)
2575 peer
= sock_addr_get_str(&p
->local
);
2576 peer
= peer
? : "*";
2580 if (use_proc
&& f
->f
) {
2581 if (strcmp(peer
, "*") == 0)
2582 memset(s
->remote
.data
, 0, sizeof(char *));
2584 sock_addr_set_str(&s
->remote
, &peer
);
2586 if (run_ssfilter(f
->f
, s
) == 0)
2590 sock_state_print(s
, unix_netid_name(s
->type
));
2592 sock_addr_print(local
?: "*", " ",
2593 int_to_str(s
->lport
, port_name
), NULL
);
2594 sock_addr_print(peer
, " ", int_to_str(s
->rport
, port_name
),
2597 if (show_proc_ctx
|| show_sock_ctx
) {
2598 if (find_entry(s
->ino
, &ctx_buf
,
2599 (show_proc_ctx
& show_sock_ctx
) ?
2600 PROC_SOCK_CTX
: PROC_CTX
) > 0) {
2601 printf(" users:(%s)", ctx_buf
);
2604 } else if (show_users
) {
2605 if (find_entry(s
->ino
, &ctx_buf
, USERS
) > 0) {
2606 printf(" users:(%s)", ctx_buf
);
2614 static int unix_show_sock(const struct sockaddr_nl
*addr
, struct nlmsghdr
*nlh
,
2617 struct filter
*f
= (struct filter
*)arg
;
2618 struct unix_diag_msg
*r
= NLMSG_DATA(nlh
);
2619 struct rtattr
*tb
[UNIX_DIAG_MAX
+1];
2621 struct sockstat stat
= {};
2623 parse_rtattr(tb
, UNIX_DIAG_MAX
, (struct rtattr
*)(r
+1),
2624 nlh
->nlmsg_len
- NLMSG_LENGTH(sizeof(*r
)));
2626 stat
.type
= r
->udiag_type
;
2627 stat
.state
= r
->udiag_state
;
2628 stat
.ino
= stat
.lport
= r
->udiag_ino
;
2629 stat
.local
.family
= stat
.remote
.family
= AF_UNIX
;
2631 if (unix_type_skip(&stat
, f
))
2634 if (tb
[UNIX_DIAG_RQLEN
]) {
2635 struct unix_diag_rqlen
*rql
= RTA_DATA(tb
[UNIX_DIAG_RQLEN
]);
2636 stat
.rq
= rql
->udiag_rqueue
;
2637 stat
.wq
= rql
->udiag_wqueue
;
2639 if (tb
[UNIX_DIAG_NAME
]) {
2640 int len
= RTA_PAYLOAD(tb
[UNIX_DIAG_NAME
]);
2642 name
= malloc(len
+ 1);
2643 memcpy(name
, RTA_DATA(tb
[UNIX_DIAG_NAME
]), len
);
2645 if (name
[0] == '\0')
2647 sock_addr_set_str(&stat
.local
, &name
);
2649 if (tb
[UNIX_DIAG_PEER
])
2650 stat
.rport
= rta_getattr_u32(tb
[UNIX_DIAG_PEER
]);
2652 if (f
->f
&& run_ssfilter(f
->f
, &stat
) == 0)
2655 unix_stats_print(&stat
, f
);
2659 print_skmeminfo(tb
, UNIX_DIAG_MEMINFO
);
2662 if (tb
[UNIX_DIAG_SHUTDOWN
]) {
2664 mask
= *(__u8
*)RTA_DATA(tb
[UNIX_DIAG_SHUTDOWN
]);
2665 printf(" %c-%c", mask
& 1 ? '-' : '<', mask
& 2 ? '-' : '>');
2668 if (show_mem
|| show_details
)
2676 static int handle_netlink_request(struct filter
*f
, struct nlmsghdr
*req
,
2677 size_t size
, rtnl_filter_t show_one_sock
)
2680 struct rtnl_handle rth
;
2682 if (rtnl_open_byproto(&rth
, 0, NETLINK_SOCK_DIAG
))
2685 rth
.dump
= MAGIC_SEQ
;
2687 if (rtnl_send(&rth
, req
, size
) < 0)
2690 if (rtnl_dump_filter(&rth
, show_one_sock
, f
))
2699 static int unix_show_netlink(struct filter
*f
)
2701 DIAG_REQUEST(req
, struct unix_diag_req r
);
2703 req
.r
.sdiag_family
= AF_UNIX
;
2704 req
.r
.udiag_states
= f
->states
;
2705 req
.r
.udiag_show
= UDIAG_SHOW_NAME
| UDIAG_SHOW_PEER
| UDIAG_SHOW_RQLEN
;
2707 req
.r
.udiag_show
|= UDIAG_SHOW_MEMINFO
;
2709 return handle_netlink_request(f
, &req
.nlh
, sizeof(req
), unix_show_sock
);
2712 static int unix_show(struct filter
*f
)
2719 struct sockstat
*list
= NULL
;
2721 if (!filter_af_get(f
, AF_UNIX
))
2724 if (!unix_use_proc() && unix_show_netlink(f
) == 0)
2727 if ((fp
= net_unix_open()) == NULL
)
2729 fgets(buf
, sizeof(buf
)-1, fp
);
2731 if (memcmp(buf
, "Peer", 4) == 0)
2735 while (fgets(buf
, sizeof(buf
)-1, fp
)) {
2736 struct sockstat
*u
, **insp
;
2739 if (!(u
= malloc(sizeof(*u
))))
2742 if (sscanf(buf
, "%x: %x %x %x %x %x %d %s",
2743 &u
->rport
, &u
->rq
, &u
->wq
, &flags
, &u
->type
,
2744 &u
->state
, &u
->ino
, name
) < 8)
2748 u
->local
.family
= u
->remote
.family
= AF_UNIX
;
2750 if (flags
& (1 << 16)) {
2751 u
->state
= SS_LISTEN
;
2753 u
->state
= unix_state_map
[u
->state
-1];
2754 if (u
->type
== SOCK_DGRAM
&& u
->state
== SS_CLOSE
&& u
->rport
)
2755 u
->state
= SS_ESTABLISHED
;
2766 if (u
->type
< (*insp
)->type
||
2767 (u
->type
== (*insp
)->type
&&
2768 u
->ino
< (*insp
)->ino
))
2770 insp
= &(*insp
)->next
;
2776 char *tmp
= strdup(name
);
2777 sock_addr_set_str(&u
->local
, &tmp
);
2779 if (++cnt
> MAX_UNIX_REMEMBER
) {
2780 unix_stats_print(list
, f
);
2781 unix_list_free(list
);
2788 unix_stats_print(list
, f
);
2789 unix_list_free(list
);
2797 static int packet_stats_print(struct sockstat
*s
, const struct filter
*f
)
2800 const char *addr
, *port
;
2804 s
->local
.family
= AF_PACKET
;
2805 s
->remote
.family
= AF_PACKET
;
2806 s
->local
.data
[0] = s
->prot
;
2807 if (run_ssfilter(f
->f
, s
) == 0)
2811 sock_state_print(s
, s
->type
== SOCK_RAW
? "p_raw" : "p_dgr");
2816 addr
= ll_proto_n2a(htons(s
->prot
), ll_name
, sizeof(ll_name
));
2821 port
= xll_index_to_name(s
->iface
);
2823 sock_addr_print(addr
, ":", port
, NULL
);
2824 sock_addr_print("", "*", "", NULL
);
2826 if (show_proc_ctx
|| show_sock_ctx
) {
2827 if (find_entry(s
->ino
, &buf
,
2828 (show_proc_ctx
& show_sock_ctx
) ?
2829 PROC_SOCK_CTX
: PROC_CTX
) > 0) {
2830 printf(" users:(%s)", buf
);
2833 } else if (show_users
) {
2834 if (find_entry(s
->ino
, &buf
, USERS
) > 0) {
2835 printf(" users:(%s)", buf
);
2841 sock_details_print(s
);
2846 static void packet_show_ring(struct packet_diag_ring
*ring
)
2848 printf("blk_size:%d", ring
->pdr_block_size
);
2849 printf(",blk_nr:%d", ring
->pdr_block_nr
);
2850 printf(",frm_size:%d", ring
->pdr_frame_size
);
2851 printf(",frm_nr:%d", ring
->pdr_frame_nr
);
2852 printf(",tmo:%d", ring
->pdr_retire_tmo
);
2853 printf(",features:0x%x", ring
->pdr_features
);
2856 static int packet_show_sock(const struct sockaddr_nl
*addr
,
2857 struct nlmsghdr
*nlh
, void *arg
)
2859 const struct filter
*f
= arg
;
2860 struct packet_diag_msg
*r
= NLMSG_DATA(nlh
);
2861 struct packet_diag_info
*pinfo
= NULL
;
2862 struct packet_diag_ring
*ring_rx
= NULL
, *ring_tx
= NULL
;
2863 struct rtattr
*tb
[PACKET_DIAG_MAX
+1];
2864 struct sockstat stat
= {};
2865 uint32_t fanout
= 0;
2866 bool has_fanout
= false;
2868 parse_rtattr(tb
, PACKET_DIAG_MAX
, (struct rtattr
*)(r
+1),
2869 nlh
->nlmsg_len
- NLMSG_LENGTH(sizeof(*r
)));
2871 /* use /proc/net/packet if all info are not available */
2872 if (!tb
[PACKET_DIAG_MEMINFO
])
2875 stat
.type
= r
->pdiag_type
;
2876 stat
.prot
= r
->pdiag_num
;
2877 stat
.ino
= r
->pdiag_ino
;
2878 stat
.state
= SS_CLOSE
;
2879 stat
.sk
= cookie_sk_get(&r
->pdiag_cookie
[0]);
2881 if (tb
[PACKET_DIAG_MEMINFO
]) {
2882 __u32
*skmeminfo
= RTA_DATA(tb
[PACKET_DIAG_MEMINFO
]);
2883 stat
.rq
= skmeminfo
[SK_MEMINFO_RMEM_ALLOC
];
2886 if (tb
[PACKET_DIAG_INFO
]) {
2887 pinfo
= RTA_DATA(tb
[PACKET_DIAG_INFO
]);
2888 stat
.lport
= stat
.iface
= pinfo
->pdi_index
;
2891 if (tb
[PACKET_DIAG_UID
])
2892 stat
.uid
= *(__u32
*)RTA_DATA(tb
[PACKET_DIAG_UID
]);
2894 if (tb
[PACKET_DIAG_RX_RING
])
2895 ring_rx
= RTA_DATA(tb
[PACKET_DIAG_RX_RING
]);
2897 if (tb
[PACKET_DIAG_TX_RING
])
2898 ring_tx
= RTA_DATA(tb
[PACKET_DIAG_TX_RING
]);
2900 if (tb
[PACKET_DIAG_FANOUT
]) {
2902 fanout
= *(uint32_t *)RTA_DATA(tb
[PACKET_DIAG_FANOUT
]);
2905 if (packet_stats_print(&stat
, f
))
2910 printf("\n\tver:%d", pinfo
->pdi_version
);
2911 printf(" cpy_thresh:%d", pinfo
->pdi_copy_thresh
);
2913 if (pinfo
->pdi_flags
& PDI_RUNNING
)
2915 if (pinfo
->pdi_flags
& PDI_AUXDATA
)
2917 if (pinfo
->pdi_flags
& PDI_ORIGDEV
)
2919 if (pinfo
->pdi_flags
& PDI_VNETHDR
)
2921 if (pinfo
->pdi_flags
& PDI_LOSS
)
2923 if (!pinfo
->pdi_flags
)
2928 printf("\n\tring_rx(");
2929 packet_show_ring(ring_rx
);
2933 printf("\n\tring_tx(");
2934 packet_show_ring(ring_tx
);
2938 uint16_t type
= (fanout
>> 16) & 0xffff;
2940 printf("\n\tfanout(");
2941 printf("id:%d,", fanout
& 0xffff);
2957 printf("0x%x", type
);
2963 if (show_bpf
&& tb
[PACKET_DIAG_FILTER
]) {
2964 struct sock_filter
*fil
=
2965 RTA_DATA(tb
[PACKET_DIAG_FILTER
]);
2966 int num
= RTA_PAYLOAD(tb
[PACKET_DIAG_FILTER
]) /
2967 sizeof(struct sock_filter
);
2969 printf("\n\tbpf filter (%d): ", num
);
2971 printf(" 0x%02x %u %u %u,",
2972 fil
->code
, fil
->jt
, fil
->jf
, fil
->k
);
2981 static int packet_show_netlink(struct filter
*f
)
2983 DIAG_REQUEST(req
, struct packet_diag_req r
);
2985 req
.r
.sdiag_family
= AF_PACKET
;
2986 req
.r
.pdiag_show
= PACKET_SHOW_INFO
| PACKET_SHOW_MEMINFO
|
2987 PACKET_SHOW_FILTER
| PACKET_SHOW_RING_CFG
| PACKET_SHOW_FANOUT
;
2989 return handle_netlink_request(f
, &req
.nlh
, sizeof(req
), packet_show_sock
);
2992 static int packet_show_line(char *buf
, const struct filter
*f
, int fam
)
2994 unsigned long long sk
;
2995 struct sockstat stat
= {};
2996 int type
, prot
, iface
, state
, rq
, uid
, ino
;
2998 sscanf(buf
, "%llx %*d %d %x %d %d %u %u %u",
3000 &type
, &prot
, &iface
, &state
,
3003 if (stat
.type
== SOCK_RAW
&& !(f
->dbs
&(1<<PACKET_R_DB
)))
3005 if (stat
.type
== SOCK_DGRAM
&& !(f
->dbs
&(1<<PACKET_DG_DB
)))
3010 stat
.lport
= stat
.iface
= iface
;
3015 stat
.state
= SS_CLOSE
;
3017 if (packet_stats_print(&stat
, f
))
3024 static int packet_show(struct filter
*f
)
3028 if (!filter_af_get(f
, AF_PACKET
) || !(f
->states
& (1 << SS_CLOSE
)))
3031 if (!getenv("PROC_NET_PACKET") && !getenv("PROC_ROOT") &&
3032 packet_show_netlink(f
) == 0)
3035 if ((fp
= net_packet_open()) == NULL
)
3037 if (generic_record_read(fp
, packet_show_line
, f
, AF_PACKET
))
3043 static int netlink_show_one(struct filter
*f
,
3044 int prot
, int pid
, unsigned groups
,
3045 int state
, int dst_pid
, unsigned dst_group
,
3047 unsigned long long sk
, unsigned long long cb
)
3050 SPRINT_BUF(prot_buf
) = {};
3051 const char *prot_name
;
3052 char procname
[64] = {};
3054 st
.state
= SS_CLOSE
;
3059 st
.local
.family
= AF_NETLINK
;
3060 st
.remote
.family
= AF_NETLINK
;
3063 st
.local
.data
[0] = prot
;
3064 if (run_ssfilter(f
->f
, &st
) == 0)
3068 sock_state_print(&st
, "nl");
3070 if (resolve_services
)
3071 prot_name
= nl_proto_n2a(prot
, prot_buf
, sizeof(prot_buf
));
3073 prot_name
= int_to_str(prot
, prot_buf
);
3077 } else if (resolve_services
) {
3081 strncpy(procname
, "kernel", 6);
3082 } else if (pid
> 0) {
3084 sprintf(procname
, "%s/%d/stat",
3085 getenv("PROC_ROOT") ? : "/proc", pid
);
3086 if ((fp
= fopen(procname
, "r")) != NULL
) {
3087 if (fscanf(fp
, "%*d (%[^)])", procname
) == 1) {
3088 sprintf(procname
+strlen(procname
), "/%d", pid
);
3095 int_to_str(pid
, procname
);
3097 int_to_str(pid
, procname
);
3100 sock_addr_print(prot_name
, ":", procname
, NULL
);
3102 if (state
== NETLINK_CONNECTED
) {
3103 char dst_group_buf
[30];
3104 char dst_pid_buf
[30];
3105 sock_addr_print(int_to_str(dst_group
, dst_group_buf
), ":",
3106 int_to_str(dst_pid
, dst_pid_buf
), NULL
);
3108 sock_addr_print("", "*", "", NULL
);
3111 char *pid_context
= NULL
;
3112 if (show_proc_ctx
) {
3113 /* The pid value will either be:
3114 * 0 if destination kernel - show kernel initial context.
3115 * A valid process pid - use getpidcon.
3116 * A unique value allocated by the kernel or netlink user
3117 * to the process - show context as "not available".
3120 security_get_initial_context("kernel", &pid_context
);
3122 getpidcon(pid
, &pid_context
);
3124 if (pid_context
!= NULL
) {
3125 printf("proc_ctx=%-*s ", serv_width
, pid_context
);
3128 printf("proc_ctx=%-*s ", serv_width
, "unavailable");
3133 printf(" sk=%llx cb=%llx groups=0x%08x", sk
, cb
, groups
);
3140 static int netlink_show_sock(const struct sockaddr_nl
*addr
,
3141 struct nlmsghdr
*nlh
, void *arg
)
3143 struct filter
*f
= (struct filter
*)arg
;
3144 struct netlink_diag_msg
*r
= NLMSG_DATA(nlh
);
3145 struct rtattr
*tb
[NETLINK_DIAG_MAX
+1];
3147 unsigned long groups
= 0;
3149 parse_rtattr(tb
, NETLINK_DIAG_MAX
, (struct rtattr
*)(r
+1),
3150 nlh
->nlmsg_len
- NLMSG_LENGTH(sizeof(*r
)));
3152 if (tb
[NETLINK_DIAG_GROUPS
] && RTA_PAYLOAD(tb
[NETLINK_DIAG_GROUPS
]))
3153 groups
= *(unsigned long *) RTA_DATA(tb
[NETLINK_DIAG_GROUPS
]);
3155 if (tb
[NETLINK_DIAG_MEMINFO
]) {
3156 const __u32
*skmeminfo
;
3157 skmeminfo
= RTA_DATA(tb
[NETLINK_DIAG_MEMINFO
]);
3159 rq
= skmeminfo
[SK_MEMINFO_RMEM_ALLOC
];
3160 wq
= skmeminfo
[SK_MEMINFO_WMEM_ALLOC
];
3163 if (netlink_show_one(f
, r
->ndiag_protocol
, r
->ndiag_portid
, groups
,
3164 r
->ndiag_state
, r
->ndiag_dst_portid
, r
->ndiag_dst_group
,
3171 print_skmeminfo(tb
, NETLINK_DIAG_MEMINFO
);
3178 static int netlink_show_netlink(struct filter
*f
)
3180 DIAG_REQUEST(req
, struct netlink_diag_req r
);
3182 req
.r
.sdiag_family
= AF_NETLINK
;
3183 req
.r
.sdiag_protocol
= NDIAG_PROTO_ALL
;
3184 req
.r
.ndiag_show
= NDIAG_SHOW_GROUPS
| NDIAG_SHOW_MEMINFO
;
3186 return handle_netlink_request(f
, &req
.nlh
, sizeof(req
), netlink_show_sock
);
3189 static int netlink_show(struct filter
*f
)
3196 unsigned long long sk
, cb
;
3198 if (!filter_af_get(f
, AF_NETLINK
) || !(f
->states
& (1 << SS_CLOSE
)))
3201 if (!getenv("PROC_NET_NETLINK") && !getenv("PROC_ROOT") &&
3202 netlink_show_netlink(f
) == 0)
3205 if ((fp
= net_netlink_open()) == NULL
)
3207 fgets(buf
, sizeof(buf
)-1, fp
);
3209 while (fgets(buf
, sizeof(buf
)-1, fp
)) {
3210 sscanf(buf
, "%llx %d %d %x %d %d %llx %d",
3212 &prot
, &pid
, &groups
, &rq
, &wq
, &cb
, &rc
);
3214 netlink_show_one(f
, prot
, pid
, groups
, 0, 0, 0, rq
, wq
, sk
, cb
);
3225 static int get_snmp_int(char *proto
, char *key
, int *result
)
3229 int protolen
= strlen(proto
);
3230 int keylen
= strlen(key
);
3234 if ((fp
= net_snmp_open()) == NULL
)
3237 while (fgets(buf
, sizeof(buf
), fp
) != NULL
) {
3240 if (memcmp(buf
, proto
, protolen
))
3242 while ((p
= strchr(p
, ' ')) != NULL
) {
3245 if (memcmp(p
, key
, keylen
) == 0 &&
3246 (p
[keylen
] == ' ' || p
[keylen
] == '\n'))
3249 if (fgets(buf
, sizeof(buf
), fp
) == NULL
)
3251 if (memcmp(buf
, proto
, protolen
))
3254 while ((p
= strchr(p
, ' ')) != NULL
) {
3257 sscanf(p
, "%d", result
);
3270 /* Get stats from sockstat */
3291 static void get_sockstat_line(char *line
, struct ssummary
*s
)
3293 char id
[256], rem
[256];
3295 if (sscanf(line
, "%[^ ] %[^\n]\n", id
, rem
) != 2)
3298 if (strcmp(id
, "sockets:") == 0)
3299 sscanf(rem
, "%*s%d", &s
->socks
);
3300 else if (strcmp(id
, "UDP:") == 0)
3301 sscanf(rem
, "%*s%d", &s
->udp4
);
3302 else if (strcmp(id
, "UDP6:") == 0)
3303 sscanf(rem
, "%*s%d", &s
->udp6
);
3304 else if (strcmp(id
, "RAW:") == 0)
3305 sscanf(rem
, "%*s%d", &s
->raw4
);
3306 else if (strcmp(id
, "RAW6:") == 0)
3307 sscanf(rem
, "%*s%d", &s
->raw6
);
3308 else if (strcmp(id
, "TCP6:") == 0)
3309 sscanf(rem
, "%*s%d", &s
->tcp6_hashed
);
3310 else if (strcmp(id
, "FRAG:") == 0)
3311 sscanf(rem
, "%*s%d%*s%d", &s
->frag4
, &s
->frag4_mem
);
3312 else if (strcmp(id
, "FRAG6:") == 0)
3313 sscanf(rem
, "%*s%d%*s%d", &s
->frag6
, &s
->frag6_mem
);
3314 else if (strcmp(id
, "TCP:") == 0)
3315 sscanf(rem
, "%*s%d%*s%d%*s%d%*s%d%*s%d",
3317 &s
->tcp_orphans
, &s
->tcp_tws
, &s
->tcp_total
, &s
->tcp_mem
);
3320 static int get_sockstat(struct ssummary
*s
)
3325 memset(s
, 0, sizeof(*s
));
3327 if ((fp
= net_sockstat_open()) == NULL
)
3329 while(fgets(buf
, sizeof(buf
), fp
) != NULL
)
3330 get_sockstat_line(buf
, s
);
3333 if ((fp
= net_sockstat6_open()) == NULL
)
3335 while(fgets(buf
, sizeof(buf
), fp
) != NULL
)
3336 get_sockstat_line(buf
, s
);
3342 static int print_summary(void)
3347 if (get_sockstat(&s
) < 0)
3348 perror("ss: get_sockstat");
3349 if (get_snmp_int("Tcp:", "CurrEstab", &sn
.tcp_estab
) < 0)
3350 perror("ss: get_snmpstat");
3352 get_slabstat(&slabstat
);
3354 printf("Total: %d (kernel %d)\n", s
.socks
, slabstat
.socks
);
3356 printf("TCP: %d (estab %d, closed %d, orphaned %d, synrecv %d, timewait %d/%d), ports %d\n",
3357 s
.tcp_total
+ slabstat
.tcp_syns
+ s
.tcp_tws
,
3359 s
.tcp_total
- (s
.tcp4_hashed
+s
.tcp6_hashed
-s
.tcp_tws
),
3362 s
.tcp_tws
, slabstat
.tcp_tws
,
3367 printf("Transport Total IP IPv6\n");
3368 printf("* %-9d %-9s %-9s\n", slabstat
.socks
, "-", "-");
3369 printf("RAW %-9d %-9d %-9d\n", s
.raw4
+s
.raw6
, s
.raw4
, s
.raw6
);
3370 printf("UDP %-9d %-9d %-9d\n", s
.udp4
+s
.udp6
, s
.udp4
, s
.udp6
);
3371 printf("TCP %-9d %-9d %-9d\n", s
.tcp4_hashed
+s
.tcp6_hashed
, s
.tcp4_hashed
, s
.tcp6_hashed
);
3372 printf("INET %-9d %-9d %-9d\n",
3373 s
.raw4
+s
.udp4
+s
.tcp4_hashed
+
3374 s
.raw6
+s
.udp6
+s
.tcp6_hashed
,
3375 s
.raw4
+s
.udp4
+s
.tcp4_hashed
,
3376 s
.raw6
+s
.udp6
+s
.tcp6_hashed
);
3377 printf("FRAG %-9d %-9d %-9d\n", s
.frag4
+s
.frag6
, s
.frag4
, s
.frag6
);
3384 static void _usage(FILE *dest
)
3387 "Usage: ss [ OPTIONS ]\n"
3388 " ss [ OPTIONS ] [ FILTER ]\n"
3389 " -h, --help this message\n"
3390 " -V, --version output version information\n"
3391 " -n, --numeric don't resolve service names\n"
3392 " -r, --resolve resolve host names\n"
3393 " -a, --all display all sockets\n"
3394 " -l, --listening display listening sockets\n"
3395 " -o, --options show timer information\n"
3396 " -e, --extended show detailed socket information\n"
3397 " -m, --memory show socket memory usage\n"
3398 " -p, --processes show process using socket\n"
3399 " -i, --info show internal TCP information\n"
3400 " -s, --summary show socket usage summary\n"
3401 " -b, --bpf show bpf filter socket information\n"
3402 " -Z, --context display process SELinux security contexts\n"
3403 " -z, --contexts display process and socket SELinux security contexts\n"
3404 " -N, --net switch to the specified network namespace name\n"
3406 " -4, --ipv4 display only IP version 4 sockets\n"
3407 " -6, --ipv6 display only IP version 6 sockets\n"
3408 " -0, --packet display PACKET sockets\n"
3409 " -t, --tcp display only TCP sockets\n"
3410 " -u, --udp display only UDP sockets\n"
3411 " -d, --dccp display only DCCP sockets\n"
3412 " -w, --raw display only RAW sockets\n"
3413 " -x, --unix display only Unix domain sockets\n"
3414 " -f, --family=FAMILY display sockets of type FAMILY\n"
3416 " -A, --query=QUERY, --socket=QUERY\n"
3417 " QUERY := {all|inet|tcp|udp|raw|unix|unix_dgram|unix_stream|unix_seqpacket|packet|netlink}[,QUERY]\n"
3419 " -D, --diag=FILE Dump raw information about TCP sockets to FILE\n"
3420 " -F, --filter=FILE read filter information from FILE\n"
3421 " FILTER := [ state STATE-FILTER ] [ EXPRESSION ]\n"
3422 " STATE-FILTER := {all|connected|synchronized|bucket|big|TCP-STATES}\n"
3423 " TCP-STATES := {established|syn-sent|syn-recv|fin-wait-{1,2}|time-wait|closed|close-wait|last-ack|listen|closing}\n"
3424 " connected := {established|syn-sent|syn-recv|fin-wait-{1,2}|time-wait|close-wait|last-ack|closing}\n"
3425 " synchronized := {established|syn-recv|fin-wait-{1,2}|time-wait|close-wait|last-ack|closing}\n"
3426 " bucket := {syn-recv|time-wait}\n"
3427 " big := {established|syn-sent|fin-wait-{1,2}|closed|close-wait|last-ack|listen|closing}\n"
3431 static void help(void) __attribute__((noreturn
));
3432 static void help(void)
3438 static void usage(void) __attribute__((noreturn
));
3439 static void usage(void)
3446 static int scan_state(const char *state
)
3449 if (strcasecmp(state
, "close") == 0 ||
3450 strcasecmp(state
, "closed") == 0)
3451 return (1<<SS_CLOSE
);
3452 if (strcasecmp(state
, "syn-rcv") == 0)
3453 return (1<<SS_SYN_RECV
);
3454 if (strcasecmp(state
, "established") == 0)
3455 return (1<<SS_ESTABLISHED
);
3456 if (strcasecmp(state
, "all") == 0)
3458 if (strcasecmp(state
, "connected") == 0)
3459 return SS_ALL
& ~((1<<SS_CLOSE
)|(1<<SS_LISTEN
));
3460 if (strcasecmp(state
, "synchronized") == 0)
3461 return SS_ALL
& ~((1<<SS_CLOSE
)|(1<<SS_LISTEN
)|(1<<SS_SYN_SENT
));
3462 if (strcasecmp(state
, "bucket") == 0)
3463 return (1<<SS_SYN_RECV
)|(1<<SS_TIME_WAIT
);
3464 if (strcasecmp(state
, "big") == 0)
3465 return SS_ALL
& ~((1<<SS_SYN_RECV
)|(1<<SS_TIME_WAIT
));
3466 for (i
=0; i
<SS_MAX
; i
++) {
3467 if (strcasecmp(state
, sstate_namel
[i
]) == 0)
3471 fprintf(stderr
, "ss: wrong state name: %s\n", state
);
3475 static const struct option long_opts
[] = {
3476 { "numeric", 0, 0, 'n' },
3477 { "resolve", 0, 0, 'r' },
3478 { "options", 0, 0, 'o' },
3479 { "extended", 0, 0, 'e' },
3480 { "memory", 0, 0, 'm' },
3481 { "info", 0, 0, 'i' },
3482 { "processes", 0, 0, 'p' },
3483 { "bpf", 0, 0, 'b' },
3484 { "dccp", 0, 0, 'd' },
3485 { "tcp", 0, 0, 't' },
3486 { "udp", 0, 0, 'u' },
3487 { "raw", 0, 0, 'w' },
3488 { "unix", 0, 0, 'x' },
3489 { "all", 0, 0, 'a' },
3490 { "listening", 0, 0, 'l' },
3491 { "ipv4", 0, 0, '4' },
3492 { "ipv6", 0, 0, '6' },
3493 { "packet", 0, 0, '0' },
3494 { "family", 1, 0, 'f' },
3495 { "socket", 1, 0, 'A' },
3496 { "query", 1, 0, 'A' },
3497 { "summary", 0, 0, 's' },
3498 { "diag", 1, 0, 'D' },
3499 { "filter", 1, 0, 'F' },
3500 { "version", 0, 0, 'V' },
3501 { "help", 0, 0, 'h' },
3502 { "context", 0, 0, 'Z' },
3503 { "contexts", 0, 0, 'z' },
3504 { "net", 1, 0, 'N' },
3509 int main(int argc
, char *argv
[])
3514 const char *dump_tcpdiag
= NULL
;
3515 FILE *filter_fp
= NULL
;
3517 int state_filter
= 0;
3519 while ((ch
= getopt_long(argc
, argv
, "dhaletuwxnro460spbf:miA:D:F:vVzZN:",
3520 long_opts
, NULL
)) != EOF
) {
3523 resolve_services
= 0;
3543 user_ent_hash_build();
3550 filter_db_set(¤t_filter
, DCCP_DB
);
3553 filter_db_set(¤t_filter
, TCP_DB
);
3556 filter_db_set(¤t_filter
, UDP_DB
);
3559 filter_db_set(¤t_filter
, RAW_DB
);
3562 filter_af_set(¤t_filter
, AF_UNIX
);
3565 state_filter
= SS_ALL
;
3568 state_filter
= (1 << SS_LISTEN
) | (1 << SS_CLOSE
);
3571 filter_af_set(¤t_filter
, AF_INET
);
3574 filter_af_set(¤t_filter
, AF_INET6
);
3577 filter_af_set(¤t_filter
, AF_PACKET
);
3580 if (strcmp(optarg
, "inet") == 0)
3581 filter_af_set(¤t_filter
, AF_INET
);
3582 else if (strcmp(optarg
, "inet6") == 0)
3583 filter_af_set(¤t_filter
, AF_INET6
);
3584 else if (strcmp(optarg
, "link") == 0)
3585 filter_af_set(¤t_filter
, AF_PACKET
);
3586 else if (strcmp(optarg
, "unix") == 0)
3587 filter_af_set(¤t_filter
, AF_UNIX
);
3588 else if (strcmp(optarg
, "netlink") == 0)
3589 filter_af_set(¤t_filter
, AF_NETLINK
);
3590 else if (strcmp(optarg
, "help") == 0)
3593 fprintf(stderr
, "ss: \"%s\" is invalid family\n",
3602 current_filter
.dbs
= 0;
3608 if ((p1
= strchr(p
, ',')) != NULL
)
3610 if (strcmp(p
, "all") == 0) {
3611 filter_default_dbs(¤t_filter
);
3612 } else if (strcmp(p
, "inet") == 0) {
3613 filter_db_set(¤t_filter
, UDP_DB
);
3614 filter_db_set(¤t_filter
, DCCP_DB
);
3615 filter_db_set(¤t_filter
, TCP_DB
);
3616 filter_db_set(¤t_filter
, RAW_DB
);
3617 } else if (strcmp(p
, "udp") == 0) {
3618 filter_db_set(¤t_filter
, UDP_DB
);
3619 } else if (strcmp(p
, "dccp") == 0) {
3620 filter_db_set(¤t_filter
, DCCP_DB
);
3621 } else if (strcmp(p
, "tcp") == 0) {
3622 filter_db_set(¤t_filter
, TCP_DB
);
3623 } else if (strcmp(p
, "raw") == 0) {
3624 filter_db_set(¤t_filter
, RAW_DB
);
3625 } else if (strcmp(p
, "unix") == 0) {
3626 filter_db_set(¤t_filter
, UNIX_ST_DB
);
3627 filter_db_set(¤t_filter
, UNIX_DG_DB
);
3628 filter_db_set(¤t_filter
, UNIX_SQ_DB
);
3629 } else if (strcasecmp(p
, "unix_stream") == 0 ||
3630 strcmp(p
, "u_str") == 0) {
3631 filter_db_set(¤t_filter
, UNIX_ST_DB
);
3632 } else if (strcasecmp(p
, "unix_dgram") == 0 ||
3633 strcmp(p
, "u_dgr") == 0) {
3634 filter_db_set(¤t_filter
, UNIX_DG_DB
);
3635 } else if (strcasecmp(p
, "unix_seqpacket") == 0 ||
3636 strcmp(p
, "u_seq") == 0) {
3637 filter_db_set(¤t_filter
, UNIX_SQ_DB
);
3638 } else if (strcmp(p
, "packet") == 0) {
3639 filter_db_set(¤t_filter
, PACKET_R_DB
);
3640 filter_db_set(¤t_filter
, PACKET_DG_DB
);
3641 } else if (strcmp(p
, "packet_raw") == 0 ||
3642 strcmp(p
, "p_raw") == 0) {
3643 filter_db_set(¤t_filter
, PACKET_R_DB
);
3644 } else if (strcmp(p
, "packet_dgram") == 0 ||
3645 strcmp(p
, "p_dgr") == 0) {
3646 filter_db_set(¤t_filter
, PACKET_DG_DB
);
3647 } else if (strcmp(p
, "netlink") == 0) {
3648 filter_db_set(¤t_filter
, NETLINK_DB
);
3650 fprintf(stderr
, "ss: \"%s\" is illegal socket table id\n", p
);
3661 dump_tcpdiag
= optarg
;
3665 fprintf(stderr
, "More than one filter file\n");
3668 if (optarg
[0] == '-')
3671 filter_fp
= fopen(optarg
, "r");
3673 perror("fopen filter file");
3679 printf("ss utility, iproute2-ss%s\n", SNAPSHOT
);
3684 if (is_selinux_enabled() <= 0) {
3685 fprintf(stderr
, "ss: SELinux is not enabled.\n");
3689 user_ent_hash_build();
3692 if (netns_switch(optarg
))
3708 if (do_default
&& argc
== 0)
3712 /* Now parse filter... */
3713 if (argc
== 0 && filter_fp
) {
3714 if (ssfilter_parse(¤t_filter
.f
, 0, NULL
, filter_fp
))
3719 if (strcmp(*argv
, "state") == 0) {
3723 state_filter
|= scan_state(*argv
);
3725 } else if (strcmp(*argv
, "exclude") == 0 ||
3726 strcmp(*argv
, "excl") == 0) {
3729 state_filter
= SS_ALL
;
3730 state_filter
&= ~scan_state(*argv
);
3739 state_filter
= state_filter
? state_filter
: SS_CONN
;
3740 filter_default_dbs(¤t_filter
);
3743 filter_states_set(¤t_filter
, state_filter
);
3744 filter_merge_defaults(¤t_filter
);
3746 if (resolve_services
&& resolve_hosts
&&
3747 (current_filter
.dbs
&(UNIX_DBM
|(1<<TCP_DB
)|(1<<UDP_DB
)|(1<<DCCP_DB
))))
3748 init_service_resolver();
3751 if (current_filter
.dbs
== 0) {
3752 fprintf(stderr
, "ss: no socket tables to show with such filter.\n");
3755 if (current_filter
.families
== 0) {
3756 fprintf(stderr
, "ss: no families to show with such filter.\n");
3759 if (current_filter
.states
== 0) {
3760 fprintf(stderr
, "ss: no socket states to show with such filter.\n");
3765 FILE *dump_fp
= stdout
;
3766 if (!(current_filter
.dbs
& (1<<TCP_DB
))) {
3767 fprintf(stderr
, "ss: tcpdiag dump requested and no tcp in filter.\n");
3770 if (dump_tcpdiag
[0] != '-') {
3771 dump_fp
= fopen(dump_tcpdiag
, "w");
3772 if (!dump_tcpdiag
) {
3773 perror("fopen dump file");
3777 inet_show_netlink(¤t_filter
, dump_fp
, IPPROTO_TCP
);
3782 if (ssfilter_parse(¤t_filter
.f
, argc
, argv
, filter_fp
))
3786 if (current_filter
.dbs
&(current_filter
.dbs
-1))
3790 if (current_filter
.states
&(current_filter
.states
-1))
3794 if (isatty(STDOUT_FILENO
)) {
3797 if (ioctl(STDOUT_FILENO
, TIOCGWINSZ
, &w
) != -1) {
3799 screen_width
= w
.ws_col
;
3803 addrp_width
= screen_width
;
3804 addrp_width
-= netid_width
+1;
3805 addrp_width
-= state_width
+1;
3808 if (addrp_width
&1) {
3811 else if (state_width
)
3818 serv_width
= resolve_services
? 7 : 5;
3820 if (addrp_width
< 15+serv_width
+1)
3821 addrp_width
= 15+serv_width
+1;
3823 addr_width
= addrp_width
- serv_width
- 1;
3826 printf("%-*s ", netid_width
, "Netid");
3828 printf("%-*s ", state_width
, "State");
3829 printf("%-6s %-6s ", "Recv-Q", "Send-Q");
3831 /* Make enough space for the local/remote port field */
3835 printf("%*s:%-*s %*s:%-*s\n",
3836 addr_width
, "Local Address", serv_width
, "Port",
3837 addr_width
, "Peer Address", serv_width
, "Port");
3841 if (current_filter
.dbs
& (1<<NETLINK_DB
))
3842 netlink_show(¤t_filter
);
3843 if (current_filter
.dbs
& PACKET_DBM
)
3844 packet_show(¤t_filter
);
3845 if (current_filter
.dbs
& UNIX_DBM
)
3846 unix_show(¤t_filter
);
3847 if (current_filter
.dbs
& (1<<RAW_DB
))
3848 raw_show(¤t_filter
);
3849 if (current_filter
.dbs
& (1<<UDP_DB
))
3850 udp_show(¤t_filter
);
3851 if (current_filter
.dbs
& (1<<TCP_DB
))
3852 tcp_show(¤t_filter
, IPPROTO_TCP
);
3853 if (current_filter
.dbs
& (1<<DCCP_DB
))
3854 tcp_show(¤t_filter
, IPPROTO_DCCP
);
3856 if (show_users
|| show_proc_ctx
|| show_sock_ctx
)