]>
git.proxmox.com Git - mirror_iproute2.git/blob - misc/ss.c
d3c4fa6597ba62d9a106a56fcc4b753e49f37b75
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>
32 #include "libnetlink.h"
35 #include <linux/tcp.h>
36 #include <linux/sock_diag.h>
37 #include <linux/inet_diag.h>
38 #include <linux/unix_diag.h>
39 #include <linux/netdevice.h> /* for MAX_ADDR_LEN */
40 #include <linux/filter.h>
41 #include <linux/packet_diag.h>
42 #include <linux/netlink_diag.h>
45 #include <selinux/selinux.h>
47 /* Stubs for SELinux functions */
48 static int is_selinux_enabled(void)
53 static int getpidcon(pid_t pid
, char **context
)
59 static int getfilecon(char *path
, char **context
)
65 static int security_get_initial_context(char *name
, char **context
)
72 int resolve_hosts
= 0;
73 int resolve_services
= 1;
74 int preferred_family
= AF_UNSPEC
;
81 int show_proc_ctx
= 0;
82 int show_sock_ctx
= 0;
83 /* If show_users & show_proc_ctx only do user_ent_hash_build() once */
84 int user_ent_hash_build_init
= 0;
93 static const char *TCP_PROTO
= "tcp";
94 static const char *UDP_PROTO
= "udp";
95 static const char *RAW_PROTO
= "raw";
96 static const char *dg_proto
= NULL
;
113 #define PACKET_DBM ((1<<PACKET_DG_DB)|(1<<PACKET_R_DB))
114 #define UNIX_DBM ((1<<UNIX_DG_DB)|(1<<UNIX_ST_DB)|(1<<UNIX_SQ_DB))
115 #define ALL_DB ((1<<MAX_DB)-1)
133 #define SS_ALL ((1<<SS_MAX)-1)
135 #include "ssfilter.h"
145 struct filter default_filter
= {
147 .states
= SS_ALL
& ~((1<<SS_LISTEN
)|(1<<SS_CLOSE
)|(1<<SS_TIME_WAIT
)|(1<<SS_SYN_RECV
)),
148 .families
= (1<<AF_INET
)|(1<<AF_INET6
),
151 struct filter current_filter
;
153 static FILE *generic_proc_open(const char *env
, const char *name
)
155 const char *p
= getenv(env
);
159 p
= getenv("PROC_ROOT") ? : "/proc";
160 snprintf(store
, sizeof(store
)-1, "%s/%s", p
, name
);
164 return fopen(p
, "r");
167 static FILE *net_tcp_open(void)
169 return generic_proc_open("PROC_NET_TCP", "net/tcp");
172 static FILE *net_tcp6_open(void)
174 return generic_proc_open("PROC_NET_TCP6", "net/tcp6");
177 static FILE *net_udp_open(void)
179 return generic_proc_open("PROC_NET_UDP", "net/udp");
182 static FILE *net_udp6_open(void)
184 return generic_proc_open("PROC_NET_UDP6", "net/udp6");
187 static FILE *net_raw_open(void)
189 return generic_proc_open("PROC_NET_RAW", "net/raw");
192 static FILE *net_raw6_open(void)
194 return generic_proc_open("PROC_NET_RAW6", "net/raw6");
197 static FILE *net_unix_open(void)
199 return generic_proc_open("PROC_NET_UNIX", "net/unix");
202 static FILE *net_packet_open(void)
204 return generic_proc_open("PROC_NET_PACKET", "net/packet");
207 static FILE *net_netlink_open(void)
209 return generic_proc_open("PROC_NET_NETLINK", "net/netlink");
212 static FILE *slabinfo_open(void)
214 return generic_proc_open("PROC_SLABINFO", "slabinfo");
217 static FILE *net_sockstat_open(void)
219 return generic_proc_open("PROC_NET_SOCKSTAT", "net/sockstat");
222 static FILE *net_sockstat6_open(void)
224 return generic_proc_open("PROC_NET_SOCKSTAT6", "net/sockstat6");
227 static FILE *net_snmp_open(void)
229 return generic_proc_open("PROC_NET_SNMP", "net/snmp");
232 static FILE *ephemeral_ports_open(void)
234 return generic_proc_open("PROC_IP_LOCAL_PORT_RANGE", "sys/net/ipv4/ip_local_port_range");
238 struct user_ent
*next
;
247 #define USER_ENT_HASH_SIZE 256
248 struct user_ent
*user_ent_hash
[USER_ENT_HASH_SIZE
];
250 static int user_ent_hashfn(unsigned int ino
)
252 int val
= (ino
>> 24) ^ (ino
>> 16) ^ (ino
>> 8) ^ ino
;
254 return val
& (USER_ENT_HASH_SIZE
- 1);
257 static void user_ent_add(unsigned int ino
, char *process
,
262 struct user_ent
*p
, **pp
;
264 p
= malloc(sizeof(struct user_ent
));
266 fprintf(stderr
, "ss: failed to malloc buffer\n");
273 p
->process
= strdup(process
);
274 p
->process_ctx
= strdup(proc_ctx
);
275 p
->socket_ctx
= strdup(sock_ctx
);
277 pp
= &user_ent_hash
[user_ent_hashfn(ino
)];
282 static void user_ent_destroy(void)
284 struct user_ent
*p
, *p_next
;
287 while (cnt
!= USER_ENT_HASH_SIZE
) {
288 p
= user_ent_hash
[cnt
];
291 free(p
->process_ctx
);
301 static void user_ent_hash_build(void)
303 const char *root
= getenv("PROC_ROOT") ? : "/proc/";
310 const char *no_ctx
= "unavailable";
312 /* If show_users & show_proc_ctx set only do this once */
313 if (user_ent_hash_build_init
!= 0)
316 user_ent_hash_build_init
= 1;
319 if (strlen(name
) == 0 || name
[strlen(name
)-1] != '/')
322 nameoff
= strlen(name
);
328 while ((d
= readdir(dir
)) != NULL
) {
336 if (sscanf(d
->d_name
, "%d%c", &pid
, &crap
) != 1)
339 if (getpidcon(pid
, &pid_context
) != 0)
340 pid_context
= strdup(no_ctx
);
342 sprintf(name
+ nameoff
, "%d/fd/", pid
);
344 if ((dir1
= opendir(name
)) == NULL
)
350 while ((d1
= readdir(dir1
)) != NULL
) {
351 const char *pattern
= "socket:[";
358 if (sscanf(d1
->d_name
, "%d%c", &fd
, &crap
) != 1)
361 sprintf(name
+pos
, "%d", fd
);
363 link_len
= readlink(name
, lnk
, sizeof(lnk
)-1);
366 lnk
[link_len
] = '\0';
368 if (strncmp(lnk
, pattern
, strlen(pattern
)))
371 sscanf(lnk
, "socket:[%u]", &ino
);
373 snprintf(tmp
, sizeof(tmp
), "%s/%d/fd/%s",
374 root
, pid
, d1
->d_name
);
376 if (getfilecon(tmp
, &sock_context
) <= 0)
377 sock_context
= strdup(no_ctx
);
382 snprintf(tmp
, sizeof(tmp
), "%s/%d/stat",
384 if ((fp
= fopen(tmp
, "r")) != NULL
) {
385 fscanf(fp
, "%*d (%[^)])", p
);
389 user_ent_add(ino
, p
, pid
, fd
,
390 pid_context
, sock_context
);
405 #define ENTRY_BUF_SIZE 512
406 static int find_entry(unsigned ino
, char **buf
, int type
)
411 char **new_buf
= buf
;
412 int len
, new_buf_len
;
419 p
= user_ent_hash
[user_ent_hashfn(ino
)];
426 ptr
= *buf
+ buf_used
;
429 len
= snprintf(ptr
, buf_len
- buf_used
,
430 "(\"%s\",pid=%d,fd=%d),",
431 p
->process
, p
->pid
, p
->fd
);
434 len
= snprintf(ptr
, buf_len
- buf_used
,
435 "(\"%s\",pid=%d,proc_ctx=%s,fd=%d),",
437 p
->process_ctx
, p
->fd
);
440 len
= snprintf(ptr
, buf_len
- buf_used
,
441 "(\"%s\",pid=%d,proc_ctx=%s,fd=%d,sock_ctx=%s),",
443 p
->process_ctx
, p
->fd
,
447 fprintf(stderr
, "ss: invalid type: %d\n", type
);
451 if (len
< 0 || len
>= buf_len
- buf_used
) {
452 new_buf_len
= buf_len
+ ENTRY_BUF_SIZE
;
453 *new_buf
= realloc(*buf
, new_buf_len
);
455 fprintf(stderr
, "ss: failed to malloc buffer\n");
459 buf_len
= new_buf_len
;
471 ptr
= *buf
+ buf_used
;
477 /* Get stats from slab */
488 struct slabstat slabstat
;
490 static const char *slabstat_ids
[] =
499 static int get_slabstat(struct slabstat
*s
)
505 memset(s
, 0, sizeof(*s
));
507 fp
= slabinfo_open();
511 cnt
= sizeof(*s
)/sizeof(int);
513 fgets(buf
, sizeof(buf
), fp
);
514 while(fgets(buf
, sizeof(buf
), fp
) != NULL
) {
516 for (i
=0; i
<sizeof(slabstat_ids
)/sizeof(slabstat_ids
[0]); i
++) {
517 if (memcmp(buf
, slabstat_ids
[i
], strlen(slabstat_ids
[i
])) == 0) {
518 sscanf(buf
, "%*s%d", ((int *)s
) + i
);
531 static const char *sstate_name
[] = {
533 [SS_ESTABLISHED
] = "ESTAB",
534 [SS_SYN_SENT
] = "SYN-SENT",
535 [SS_SYN_RECV
] = "SYN-RECV",
536 [SS_FIN_WAIT1
] = "FIN-WAIT-1",
537 [SS_FIN_WAIT2
] = "FIN-WAIT-2",
538 [SS_TIME_WAIT
] = "TIME-WAIT",
539 [SS_CLOSE
] = "UNCONN",
540 [SS_CLOSE_WAIT
] = "CLOSE-WAIT",
541 [SS_LAST_ACK
] = "LAST-ACK",
542 [SS_LISTEN
] = "LISTEN",
543 [SS_CLOSING
] = "CLOSING",
546 static const char *sstate_namel
[] = {
548 [SS_ESTABLISHED
] = "established",
549 [SS_SYN_SENT
] = "syn-sent",
550 [SS_SYN_RECV
] = "syn-recv",
551 [SS_FIN_WAIT1
] = "fin-wait-1",
552 [SS_FIN_WAIT2
] = "fin-wait-2",
553 [SS_TIME_WAIT
] = "time-wait",
554 [SS_CLOSE
] = "unconnected",
555 [SS_CLOSE_WAIT
] = "close-wait",
556 [SS_LAST_ACK
] = "last-ack",
557 [SS_LISTEN
] = "listening",
558 [SS_CLOSING
] = "closing",
576 unsigned long long sk
;
577 int rto
, ato
, qack
, cwnd
, ssthresh
;
580 static const char *tmr_name
[] = {
589 static const char *print_ms_timer(int timeout
)
592 int secs
, msecs
, minutes
;
598 msecs
= timeout
%1000;
602 snprintf(buf
, sizeof(buf
)-16, "%dmin", minutes
);
609 sprintf(buf
+strlen(buf
), "%d%s", secs
, msecs
? "." : "sec");
612 sprintf(buf
+strlen(buf
), "%03dms", msecs
);
616 static const char *print_hz_timer(int timeout
)
618 int hz
= get_user_hz();
619 return print_ms_timer(((timeout
*1000) + hz
-1)/hz
);
630 struct scache
*rlist
;
632 static void init_service_resolver(void)
635 FILE *fp
= popen("/usr/sbin/rpcinfo -p 2>/dev/null", "r");
637 fgets(buf
, sizeof(buf
), fp
);
638 while (fgets(buf
, sizeof(buf
), fp
) != NULL
) {
639 unsigned int progn
, port
;
640 char proto
[128], prog
[128];
641 if (sscanf(buf
, "%u %*d %s %u %s", &progn
, proto
,
642 &port
, prog
+4) == 4) {
643 struct scache
*c
= malloc(sizeof(*c
));
646 memcpy(prog
, "rpc.", 4);
647 c
->name
= strdup(prog
);
648 if (strcmp(proto
, TCP_PROTO
) == 0)
649 c
->proto
= TCP_PROTO
;
650 else if (strcmp(proto
, UDP_PROTO
) == 0)
651 c
->proto
= UDP_PROTO
;
663 static int ip_local_port_min
, ip_local_port_max
;
665 /* Even do not try default linux ephemeral port ranges:
666 * default /etc/services contains so much of useless crap
667 * wouldbe "allocated" to this area that resolution
668 * is really harmful. I shrug each time when seeing
669 * "socks" or "cfinger" in dumps.
671 static int is_ephemeral(int port
)
673 if (!ip_local_port_min
) {
674 FILE *f
= ephemeral_ports_open();
677 &ip_local_port_min
, &ip_local_port_max
);
680 ip_local_port_min
= 1024;
681 ip_local_port_max
= 4999;
685 return (port
>= ip_local_port_min
&& port
<= ip_local_port_max
);
689 static const char *__resolve_service(int port
)
693 for (c
= rlist
; c
; c
= c
->next
) {
694 if (c
->port
== port
&& c
->proto
== dg_proto
)
698 if (!is_ephemeral(port
)) {
705 se
= getservbyport(htons(port
), dg_proto
);
714 static const char *resolve_service(int port
)
716 static char buf
[128];
717 static struct scache cache
[256];
725 if (resolve_services
) {
726 if (dg_proto
== RAW_PROTO
) {
727 return inet_proto_n2a(port
, buf
, sizeof(buf
));
731 int hash
= (port
^(((unsigned long)dg_proto
)>>2))&255;
733 for (c
= &cache
[hash
]; c
; c
= c
->next
) {
734 if (c
->port
== port
&&
735 c
->proto
== dg_proto
) {
742 if ((res
= __resolve_service(port
)) != NULL
) {
743 if ((c
= malloc(sizeof(*c
))) == NULL
)
754 c
->name
= strdup(res
);
755 c
->next
= cache
[hash
].next
;
756 cache
[hash
].next
= c
;
764 sprintf(buf
, "%u", port
);
768 static void formatted_print(const inet_prefix
*a
, int port
, unsigned int ifindex
)
771 const char *ap
= buf
;
774 est_len
= addr_width
;
776 if (a
->family
== AF_INET
) {
777 if (a
->data
[0] == 0) {
781 ap
= format_host(AF_INET
, 4, a
->data
, buf
, sizeof(buf
));
784 ap
= format_host(a
->family
, 16, a
->data
, buf
, sizeof(buf
));
785 est_len
= strlen(ap
);
786 if (est_len
<= addr_width
)
787 est_len
= addr_width
;
789 est_len
= addr_width
+ ((est_len
-addr_width
+3)/4)*4;
792 const char *ifname
= ll_index_to_name(ifindex
);
793 const int len
= strlen(ifname
) + 1; /* +1 for percent char */
795 printf("%*s%%%s:%-*s ", est_len
- len
, ap
, ifname
, serv_width
,
796 resolve_service(port
));
798 printf("%*s:%-*s ", est_len
, ap
, serv_width
, resolve_service(port
));
805 struct aafilter
*next
;
808 static int inet2_addr_match(const inet_prefix
*a
, const inet_prefix
*p
,
811 if (!inet_addr_match(a
, p
, plen
))
814 /* Cursed "v4 mapped" addresses: v4 mapped socket matches
815 * pure IPv4 rule, but v4-mapped rule selects only v4-mapped
817 if (p
->family
== AF_INET
&& a
->family
== AF_INET6
) {
818 if (a
->data
[0] == 0 && a
->data
[1] == 0 &&
819 a
->data
[2] == htonl(0xffff)) {
820 inet_prefix tmp
= *a
;
821 tmp
.data
[0] = a
->data
[3];
822 return inet_addr_match(&tmp
, p
, plen
);
828 static int unix_match(const inet_prefix
*a
, const inet_prefix
*p
)
830 char *addr
, *pattern
;
831 memcpy(&addr
, a
->data
, sizeof(addr
));
832 memcpy(&pattern
, p
->data
, sizeof(pattern
));
837 return !fnmatch(pattern
, addr
, 0);
840 static int run_ssfilter(struct ssfilter
*f
, struct tcpstat
*s
)
845 static int low
, high
=65535;
847 if (s
->local
.family
== AF_UNIX
) {
849 memcpy(&p
, s
->local
.data
, sizeof(p
));
850 return p
== NULL
|| (p
[0] == '@' && strlen(p
) == 6 &&
851 strspn(p
+1, "0123456789abcdef") == 5);
853 if (s
->local
.family
== AF_PACKET
)
854 return s
->lport
== 0 && s
->local
.data
== 0;
855 if (s
->local
.family
== AF_NETLINK
)
859 FILE *fp
= ephemeral_ports_open();
861 fscanf(fp
, "%d%d", &low
, &high
);
865 return s
->lport
>= low
&& s
->lport
<= high
;
869 struct aafilter
*a
= (void*)f
->pred
;
870 if (a
->addr
.family
== AF_UNIX
)
871 return unix_match(&s
->remote
, &a
->addr
);
872 if (a
->port
!= -1 && a
->port
!= s
->rport
)
874 if (a
->addr
.bitlen
) {
876 if (!inet2_addr_match(&s
->remote
, &a
->addr
, a
->addr
.bitlen
))
878 } while ((a
= a
->next
) != NULL
);
885 struct aafilter
*a
= (void*)f
->pred
;
886 if (a
->addr
.family
== AF_UNIX
)
887 return unix_match(&s
->local
, &a
->addr
);
888 if (a
->port
!= -1 && a
->port
!= s
->lport
)
890 if (a
->addr
.bitlen
) {
892 if (!inet2_addr_match(&s
->local
, &a
->addr
, a
->addr
.bitlen
))
894 } while ((a
= a
->next
) != NULL
);
901 struct aafilter
*a
= (void*)f
->pred
;
902 return s
->rport
>= a
->port
;
906 struct aafilter
*a
= (void*)f
->pred
;
907 return s
->rport
<= a
->port
;
911 struct aafilter
*a
= (void*)f
->pred
;
912 return s
->lport
>= a
->port
;
916 struct aafilter
*a
= (void*)f
->pred
;
917 return s
->lport
<= a
->port
;
920 /* Yup. It is recursion. Sorry. */
922 return run_ssfilter(f
->pred
, s
) && run_ssfilter(f
->post
, s
);
924 return run_ssfilter(f
->pred
, s
) || run_ssfilter(f
->post
, s
);
926 return !run_ssfilter(f
->pred
, s
);
932 /* Relocate external jumps by reloc. */
933 static void ssfilter_patch(char *a
, int len
, int reloc
)
936 struct inet_diag_bc_op
*op
= (struct inet_diag_bc_op
*)a
;
946 static int ssfilter_bytecompile(struct ssfilter
*f
, char **bytecode
)
951 if (!(*bytecode
=malloc(4))) abort();
952 ((struct inet_diag_bc_op
*)*bytecode
)[0] = (struct inet_diag_bc_op
){ INET_DIAG_BC_AUTO
, 4, 8 };
958 struct aafilter
*a
= (void*)f
->pred
;
961 int code
= (f
->type
== SSF_DCOND
? INET_DIAG_BC_D_COND
: INET_DIAG_BC_S_COND
);
964 for (b
=a
; b
; b
=b
->next
) {
965 len
+= 4 + sizeof(struct inet_diag_hostcond
);
966 if (a
->addr
.family
== AF_INET6
)
973 if (!(ptr
= malloc(len
))) abort();
975 for (b
=a
; b
; b
=b
->next
) {
976 struct inet_diag_bc_op
*op
= (struct inet_diag_bc_op
*)ptr
;
977 int alen
= (a
->addr
.family
== AF_INET6
? 16 : 4);
978 int oplen
= alen
+ 4 + sizeof(struct inet_diag_hostcond
);
979 struct inet_diag_hostcond
*cond
= (struct inet_diag_hostcond
*)(ptr
+4);
981 *op
= (struct inet_diag_bc_op
){ code
, oplen
, oplen
+4 };
982 cond
->family
= a
->addr
.family
;
983 cond
->port
= a
->port
;
984 cond
->prefix_len
= a
->addr
.bitlen
;
985 memcpy(cond
->addr
, a
->addr
.data
, alen
);
988 op
= (struct inet_diag_bc_op
*)ptr
;
989 *op
= (struct inet_diag_bc_op
){ INET_DIAG_BC_JMP
, 4, len
- (ptr
-*bytecode
)};
993 return ptr
- *bytecode
;
997 struct aafilter
*x
= (void*)f
->pred
;
998 if (!(*bytecode
=malloc(8))) abort();
999 ((struct inet_diag_bc_op
*)*bytecode
)[0] = (struct inet_diag_bc_op
){ INET_DIAG_BC_D_GE
, 8, 12 };
1000 ((struct inet_diag_bc_op
*)*bytecode
)[1] = (struct inet_diag_bc_op
){ 0, 0, x
->port
};
1005 struct aafilter
*x
= (void*)f
->pred
;
1006 if (!(*bytecode
=malloc(8))) abort();
1007 ((struct inet_diag_bc_op
*)*bytecode
)[0] = (struct inet_diag_bc_op
){ INET_DIAG_BC_D_LE
, 8, 12 };
1008 ((struct inet_diag_bc_op
*)*bytecode
)[1] = (struct inet_diag_bc_op
){ 0, 0, x
->port
};
1013 struct aafilter
*x
= (void*)f
->pred
;
1014 if (!(*bytecode
=malloc(8))) abort();
1015 ((struct inet_diag_bc_op
*)*bytecode
)[0] = (struct inet_diag_bc_op
){ INET_DIAG_BC_S_GE
, 8, 12 };
1016 ((struct inet_diag_bc_op
*)*bytecode
)[1] = (struct inet_diag_bc_op
){ 0, 0, x
->port
};
1021 struct aafilter
*x
= (void*)f
->pred
;
1022 if (!(*bytecode
=malloc(8))) abort();
1023 ((struct inet_diag_bc_op
*)*bytecode
)[0] = (struct inet_diag_bc_op
){ INET_DIAG_BC_S_LE
, 8, 12 };
1024 ((struct inet_diag_bc_op
*)*bytecode
)[1] = (struct inet_diag_bc_op
){ 0, 0, x
->port
};
1032 l1
= ssfilter_bytecompile(f
->pred
, &a1
);
1033 l2
= ssfilter_bytecompile(f
->post
, &a2
);
1034 if (!(a
= malloc(l1
+l2
))) abort();
1036 memcpy(a
+l1
, a2
, l2
);
1038 ssfilter_patch(a
, l1
, l2
);
1046 l1
= ssfilter_bytecompile(f
->pred
, &a1
);
1047 l2
= ssfilter_bytecompile(f
->post
, &a2
);
1048 if (!(a
= malloc(l1
+l2
+4))) abort();
1050 memcpy(a
+l1
+4, a2
, l2
);
1052 *(struct inet_diag_bc_op
*)(a
+l1
) = (struct inet_diag_bc_op
){ INET_DIAG_BC_JMP
, 4, l2
+4 };
1060 l1
= ssfilter_bytecompile(f
->pred
, &a1
);
1061 if (!(a
= malloc(l1
+4))) abort();
1064 *(struct inet_diag_bc_op
*)(a
+l1
) = (struct inet_diag_bc_op
){ INET_DIAG_BC_JMP
, 4, 8 };
1073 static int remember_he(struct aafilter
*a
, struct hostent
*he
)
1075 char **ptr
= he
->h_addr_list
;
1079 if (he
->h_addrtype
== AF_INET
)
1081 else if (he
->h_addrtype
== AF_INET6
)
1087 struct aafilter
*b
= a
;
1088 if (a
->addr
.bitlen
) {
1089 if ((b
= malloc(sizeof(*b
))) == NULL
)
1095 memcpy(b
->addr
.data
, *ptr
, len
);
1096 b
->addr
.bytelen
= len
;
1097 b
->addr
.bitlen
= len
*8;
1098 b
->addr
.family
= he
->h_addrtype
;
1105 static int get_dns_host(struct aafilter
*a
, const char *addr
, int fam
)
1107 static int notfirst
;
1116 he
= gethostbyname2(addr
, fam
== AF_UNSPEC
? AF_INET
: fam
);
1118 cnt
= remember_he(a
, he
);
1119 if (fam
== AF_UNSPEC
) {
1120 he
= gethostbyname2(addr
, AF_INET6
);
1122 cnt
+= remember_he(a
, he
);
1127 static int xll_initted
= 0;
1129 static void xll_init(void)
1131 struct rtnl_handle rth
;
1132 if (rtnl_open(&rth
, 0) < 0)
1140 static const char *xll_index_to_name(int index
)
1144 return ll_index_to_name(index
);
1147 static int xll_name_to_index(const char *dev
)
1151 return ll_name_to_index(dev
);
1154 void *parse_hostcond(char *addr
)
1158 struct aafilter
*res
;
1159 int fam
= preferred_family
;
1161 memset(&a
, 0, sizeof(a
));
1164 if (fam
== AF_UNIX
|| strncmp(addr
, "unix:", 5) == 0) {
1166 a
.addr
.family
= AF_UNIX
;
1167 if (strncmp(addr
, "unix:", 5) == 0)
1170 a
.addr
.bitlen
= 8*strlen(p
);
1171 memcpy(a
.addr
.data
, &p
, sizeof(p
));
1175 if (fam
== AF_PACKET
|| strncmp(addr
, "link:", 5) == 0) {
1176 a
.addr
.family
= AF_PACKET
;
1178 if (strncmp(addr
, "link:", 5) == 0)
1180 port
= strchr(addr
, ':');
1183 if (port
[1] && strcmp(port
+1, "*")) {
1184 if (get_integer(&a
.port
, port
+1, 0)) {
1185 if ((a
.port
= xll_name_to_index(port
+1)) <= 0)
1190 if (addr
[0] && strcmp(addr
, "*")) {
1193 if (ll_proto_a2n(&tmp
, addr
))
1195 a
.addr
.data
[0] = ntohs(tmp
);
1200 if (fam
== AF_NETLINK
|| strncmp(addr
, "netlink:", 8) == 0) {
1201 a
.addr
.family
= AF_NETLINK
;
1203 if (strncmp(addr
, "netlink:", 8) == 0)
1205 port
= strchr(addr
, ':');
1208 if (port
[1] && strcmp(port
+1, "*")) {
1209 if (get_integer(&a
.port
, port
+1, 0)) {
1210 if (strcmp(port
+1, "kernel") == 0)
1217 if (addr
[0] && strcmp(addr
, "*")) {
1219 if (get_u32(a
.addr
.data
, addr
, 0)) {
1220 if (strcmp(addr
, "rtnl") == 0)
1222 else if (strcmp(addr
, "fw") == 0)
1224 else if (strcmp(addr
, "tcpdiag") == 0)
1233 if (strncmp(addr
, "inet:", 5) == 0) {
1236 } else if (strncmp(addr
, "inet6:", 6) == 0) {
1241 /* URL-like literal [] */
1242 if (addr
[0] == '[') {
1244 if ((port
= strchr(addr
, ']')) == NULL
)
1247 } else if (addr
[0] == '*') {
1250 port
= strrchr(strchr(addr
, '/') ? : addr
, ':');
1252 if (port
&& *port
) {
1256 if (*port
&& *port
!= '*') {
1257 if (get_integer(&a
.port
, port
, 0)) {
1258 struct servent
*se1
= NULL
;
1259 struct servent
*se2
= NULL
;
1260 if (current_filter
.dbs
&(1<<UDP_DB
))
1261 se1
= getservbyname(port
, UDP_PROTO
);
1262 if (current_filter
.dbs
&(1<<TCP_DB
))
1263 se2
= getservbyname(port
, TCP_PROTO
);
1264 if (se1
&& se2
&& se1
->s_port
!= se2
->s_port
) {
1265 fprintf(stderr
, "Error: ambiguous port \"%s\".\n", port
);
1271 a
.port
= ntohs(se1
->s_port
);
1274 for (s
= rlist
; s
; s
= s
->next
) {
1275 if ((s
->proto
== UDP_PROTO
&&
1276 (current_filter
.dbs
&(1<<UDP_DB
))) ||
1277 (s
->proto
== TCP_PROTO
&&
1278 (current_filter
.dbs
&(1<<TCP_DB
)))) {
1279 if (s
->name
&& strcmp(s
->name
, port
) == 0) {
1280 if (a
.port
> 0 && a
.port
!= s
->port
) {
1281 fprintf(stderr
, "Error: ambiguous port \"%s\".\n", port
);
1289 fprintf(stderr
, "Error: \"%s\" does not look like a port.\n", port
);
1296 if (addr
&& *addr
&& *addr
!= '*') {
1297 if (get_prefix_1(&a
.addr
, addr
, fam
)) {
1298 if (get_dns_host(&a
, addr
, fam
)) {
1299 fprintf(stderr
, "Error: an inet prefix is expected rather than \"%s\".\n", addr
);
1306 res
= malloc(sizeof(*res
));
1308 memcpy(res
, &a
, sizeof(a
));
1312 static int tcp_show_line(char *line
, const struct filter
*f
, int family
)
1315 char *loc
, *rem
, *data
;
1320 if ((p
= strchr(line
, ':')) == NULL
)
1324 if ((p
= strchr(loc
, ':')) == NULL
)
1329 if ((p
= strchr(rem
, ':')) == NULL
)
1335 int state
= (data
[1] >= 'A') ? (data
[1] - 'A' + 10) : (data
[1] - '0');
1337 if (!(f
->states
& (1<<state
)))
1341 s
.local
.family
= s
.remote
.family
= family
;
1342 if (family
== AF_INET
) {
1343 sscanf(loc
, "%x:%x", s
.local
.data
, (unsigned*)&s
.lport
);
1344 sscanf(rem
, "%x:%x", s
.remote
.data
, (unsigned*)&s
.rport
);
1345 s
.local
.bytelen
= s
.remote
.bytelen
= 4;
1347 sscanf(loc
, "%08x%08x%08x%08x:%x",
1353 sscanf(rem
, "%08x%08x%08x%08x:%x",
1359 s
.local
.bytelen
= s
.remote
.bytelen
= 16;
1362 if (f
->f
&& run_ssfilter(f
->f
, &s
) == 0)
1366 n
= sscanf(data
, "%x %x:%x %x:%x %x %d %d %u %d %llx %d %d %d %d %d %[^\n]\n",
1367 &s
.state
, &s
.wq
, &s
.rq
,
1368 &s
.timer
, &s
.timeout
, &s
.retrs
, &s
.uid
, &s
.probes
, &s
.ino
,
1369 &s
.refcnt
, &s
.sk
, &s
.rto
, &s
.ato
, &s
.qack
,
1370 &s
.cwnd
, &s
.ssthresh
, opt
);
1383 printf("%-*s ", netid_width
, "tcp");
1385 printf("%-*s ", state_width
, sstate_name
[s
.state
]);
1387 printf("%-6d %-6d ", s
.rq
, s
.wq
);
1389 formatted_print(&s
.local
, s
.lport
, 0);
1390 formatted_print(&s
.remote
, s
.rport
, 0);
1396 printf(" timer:(%s,%s,%d)",
1398 print_hz_timer(s
.timeout
),
1399 s
.timer
!= 1 ? s
.probes
: s
.retrs
);
1403 int hz
= get_user_hz();
1404 if (s
.rto
&& s
.rto
!= 3*hz
)
1405 printf(" rto:%g", (double)s
.rto
/hz
);
1407 printf(" ato:%g", (double)s
.ato
/hz
);
1409 printf(" cwnd:%d", s
.cwnd
);
1410 if (s
.ssthresh
!= -1)
1411 printf(" ssthresh:%d", s
.ssthresh
);
1413 printf(" qack:%d", s
.qack
/2);
1418 if (show_proc_ctx
|| show_sock_ctx
) {
1419 if (find_entry(s
.ino
, &buf
,
1420 (show_proc_ctx
& show_sock_ctx
) ?
1421 PROC_SOCK_CTX
: PROC_CTX
) > 0) {
1422 printf(" users:(%s)", buf
);
1425 } else if (show_users
) {
1426 if (find_entry(s
.ino
, &buf
, USERS
) > 0) {
1427 printf(" users:(%s)", buf
);
1434 printf(" uid:%u", (unsigned)s
.uid
);
1435 printf(" ino:%u", s
.ino
);
1436 printf(" sk:%llx", s
.sk
);
1438 printf(" opt:\"%s\"", opt
);
1445 static int generic_record_read(FILE *fp
,
1446 int (*worker
)(char*, const struct filter
*, int),
1447 const struct filter
*f
, int fam
)
1452 if (fgets(line
, sizeof(line
), fp
) == NULL
)
1455 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
1456 int n
= strlen(line
);
1457 if (n
== 0 || line
[n
-1] != '\n') {
1463 if (worker(line
, f
, fam
) < 0)
1468 return ferror(fp
) ? -1 : 0;
1471 static char *sprint_bw(char *buf
, double bw
)
1474 sprintf(buf
,"%.1fM", bw
/ 1000000.);
1475 else if (bw
> 1000.)
1476 sprintf(buf
,"%.1fK", bw
/ 1000.);
1478 sprintf(buf
, "%g", bw
);
1483 static void print_skmeminfo(struct rtattr
*tb
[], int attrtype
)
1485 const __u32
*skmeminfo
;
1488 skmeminfo
= RTA_DATA(tb
[attrtype
]);
1490 printf(" skmem:(r%u,rb%u,t%u,tb%u,f%u,w%u,o%u",
1491 skmeminfo
[SK_MEMINFO_RMEM_ALLOC
],
1492 skmeminfo
[SK_MEMINFO_RCVBUF
],
1493 skmeminfo
[SK_MEMINFO_WMEM_ALLOC
],
1494 skmeminfo
[SK_MEMINFO_SNDBUF
],
1495 skmeminfo
[SK_MEMINFO_FWD_ALLOC
],
1496 skmeminfo
[SK_MEMINFO_WMEM_QUEUED
],
1497 skmeminfo
[SK_MEMINFO_OPTMEM
]);
1499 if (RTA_PAYLOAD(tb
[attrtype
]) >=
1500 (SK_MEMINFO_BACKLOG
+ 1) * sizeof(__u32
))
1501 printf(",bl%u", skmeminfo
[SK_MEMINFO_BACKLOG
]);
1506 static void tcp_show_info(const struct nlmsghdr
*nlh
, struct inet_diag_msg
*r
,
1507 struct rtattr
*tb
[])
1512 if (tb
[INET_DIAG_SKMEMINFO
]) {
1513 print_skmeminfo(tb
, INET_DIAG_SKMEMINFO
);
1514 } else if (tb
[INET_DIAG_MEMINFO
]) {
1515 const struct inet_diag_meminfo
*minfo
1516 = RTA_DATA(tb
[INET_DIAG_MEMINFO
]);
1517 printf(" mem:(r%u,w%u,f%u,t%u)",
1524 if (tb
[INET_DIAG_INFO
]) {
1525 struct tcp_info
*info
;
1526 int len
= RTA_PAYLOAD(tb
[INET_DIAG_INFO
]);
1528 /* workaround for older kernels with less fields */
1529 if (len
< sizeof(*info
)) {
1530 info
= alloca(sizeof(*info
));
1531 memset(info
, 0, sizeof(*info
));
1532 memcpy(info
, RTA_DATA(tb
[INET_DIAG_INFO
]), len
);
1534 info
= RTA_DATA(tb
[INET_DIAG_INFO
]);
1537 if (info
->tcpi_options
& TCPI_OPT_TIMESTAMPS
)
1539 if (info
->tcpi_options
& TCPI_OPT_SACK
)
1541 if (info
->tcpi_options
& TCPI_OPT_ECN
)
1543 if (info
->tcpi_options
& TCPI_OPT_ECN_SEEN
)
1545 if (info
->tcpi_options
& TCPI_OPT_SYN_DATA
)
1546 printf(" fastopen");
1549 if (tb
[INET_DIAG_CONG
])
1550 printf(" %s", rta_getattr_str(tb
[INET_DIAG_CONG
]));
1552 if (info
->tcpi_options
& TCPI_OPT_WSCALE
)
1553 printf(" wscale:%d,%d", info
->tcpi_snd_wscale
,
1554 info
->tcpi_rcv_wscale
);
1555 if (info
->tcpi_rto
&& info
->tcpi_rto
!= 3000000)
1556 printf(" rto:%g", (double)info
->tcpi_rto
/1000);
1557 if (info
->tcpi_backoff
)
1558 printf(" backoff:%u", info
->tcpi_backoff
);
1560 printf(" rtt:%g/%g", (double)info
->tcpi_rtt
/1000,
1561 (double)info
->tcpi_rttvar
/1000);
1563 printf(" ato:%g", (double)info
->tcpi_ato
/1000);
1564 if (info
->tcpi_snd_mss
)
1565 printf(" mss:%d", info
->tcpi_snd_mss
);
1566 if (info
->tcpi_snd_cwnd
!= 2)
1567 printf(" cwnd:%d", info
->tcpi_snd_cwnd
);
1568 if (info
->tcpi_snd_ssthresh
< 0xFFFF)
1569 printf(" ssthresh:%d", info
->tcpi_snd_ssthresh
);
1571 rtt
= (double) info
->tcpi_rtt
;
1572 if (tb
[INET_DIAG_VEGASINFO
]) {
1573 const struct tcpvegas_info
*vinfo
1574 = RTA_DATA(tb
[INET_DIAG_VEGASINFO
]);
1576 if (vinfo
->tcpv_enabled
&&
1577 vinfo
->tcpv_rtt
&& vinfo
->tcpv_rtt
!= 0x7fffffff)
1578 rtt
= vinfo
->tcpv_rtt
;
1581 if (tb
[INET_DIAG_DCTCPINFO
]) {
1582 const struct tcp_dctcp_info
*dinfo
1583 = RTA_DATA(tb
[INET_DIAG_DCTCPINFO
]);
1585 if (dinfo
->dctcp_enabled
) {
1586 printf(" ce_state %u alpha %u ab_ecn %u ab_tot %u",
1587 dinfo
->dctcp_ce_state
, dinfo
->dctcp_alpha
,
1588 dinfo
->dctcp_ab_ecn
, dinfo
->dctcp_ab_tot
);
1590 printf(" fallback_mode");
1594 if (rtt
> 0 && info
->tcpi_snd_mss
&& info
->tcpi_snd_cwnd
) {
1595 printf(" send %sbps",
1596 sprint_bw(b1
, (double) info
->tcpi_snd_cwnd
*
1597 (double) info
->tcpi_snd_mss
* 8000000.
1601 if (info
->tcpi_last_data_sent
)
1602 printf(" lastsnd:%u", info
->tcpi_last_data_sent
);
1604 if (info
->tcpi_last_data_recv
)
1605 printf(" lastrcv:%u", info
->tcpi_last_data_recv
);
1607 if (info
->tcpi_last_ack_recv
)
1608 printf(" lastack:%u", info
->tcpi_last_ack_recv
);
1610 if (info
->tcpi_pacing_rate
&&
1611 info
->tcpi_pacing_rate
!= ~0ULL) {
1612 printf(" pacing_rate %sbps",
1613 sprint_bw(b1
, info
->tcpi_pacing_rate
* 8.));
1615 if (info
->tcpi_max_pacing_rate
&&
1616 info
->tcpi_max_pacing_rate
!= ~0ULL)
1618 sprint_bw(b1
, info
->tcpi_max_pacing_rate
* 8.));
1620 if (info
->tcpi_unacked
)
1621 printf(" unacked:%u", info
->tcpi_unacked
);
1622 if (info
->tcpi_retrans
|| info
->tcpi_total_retrans
)
1623 printf(" retrans:%u/%u", info
->tcpi_retrans
,
1624 info
->tcpi_total_retrans
);
1625 if (info
->tcpi_lost
)
1626 printf(" lost:%u", info
->tcpi_lost
);
1627 if (info
->tcpi_sacked
&& r
->idiag_state
!= SS_LISTEN
)
1628 printf(" sacked:%u", info
->tcpi_sacked
);
1629 if (info
->tcpi_fackets
)
1630 printf(" fackets:%u", info
->tcpi_fackets
);
1631 if (info
->tcpi_reordering
!= 3)
1632 printf(" reordering:%d", info
->tcpi_reordering
);
1633 if (info
->tcpi_rcv_rtt
)
1634 printf(" rcv_rtt:%g", (double) info
->tcpi_rcv_rtt
/1000);
1635 if (info
->tcpi_rcv_space
)
1636 printf(" rcv_space:%d", info
->tcpi_rcv_space
);
1641 static char *proto_name(int protocol
)
1655 static int inet_show_sock(struct nlmsghdr
*nlh
, struct filter
*f
, int protocol
)
1657 struct rtattr
* tb
[INET_DIAG_MAX
+1];
1658 struct inet_diag_msg
*r
= NLMSG_DATA(nlh
);
1661 parse_rtattr(tb
, INET_DIAG_MAX
, (struct rtattr
*)(r
+1),
1662 nlh
->nlmsg_len
- NLMSG_LENGTH(sizeof(*r
)));
1664 s
.state
= r
->idiag_state
;
1665 s
.local
.family
= s
.remote
.family
= r
->idiag_family
;
1666 s
.lport
= ntohs(r
->id
.idiag_sport
);
1667 s
.rport
= ntohs(r
->id
.idiag_dport
);
1668 if (s
.local
.family
== AF_INET
) {
1669 s
.local
.bytelen
= s
.remote
.bytelen
= 4;
1671 s
.local
.bytelen
= s
.remote
.bytelen
= 16;
1673 memcpy(s
.local
.data
, r
->id
.idiag_src
, s
.local
.bytelen
);
1674 memcpy(s
.remote
.data
, r
->id
.idiag_dst
, s
.local
.bytelen
);
1676 if (f
&& f
->f
&& run_ssfilter(f
->f
, &s
) == 0)
1680 printf("%-*s ", netid_width
, proto_name(protocol
));
1682 printf("%-*s ", state_width
, sstate_name
[s
.state
]);
1684 printf("%-6d %-6d ", r
->idiag_rqueue
, r
->idiag_wqueue
);
1686 formatted_print(&s
.local
, s
.lport
, r
->id
.idiag_if
);
1687 formatted_print(&s
.remote
, s
.rport
, 0);
1690 if (r
->idiag_timer
) {
1691 if (r
->idiag_timer
> 4)
1693 printf(" timer:(%s,%s,%d)",
1694 tmr_name
[r
->idiag_timer
],
1695 print_ms_timer(r
->idiag_expires
),
1701 if (show_proc_ctx
|| show_sock_ctx
) {
1702 if (find_entry(r
->idiag_inode
, &buf
,
1703 (show_proc_ctx
& show_sock_ctx
) ?
1704 PROC_SOCK_CTX
: PROC_CTX
) > 0) {
1705 printf(" users:(%s)", buf
);
1708 } else if (show_users
) {
1709 if (find_entry(r
->idiag_inode
, &buf
, USERS
) > 0) {
1710 printf(" users:(%s)", buf
);
1717 printf(" uid:%u", (unsigned)r
->idiag_uid
);
1718 printf(" ino:%u", r
->idiag_inode
);
1720 if (r
->id
.idiag_cookie
[1] != 0)
1721 printf("%08x", r
->id
.idiag_cookie
[1]);
1722 printf("%08x", r
->id
.idiag_cookie
[0]);
1723 if (tb
[INET_DIAG_SHUTDOWN
]) {
1725 mask
= *(__u8
*)RTA_DATA(tb
[INET_DIAG_SHUTDOWN
]);
1726 printf(" %c-%c", mask
& 1 ? '-' : '<', mask
& 2 ? '-' : '>');
1729 if (show_mem
|| show_tcpinfo
) {
1731 tcp_show_info(nlh
, r
, tb
);
1739 static int tcpdiag_send(int fd
, int protocol
, struct filter
*f
)
1741 struct sockaddr_nl nladdr
;
1743 struct nlmsghdr nlh
;
1744 struct inet_diag_req r
;
1750 struct iovec iov
[3];
1752 if (protocol
== IPPROTO_UDP
)
1755 memset(&nladdr
, 0, sizeof(nladdr
));
1756 nladdr
.nl_family
= AF_NETLINK
;
1758 req
.nlh
.nlmsg_len
= sizeof(req
);
1759 if (protocol
== IPPROTO_TCP
)
1760 req
.nlh
.nlmsg_type
= TCPDIAG_GETSOCK
;
1762 req
.nlh
.nlmsg_type
= DCCPDIAG_GETSOCK
;
1763 req
.nlh
.nlmsg_flags
= NLM_F_ROOT
|NLM_F_MATCH
|NLM_F_REQUEST
;
1764 req
.nlh
.nlmsg_pid
= 0;
1765 req
.nlh
.nlmsg_seq
= 123456;
1766 memset(&req
.r
, 0, sizeof(req
.r
));
1767 req
.r
.idiag_family
= AF_INET
;
1768 req
.r
.idiag_states
= f
->states
;
1770 req
.r
.idiag_ext
|= (1<<(INET_DIAG_MEMINFO
-1));
1771 req
.r
.idiag_ext
|= (1<<(INET_DIAG_SKMEMINFO
-1));
1775 req
.r
.idiag_ext
|= (1<<(INET_DIAG_INFO
-1));
1776 req
.r
.idiag_ext
|= (1<<(INET_DIAG_VEGASINFO
-1));
1777 req
.r
.idiag_ext
|= (1<<(INET_DIAG_CONG
-1));
1780 iov
[0] = (struct iovec
){
1782 .iov_len
= sizeof(req
)
1785 bclen
= ssfilter_bytecompile(f
->f
, &bc
);
1786 rta
.rta_type
= INET_DIAG_REQ_BYTECODE
;
1787 rta
.rta_len
= RTA_LENGTH(bclen
);
1788 iov
[1] = (struct iovec
){ &rta
, sizeof(rta
) };
1789 iov
[2] = (struct iovec
){ bc
, bclen
};
1790 req
.nlh
.nlmsg_len
+= RTA_LENGTH(bclen
);
1793 msg
= (struct msghdr
) {
1794 .msg_name
= (void*)&nladdr
,
1795 .msg_namelen
= sizeof(nladdr
),
1797 .msg_iovlen
= f
->f
? 3 : 1,
1800 if (sendmsg(fd
, &msg
, 0) < 0) {
1808 static int sockdiag_send(int family
, int fd
, int protocol
, struct filter
*f
)
1810 struct sockaddr_nl nladdr
;
1812 struct nlmsghdr nlh
;
1813 struct inet_diag_req_v2 r
;
1819 struct iovec iov
[3];
1821 if (family
== PF_UNSPEC
)
1822 return tcpdiag_send(fd
, protocol
, f
);
1824 memset(&nladdr
, 0, sizeof(nladdr
));
1825 nladdr
.nl_family
= AF_NETLINK
;
1827 req
.nlh
.nlmsg_len
= sizeof(req
);
1828 req
.nlh
.nlmsg_type
= SOCK_DIAG_BY_FAMILY
;
1829 req
.nlh
.nlmsg_flags
= NLM_F_ROOT
|NLM_F_MATCH
|NLM_F_REQUEST
;
1830 req
.nlh
.nlmsg_pid
= 0;
1831 req
.nlh
.nlmsg_seq
= 123456;
1832 memset(&req
.r
, 0, sizeof(req
.r
));
1833 req
.r
.sdiag_family
= family
;
1834 req
.r
.sdiag_protocol
= protocol
;
1835 req
.r
.idiag_states
= f
->states
;
1837 req
.r
.idiag_ext
|= (1<<(INET_DIAG_MEMINFO
-1));
1838 req
.r
.idiag_ext
|= (1<<(INET_DIAG_SKMEMINFO
-1));
1842 req
.r
.idiag_ext
|= (1<<(INET_DIAG_INFO
-1));
1843 req
.r
.idiag_ext
|= (1<<(INET_DIAG_VEGASINFO
-1));
1844 req
.r
.idiag_ext
|= (1<<(INET_DIAG_CONG
-1));
1847 iov
[0] = (struct iovec
){
1849 .iov_len
= sizeof(req
)
1852 bclen
= ssfilter_bytecompile(f
->f
, &bc
);
1853 rta
.rta_type
= INET_DIAG_REQ_BYTECODE
;
1854 rta
.rta_len
= RTA_LENGTH(bclen
);
1855 iov
[1] = (struct iovec
){ &rta
, sizeof(rta
) };
1856 iov
[2] = (struct iovec
){ bc
, bclen
};
1857 req
.nlh
.nlmsg_len
+= RTA_LENGTH(bclen
);
1860 msg
= (struct msghdr
) {
1861 .msg_name
= (void*)&nladdr
,
1862 .msg_namelen
= sizeof(nladdr
),
1864 .msg_iovlen
= f
->f
? 3 : 1,
1867 if (sendmsg(fd
, &msg
, 0) < 0) {
1875 static int inet_show_netlink(struct filter
*f
, FILE *dump_fp
, int protocol
)
1878 struct sockaddr_nl nladdr
;
1881 struct iovec iov
[3];
1883 if ((fd
= socket(AF_NETLINK
, SOCK_RAW
, NETLINK_INET_DIAG
)) < 0)
1888 if (sockdiag_send(family
, fd
, protocol
, f
))
1891 memset(&nladdr
, 0, sizeof(nladdr
));
1892 nladdr
.nl_family
= AF_NETLINK
;
1894 iov
[0] = (struct iovec
){
1896 .iov_len
= sizeof(buf
)
1903 msg
= (struct msghdr
) {
1904 (void*)&nladdr
, sizeof(nladdr
),
1910 status
= recvmsg(fd
, &msg
, 0);
1919 fprintf(stderr
, "EOF on netlink\n");
1925 fwrite(buf
, 1, NLMSG_ALIGN(status
), dump_fp
);
1927 h
= (struct nlmsghdr
*)buf
;
1928 while (NLMSG_OK(h
, status
)) {
1930 struct inet_diag_msg
*r
= NLMSG_DATA(h
);
1932 if (/*h->nlmsg_pid != rth->local.nl_pid ||*/
1933 h
->nlmsg_seq
!= 123456)
1936 if (h
->nlmsg_type
== NLMSG_DONE
)
1939 if (h
->nlmsg_type
== NLMSG_ERROR
) {
1940 struct nlmsgerr
*err
= (struct nlmsgerr
*)NLMSG_DATA(h
);
1941 if (h
->nlmsg_len
< NLMSG_LENGTH(sizeof(struct nlmsgerr
))) {
1942 fprintf(stderr
, "ERROR truncated\n");
1944 if (family
!= PF_UNSPEC
) {
1949 errno
= -err
->error
;
1950 if (errno
== EOPNOTSUPP
) {
1954 perror("TCPDIAG answers");
1960 if (!(f
->families
& (1<<r
->idiag_family
))) {
1961 h
= NLMSG_NEXT(h
, status
);
1964 err
= inet_show_sock(h
, NULL
, protocol
);
1972 h
= NLMSG_NEXT(h
, status
);
1974 if (msg
.msg_flags
& MSG_TRUNC
) {
1975 fprintf(stderr
, "Message truncated\n");
1979 fprintf(stderr
, "!!!Remnant of size %d\n", status
);
1984 if (family
== PF_INET
) {
1993 static int tcp_show_netlink_file(struct filter
*f
)
1998 if ((fp
= fopen(getenv("TCPDIAG_FILE"), "r")) == NULL
) {
1999 perror("fopen($TCPDIAG_FILE)");
2005 struct nlmsghdr
*h
= (struct nlmsghdr
*)buf
;
2007 status
= fread(buf
, 1, sizeof(*h
), fp
);
2009 perror("Reading header from $TCPDIAG_FILE");
2012 if (status
!= sizeof(*h
)) {
2013 perror("Unexpected EOF reading $TCPDIAG_FILE");
2017 status
= fread(h
+1, 1, NLMSG_ALIGN(h
->nlmsg_len
-sizeof(*h
)), fp
);
2020 perror("Reading $TCPDIAG_FILE");
2023 if (status
+ sizeof(*h
) < h
->nlmsg_len
) {
2024 perror("Unexpected EOF reading $TCPDIAG_FILE");
2028 /* The only legal exit point */
2029 if (h
->nlmsg_type
== NLMSG_DONE
)
2032 if (h
->nlmsg_type
== NLMSG_ERROR
) {
2033 struct nlmsgerr
*err
= (struct nlmsgerr
*)NLMSG_DATA(h
);
2034 if (h
->nlmsg_len
< NLMSG_LENGTH(sizeof(struct nlmsgerr
))) {
2035 fprintf(stderr
, "ERROR truncated\n");
2037 errno
= -err
->error
;
2038 perror("TCPDIAG answered");
2043 err
= inet_show_sock(h
, f
, IPPROTO_TCP
);
2049 static int tcp_show(struct filter
*f
, int socktype
)
2053 int bufsize
= 64*1024;
2055 dg_proto
= TCP_PROTO
;
2057 if (getenv("TCPDIAG_FILE"))
2058 return tcp_show_netlink_file(f
);
2060 if (!getenv("PROC_NET_TCP") && !getenv("PROC_ROOT")
2061 && inet_show_netlink(f
, NULL
, socktype
) == 0)
2064 /* Sigh... We have to parse /proc/net/tcp... */
2067 /* Estimate amount of sockets and try to allocate
2068 * huge buffer to read all the table at one read.
2069 * Limit it by 16MB though. The assumption is: as soon as
2070 * kernel was able to hold information about N connections,
2071 * it is able to give us some memory for snapshot.
2074 int guess
= slabstat
.socks
+slabstat
.tcp_syns
;
2075 if (f
->states
&(1<<SS_TIME_WAIT
))
2076 guess
+= slabstat
.tcp_tws
;
2077 if (guess
> (16*1024*1024)/128)
2078 guess
= (16*1024*1024)/128;
2080 if (guess
> bufsize
)
2083 while (bufsize
>= 64*1024) {
2084 if ((buf
= malloc(bufsize
)) != NULL
)
2093 if (f
->families
& (1<<AF_INET
)) {
2094 if ((fp
= net_tcp_open()) == NULL
)
2097 setbuffer(fp
, buf
, bufsize
);
2098 if (generic_record_read(fp
, tcp_show_line
, f
, AF_INET
))
2103 if ((f
->families
& (1<<AF_INET6
)) &&
2104 (fp
= net_tcp6_open()) != NULL
) {
2105 setbuffer(fp
, buf
, bufsize
);
2106 if (generic_record_read(fp
, tcp_show_line
, f
, AF_INET6
))
2116 int saved_errno
= errno
;
2121 errno
= saved_errno
;
2127 static int dgram_show_line(char *line
, const struct filter
*f
, int family
)
2130 char *loc
, *rem
, *data
;
2135 if ((p
= strchr(line
, ':')) == NULL
)
2139 if ((p
= strchr(loc
, ':')) == NULL
)
2144 if ((p
= strchr(rem
, ':')) == NULL
)
2150 int state
= (data
[1] >= 'A') ? (data
[1] - 'A' + 10) : (data
[1] - '0');
2152 if (!(f
->states
& (1<<state
)))
2156 s
.local
.family
= s
.remote
.family
= family
;
2157 if (family
== AF_INET
) {
2158 sscanf(loc
, "%x:%x", s
.local
.data
, (unsigned*)&s
.lport
);
2159 sscanf(rem
, "%x:%x", s
.remote
.data
, (unsigned*)&s
.rport
);
2160 s
.local
.bytelen
= s
.remote
.bytelen
= 4;
2162 sscanf(loc
, "%08x%08x%08x%08x:%x",
2168 sscanf(rem
, "%08x%08x%08x%08x:%x",
2174 s
.local
.bytelen
= s
.remote
.bytelen
= 16;
2177 if (f
->f
&& run_ssfilter(f
->f
, &s
) == 0)
2181 n
= sscanf(data
, "%x %x:%x %*x:%*x %*x %d %*d %u %d %llx %[^\n]\n",
2182 &s
.state
, &s
.wq
, &s
.rq
,
2184 &s
.refcnt
, &s
.sk
, opt
);
2190 printf("%-*s ", netid_width
, dg_proto
);
2192 printf("%-*s ", state_width
, sstate_name
[s
.state
]);
2194 printf("%-6d %-6d ", s
.rq
, s
.wq
);
2196 formatted_print(&s
.local
, s
.lport
, 0);
2197 formatted_print(&s
.remote
, s
.rport
, 0);
2201 if (show_proc_ctx
|| show_sock_ctx
) {
2202 if (find_entry(s
.ino
, &buf
,
2203 (show_proc_ctx
& show_sock_ctx
) ?
2204 PROC_SOCK_CTX
: PROC_CTX
) > 0) {
2205 printf(" users:(%s)", buf
);
2208 } else if (show_users
) {
2209 if (find_entry(s
.ino
, &buf
, USERS
) > 0) {
2210 printf(" users:(%s)", buf
);
2217 printf(" uid=%u", (unsigned)s
.uid
);
2218 printf(" ino=%u", s
.ino
);
2219 printf(" sk=%llx", s
.sk
);
2221 printf(" opt:\"%s\"", opt
);
2229 static int udp_show(struct filter
*f
)
2233 if (!getenv("PROC_NET_UDP") && !getenv("PROC_ROOT")
2234 && inet_show_netlink(f
, NULL
, IPPROTO_UDP
) == 0)
2237 dg_proto
= UDP_PROTO
;
2239 if (f
->families
&(1<<AF_INET
)) {
2240 if ((fp
= net_udp_open()) == NULL
)
2242 if (generic_record_read(fp
, dgram_show_line
, f
, AF_INET
))
2247 if ((f
->families
&(1<<AF_INET6
)) &&
2248 (fp
= net_udp6_open()) != NULL
) {
2249 if (generic_record_read(fp
, dgram_show_line
, f
, AF_INET6
))
2257 int saved_errno
= errno
;
2260 errno
= saved_errno
;
2265 static int raw_show(struct filter
*f
)
2269 dg_proto
= RAW_PROTO
;
2271 if (f
->families
&(1<<AF_INET
)) {
2272 if ((fp
= net_raw_open()) == NULL
)
2274 if (generic_record_read(fp
, dgram_show_line
, f
, AF_INET
))
2279 if ((f
->families
&(1<<AF_INET6
)) &&
2280 (fp
= net_raw6_open()) != NULL
) {
2281 if (generic_record_read(fp
, dgram_show_line
, f
, AF_INET6
))
2289 int saved_errno
= errno
;
2292 errno
= saved_errno
;
2300 struct unixstat
*next
;
2312 int unix_state_map
[] = { SS_CLOSE
, SS_SYN_SENT
,
2313 SS_ESTABLISHED
, SS_CLOSING
};
2316 #define MAX_UNIX_REMEMBER (1024*1024/sizeof(struct unixstat))
2318 static void unix_list_free(struct unixstat
*list
)
2321 struct unixstat
*s
= list
;
2329 static const char *unix_netid_name(int type
)
2337 case SOCK_SEQPACKET
:
2348 static void unix_list_print(struct unixstat
*list
, struct filter
*f
)
2353 for (s
= list
; s
; s
= s
->next
) {
2354 if (!(f
->states
& (1<<s
->state
)))
2356 if (s
->type
== SOCK_STREAM
&& !(f
->dbs
&(1<<UNIX_ST_DB
)))
2358 if (s
->type
== SOCK_DGRAM
&& !(f
->dbs
&(1<<UNIX_DG_DB
)))
2360 if (s
->type
== SOCK_SEQPACKET
&& !(f
->dbs
&(1<<UNIX_SQ_DB
)))
2366 for (p
= list
; p
; p
= p
->next
) {
2367 if (s
->peer
== p
->ino
)
2373 peer
= p
->name
? : "*";
2379 tst
.local
.family
= AF_UNIX
;
2380 tst
.remote
.family
= AF_UNIX
;
2381 memcpy(tst
.local
.data
, &s
->name
, sizeof(s
->name
));
2382 if (strcmp(peer
, "*") == 0)
2383 memset(tst
.remote
.data
, 0, sizeof(peer
));
2385 memcpy(tst
.remote
.data
, &peer
, sizeof(peer
));
2386 if (run_ssfilter(f
->f
, &tst
) == 0)
2391 printf("%-*s ", netid_width
,
2392 unix_netid_name(s
->type
));
2394 printf("%-*s ", state_width
, sstate_name
[s
->state
]);
2395 printf("%-6d %-6d ", s
->rq
, s
->wq
);
2396 printf("%*s %-*d %*s %-*d",
2397 addr_width
, s
->name
? : "*", serv_width
, s
->ino
,
2398 addr_width
, peer
, serv_width
, s
->peer
);
2401 if (show_proc_ctx
|| show_sock_ctx
) {
2402 if (find_entry(s
->ino
, &buf
,
2403 (show_proc_ctx
& show_sock_ctx
) ?
2404 PROC_SOCK_CTX
: PROC_CTX
) > 0) {
2405 printf(" users:(%s)", buf
);
2408 } else if (show_users
) {
2409 if (find_entry(s
->ino
, &buf
, USERS
) > 0) {
2410 printf(" users:(%s)", buf
);
2418 static int unix_show_sock(struct nlmsghdr
*nlh
, struct filter
*f
)
2420 struct unix_diag_msg
*r
= NLMSG_DATA(nlh
);
2421 struct rtattr
*tb
[UNIX_DIAG_MAX
+1];
2426 parse_rtattr(tb
, UNIX_DIAG_MAX
, (struct rtattr
*)(r
+1),
2427 nlh
->nlmsg_len
- NLMSG_LENGTH(sizeof(*r
)));
2429 if (r
->udiag_type
== SOCK_STREAM
&& !(f
->dbs
&(1<<UNIX_ST_DB
)))
2431 if (r
->udiag_type
== SOCK_DGRAM
&& !(f
->dbs
&(1<<UNIX_DG_DB
)))
2433 if (r
->udiag_type
== SOCK_SEQPACKET
&& !(f
->dbs
&(1<<UNIX_SQ_DB
)))
2437 printf("%-*s ", netid_width
,
2438 unix_netid_name(r
->udiag_type
));
2440 printf("%-*s ", state_width
, sstate_name
[r
->udiag_state
]);
2442 if (tb
[UNIX_DIAG_RQLEN
]) {
2443 struct unix_diag_rqlen
*rql
= RTA_DATA(tb
[UNIX_DIAG_RQLEN
]);
2444 rqlen
= rql
->udiag_rqueue
;
2445 wqlen
= rql
->udiag_wqueue
;
2451 printf("%-6u %-6u ", rqlen
, wqlen
);
2453 if (tb
[UNIX_DIAG_NAME
]) {
2454 int len
= RTA_PAYLOAD(tb
[UNIX_DIAG_NAME
]);
2456 memcpy(name
, RTA_DATA(tb
[UNIX_DIAG_NAME
]), len
);
2458 if (name
[0] == '\0')
2463 if (tb
[UNIX_DIAG_PEER
])
2464 peer_ino
= rta_getattr_u32(tb
[UNIX_DIAG_PEER
]);
2468 printf("%*s %-*d %*s %-*d",
2470 serv_width
, r
->udiag_ino
,
2471 addr_width
, "*", /* FIXME */
2472 serv_width
, peer_ino
);
2476 if (show_proc_ctx
|| show_sock_ctx
) {
2477 if (find_entry(r
->udiag_ino
, &buf
,
2478 (show_proc_ctx
& show_sock_ctx
) ?
2479 PROC_SOCK_CTX
: PROC_CTX
) > 0) {
2480 printf(" users:(%s)", buf
);
2483 } else if (show_users
) {
2484 if (find_entry(r
->udiag_ino
, &buf
, USERS
) > 0) {
2485 printf(" users:(%s)", buf
);
2492 print_skmeminfo(tb
, UNIX_DIAG_MEMINFO
);
2496 if (tb
[UNIX_DIAG_SHUTDOWN
]) {
2498 mask
= *(__u8
*)RTA_DATA(tb
[UNIX_DIAG_SHUTDOWN
]);
2499 printf(" %c-%c", mask
& 1 ? '-' : '<', mask
& 2 ? '-' : '>');
2508 static int handle_netlink_request(struct filter
*f
, FILE *dump_fp
,
2509 struct nlmsghdr
*req
, size_t size
,
2510 int (* show_one_sock
)(struct nlmsghdr
*nlh
, struct filter
*f
))
2515 if ((fd
= socket(AF_NETLINK
, SOCK_RAW
, NETLINK_INET_DIAG
)) < 0)
2518 if (send(fd
, req
, size
, 0) < 0) {
2526 struct sockaddr_nl nladdr
;
2527 socklen_t slen
= sizeof(nladdr
);
2529 status
= recvfrom(fd
, buf
, sizeof(buf
), 0,
2530 (struct sockaddr
*) &nladdr
, &slen
);
2538 fprintf(stderr
, "EOF on netlink\n");
2543 fwrite(buf
, 1, NLMSG_ALIGN(status
), dump_fp
);
2545 h
= (struct nlmsghdr
*)buf
;
2546 while (NLMSG_OK(h
, status
)) {
2549 if (/*h->nlmsg_pid != rth->local.nl_pid ||*/
2550 h
->nlmsg_seq
!= 123456)
2553 if (h
->nlmsg_type
== NLMSG_DONE
)
2556 if (h
->nlmsg_type
== NLMSG_ERROR
) {
2557 struct nlmsgerr
*err
= (struct nlmsgerr
*)NLMSG_DATA(h
);
2558 if (h
->nlmsg_len
< NLMSG_LENGTH(sizeof(struct nlmsgerr
))) {
2559 fprintf(stderr
, "ERROR truncated\n");
2561 errno
= -err
->error
;
2562 if (errno
!= ENOENT
)
2563 fprintf(stderr
, "DIAG answers %d\n", errno
);
2569 err
= show_one_sock(h
, f
);
2577 h
= NLMSG_NEXT(h
, status
);
2581 fprintf(stderr
, "!!!Remnant of size %zd\n", status
);
2591 static int unix_show_netlink(struct filter
*f
, FILE *dump_fp
)
2594 struct nlmsghdr nlh
;
2595 struct unix_diag_req r
;
2598 memset(&req
, 0, sizeof(req
));
2599 req
.nlh
.nlmsg_len
= sizeof(req
);
2600 req
.nlh
.nlmsg_type
= SOCK_DIAG_BY_FAMILY
;
2601 req
.nlh
.nlmsg_flags
= NLM_F_ROOT
|NLM_F_MATCH
|NLM_F_REQUEST
;
2602 req
.nlh
.nlmsg_seq
= 123456;
2604 req
.r
.sdiag_family
= AF_UNIX
;
2605 req
.r
.udiag_states
= f
->states
;
2606 req
.r
.udiag_show
= UDIAG_SHOW_NAME
| UDIAG_SHOW_PEER
| UDIAG_SHOW_RQLEN
;
2608 req
.r
.udiag_show
|= UDIAG_SHOW_MEMINFO
;
2610 return handle_netlink_request(f
, dump_fp
, &req
.nlh
,
2611 sizeof(req
), unix_show_sock
);
2614 static int unix_show(struct filter
*f
)
2621 struct unixstat
*list
= NULL
;
2623 if (!getenv("PROC_NET_UNIX") && !getenv("PROC_ROOT")
2624 && unix_show_netlink(f
, NULL
) == 0)
2627 if ((fp
= net_unix_open()) == NULL
)
2629 fgets(buf
, sizeof(buf
)-1, fp
);
2631 if (memcmp(buf
, "Peer", 4) == 0)
2635 while (fgets(buf
, sizeof(buf
)-1, fp
)) {
2636 struct unixstat
*u
, **insp
;
2639 if (!(u
= malloc(sizeof(*u
))))
2643 if (sscanf(buf
, "%x: %x %x %x %x %x %d %s",
2644 &u
->peer
, &u
->rq
, &u
->wq
, &flags
, &u
->type
,
2645 &u
->state
, &u
->ino
, name
) < 8)
2648 if (flags
&(1<<16)) {
2649 u
->state
= SS_LISTEN
;
2651 u
->state
= unix_state_map
[u
->state
-1];
2652 if (u
->type
== SOCK_DGRAM
&&
2653 u
->state
== SS_CLOSE
&&
2655 u
->state
= SS_ESTABLISHED
;
2666 if (u
->type
< (*insp
)->type
||
2667 (u
->type
== (*insp
)->type
&&
2668 u
->ino
< (*insp
)->ino
))
2670 insp
= &(*insp
)->next
;
2676 if ((u
->name
= malloc(strlen(name
)+1)) == NULL
)
2678 strcpy(u
->name
, name
);
2680 if (++cnt
> MAX_UNIX_REMEMBER
) {
2681 unix_list_print(list
, f
);
2682 unix_list_free(list
);
2689 unix_list_print(list
, f
);
2690 unix_list_free(list
);
2698 static int packet_show_sock(struct nlmsghdr
*nlh
, struct filter
*f
)
2700 struct packet_diag_msg
*r
= NLMSG_DATA(nlh
);
2701 struct rtattr
*tb
[PACKET_DIAG_MAX
+1];
2704 parse_rtattr(tb
, PACKET_DIAG_MAX
, (struct rtattr
*)(r
+1),
2705 nlh
->nlmsg_len
- NLMSG_LENGTH(sizeof(*r
)));
2707 /* use /proc/net/packet if all info are not available */
2708 if (!tb
[PACKET_DIAG_MEMINFO
])
2712 printf("%-*s ", netid_width
,
2713 r
->pdiag_type
== SOCK_RAW
? "p_raw" : "p_dgr");
2715 printf("%-*s ", state_width
, "UNCONN");
2717 if (tb
[PACKET_DIAG_MEMINFO
]) {
2718 __u32
*skmeminfo
= RTA_DATA(tb
[PACKET_DIAG_MEMINFO
]);
2720 rq
= skmeminfo
[SK_MEMINFO_RMEM_ALLOC
];
2723 printf("%-6d %-6d ", rq
, 0);
2725 if (r
->pdiag_num
== 3) {
2726 printf("%*s:", addr_width
, "*");
2729 printf("%*s:", addr_width
,
2730 ll_proto_n2a(htons(r
->pdiag_num
), tb2
, sizeof(tb2
)));
2732 if (tb
[PACKET_DIAG_INFO
]) {
2733 struct packet_diag_info
*pinfo
= RTA_DATA(tb
[PACKET_DIAG_INFO
]);
2735 if (pinfo
->pdi_index
== 0)
2736 printf("%-*s ", serv_width
, "*");
2738 printf("%-*s ", serv_width
, xll_index_to_name(pinfo
->pdi_index
));
2740 printf("%-*s ", serv_width
, "*");
2743 addr_width
, "", serv_width
, "");
2747 if (show_proc_ctx
|| show_sock_ctx
) {
2748 if (find_entry(r
->pdiag_ino
, &buf
,
2749 (show_proc_ctx
& show_sock_ctx
) ?
2750 PROC_SOCK_CTX
: PROC_CTX
) > 0) {
2751 printf(" users:(%s)", buf
);
2754 } else if (show_users
) {
2755 if (find_entry(r
->pdiag_ino
, &buf
, USERS
) > 0) {
2756 printf(" users:(%s)", buf
);
2764 if (tb
[PACKET_DIAG_UID
])
2765 uid
= *(__u32
*)RTA_DATA(tb
[PACKET_DIAG_UID
]);
2767 printf(" ino=%u uid=%u sk=", r
->pdiag_ino
, uid
);
2768 if (r
->pdiag_cookie
[1] != 0)
2769 printf("%08x", r
->pdiag_cookie
[1]);
2770 printf("%08x", r
->pdiag_cookie
[0]);
2773 if (show_bpf
&& tb
[PACKET_DIAG_FILTER
]) {
2774 struct sock_filter
*fil
=
2775 RTA_DATA(tb
[PACKET_DIAG_FILTER
]);
2776 int num
= RTA_PAYLOAD(tb
[PACKET_DIAG_FILTER
]) /
2777 sizeof(struct sock_filter
);
2779 printf("\n\tbpf filter (%d): ", num
);
2781 printf(" 0x%02x %u %u %u,",
2782 fil
->code
, fil
->jt
, fil
->jf
, fil
->k
);
2791 static int packet_show_netlink(struct filter
*f
, FILE *dump_fp
)
2795 struct nlmsghdr nlh
;
2796 struct packet_diag_req r
;
2800 if ((fd
= socket(AF_NETLINK
, SOCK_RAW
, NETLINK_INET_DIAG
)) < 0)
2803 memset(&req
, 0, sizeof(req
));
2804 req
.nlh
.nlmsg_len
= sizeof(req
);
2805 req
.nlh
.nlmsg_type
= SOCK_DIAG_BY_FAMILY
;
2806 req
.nlh
.nlmsg_flags
= NLM_F_ROOT
|NLM_F_MATCH
|NLM_F_REQUEST
;
2807 req
.nlh
.nlmsg_seq
= 123456;
2809 req
.r
.sdiag_family
= AF_PACKET
;
2810 req
.r
.pdiag_show
= PACKET_SHOW_INFO
| PACKET_SHOW_MEMINFO
| PACKET_SHOW_FILTER
;
2812 if (send(fd
, &req
, sizeof(req
), 0) < 0) {
2820 struct sockaddr_nl nladdr
;
2821 socklen_t slen
= sizeof(nladdr
);
2823 status
= recvfrom(fd
, buf
, sizeof(buf
), 0,
2824 (struct sockaddr
*) &nladdr
, &slen
);
2832 fprintf(stderr
, "EOF on netlink\n");
2837 fwrite(buf
, 1, NLMSG_ALIGN(status
), dump_fp
);
2839 h
= (struct nlmsghdr
*)buf
;
2840 while (NLMSG_OK(h
, status
)) {
2843 if (h
->nlmsg_seq
!= 123456)
2846 if (h
->nlmsg_type
== NLMSG_DONE
)
2849 if (h
->nlmsg_type
== NLMSG_ERROR
) {
2850 struct nlmsgerr
*err
= (struct nlmsgerr
*)NLMSG_DATA(h
);
2851 if (h
->nlmsg_len
< NLMSG_LENGTH(sizeof(struct nlmsgerr
))) {
2852 fprintf(stderr
, "ERROR truncated\n");
2854 errno
= -err
->error
;
2855 if (errno
!= ENOENT
)
2856 fprintf(stderr
, "UDIAG answers %d\n", errno
);
2862 err
= packet_show_sock(h
, f
);
2870 h
= NLMSG_NEXT(h
, status
);
2874 fprintf(stderr
, "!!!Remnant of size %zd\n", status
);
2885 static int packet_show(struct filter
*f
)
2896 unsigned long long sk
;
2898 if (!(f
->states
& (1<<SS_CLOSE
)))
2901 if (packet_show_netlink(f
, NULL
) == 0)
2904 if ((fp
= net_packet_open()) == NULL
)
2906 fgets(buf
, sizeof(buf
)-1, fp
);
2908 while (fgets(buf
, sizeof(buf
)-1, fp
)) {
2909 sscanf(buf
, "%llx %*d %d %x %d %d %u %u %u",
2911 &type
, &prot
, &iface
, &state
,
2914 if (type
== SOCK_RAW
&& !(f
->dbs
&(1<<PACKET_R_DB
)))
2916 if (type
== SOCK_DGRAM
&& !(f
->dbs
&(1<<PACKET_DG_DB
)))
2920 tst
.local
.family
= AF_PACKET
;
2921 tst
.remote
.family
= AF_PACKET
;
2924 tst
.local
.data
[0] = prot
;
2925 tst
.remote
.data
[0] = 0;
2926 if (run_ssfilter(f
->f
, &tst
) == 0)
2931 printf("%-*s ", netid_width
,
2932 type
== SOCK_RAW
? "p_raw" : "p_dgr");
2934 printf("%-*s ", state_width
, "UNCONN");
2935 printf("%-6d %-6d ", rq
, 0);
2937 printf("%*s:", addr_width
, "*");
2940 printf("%*s:", addr_width
,
2941 ll_proto_n2a(htons(prot
), tb
, sizeof(tb
)));
2944 printf("%-*s ", serv_width
, "*");
2946 printf("%-*s ", serv_width
, xll_index_to_name(iface
));
2949 addr_width
, "", serv_width
, "");
2953 if (show_proc_ctx
|| show_sock_ctx
) {
2954 if (find_entry(ino
, &buf
,
2955 (show_proc_ctx
& show_sock_ctx
) ?
2956 PROC_SOCK_CTX
: PROC_CTX
) > 0) {
2957 printf(" users:(%s)", buf
);
2960 } else if (show_users
) {
2961 if (find_entry(ino
, &buf
, USERS
) > 0) {
2962 printf(" users:(%s)", buf
);
2968 printf(" ino=%u uid=%u sk=%llx", ino
, uid
, sk
);
2976 static void netlink_show_one(struct filter
*f
,
2977 int prot
, int pid
, unsigned groups
,
2978 int state
, int dst_pid
, unsigned dst_group
,
2980 unsigned long long sk
, unsigned long long cb
)
2984 tst
.local
.family
= AF_NETLINK
;
2985 tst
.remote
.family
= AF_NETLINK
;
2988 tst
.local
.data
[0] = prot
;
2989 tst
.remote
.data
[0] = 0;
2990 if (run_ssfilter(f
->f
, &tst
) == 0)
2995 printf("%-*s ", netid_width
, "nl");
2997 printf("%-*s ", state_width
, "UNCONN");
2998 printf("%-6d %-6d ", rq
, wq
);
2999 if (resolve_services
&& prot
== 0)
3000 printf("%*s:", addr_width
, "rtnl");
3001 else if (resolve_services
&& prot
== 3)
3002 printf("%*s:", addr_width
, "fw");
3003 else if (resolve_services
&& prot
== 4)
3004 printf("%*s:", addr_width
, "tcpdiag");
3006 printf("%*d:", addr_width
, prot
);
3008 printf("%-*s ", serv_width
, "*");
3009 } else if (resolve_services
) {
3013 printf("%-*s ", serv_width
, "kernel");
3014 } else if (pid
> 0) {
3017 sprintf(procname
, "%s/%d/stat",
3018 getenv("PROC_ROOT") ? : "/proc", pid
);
3019 if ((fp
= fopen(procname
, "r")) != NULL
) {
3020 if (fscanf(fp
, "%*d (%[^)])", procname
) == 1) {
3021 sprintf(procname
+strlen(procname
), "/%d", pid
);
3022 printf("%-*s ", serv_width
, procname
);
3029 printf("%-*d ", serv_width
, pid
);
3031 printf("%-*d ", serv_width
, pid
);
3034 if (state
== NETLINK_CONNECTED
) {
3036 addr_width
, dst_group
, serv_width
, dst_pid
);
3039 addr_width
, "", serv_width
, "");
3042 char *pid_context
= NULL
;
3043 if (show_proc_ctx
) {
3044 /* The pid value will either be:
3045 * 0 if destination kernel - show kernel initial context.
3046 * A valid process pid - use getpidcon.
3047 * A unique value allocated by the kernel or netlink user
3048 * to the process - show context as "not available".
3051 security_get_initial_context("kernel", &pid_context
);
3053 getpidcon(pid
, &pid_context
);
3055 if (pid_context
!= NULL
) {
3056 printf("proc_ctx=%-*s ", serv_width
, pid_context
);
3059 printf("proc_ctx=%-*s ", serv_width
, "unavailable");
3064 printf(" sk=%llx cb=%llx groups=0x%08x", sk
, cb
, groups
);
3071 static int netlink_show_sock(struct nlmsghdr
*nlh
, struct filter
*f
)
3073 struct netlink_diag_msg
*r
= NLMSG_DATA(nlh
);
3074 struct rtattr
*tb
[NETLINK_DIAG_MAX
+1];
3076 unsigned long groups
= 0;
3078 parse_rtattr(tb
, NETLINK_DIAG_MAX
, (struct rtattr
*)(r
+1),
3079 nlh
->nlmsg_len
- NLMSG_LENGTH(sizeof(*r
)));
3081 if (tb
[NETLINK_DIAG_GROUPS
] && RTA_PAYLOAD(tb
[NETLINK_DIAG_GROUPS
]))
3082 groups
= *(unsigned long *) RTA_DATA(tb
[NETLINK_DIAG_GROUPS
]);
3084 if (tb
[NETLINK_DIAG_MEMINFO
]) {
3085 const __u32
*skmeminfo
;
3086 skmeminfo
= RTA_DATA(tb
[NETLINK_DIAG_MEMINFO
]);
3088 rq
= skmeminfo
[SK_MEMINFO_RMEM_ALLOC
];
3089 wq
= skmeminfo
[SK_MEMINFO_WMEM_ALLOC
];
3092 netlink_show_one(f
, r
->ndiag_protocol
, r
->ndiag_portid
, groups
,
3093 r
->ndiag_state
, r
->ndiag_dst_portid
, r
->ndiag_dst_group
,
3098 print_skmeminfo(tb
, NETLINK_DIAG_MEMINFO
);
3105 static int netlink_show_netlink(struct filter
*f
, FILE *dump_fp
)
3108 struct nlmsghdr nlh
;
3109 struct netlink_diag_req r
;
3112 memset(&req
, 0, sizeof(req
));
3113 req
.nlh
.nlmsg_len
= sizeof(req
);
3114 req
.nlh
.nlmsg_type
= SOCK_DIAG_BY_FAMILY
;
3115 req
.nlh
.nlmsg_flags
= NLM_F_ROOT
|NLM_F_MATCH
|NLM_F_REQUEST
;
3116 req
.nlh
.nlmsg_seq
= 123456;
3118 req
.r
.sdiag_family
= AF_NETLINK
;
3119 req
.r
.sdiag_protocol
= NDIAG_PROTO_ALL
;
3120 req
.r
.ndiag_show
= NDIAG_SHOW_GROUPS
| NDIAG_SHOW_MEMINFO
;
3122 return handle_netlink_request(f
, dump_fp
, &req
.nlh
,
3123 sizeof(req
), netlink_show_sock
);
3126 static int netlink_show(struct filter
*f
)
3133 unsigned long long sk
, cb
;
3135 if (!(f
->states
& (1<<SS_CLOSE
)))
3138 if (!getenv("PROC_NET_NETLINK") && !getenv("PROC_ROOT") &&
3139 netlink_show_netlink(f
, NULL
) == 0)
3142 if ((fp
= net_netlink_open()) == NULL
)
3144 fgets(buf
, sizeof(buf
)-1, fp
);
3146 while (fgets(buf
, sizeof(buf
)-1, fp
)) {
3147 sscanf(buf
, "%llx %d %d %x %d %d %llx %d",
3149 &prot
, &pid
, &groups
, &rq
, &wq
, &cb
, &rc
);
3151 netlink_show_one(f
, prot
, pid
, groups
, 0, 0, 0, rq
, wq
, sk
, cb
);
3162 static int get_snmp_int(char *proto
, char *key
, int *result
)
3166 int protolen
= strlen(proto
);
3167 int keylen
= strlen(key
);
3171 if ((fp
= net_snmp_open()) == NULL
)
3174 while (fgets(buf
, sizeof(buf
), fp
) != NULL
) {
3177 if (memcmp(buf
, proto
, protolen
))
3179 while ((p
= strchr(p
, ' ')) != NULL
) {
3182 if (memcmp(p
, key
, keylen
) == 0 &&
3183 (p
[keylen
] == ' ' || p
[keylen
] == '\n'))
3186 if (fgets(buf
, sizeof(buf
), fp
) == NULL
)
3188 if (memcmp(buf
, proto
, protolen
))
3191 while ((p
= strchr(p
, ' ')) != NULL
) {
3194 sscanf(p
, "%d", result
);
3207 /* Get stats from sockstat */
3228 static void get_sockstat_line(char *line
, struct sockstat
*s
)
3230 char id
[256], rem
[256];
3232 if (sscanf(line
, "%[^ ] %[^\n]\n", id
, rem
) != 2)
3235 if (strcmp(id
, "sockets:") == 0)
3236 sscanf(rem
, "%*s%d", &s
->socks
);
3237 else if (strcmp(id
, "UDP:") == 0)
3238 sscanf(rem
, "%*s%d", &s
->udp4
);
3239 else if (strcmp(id
, "UDP6:") == 0)
3240 sscanf(rem
, "%*s%d", &s
->udp6
);
3241 else if (strcmp(id
, "RAW:") == 0)
3242 sscanf(rem
, "%*s%d", &s
->raw4
);
3243 else if (strcmp(id
, "RAW6:") == 0)
3244 sscanf(rem
, "%*s%d", &s
->raw6
);
3245 else if (strcmp(id
, "TCP6:") == 0)
3246 sscanf(rem
, "%*s%d", &s
->tcp6_hashed
);
3247 else if (strcmp(id
, "FRAG:") == 0)
3248 sscanf(rem
, "%*s%d%*s%d", &s
->frag4
, &s
->frag4_mem
);
3249 else if (strcmp(id
, "FRAG6:") == 0)
3250 sscanf(rem
, "%*s%d%*s%d", &s
->frag6
, &s
->frag6_mem
);
3251 else if (strcmp(id
, "TCP:") == 0)
3252 sscanf(rem
, "%*s%d%*s%d%*s%d%*s%d%*s%d",
3254 &s
->tcp_orphans
, &s
->tcp_tws
, &s
->tcp_total
, &s
->tcp_mem
);
3257 static int get_sockstat(struct sockstat
*s
)
3262 memset(s
, 0, sizeof(*s
));
3264 if ((fp
= net_sockstat_open()) == NULL
)
3266 while(fgets(buf
, sizeof(buf
), fp
) != NULL
)
3267 get_sockstat_line(buf
, s
);
3270 if ((fp
= net_sockstat6_open()) == NULL
)
3272 while(fgets(buf
, sizeof(buf
), fp
) != NULL
)
3273 get_sockstat_line(buf
, s
);
3279 static int print_summary(void)
3284 if (get_sockstat(&s
) < 0)
3285 perror("ss: get_sockstat");
3286 if (get_snmp_int("Tcp:", "CurrEstab", &sn
.tcp_estab
) < 0)
3287 perror("ss: get_snmpstat");
3289 printf("Total: %d (kernel %d)\n", s
.socks
, slabstat
.socks
);
3291 printf("TCP: %d (estab %d, closed %d, orphaned %d, synrecv %d, timewait %d/%d), ports %d\n",
3292 s
.tcp_total
+ slabstat
.tcp_syns
+ s
.tcp_tws
,
3294 s
.tcp_total
- (s
.tcp4_hashed
+s
.tcp6_hashed
-s
.tcp_tws
),
3297 s
.tcp_tws
, slabstat
.tcp_tws
,
3302 printf("Transport Total IP IPv6\n");
3303 printf("* %-9d %-9s %-9s\n", slabstat
.socks
, "-", "-");
3304 printf("RAW %-9d %-9d %-9d\n", s
.raw4
+s
.raw6
, s
.raw4
, s
.raw6
);
3305 printf("UDP %-9d %-9d %-9d\n", s
.udp4
+s
.udp6
, s
.udp4
, s
.udp6
);
3306 printf("TCP %-9d %-9d %-9d\n", s
.tcp4_hashed
+s
.tcp6_hashed
, s
.tcp4_hashed
, s
.tcp6_hashed
);
3307 printf("INET %-9d %-9d %-9d\n",
3308 s
.raw4
+s
.udp4
+s
.tcp4_hashed
+
3309 s
.raw6
+s
.udp6
+s
.tcp6_hashed
,
3310 s
.raw4
+s
.udp4
+s
.tcp4_hashed
,
3311 s
.raw6
+s
.udp6
+s
.tcp6_hashed
);
3312 printf("FRAG %-9d %-9d %-9d\n", s
.frag4
+s
.frag6
, s
.frag4
, s
.frag6
);
3319 static void _usage(FILE *dest
)
3322 "Usage: ss [ OPTIONS ]\n"
3323 " ss [ OPTIONS ] [ FILTER ]\n"
3324 " -h, --help this message\n"
3325 " -V, --version output version information\n"
3326 " -n, --numeric don't resolve service names\n"
3327 " -r, --resolve resolve host names\n"
3328 " -a, --all display all sockets\n"
3329 " -l, --listening display listening sockets\n"
3330 " -o, --options show timer information\n"
3331 " -e, --extended show detailed socket information\n"
3332 " -m, --memory show socket memory usage\n"
3333 " -p, --processes show process using socket\n"
3334 " -i, --info show internal TCP information\n"
3335 " -s, --summary show socket usage summary\n"
3336 " -b, --bpf show bpf filter socket information\n"
3337 " -Z, --context display process SELinux security contexts\n"
3338 " -z, --contexts display process and socket SELinux security contexts\n"
3340 " -4, --ipv4 display only IP version 4 sockets\n"
3341 " -6, --ipv6 display only IP version 6 sockets\n"
3342 " -0, --packet display PACKET sockets\n"
3343 " -t, --tcp display only TCP sockets\n"
3344 " -u, --udp display only UDP sockets\n"
3345 " -d, --dccp display only DCCP sockets\n"
3346 " -w, --raw display only RAW sockets\n"
3347 " -x, --unix display only Unix domain sockets\n"
3348 " -f, --family=FAMILY display sockets of type FAMILY\n"
3350 " -A, --query=QUERY, --socket=QUERY\n"
3351 " QUERY := {all|inet|tcp|udp|raw|unix|unix_dgram|unix_stream|unix_seqpacket|packet|netlink}[,QUERY]\n"
3353 " -D, --diag=FILE Dump raw information about TCP sockets to FILE\n"
3354 " -F, --filter=FILE read filter information from FILE\n"
3355 " FILTER := [ state TCP-STATE ] [ EXPRESSION ]\n"
3359 static void help(void) __attribute__((noreturn
));
3360 static void help(void)
3366 static void usage(void) __attribute__((noreturn
));
3367 static void usage(void)
3374 static int scan_state(const char *state
)
3377 if (strcasecmp(state
, "close") == 0 ||
3378 strcasecmp(state
, "closed") == 0)
3379 return (1<<SS_CLOSE
);
3380 if (strcasecmp(state
, "syn-rcv") == 0)
3381 return (1<<SS_SYN_RECV
);
3382 if (strcasecmp(state
, "established") == 0)
3383 return (1<<SS_ESTABLISHED
);
3384 if (strcasecmp(state
, "all") == 0)
3386 if (strcasecmp(state
, "connected") == 0)
3387 return SS_ALL
& ~((1<<SS_CLOSE
)|(1<<SS_LISTEN
));
3388 if (strcasecmp(state
, "synchronized") == 0)
3389 return SS_ALL
& ~((1<<SS_CLOSE
)|(1<<SS_LISTEN
)|(1<<SS_SYN_SENT
));
3390 if (strcasecmp(state
, "bucket") == 0)
3391 return (1<<SS_SYN_RECV
)|(1<<SS_TIME_WAIT
);
3392 if (strcasecmp(state
, "big") == 0)
3393 return SS_ALL
& ~((1<<SS_SYN_RECV
)|(1<<SS_TIME_WAIT
));
3394 for (i
=0; i
<SS_MAX
; i
++) {
3395 if (strcasecmp(state
, sstate_namel
[i
]) == 0)
3401 static const struct option long_opts
[] = {
3402 { "numeric", 0, 0, 'n' },
3403 { "resolve", 0, 0, 'r' },
3404 { "options", 0, 0, 'o' },
3405 { "extended", 0, 0, 'e' },
3406 { "memory", 0, 0, 'm' },
3407 { "info", 0, 0, 'i' },
3408 { "processes", 0, 0, 'p' },
3409 { "bpf", 0, 0, 'b' },
3410 { "dccp", 0, 0, 'd' },
3411 { "tcp", 0, 0, 't' },
3412 { "udp", 0, 0, 'u' },
3413 { "raw", 0, 0, 'w' },
3414 { "unix", 0, 0, 'x' },
3415 { "all", 0, 0, 'a' },
3416 { "listening", 0, 0, 'l' },
3417 { "ipv4", 0, 0, '4' },
3418 { "ipv6", 0, 0, '6' },
3419 { "packet", 0, 0, '0' },
3420 { "family", 1, 0, 'f' },
3421 { "socket", 1, 0, 'A' },
3422 { "query", 1, 0, 'A' },
3423 { "summary", 0, 0, 's' },
3424 { "diag", 1, 0, 'D' },
3425 { "filter", 1, 0, 'F' },
3426 { "version", 0, 0, 'V' },
3427 { "help", 0, 0, 'h' },
3428 { "context", 0, 0, 'Z' },
3429 { "contexts", 0, 0, 'z' },
3434 int main(int argc
, char *argv
[])
3440 const char *dump_tcpdiag
= NULL
;
3441 FILE *filter_fp
= NULL
;
3444 memset(¤t_filter
, 0, sizeof(current_filter
));
3446 current_filter
.states
= default_filter
.states
;
3448 while ((ch
= getopt_long(argc
, argv
, "dhaletuwxnro460spbf:miA:D:F:vVzZ",
3449 long_opts
, NULL
)) != EOF
) {
3452 resolve_services
= 0;
3472 user_ent_hash_build();
3479 current_filter
.dbs
|= (1<<DCCP_DB
);
3483 current_filter
.dbs
|= (1<<TCP_DB
);
3487 current_filter
.dbs
|= (1<<UDP_DB
);
3491 current_filter
.dbs
|= (1<<RAW_DB
);
3495 current_filter
.dbs
|= UNIX_DBM
;
3499 current_filter
.states
= SS_ALL
;
3502 current_filter
.states
= (1<<SS_LISTEN
) | (1<<SS_CLOSE
);
3505 preferred_family
= AF_INET
;
3508 preferred_family
= AF_INET6
;
3511 preferred_family
= AF_PACKET
;
3514 if (strcmp(optarg
, "inet") == 0)
3515 preferred_family
= AF_INET
;
3516 else if (strcmp(optarg
, "inet6") == 0)
3517 preferred_family
= AF_INET6
;
3518 else if (strcmp(optarg
, "link") == 0)
3519 preferred_family
= AF_PACKET
;
3520 else if (strcmp(optarg
, "unix") == 0)
3521 preferred_family
= AF_UNIX
;
3522 else if (strcmp(optarg
, "netlink") == 0)
3523 preferred_family
= AF_NETLINK
;
3524 else if (strcmp(optarg
, "help") == 0)
3527 fprintf(stderr
, "ss: \"%s\" is invalid family\n", optarg
);
3535 current_filter
.dbs
= 0;
3541 if ((p1
= strchr(p
, ',')) != NULL
)
3543 if (strcmp(p
, "all") == 0) {
3544 current_filter
.dbs
= ALL_DB
;
3545 } else if (strcmp(p
, "inet") == 0) {
3546 current_filter
.dbs
|= (1<<TCP_DB
)|(1<<DCCP_DB
)|(1<<UDP_DB
)|(1<<RAW_DB
);
3547 } else if (strcmp(p
, "udp") == 0) {
3548 current_filter
.dbs
|= (1<<UDP_DB
);
3549 } else if (strcmp(p
, "dccp") == 0) {
3550 current_filter
.dbs
|= (1<<DCCP_DB
);
3551 } else if (strcmp(p
, "tcp") == 0) {
3552 current_filter
.dbs
|= (1<<TCP_DB
);
3553 } else if (strcmp(p
, "raw") == 0) {
3554 current_filter
.dbs
|= (1<<RAW_DB
);
3555 } else if (strcmp(p
, "unix") == 0) {
3556 current_filter
.dbs
|= UNIX_DBM
;
3557 } else if (strcasecmp(p
, "unix_stream") == 0 ||
3558 strcmp(p
, "u_str") == 0) {
3559 current_filter
.dbs
|= (1<<UNIX_ST_DB
);
3560 } else if (strcasecmp(p
, "unix_dgram") == 0 ||
3561 strcmp(p
, "u_dgr") == 0) {
3562 current_filter
.dbs
|= (1<<UNIX_DG_DB
);
3563 } else if (strcasecmp(p
, "unix_seqpacket") == 0 ||
3564 strcmp(p
, "u_seq") == 0) {
3565 current_filter
.dbs
|= (1<<UNIX_SQ_DB
);
3566 } else if (strcmp(p
, "packet") == 0) {
3567 current_filter
.dbs
|= PACKET_DBM
;
3568 } else if (strcmp(p
, "packet_raw") == 0 ||
3569 strcmp(p
, "p_raw") == 0) {
3570 current_filter
.dbs
|= (1<<PACKET_R_DB
);
3571 } else if (strcmp(p
, "packet_dgram") == 0 ||
3572 strcmp(p
, "p_dgr") == 0) {
3573 current_filter
.dbs
|= (1<<PACKET_DG_DB
);
3574 } else if (strcmp(p
, "netlink") == 0) {
3575 current_filter
.dbs
|= (1<<NETLINK_DB
);
3577 fprintf(stderr
, "ss: \"%s\" is illegal socket table id\n", p
);
3588 dump_tcpdiag
= optarg
;
3592 fprintf(stderr
, "More than one filter file\n");
3595 if (optarg
[0] == '-')
3598 filter_fp
= fopen(optarg
, "r");
3600 perror("fopen filter file");
3606 printf("ss utility, iproute2-ss%s\n", SNAPSHOT
);
3611 if (is_selinux_enabled() <= 0) {
3612 fprintf(stderr
, "ss: SELinux is not enabled.\n");
3616 user_ent_hash_build();
3629 get_slabstat(&slabstat
);
3633 if (do_default
&& argc
== 0)
3638 current_filter
.dbs
= default_filter
.dbs
;
3640 if (preferred_family
== AF_UNSPEC
) {
3641 if (!(current_filter
.dbs
&~UNIX_DBM
))
3642 preferred_family
= AF_UNIX
;
3643 else if (!(current_filter
.dbs
&~PACKET_DBM
))
3644 preferred_family
= AF_PACKET
;
3645 else if (!(current_filter
.dbs
&~(1<<NETLINK_DB
)))
3646 preferred_family
= AF_NETLINK
;
3649 if (preferred_family
!= AF_UNSPEC
) {
3651 if (preferred_family
== AF_INET
||
3652 preferred_family
== AF_INET6
) {
3653 mask2
= current_filter
.dbs
;
3654 } else if (preferred_family
== AF_PACKET
) {
3656 } else if (preferred_family
== AF_UNIX
) {
3658 } else if (preferred_family
== AF_NETLINK
) {
3659 mask2
= (1<<NETLINK_DB
);
3665 current_filter
.dbs
= mask2
;
3667 current_filter
.dbs
&= mask2
;
3668 current_filter
.families
= (1<<preferred_family
);
3671 current_filter
.families
= ~0;
3673 current_filter
.families
= default_filter
.families
;
3675 if (current_filter
.dbs
== 0) {
3676 fprintf(stderr
, "ss: no socket tables to show with such filter.\n");
3679 if (current_filter
.families
== 0) {
3680 fprintf(stderr
, "ss: no families to show with such filter.\n");
3684 if (resolve_services
&& resolve_hosts
&&
3685 (current_filter
.dbs
&(UNIX_DBM
|(1<<TCP_DB
)|(1<<UDP_DB
)|(1<<DCCP_DB
))))
3686 init_service_resolver();
3688 /* Now parse filter... */
3689 if (argc
== 0 && filter_fp
) {
3690 if (ssfilter_parse(¤t_filter
.f
, 0, NULL
, filter_fp
))
3695 if (strcmp(*argv
, "state") == 0) {
3698 current_filter
.states
= 0;
3699 current_filter
.states
|= scan_state(*argv
);
3701 } else if (strcmp(*argv
, "exclude") == 0 ||
3702 strcmp(*argv
, "excl") == 0) {
3705 current_filter
.states
= SS_ALL
;
3706 current_filter
.states
&= ~scan_state(*argv
);
3709 if (ssfilter_parse(¤t_filter
.f
, argc
, argv
, filter_fp
))
3716 if (current_filter
.states
== 0) {
3717 fprintf(stderr
, "ss: no socket states to show with such filter.\n");
3722 FILE *dump_fp
= stdout
;
3723 if (!(current_filter
.dbs
& (1<<TCP_DB
))) {
3724 fprintf(stderr
, "ss: tcpdiag dump requested and no tcp in filter.\n");
3727 if (dump_tcpdiag
[0] != '-') {
3728 dump_fp
= fopen(dump_tcpdiag
, "w");
3729 if (!dump_tcpdiag
) {
3730 perror("fopen dump file");
3734 inet_show_netlink(¤t_filter
, dump_fp
, IPPROTO_TCP
);
3740 if (current_filter
.dbs
&(current_filter
.dbs
-1))
3744 if (current_filter
.states
&(current_filter
.states
-1))
3748 if (isatty(STDOUT_FILENO
)) {
3751 if (ioctl(STDOUT_FILENO
, TIOCGWINSZ
, &w
) != -1) {
3753 screen_width
= w
.ws_col
;
3757 addrp_width
= screen_width
;
3758 addrp_width
-= netid_width
+1;
3759 addrp_width
-= state_width
+1;
3762 if (addrp_width
&1) {
3765 else if (state_width
)
3772 serv_width
= resolve_services
? 7 : 5;
3774 if (addrp_width
< 15+serv_width
+1)
3775 addrp_width
= 15+serv_width
+1;
3777 addr_width
= addrp_width
- serv_width
- 1;
3780 printf("%-*s ", netid_width
, "Netid");
3782 printf("%-*s ", state_width
, "State");
3783 printf("%-6s %-6s ", "Recv-Q", "Send-Q");
3785 printf("%*s:%-*s %*s:%-*s\n",
3786 addr_width
, "Local Address", serv_width
, "Port",
3787 addr_width
, "Peer Address", serv_width
, "Port");
3791 if (current_filter
.dbs
& (1<<NETLINK_DB
))
3792 netlink_show(¤t_filter
);
3793 if (current_filter
.dbs
& PACKET_DBM
)
3794 packet_show(¤t_filter
);
3795 if (current_filter
.dbs
& UNIX_DBM
)
3796 unix_show(¤t_filter
);
3797 if (current_filter
.dbs
& (1<<RAW_DB
))
3798 raw_show(¤t_filter
);
3799 if (current_filter
.dbs
& (1<<UDP_DB
))
3800 udp_show(¤t_filter
);
3801 if (current_filter
.dbs
& (1<<TCP_DB
))
3802 tcp_show(¤t_filter
, IPPROTO_TCP
);
3803 if (current_filter
.dbs
& (1<<DCCP_DB
))
3804 tcp_show(¤t_filter
, IPPROTO_DCCP
);
3806 if (show_users
|| show_proc_ctx
|| show_sock_ctx
)