1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2002 Dag-Erling Smørgrav
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer
12 * in this position and unchanged.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include <sys/param.h>
32 #include <sys/file.h>
33 #include <sys/socket.h>
34 #include <sys/socketvar.h>
35 #include <sys/sysctl.h>
36 #include <sys/jail.h>
37 #include <sys/user.h>
38 #include <sys/queue.h>
39 #include <sys/tree.h>
40
41 #include <sys/un.h>
42 #include <sys/unpcb.h>
43
44 #include <net/route.h>
45
46 #include <netinet/in.h>
47 #include <netinet/in_pcb.h>
48 #include <netinet/sctp.h>
49 #include <netinet/tcp.h>
50 #define TCPSTATES /* load state names */
51 #include <netinet/tcp_fsm.h>
52 #include <netinet/tcp_seq.h>
53 #include <netinet/tcp_var.h>
54 #include <netinet/tcp_log_buf.h>
55 #include <arpa/inet.h>
56
57 #include <capsicum_helpers.h>
58 #include <errno.h>
59 #include <inttypes.h>
60 #include <jail.h>
61 #include <netdb.h>
62 #include <pwd.h>
63 #include <stdarg.h>
64 #include <stdbool.h>
65 #include <stdio.h>
66 #include <stdlib.h>
67 #include <string.h>
68 #include <unistd.h>
69 #include <libxo/xo.h>
70
71 #include <libcasper.h>
72 #include <casper/cap_net.h>
73 #include <casper/cap_netdb.h>
74 #include <casper/cap_pwd.h>
75 #include <casper/cap_sysctl.h>
76
77 #include "sockstat.h"
78
79 #define SOCKSTAT_XO_VERSION "1"
80 #define sstosin(ss) ((struct sockaddr_in *)(ss))
81 #define sstosin6(ss) ((struct sockaddr_in6 *)(ss))
82 #define sstosun(ss) ((struct sockaddr_un *)(ss))
83 #define sstosa(ss) ((struct sockaddr *)(ss))
84
85 static bool opt_4; /* Show IPv4 sockets */
86 static bool opt_6; /* Show IPv6 sockets */
87 static bool opt_A; /* Show kernel address of pcb */
88 static bool opt_b; /* Show BBLog state */
89 static bool opt_C; /* Show congestion control */
90 static bool opt_c; /* Show connected sockets */
91 static bool opt_f; /* Show FIB numbers */
92 static bool opt_I; /* Show spliced socket addresses */
93 static bool opt_i; /* Show inp_gencnt */
94 static int opt_j; /* Show specified jail */
95 static bool opt_L; /* Don't show IPv4 or IPv6 loopback sockets */
96 static bool opt_l; /* Show listening sockets */
97 static bool opt_n; /* Don't resolve UIDs to user names */
98 static bool opt_q; /* Don't show header */
99 static bool opt_S; /* Show protocol stack if applicable */
100 static bool opt_s; /* Show protocol state if applicable */
101 static bool opt_U; /* Show remote UDP encapsulation port number */
102 static bool opt_u; /* Show Unix domain sockets */
103 static u_int opt_v; /* Verbose mode */
104 static bool opt_w; /* Automatically size the columns */
105 static bool is_xo_style_encoding;
106 static bool show_path_state = false;
107
108 /*
109 * Default protocols to use if no -P was defined.
110 */
111 static const char *default_protos[] = {"sctp", "tcp", "udp", "divert" };
112 static size_t default_numprotos = nitems(default_protos);
113
114 static int *protos; /* protocols to use */
115 static size_t numprotos; /* allocated size of protos[] */
116
117 struct addr {
118 union {
119 struct sockaddr_storage address;
120 struct { /* unix(4) faddr */
121 kvaddr_t conn;
122 kvaddr_t firstref;
123 kvaddr_t nextref;
124 };
125 };
126 unsigned int encaps_port;
127 int state;
128 struct addr *next;
129 };
130
131 struct sock {
132 union {
133 RB_ENTRY(sock) socket_tree; /* tree of pcbs with socket */
134 SLIST_ENTRY(sock) socket_list; /* list of pcbs w/o socket */
135 };
136 RB_ENTRY(sock) pcb_tree;
137 kvaddr_t socket;
138 kvaddr_t pcb;
139 kvaddr_t splice_socket;
140 uint64_t inp_gencnt;
141 int shown;
142 int vflag;
143 int family;
144 int proto;
145 int state;
146 int fibnum;
147 int bblog_state;
148 const char *protoname;
149 char stack[TCP_FUNCTION_NAME_LEN_MAX];
150 char cc[TCP_CA_NAME_MAX];
151 struct addr *laddr;
152 struct addr *faddr;
153 };
154
155 static RB_HEAD(socks_t, sock) socks = RB_INITIALIZER(&socks);
156 static int64_t
socket_compare(const struct sock * a,const struct sock * b)157 socket_compare(const struct sock *a, const struct sock *b)
158 {
159 return ((int64_t)(a->socket/2 - b->socket/2));
160 }
161 RB_GENERATE_STATIC(socks_t, sock, socket_tree, socket_compare);
162
163 static RB_HEAD(pcbs_t, sock) pcbs = RB_INITIALIZER(&pcbs);
164 static int64_t
pcb_compare(const struct sock * a,const struct sock * b)165 pcb_compare(const struct sock *a, const struct sock *b)
166 {
167 return ((int64_t)(a->pcb/2 - b->pcb/2));
168 }
169 RB_GENERATE_STATIC(pcbs_t, sock, pcb_tree, pcb_compare);
170
171 static SLIST_HEAD(, sock) nosocks = SLIST_HEAD_INITIALIZER(&nosocks);
172
173 struct file {
174 RB_ENTRY(file) file_tree;
175 kvaddr_t xf_data;
176 pid_t xf_pid;
177 uid_t xf_uid;
178 int xf_fd;
179 };
180
181 static RB_HEAD(files_t, file) ftree = RB_INITIALIZER(&ftree);
182 static int64_t
file_compare(const struct file * a,const struct file * b)183 file_compare(const struct file *a, const struct file *b)
184 {
185 return ((int64_t)(a->xf_data/2 - b->xf_data/2));
186 }
187 RB_GENERATE_STATIC(files_t, file, file_tree, file_compare);
188
189 static struct file *files;
190 static int nfiles;
191
192 static cap_channel_t *capnet;
193 static cap_channel_t *capnetdb;
194 static cap_channel_t *capsysctl;
195 static cap_channel_t *cappwd;
196
197 static bool
_check_ksize(size_t received_size,size_t expected_size,const char * struct_name)198 _check_ksize(size_t received_size, size_t expected_size, const char *struct_name)
199 {
200 if (received_size != expected_size) {
201 xo_warnx("%s size mismatch: expected %zd, received %zd",
202 struct_name, expected_size, received_size);
203 return false;
204 }
205 return true;
206 }
207 #define check_ksize(_sz, _struct) (_check_ksize(_sz, sizeof(_struct), #_struct))
208
209 static void
_enforce_ksize(size_t received_size,size_t expected_size,const char * struct_name)210 _enforce_ksize(size_t received_size, size_t expected_size, const char *struct_name)
211 {
212 if (received_size != expected_size) {
213 xo_errx(1, "fatal: struct %s size mismatch: expected %zd, received %zd",
214 struct_name, expected_size, received_size);
215 }
216 }
217 #define enforce_ksize(_sz, _struct) (_enforce_ksize(_sz, sizeof(_struct), #_struct))
218
219 static int
get_proto_type(const char * proto)220 get_proto_type(const char *proto)
221 {
222 struct protoent *pent;
223
224 if (strlen(proto) == 0)
225 return (0);
226 if (capnetdb != NULL)
227 pent = cap_getprotobyname(capnetdb, proto);
228 else
229 pent = getprotobyname(proto);
230 if (pent == NULL) {
231 xo_warn("cap_getprotobyname");
232 return (-1);
233 }
234 return (pent->p_proto);
235 }
236
237 static void
init_protos(int num)238 init_protos(int num)
239 {
240 int proto_count = 0;
241
242 if (num > 0) {
243 proto_count = num;
244 } else {
245 /* Find the maximum number of possible protocols. */
246 while (getprotoent() != NULL)
247 proto_count++;
248 endprotoent();
249 }
250
251 if ((protos = malloc(sizeof(int) * proto_count)) == NULL)
252 xo_err(1, "malloc");
253 numprotos = proto_count;
254 }
255
256 static int
parse_protos(char * protospec)257 parse_protos(char *protospec)
258 {
259 char *prot;
260 int proto_type, proto_index;
261
262 if (protospec == NULL)
263 return (-1);
264
265 init_protos(0);
266 proto_index = 0;
267 while ((prot = strsep(&protospec, ",")) != NULL) {
268 if (strlen(prot) == 0)
269 continue;
270 proto_type = get_proto_type(prot);
271 if (proto_type != -1)
272 protos[proto_index++] = proto_type;
273 }
274 numprotos = proto_index;
275 return (proto_index);
276 }
277
278 static void
sockaddr(struct sockaddr_storage * ss,int af,void * addr,int port)279 sockaddr(struct sockaddr_storage *ss, int af, void *addr, int port)
280 {
281 struct sockaddr_in *sin4;
282 struct sockaddr_in6 *sin6;
283
284 bzero(ss, sizeof(*ss));
285 switch (af) {
286 case AF_INET:
287 sin4 = sstosin(ss);
288 sin4->sin_len = sizeof(*sin4);
289 sin4->sin_family = af;
290 sin4->sin_port = port;
291 sin4->sin_addr = *(struct in_addr *)addr;
292 break;
293 case AF_INET6:
294 sin6 = sstosin6(ss);
295 sin6->sin6_len = sizeof(*sin6);
296 sin6->sin6_family = af;
297 sin6->sin6_port = port;
298 sin6->sin6_addr = *(struct in6_addr *)addr;
299 #define s6_addr16 __u6_addr.__u6_addr16
300 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
301 sin6->sin6_scope_id =
302 ntohs(sin6->sin6_addr.s6_addr16[1]);
303 sin6->sin6_addr.s6_addr16[1] = 0;
304 }
305 break;
306 default:
307 abort();
308 }
309 }
310
311 static void
free_socket(struct sock * sock)312 free_socket(struct sock *sock)
313 {
314 struct addr *cur, *next;
315
316 cur = sock->laddr;
317 while (cur != NULL) {
318 next = cur->next;
319 free(cur);
320 cur = next;
321 }
322 cur = sock->faddr;
323 while (cur != NULL) {
324 next = cur->next;
325 free(cur);
326 cur = next;
327 }
328 free(sock);
329 }
330
331 static void
gather_sctp(void)332 gather_sctp(void)
333 {
334 struct sock *sock;
335 struct addr *laddr, *prev_laddr, *faddr, *prev_faddr;
336 struct xsctp_inpcb *xinpcb;
337 struct xsctp_tcb *xstcb;
338 struct xsctp_raddr *xraddr;
339 struct xsctp_laddr *xladdr;
340 const char *varname;
341 size_t len, offset;
342 char *buf;
343 int vflag;
344 int no_stcb, local_all_loopback, foreign_all_loopback;
345
346 vflag = 0;
347 if (opt_4)
348 vflag |= INP_IPV4;
349 if (opt_6)
350 vflag |= INP_IPV6;
351
352 varname = "net.inet.sctp.assoclist";
353 if (cap_sysctlbyname(capsysctl, varname, 0, &len, 0, 0) < 0) {
354 if (errno != ENOENT)
355 xo_err(1, "cap_sysctlbyname()");
356 return;
357 }
358 if ((buf = (char *)malloc(len)) == NULL) {
359 xo_err(1, "malloc()");
360 return;
361 }
362 if (cap_sysctlbyname(capsysctl, varname, buf, &len, 0, 0) < 0) {
363 xo_err(1, "cap_sysctlbyname()");
364 free(buf);
365 return;
366 }
367 xinpcb = (struct xsctp_inpcb *)(void *)buf;
368 offset = sizeof(struct xsctp_inpcb);
369 while ((offset < len) && (xinpcb->last == 0)) {
370 if ((sock = calloc(1, sizeof *sock)) == NULL)
371 xo_err(1, "malloc()");
372 sock->socket = xinpcb->socket;
373 sock->proto = IPPROTO_SCTP;
374 sock->protoname = "sctp";
375 if (xinpcb->maxqlen == 0)
376 sock->state = SCTP_CLOSED;
377 else
378 sock->state = SCTP_LISTEN;
379 if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) {
380 sock->family = AF_INET6;
381 /*
382 * Currently there is no way to distinguish between
383 * IPv6 only sockets or dual family sockets.
384 * So mark it as dual socket.
385 */
386 sock->vflag = INP_IPV6 | INP_IPV4;
387 } else {
388 sock->family = AF_INET;
389 sock->vflag = INP_IPV4;
390 }
391 prev_laddr = NULL;
392 local_all_loopback = 1;
393 while (offset < len) {
394 xladdr = (struct xsctp_laddr *)(void *)(buf + offset);
395 offset += sizeof(struct xsctp_laddr);
396 if (xladdr->last == 1)
397 break;
398 if ((laddr = calloc(1, sizeof(struct addr))) == NULL)
399 xo_err(1, "malloc()");
400 switch (xladdr->address.sa.sa_family) {
401 case AF_INET:
402 #define __IN_IS_ADDR_LOOPBACK(pina) \
403 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
404 if (!__IN_IS_ADDR_LOOPBACK(
405 &xladdr->address.sin.sin_addr))
406 local_all_loopback = 0;
407 #undef __IN_IS_ADDR_LOOPBACK
408 sockaddr(&laddr->address, AF_INET,
409 &xladdr->address.sin.sin_addr,
410 htons(xinpcb->local_port));
411 break;
412 case AF_INET6:
413 if (!IN6_IS_ADDR_LOOPBACK(
414 &xladdr->address.sin6.sin6_addr))
415 local_all_loopback = 0;
416 sockaddr(&laddr->address, AF_INET6,
417 &xladdr->address.sin6.sin6_addr,
418 htons(xinpcb->local_port));
419 break;
420 default:
421 xo_errx(1, "address family %d not supported",
422 xladdr->address.sa.sa_family);
423 }
424 laddr->next = NULL;
425 if (prev_laddr == NULL)
426 sock->laddr = laddr;
427 else
428 prev_laddr->next = laddr;
429 prev_laddr = laddr;
430 }
431 if (sock->laddr == NULL) {
432 if ((sock->laddr =
433 calloc(1, sizeof(struct addr))) == NULL)
434 xo_err(1, "malloc()");
435 sock->laddr->address.ss_family = sock->family;
436 if (sock->family == AF_INET)
437 sock->laddr->address.ss_len =
438 sizeof(struct sockaddr_in);
439 else
440 sock->laddr->address.ss_len =
441 sizeof(struct sockaddr_in6);
442 local_all_loopback = 0;
443 }
444 if ((sock->faddr = calloc(1, sizeof(struct addr))) == NULL)
445 xo_err(1, "malloc()");
446 sock->faddr->address.ss_family = sock->family;
447 if (sock->family == AF_INET)
448 sock->faddr->address.ss_len =
449 sizeof(struct sockaddr_in);
450 else
451 sock->faddr->address.ss_len =
452 sizeof(struct sockaddr_in6);
453 no_stcb = 1;
454 while (offset < len) {
455 xstcb = (struct xsctp_tcb *)(void *)(buf + offset);
456 offset += sizeof(struct xsctp_tcb);
457 if (no_stcb) {
458 if (opt_l && (sock->vflag & vflag) &&
459 (!opt_L || !local_all_loopback) &&
460 ((xinpcb->flags & SCTP_PCB_FLAGS_UDPTYPE) ||
461 (xstcb->last == 1))) {
462 RB_INSERT(socks_t, &socks, sock);
463 } else {
464 free_socket(sock);
465 }
466 }
467 if (xstcb->last == 1)
468 break;
469 no_stcb = 0;
470 if (opt_c) {
471 if ((sock = calloc(1, sizeof *sock)) == NULL)
472 xo_err(1, "malloc()");
473 sock->socket = xinpcb->socket;
474 sock->proto = IPPROTO_SCTP;
475 sock->protoname = "sctp";
476 sock->state = (int)xstcb->state;
477 if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) {
478 sock->family = AF_INET6;
479 /*
480 * Currently there is no way to distinguish
481 * between IPv6 only sockets or dual family
482 * sockets. So mark it as dual socket.
483 */
484 sock->vflag = INP_IPV6 | INP_IPV4;
485 } else {
486 sock->family = AF_INET;
487 sock->vflag = INP_IPV4;
488 }
489 }
490 prev_laddr = NULL;
491 local_all_loopback = 1;
492 while (offset < len) {
493 xladdr = (struct xsctp_laddr *)(void *)(buf +
494 offset);
495 offset += sizeof(struct xsctp_laddr);
496 if (xladdr->last == 1)
497 break;
498 if (!opt_c)
499 continue;
500 laddr = calloc(1, sizeof(struct addr));
501 if (laddr == NULL)
502 xo_err(1, "malloc()");
503 switch (xladdr->address.sa.sa_family) {
504 case AF_INET:
505 #define __IN_IS_ADDR_LOOPBACK(pina) \
506 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
507 if (!__IN_IS_ADDR_LOOPBACK(
508 &xladdr->address.sin.sin_addr))
509 local_all_loopback = 0;
510 #undef __IN_IS_ADDR_LOOPBACK
511 sockaddr(&laddr->address, AF_INET,
512 &xladdr->address.sin.sin_addr,
513 htons(xstcb->local_port));
514 break;
515 case AF_INET6:
516 if (!IN6_IS_ADDR_LOOPBACK(
517 &xladdr->address.sin6.sin6_addr))
518 local_all_loopback = 0;
519 sockaddr(&laddr->address, AF_INET6,
520 &xladdr->address.sin6.sin6_addr,
521 htons(xstcb->local_port));
522 break;
523 default:
524 xo_errx(1,
525 "address family %d not supported",
526 xladdr->address.sa.sa_family);
527 }
528 laddr->next = NULL;
529 if (prev_laddr == NULL)
530 sock->laddr = laddr;
531 else
532 prev_laddr->next = laddr;
533 prev_laddr = laddr;
534 }
535 prev_faddr = NULL;
536 foreign_all_loopback = 1;
537 while (offset < len) {
538 xraddr = (struct xsctp_raddr *)(void *)(buf +
539 offset);
540 offset += sizeof(struct xsctp_raddr);
541 if (xraddr->last == 1)
542 break;
543 if (!opt_c)
544 continue;
545 faddr = calloc(1, sizeof(struct addr));
546 if (faddr == NULL)
547 xo_err(1, "malloc()");
548 switch (xraddr->address.sa.sa_family) {
549 case AF_INET:
550 #define __IN_IS_ADDR_LOOPBACK(pina) \
551 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
552 if (!__IN_IS_ADDR_LOOPBACK(
553 &xraddr->address.sin.sin_addr))
554 foreign_all_loopback = 0;
555 #undef __IN_IS_ADDR_LOOPBACK
556 sockaddr(&faddr->address, AF_INET,
557 &xraddr->address.sin.sin_addr,
558 htons(xstcb->remote_port));
559 break;
560 case AF_INET6:
561 if (!IN6_IS_ADDR_LOOPBACK(
562 &xraddr->address.sin6.sin6_addr))
563 foreign_all_loopback = 0;
564 sockaddr(&faddr->address, AF_INET6,
565 &xraddr->address.sin6.sin6_addr,
566 htons(xstcb->remote_port));
567 break;
568 default:
569 xo_errx(1,
570 "address family %d not supported",
571 xraddr->address.sa.sa_family);
572 }
573 faddr->encaps_port = xraddr->encaps_port;
574 faddr->state = xraddr->state;
575 faddr->next = NULL;
576 if (prev_faddr == NULL)
577 sock->faddr = faddr;
578 else
579 prev_faddr->next = faddr;
580 prev_faddr = faddr;
581 }
582 if (opt_c) {
583 if ((sock->vflag & vflag) &&
584 (!opt_L ||
585 !(local_all_loopback ||
586 foreign_all_loopback))) {
587 RB_INSERT(socks_t, &socks, sock);
588 show_path_state = true;
589 } else {
590 free_socket(sock);
591 }
592 }
593 }
594 xinpcb = (struct xsctp_inpcb *)(void *)(buf + offset);
595 offset += sizeof(struct xsctp_inpcb);
596 }
597 free(buf);
598 }
599
600 static void
gather_inet(int proto)601 gather_inet(int proto)
602 {
603 struct xinpgen *xig, *exig;
604 struct xinpcb *xip;
605 struct xtcpcb *xtp = NULL;
606 struct xsocket *so;
607 struct sock *sock;
608 struct addr *laddr, *faddr;
609 const char *varname, *protoname;
610 size_t len, bufsize;
611 void *buf;
612 int retry, vflag;
613
614 vflag = 0;
615 if (opt_4)
616 vflag |= INP_IPV4;
617 if (opt_6)
618 vflag |= INP_IPV6;
619
620 switch (proto) {
621 case IPPROTO_TCP:
622 varname = "net.inet.tcp.pcblist";
623 protoname = "tcp";
624 break;
625 case IPPROTO_UDP:
626 varname = "net.inet.udp.pcblist";
627 protoname = "udp";
628 break;
629 case IPPROTO_DIVERT:
630 varname = "net.inet.divert.pcblist";
631 protoname = "div";
632 break;
633 default:
634 xo_errx(1, "protocol %d not supported", proto);
635 }
636
637 buf = NULL;
638 bufsize = 8192;
639 retry = 5;
640 do {
641 for (;;) {
642 if ((buf = realloc(buf, bufsize)) == NULL)
643 xo_err(1, "realloc()");
644 len = bufsize;
645 if (cap_sysctlbyname(capsysctl, varname, buf, &len,
646 NULL, 0) == 0)
647 break;
648 if (errno == ENOENT)
649 goto out;
650 if (errno != ENOMEM || len != bufsize)
651 xo_err(1, "cap_sysctlbyname()");
652 bufsize *= 2;
653 }
654 xig = (struct xinpgen *)buf;
655 exig = (struct xinpgen *)(void *)
656 ((char *)buf + len - sizeof *exig);
657 enforce_ksize(xig->xig_len, struct xinpgen);
658 enforce_ksize(exig->xig_len, struct xinpgen);
659 } while (xig->xig_gen != exig->xig_gen && retry--);
660
661 if (xig->xig_gen != exig->xig_gen && opt_v)
662 xo_warnx("warning: data may be inconsistent");
663
664 for (;;) {
665 xig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len);
666 if (xig >= exig)
667 break;
668 switch (proto) {
669 case IPPROTO_TCP:
670 xtp = (struct xtcpcb *)xig;
671 xip = &xtp->xt_inp;
672 if (!check_ksize(xtp->xt_len, struct xtcpcb))
673 goto out;
674 protoname = xtp->t_flags & TF_TOE ? "toe" : "tcp";
675 break;
676 case IPPROTO_UDP:
677 case IPPROTO_DIVERT:
678 xip = (struct xinpcb *)xig;
679 if (!check_ksize(xip->xi_len, struct xinpcb))
680 goto out;
681 break;
682 default:
683 xo_errx(1, "protocol %d not supported", proto);
684 }
685 so = &xip->xi_socket;
686 if ((xip->inp_vflag & vflag) == 0)
687 continue;
688 if (xip->inp_vflag & INP_IPV4) {
689 if ((xip->inp_fport == 0 && !opt_l) ||
690 (xip->inp_fport != 0 && !opt_c))
691 continue;
692 #define __IN_IS_ADDR_LOOPBACK(pina) \
693 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
694 if (opt_L &&
695 (__IN_IS_ADDR_LOOPBACK(&xip->inp_faddr) ||
696 __IN_IS_ADDR_LOOPBACK(&xip->inp_laddr)))
697 continue;
698 #undef __IN_IS_ADDR_LOOPBACK
699 } else if (xip->inp_vflag & INP_IPV6) {
700 if ((xip->inp_fport == 0 && !opt_l) ||
701 (xip->inp_fport != 0 && !opt_c))
702 continue;
703 if (opt_L &&
704 (IN6_IS_ADDR_LOOPBACK(&xip->in6p_faddr) ||
705 IN6_IS_ADDR_LOOPBACK(&xip->in6p_laddr)))
706 continue;
707 } else {
708 if (opt_v)
709 xo_warnx("invalid vflag 0x%x", xip->inp_vflag);
710 continue;
711 }
712 if ((sock = calloc(1, sizeof(*sock))) == NULL)
713 xo_err(1, "malloc()");
714 if ((laddr = calloc(1, sizeof *laddr)) == NULL)
715 xo_err(1, "malloc()");
716 if ((faddr = calloc(1, sizeof *faddr)) == NULL)
717 xo_err(1, "malloc()");
718 sock->socket = so->xso_so;
719 sock->pcb = so->so_pcb;
720 sock->splice_socket = so->so_splice_so;
721 sock->proto = proto;
722 sock->inp_gencnt = xip->inp_gencnt;
723 sock->fibnum = so->so_fibnum;
724 if (xip->inp_vflag & INP_IPV4) {
725 sock->family = AF_INET;
726 sockaddr(&laddr->address, sock->family,
727 &xip->inp_laddr, xip->inp_lport);
728 sockaddr(&faddr->address, sock->family,
729 &xip->inp_faddr, xip->inp_fport);
730 } else if (xip->inp_vflag & INP_IPV6) {
731 sock->family = AF_INET6;
732 sockaddr(&laddr->address, sock->family,
733 &xip->in6p_laddr, xip->inp_lport);
734 sockaddr(&faddr->address, sock->family,
735 &xip->in6p_faddr, xip->inp_fport);
736 }
737 if (proto == IPPROTO_TCP)
738 faddr->encaps_port = xtp->xt_encaps_port;
739 laddr->next = NULL;
740 faddr->next = NULL;
741 sock->laddr = laddr;
742 sock->faddr = faddr;
743 sock->vflag = xip->inp_vflag;
744 if (proto == IPPROTO_TCP) {
745 sock->state = xtp->t_state;
746 sock->bblog_state = xtp->t_logstate;
747 memcpy(sock->stack, xtp->xt_stack,
748 TCP_FUNCTION_NAME_LEN_MAX);
749 memcpy(sock->cc, xtp->xt_cc, TCP_CA_NAME_MAX);
750 }
751 sock->protoname = protoname;
752 if (sock->socket != 0)
753 RB_INSERT(socks_t, &socks, sock);
754 else
755 SLIST_INSERT_HEAD(&nosocks, sock, socket_list);
756 }
757 out:
758 free(buf);
759 }
760
761 static void
gather_unix(int proto)762 gather_unix(int proto)
763 {
764 struct xunpgen *xug, *exug;
765 struct xunpcb *xup;
766 struct sock *sock;
767 struct addr *laddr, *faddr;
768 const char *varname, *protoname;
769 size_t len, bufsize;
770 void *buf;
771 int retry;
772
773 switch (proto) {
774 case SOCK_STREAM:
775 varname = "net.local.stream.pcblist";
776 protoname = "stream";
777 break;
778 case SOCK_DGRAM:
779 varname = "net.local.dgram.pcblist";
780 protoname = "dgram";
781 break;
782 case SOCK_SEQPACKET:
783 varname = "net.local.seqpacket.pcblist";
784 protoname = is_xo_style_encoding ? "seqpacket" : "seqpack";
785 break;
786 default:
787 abort();
788 }
789 buf = NULL;
790 bufsize = 8192;
791 retry = 5;
792 do {
793 for (;;) {
794 if ((buf = realloc(buf, bufsize)) == NULL)
795 xo_err(1, "realloc()");
796 len = bufsize;
797 if (cap_sysctlbyname(capsysctl, varname, buf, &len,
798 NULL, 0) == 0)
799 break;
800 if (errno != ENOMEM || len != bufsize)
801 xo_err(1, "cap_sysctlbyname()");
802 bufsize *= 2;
803 }
804 xug = (struct xunpgen *)buf;
805 exug = (struct xunpgen *)(void *)
806 ((char *)buf + len - sizeof(*exug));
807 if (!check_ksize(xug->xug_len, struct xunpgen) ||
808 !check_ksize(exug->xug_len, struct xunpgen))
809 goto out;
810 } while (xug->xug_gen != exug->xug_gen && retry--);
811
812 if (xug->xug_gen != exug->xug_gen && opt_v)
813 xo_warnx("warning: data may be inconsistent");
814
815 for (;;) {
816 xug = (struct xunpgen *)(void *)((char *)xug + xug->xug_len);
817 if (xug >= exug)
818 break;
819 xup = (struct xunpcb *)xug;
820 if (!check_ksize(xup->xu_len, struct xunpcb))
821 goto out;
822 if ((xup->unp_conn == 0 && !opt_l) ||
823 (xup->unp_conn != 0 && !opt_c))
824 continue;
825 if ((sock = calloc(1, sizeof(*sock))) == NULL)
826 xo_err(1, "malloc()");
827 if ((laddr = calloc(1, sizeof *laddr)) == NULL)
828 xo_err(1, "malloc()");
829 if ((faddr = calloc(1, sizeof *faddr)) == NULL)
830 xo_err(1, "malloc()");
831 sock->socket = xup->xu_socket.xso_so;
832 sock->pcb = xup->xu_unpp;
833 sock->proto = proto;
834 sock->family = AF_UNIX;
835 sock->protoname = protoname;
836 if (xup->xu_addr.sun_family == AF_UNIX)
837 laddr->address =
838 *(struct sockaddr_storage *)(void *)&xup->xu_addr;
839 faddr->conn = xup->unp_conn;
840 faddr->firstref = xup->xu_firstref;
841 faddr->nextref = xup->xu_nextref;
842 laddr->next = NULL;
843 faddr->next = NULL;
844 sock->laddr = laddr;
845 sock->faddr = faddr;
846 RB_INSERT(socks_t, &socks, sock);
847 RB_INSERT(pcbs_t, &pcbs, sock);
848 }
849 out:
850 free(buf);
851 }
852
853 static void
getfiles(void)854 getfiles(void)
855 {
856 struct xfile *xfiles;
857 size_t len, olen;
858
859 olen = len = sizeof(*xfiles);
860 if ((xfiles = malloc(len)) == NULL)
861 xo_err(1, "malloc()");
862 while (cap_sysctlbyname(capsysctl, "kern.file", xfiles, &len, 0, 0)
863 == -1) {
864 if (errno != ENOMEM || len != olen)
865 xo_err(1, "cap_sysctlbyname()");
866 olen = len *= 2;
867 if ((xfiles = realloc(xfiles, len)) == NULL)
868 xo_err(1, "realloc()");
869 }
870 if (len > 0)
871 enforce_ksize(xfiles->xf_size, struct xfile);
872 nfiles = len / sizeof(*xfiles);
873
874 if ((files = malloc(nfiles * sizeof(struct file))) == NULL)
875 xo_err(1, "malloc()");
876
877 for (int i = 0; i < nfiles; i++) {
878 files[i].xf_data = xfiles[i].xf_data;
879 files[i].xf_pid = xfiles[i].xf_pid;
880 files[i].xf_uid = xfiles[i].xf_uid;
881 files[i].xf_fd = xfiles[i].xf_fd;
882 RB_INSERT(files_t, &ftree, &files[i]);
883 }
884
885 free(xfiles);
886 }
887
888 static int
formataddr(struct sockaddr_storage * ss,char * buf,size_t bufsize)889 formataddr(struct sockaddr_storage *ss, char *buf, size_t bufsize)
890 {
891 struct sockaddr_un *sun;
892 char addrstr[NI_MAXHOST] = { '\0', '\0' };
893 int error, off, port = 0;
894
895 switch (ss->ss_family) {
896 case AF_INET:
897 if (sstosin(ss)->sin_addr.s_addr == INADDR_ANY)
898 addrstr[0] = '*';
899 port = ntohs(sstosin(ss)->sin_port);
900 break;
901 case AF_INET6:
902 if (IN6_IS_ADDR_UNSPECIFIED(&sstosin6(ss)->sin6_addr))
903 addrstr[0] = '*';
904 port = ntohs(sstosin6(ss)->sin6_port);
905 break;
906 case AF_UNIX:
907 sun = sstosun(ss);
908 off = (int)((char *)&sun->sun_path - (char *)sun);
909 if (is_xo_style_encoding) {
910 xo_emit("{:path/%.*s}", sun->sun_len - off,
911 sun->sun_path);
912 return 0;
913 }
914 return snprintf(buf, bufsize, "%.*s",
915 sun->sun_len - off, sun->sun_path);
916 }
917 if (addrstr[0] == '\0') {
918 error = cap_getnameinfo(capnet, sstosa(ss), ss->ss_len,
919 addrstr, sizeof(addrstr), NULL, 0, NI_NUMERICHOST);
920 if (error)
921 xo_errx(1, "cap_getnameinfo()");
922 }
923 if (is_xo_style_encoding) {
924 xo_emit("{:address/%s}", addrstr);
925 xo_emit("{:port/%d}", port);
926 return 0;
927 }
928 if (port == 0)
929 return snprintf(buf, bufsize, "%s:*", addrstr);
930 return snprintf(buf, bufsize, "%s:%d", addrstr, port);
931 }
932
933 static const char *
getprocname(pid_t pid)934 getprocname(pid_t pid)
935 {
936 static struct kinfo_proc proc;
937 size_t len;
938 int mib[4];
939
940 mib[0] = CTL_KERN;
941 mib[1] = KERN_PROC;
942 mib[2] = KERN_PROC_PID;
943 mib[3] = (int)pid;
944 len = sizeof(proc);
945 if (cap_sysctl(capsysctl, mib, nitems(mib), &proc, &len, NULL, 0)
946 == -1) {
947 /* Do not warn if the process exits before we get its name. */
948 if (errno != ESRCH)
949 xo_warn("cap_sysctl()");
950 return ("??");
951 }
952 return (proc.ki_comm);
953 }
954
955 static int
getprocjid(pid_t pid)956 getprocjid(pid_t pid)
957 {
958 static struct kinfo_proc proc;
959 size_t len;
960 int mib[4];
961
962 mib[0] = CTL_KERN;
963 mib[1] = KERN_PROC;
964 mib[2] = KERN_PROC_PID;
965 mib[3] = (int)pid;
966 len = sizeof(proc);
967 if (cap_sysctl(capsysctl, mib, nitems(mib), &proc, &len, NULL, 0)
968 == -1) {
969 /* Do not warn if the process exits before we get its jid. */
970 if (errno != ESRCH)
971 xo_warn("cap_sysctl()");
972 return (-1);
973 }
974 return (proc.ki_jid);
975 }
976
977 static int
check_ports(struct sock * s)978 check_ports(struct sock *s)
979 {
980 int port;
981 struct addr *addr;
982
983 if (ports == NULL)
984 return (1);
985 if ((s->family != AF_INET) && (s->family != AF_INET6))
986 return (1);
987 for (addr = s->laddr; addr != NULL; addr = addr->next) {
988 if (s->family == AF_INET)
989 port = ntohs(sstosin(&addr->address)->sin_port);
990 else
991 port = ntohs(sstosin6(&addr->address)->sin6_port);
992 if (CHK_PORT(port))
993 return (1);
994 }
995 for (addr = s->faddr; addr != NULL; addr = addr->next) {
996 if (s->family == AF_INET)
997 port = ntohs(sstosin(&addr->address)->sin_port);
998 else
999 port = ntohs(sstosin6(&addr->address)->sin6_port);
1000 if (CHK_PORT(port))
1001 return (1);
1002 }
1003 return (0);
1004 }
1005
1006 static const char *
sctp_conn_state(int state)1007 sctp_conn_state(int state)
1008 {
1009 switch (state) {
1010 case SCTP_CLOSED:
1011 return "CLOSED";
1012 break;
1013 case SCTP_BOUND:
1014 return "BOUND";
1015 break;
1016 case SCTP_LISTEN:
1017 return "LISTEN";
1018 break;
1019 case SCTP_COOKIE_WAIT:
1020 return "COOKIE_WAIT";
1021 break;
1022 case SCTP_COOKIE_ECHOED:
1023 return "COOKIE_ECHOED";
1024 break;
1025 case SCTP_ESTABLISHED:
1026 return "ESTABLISHED";
1027 break;
1028 case SCTP_SHUTDOWN_SENT:
1029 return "SHUTDOWN_SENT";
1030 break;
1031 case SCTP_SHUTDOWN_RECEIVED:
1032 return "SHUTDOWN_RECEIVED";
1033 break;
1034 case SCTP_SHUTDOWN_ACK_SENT:
1035 return "SHUTDOWN_ACK_SENT";
1036 break;
1037 case SCTP_SHUTDOWN_PENDING:
1038 return "SHUTDOWN_PENDING";
1039 break;
1040 default:
1041 return "UNKNOWN";
1042 break;
1043 }
1044 }
1045
1046 static const char *
sctp_path_state(int state)1047 sctp_path_state(int state)
1048 {
1049 switch (state) {
1050 case SCTP_UNCONFIRMED:
1051 return "UNCONFIRMED";
1052 break;
1053 case SCTP_ACTIVE:
1054 return "ACTIVE";
1055 break;
1056 case SCTP_INACTIVE:
1057 return "INACTIVE";
1058 break;
1059 default:
1060 return "UNKNOWN";
1061 break;
1062 }
1063 }
1064
1065 static const char *
bblog_state(int state)1066 bblog_state(int state)
1067 {
1068 switch (state) {
1069 case TCP_LOG_STATE_OFF:
1070 return "OFF";
1071 break;
1072 case TCP_LOG_STATE_TAIL:
1073 return "TAIL";
1074 break;
1075 case TCP_LOG_STATE_HEAD:
1076 return "HEAD";
1077 break;
1078 case TCP_LOG_STATE_HEAD_AUTO:
1079 return "HEAD_AUTO";
1080 break;
1081 case TCP_LOG_STATE_CONTINUAL:
1082 return "CONTINUAL";
1083 break;
1084 case TCP_LOG_STATE_TAIL_AUTO:
1085 return "TAIL_AUTO";
1086 break;
1087 case TCP_LOG_VIA_BBPOINTS:
1088 return "BBPOINTS";
1089 break;
1090 default:
1091 return "UNKNOWN";
1092 break;
1093 }
1094 }
1095
1096 static int
format_unix_faddr(struct addr * faddr,char * buf,size_t bufsize)1097 format_unix_faddr(struct addr *faddr, char *buf, size_t bufsize) {
1098 #define SAFEBUF (buf == NULL ? NULL : buf + pos)
1099 #define SAFESIZE (buf == NULL ? 0 : bufsize - pos)
1100
1101 size_t pos = 0;
1102 if (faddr->conn != 0) {
1103 /* Remote peer we connect(2) to, if any. */
1104 struct sock *p;
1105 if (!is_xo_style_encoding)
1106 pos += strlcpy(SAFEBUF, "-> ", SAFESIZE);
1107 p = RB_FIND(pcbs_t, &pcbs,
1108 &(struct sock){ .pcb = faddr->conn });
1109 if (__predict_false(p == NULL) && !is_xo_style_encoding) {
1110 /* XXGL: can this happen at all? */
1111 pos += snprintf(SAFEBUF, SAFESIZE, "??");
1112 } else if (p->laddr->address.ss_len == 0) {
1113 struct file *f;
1114 f = RB_FIND(files_t, &ftree,
1115 &(struct file){ .xf_data =
1116 p->socket });
1117 if (f != NULL) {
1118 if (!is_xo_style_encoding) {
1119 pos += snprintf(SAFEBUF, SAFESIZE,
1120 "[%lu %d]", (u_long)f->xf_pid,
1121 f->xf_fd);
1122 } else {
1123 xo_open_list("connections");
1124 xo_open_instance("connections");
1125 xo_emit("{:pid/%lu}", (u_long)f->xf_pid);
1126 xo_emit("{:fd/%d}", f->xf_fd);
1127 xo_close_instance("connections");
1128 xo_close_list("connections");
1129 }
1130 }
1131 } else
1132 pos += formataddr(&p->laddr->address,
1133 SAFEBUF, SAFESIZE);
1134 } else if (faddr->firstref != 0) {
1135 /* Remote peer(s) connect(2)ed to us, if any. */
1136 struct sock *p;
1137 struct file *f;
1138 kvaddr_t ref = faddr->firstref;
1139 bool fref = true;
1140
1141 if (!is_xo_style_encoding)
1142 pos += snprintf(SAFEBUF, SAFESIZE, " <- ");
1143 xo_open_list("connections");
1144 while ((p = RB_FIND(pcbs_t, &pcbs,
1145 &(struct sock){ .pcb = ref })) != 0) {
1146 f = RB_FIND(files_t, &ftree,
1147 &(struct file){ .xf_data = p->socket });
1148 if (f != NULL) {
1149 if (!is_xo_style_encoding) {
1150 pos += snprintf(SAFEBUF, SAFESIZE,
1151 "%s[%lu %d]", fref ? "" : ",",
1152 (u_long)f->xf_pid, f->xf_fd);
1153 } else {
1154 xo_open_instance("connections");
1155 xo_emit("{:pid/%lu}", (u_long)f->xf_pid);
1156 xo_emit("{:fd/%d}", f->xf_fd);
1157 xo_close_instance("connections");
1158 }
1159 }
1160 ref = p->faddr->nextref;
1161 fref = false;
1162 }
1163 xo_close_list("connections");
1164 }
1165 return pos;
1166 }
1167
1168 struct col_widths {
1169 int user;
1170 int command;
1171 int pid;
1172 int fd;
1173 int proto;
1174 int local_addr;
1175 int foreign_addr;
1176 int pcb_kva;
1177 int fib;
1178 int splice_address;
1179 int inp_gencnt;
1180 int encaps;
1181 int path_state;
1182 int conn_state;
1183 int bblog_state;
1184 int stack;
1185 int cc;
1186 };
1187
1188 static void
calculate_sock_column_widths(struct col_widths * cw,struct sock * s)1189 calculate_sock_column_widths(struct col_widths *cw, struct sock *s)
1190 {
1191 struct addr *laddr, *faddr;
1192 bool first = true;
1193 int len = 0;
1194 laddr = s->laddr;
1195 faddr = s->faddr;
1196 first = true;
1197
1198 len = strlen(s->protoname);
1199 if (s->vflag & (INP_IPV4 | INP_IPV6))
1200 len += 1;
1201 cw->proto = MAX(cw->proto, len);
1202
1203 while (laddr != NULL || faddr != NULL) {
1204 if (opt_w && s->family == AF_UNIX) {
1205 if ((laddr == NULL) || (faddr == NULL))
1206 xo_errx(1, "laddr = %p or faddr = %p is NULL",
1207 (void *)laddr, (void *)faddr);
1208 if (laddr->address.ss_len > 0)
1209 len = formataddr(&laddr->address, NULL, 0);
1210 cw->local_addr = MAX(cw->local_addr, len);
1211 len = format_unix_faddr(faddr, NULL, 0);
1212 cw->foreign_addr = MAX(cw->foreign_addr, len);
1213 } else if (opt_w) {
1214 if (laddr != NULL) {
1215 len = formataddr(&laddr->address, NULL, 0);
1216 cw->local_addr = MAX(cw->local_addr, len);
1217 }
1218 if (faddr != NULL) {
1219 len = formataddr(&faddr->address, NULL, 0);
1220 cw->foreign_addr = MAX(cw->foreign_addr, len);
1221 }
1222 }
1223 if (opt_f) {
1224 len = snprintf(NULL, 0, "%d", s->fibnum);
1225 cw->fib = MAX(cw->fib, len);
1226 }
1227 if (opt_I) {
1228 if (s->splice_socket != 0) {
1229 struct sock *sp;
1230
1231 sp = RB_FIND(socks_t, &socks, &(struct sock)
1232 { .socket = s->splice_socket });
1233 if (sp != NULL) {
1234 len = formataddr(&sp->laddr->address,
1235 NULL, 0);
1236 cw->splice_address = MAX(
1237 cw->splice_address, len);
1238 }
1239 }
1240 }
1241 if (opt_i) {
1242 if (s->proto == IPPROTO_TCP ||
1243 s->proto == IPPROTO_UDP) {
1244 len = snprintf(NULL, 0,
1245 "%" PRIu64, s->inp_gencnt);
1246 cw->inp_gencnt = MAX(cw->inp_gencnt, len);
1247 }
1248 }
1249 if (opt_U) {
1250 if (faddr != NULL &&
1251 ((s->proto == IPPROTO_SCTP &&
1252 s->state != SCTP_CLOSED &&
1253 s->state != SCTP_BOUND &&
1254 s->state != SCTP_LISTEN) ||
1255 (s->proto == IPPROTO_TCP &&
1256 s->state != TCPS_CLOSED &&
1257 s->state != TCPS_LISTEN))) {
1258 len = snprintf(NULL, 0, "%u",
1259 ntohs(faddr->encaps_port));
1260 cw->encaps = MAX(cw->encaps, len);
1261 }
1262 }
1263 if (opt_s) {
1264 if (faddr != NULL &&
1265 s->proto == IPPROTO_SCTP &&
1266 s->state != SCTP_CLOSED &&
1267 s->state != SCTP_BOUND &&
1268 s->state != SCTP_LISTEN) {
1269 len = strlen(sctp_path_state(faddr->state));
1270 cw->path_state = MAX(cw->path_state, len);
1271 }
1272 }
1273 if (first) {
1274 if (opt_s) {
1275 if (s->proto == IPPROTO_SCTP ||
1276 s->proto == IPPROTO_TCP) {
1277 switch (s->proto) {
1278 case IPPROTO_SCTP:
1279 len = strlen(
1280 sctp_conn_state(s->state));
1281 cw->conn_state = MAX(
1282 cw->conn_state, len);
1283 break;
1284 case IPPROTO_TCP:
1285 if (s->state >= 0 &&
1286 s->state < TCP_NSTATES) {
1287 len = strlen(
1288 tcpstates[s->state]);
1289 cw->conn_state = MAX(
1290 cw->conn_state,
1291 len);
1292 }
1293 break;
1294 }
1295 }
1296 }
1297 if (opt_S && s->proto == IPPROTO_TCP) {
1298 len = strlen(s->stack);
1299 cw->stack = MAX(cw->stack, len);
1300 }
1301 if (opt_C && s->proto == IPPROTO_TCP) {
1302 len = strlen(s->cc);
1303 cw->cc = MAX(cw->cc, len);
1304 }
1305 }
1306 if (laddr != NULL)
1307 laddr = laddr->next;
1308 if (faddr != NULL)
1309 faddr = faddr->next;
1310 first = false;
1311 }
1312 }
1313
1314 static void
calculate_column_widths(struct col_widths * cw)1315 calculate_column_widths(struct col_widths *cw)
1316 {
1317 int n, len;
1318 struct file *xf;
1319 struct sock *s;
1320 struct passwd *pwd;
1321
1322 cap_setpassent(cappwd, 1);
1323 for (xf = files, n = 0; n < nfiles; ++n, ++xf) {
1324 if (xf->xf_data == 0)
1325 continue;
1326 if (opt_j >= 0 && opt_j != getprocjid(xf->xf_pid))
1327 continue;
1328 s = RB_FIND(socks_t, &socks,
1329 &(struct sock){ .socket = xf->xf_data});
1330 if (s == NULL || (!check_ports(s)))
1331 continue;
1332 s->shown = 1;
1333 if (opt_n ||
1334 (pwd = cap_getpwuid(cappwd, xf->xf_uid)) == NULL)
1335 len = snprintf(NULL, 0, "%lu", (u_long)xf->xf_uid);
1336 else
1337 len = snprintf(NULL, 0, "%s", pwd->pw_name);
1338 cw->user = MAX(cw->user, len);
1339 len = snprintf(NULL, 0, "%lu", (u_long)xf->xf_pid);
1340 cw->pid = MAX(cw->pid, len);
1341 len = snprintf(NULL, 0, "%d", xf->xf_fd);
1342 cw->fd = MAX(cw->fd, len);
1343
1344 calculate_sock_column_widths(cw, s);
1345 }
1346 if (opt_j >= 0)
1347 return;
1348 SLIST_FOREACH(s, &nosocks, socket_list) {
1349 if (!check_ports(s))
1350 continue;
1351 calculate_sock_column_widths(cw, s);
1352 }
1353 RB_FOREACH(s, socks_t, &socks) {
1354 if (s->shown)
1355 continue;
1356 if (!check_ports(s))
1357 continue;
1358 calculate_sock_column_widths(cw, s);
1359 }
1360 }
1361
1362 static void
display_sock(struct sock * s,struct col_widths * cw,char * buf,size_t bufsize)1363 display_sock(struct sock *s, struct col_widths *cw, char *buf, size_t bufsize)
1364 {
1365 struct addr *laddr, *faddr;
1366 bool first;
1367 laddr = s->laddr;
1368 faddr = s->faddr;
1369 first = true;
1370
1371 snprintf(buf, bufsize, "%s%s%s",
1372 s->protoname,
1373 s->vflag & INP_IPV4 ? "4" : "",
1374 s->vflag & INP_IPV6 ? "6" : "");
1375 xo_emit(" {:proto/%-*s}", cw->proto, buf);
1376 while (laddr != NULL || faddr != NULL) {
1377 if (s->family == AF_UNIX) {
1378 if ((laddr == NULL) || (faddr == NULL))
1379 xo_errx(1, "laddr = %p or faddr = %p is NULL",
1380 (void *)laddr, (void *)faddr);
1381 if (laddr->address.ss_len > 0) {
1382 xo_open_container("local");
1383 formataddr(&laddr->address, buf, bufsize);
1384 if (!is_xo_style_encoding) {
1385 xo_emit(" {:local-address/%-*.*s}",
1386 cw->local_addr, cw->local_addr,
1387 buf);
1388 }
1389 xo_close_container("local");
1390 } else if (laddr->address.ss_len == 0 &&
1391 faddr->conn == 0 && !is_xo_style_encoding) {
1392 xo_emit(" {:local-address/%-*.*s}",
1393 cw->local_addr, cw->local_addr,
1394 "(not connected)");
1395 } else if (!is_xo_style_encoding) {
1396 xo_emit(" {:local-address/%-*.*s}",
1397 cw->local_addr, cw->local_addr, "??");
1398 }
1399 if (faddr->conn != 0 || faddr->firstref != 0) {
1400 xo_open_container("foreign");
1401 int len = format_unix_faddr(faddr, buf,
1402 bufsize);
1403 if (len == 0 && !is_xo_style_encoding)
1404 xo_emit(" {:foreign-address/%-*s}",
1405 cw->foreign_addr, "??");
1406 else if (!is_xo_style_encoding)
1407 xo_emit(" {:foreign-address/%-*.*s}",
1408 cw->foreign_addr,
1409 cw->foreign_addr, buf);
1410 xo_close_container("foreign");
1411 } else if (!is_xo_style_encoding)
1412 xo_emit(" {:foreign-address/%-*s}",
1413 cw->foreign_addr, "??");
1414 } else {
1415 if (laddr != NULL) {
1416 xo_open_container("local");
1417 formataddr(&laddr->address, buf, bufsize);
1418 if (!is_xo_style_encoding) {
1419 xo_emit(" {:local-address/%-*.*s}",
1420 cw->local_addr, cw->local_addr,
1421 buf);
1422 }
1423 xo_close_container("local");
1424 } else if (!is_xo_style_encoding)
1425 xo_emit(" {:local-address/%-*.*s}",
1426 cw->local_addr, cw->local_addr, "??");
1427 if (faddr != NULL) {
1428 xo_open_container("foreign");
1429 formataddr(&faddr->address, buf, bufsize);
1430 if (!is_xo_style_encoding) {
1431 xo_emit(" {:foreign-address/%-*.*s}",
1432 cw->foreign_addr,
1433 cw->foreign_addr, buf);
1434 }
1435 xo_close_container("foreign");
1436 } else if (!is_xo_style_encoding) {
1437 xo_emit(" {:foreign-address/%-*.*s}",
1438 cw->foreign_addr, cw->foreign_addr,
1439 "??");
1440 }
1441 }
1442 if (opt_A) {
1443 snprintf(buf, bufsize, "%#*" PRIx64,
1444 cw->pcb_kva, s->pcb);
1445 xo_emit(" {:pcb-kva/%s}", buf);
1446 }
1447 if (opt_f)
1448 xo_emit(" {:fib/%*d}", cw->fib, s->fibnum);
1449 if (opt_I) {
1450 if (s->splice_socket != 0) {
1451 struct sock *sp;
1452 sp = RB_FIND(socks_t, &socks, &(struct sock)
1453 { .socket = s->splice_socket });
1454 if (sp != NULL) {
1455 xo_open_container("splice");
1456 formataddr(&sp->laddr->address,
1457 buf, bufsize);
1458 xo_close_container("splice");
1459 } else if (!is_xo_style_encoding)
1460 strlcpy(buf, "??", bufsize);
1461 } else if (!is_xo_style_encoding)
1462 strlcpy(buf, "??", bufsize);
1463 if (!is_xo_style_encoding)
1464 xo_emit(" {:splice-address/%-*s}",
1465 cw->splice_address, buf);
1466 }
1467 if (opt_i) {
1468 if (s->proto == IPPROTO_TCP ||
1469 s->proto == IPPROTO_UDP) {
1470 snprintf(buf, bufsize, "%" PRIu64,
1471 s->inp_gencnt);
1472 xo_emit(" {:id/%*s}", cw->inp_gencnt, buf);
1473 } else if (!is_xo_style_encoding)
1474 xo_emit(" {:id/%*s}", cw->inp_gencnt, "??");
1475 }
1476 if (opt_U) {
1477 if (faddr != NULL &&
1478 ((s->proto == IPPROTO_SCTP &&
1479 s->state != SCTP_CLOSED &&
1480 s->state != SCTP_BOUND &&
1481 s->state != SCTP_LISTEN) ||
1482 (s->proto == IPPROTO_TCP &&
1483 s->state != TCPS_CLOSED &&
1484 s->state != TCPS_LISTEN))) {
1485 xo_emit(" {:encaps/%*u}", cw->encaps,
1486 ntohs(faddr->encaps_port));
1487 } else if (!is_xo_style_encoding)
1488 xo_emit(" {:encaps/%*s}", cw->encaps, "??");
1489 }
1490 if (opt_s && show_path_state) {
1491 if (faddr != NULL &&
1492 s->proto == IPPROTO_SCTP &&
1493 s->state != SCTP_CLOSED &&
1494 s->state != SCTP_BOUND &&
1495 s->state != SCTP_LISTEN) {
1496 xo_emit(" {:path-state/%-*s}", cw->path_state,
1497 sctp_path_state(faddr->state));
1498 } else if (!is_xo_style_encoding)
1499 xo_emit(" {:path-state/%-*s}", cw->path_state,
1500 "??");
1501 }
1502 if (first) {
1503 if (opt_s) {
1504 if (s->proto == IPPROTO_SCTP ||
1505 s->proto == IPPROTO_TCP) {
1506 switch (s->proto) {
1507 case IPPROTO_SCTP:
1508 xo_emit(" {:conn-state/%-*s}",
1509 cw->conn_state,
1510 sctp_conn_state(s->state));
1511 break;
1512 case IPPROTO_TCP:
1513 if (s->state >= 0 &&
1514 s->state < TCP_NSTATES)
1515 xo_emit(" {:conn-state/%-*s}",
1516 cw->conn_state,
1517 tcpstates[s->state]);
1518 else if (!is_xo_style_encoding)
1519 xo_emit(" {:conn-state/%-*s}",
1520 cw->conn_state, "??");
1521 break;
1522 }
1523 } else if (!is_xo_style_encoding)
1524 xo_emit(" {:conn-state/%-*s}",
1525 cw->conn_state, "??");
1526 }
1527 if (opt_b) {
1528 if (s->proto == IPPROTO_TCP)
1529 xo_emit(" {:bblog-state/%-*s}",
1530 cw->bblog_state,
1531 bblog_state(s->bblog_state));
1532 else if (!is_xo_style_encoding)
1533 xo_emit(" {:bblog-state/%-*s}",
1534 cw->bblog_state, "??");
1535 }
1536 if (opt_S) {
1537 if (s->proto == IPPROTO_TCP)
1538 xo_emit(" {:stack/%-*s}",
1539 cw->stack, s->stack);
1540 else if (!is_xo_style_encoding)
1541 xo_emit(" {:stack/%-*s}",
1542 cw->stack, "??");
1543 }
1544 if (opt_C) {
1545 if (s->proto == IPPROTO_TCP)
1546 xo_emit(" {:cc/%-*s}", cw->cc, s->cc);
1547 else if (!is_xo_style_encoding)
1548 xo_emit(" {:cc/%-*s}", cw->cc, "??");
1549 }
1550 } else if (!is_xo_style_encoding) {
1551 if (opt_s)
1552 xo_emit(" {:conn-state/%-*s}", cw->conn_state,
1553 "??");
1554 if (opt_b)
1555 xo_emit(" {:bblog-state/%-*s}", cw->bblog_state,
1556 "??");
1557 if (opt_S)
1558 xo_emit(" {:stack/%-*s}", cw->stack, "??");
1559 if (opt_C)
1560 xo_emit(" {:cc/%-*s}", cw->cc, "??");
1561 }
1562 if (laddr != NULL)
1563 laddr = laddr->next;
1564 if (faddr != NULL)
1565 faddr = faddr->next;
1566 xo_emit("\n");
1567 if (!is_xo_style_encoding && (laddr != NULL || faddr != NULL))
1568 xo_emit("{:user/%-*s} {:command/%-*s} {:pid/%*s}"
1569 " {:fd/%*s} {:proto/%-*s}", cw->user, "??",
1570 cw->command, "??", cw->pid, "??", cw->fd, "??",
1571 cw->proto, "??");
1572 first = false;
1573 }
1574 }
1575
1576 static void
display(void)1577 display(void)
1578 {
1579 struct passwd *pwd;
1580 struct file *xf;
1581 struct sock *s;
1582 int n;
1583 struct col_widths cw;
1584 const size_t bufsize = 512;
1585 void *buf;
1586 if ((buf = (char *)malloc(bufsize)) == NULL) {
1587 xo_err(1, "malloc()");
1588 return;
1589 }
1590
1591 if (!is_xo_style_encoding) {
1592 cw = (struct col_widths) {
1593 .user = strlen("USER"),
1594 .command = 10,
1595 .pid = strlen("PID"),
1596 .fd = strlen("FD"),
1597 .proto = strlen("PROTO"),
1598 .local_addr = opt_w ? strlen("LOCAL ADDRESS") : 21,
1599 .foreign_addr = opt_w ? strlen("FOREIGN ADDRESS") : 21,
1600 .pcb_kva = 18,
1601 .fib = strlen("FIB"),
1602 .splice_address = strlen("SPLICE ADDRESS"),
1603 .inp_gencnt = strlen("ID"),
1604 .encaps = strlen("ENCAPS"),
1605 .path_state = strlen("PATH STATE"),
1606 .conn_state = strlen("CONN STATE"),
1607 .bblog_state = strlen("BBLOG STATE"),
1608 .stack = strlen("STACK"),
1609 .cc = strlen("CC"),
1610 };
1611 calculate_column_widths(&cw);
1612 } else
1613 memset(&cw, 0, sizeof(cw));
1614
1615 xo_set_version(SOCKSTAT_XO_VERSION);
1616 xo_open_container("sockstat");
1617 xo_open_list("socket");
1618 if (!opt_q) {
1619 xo_emit("{T:/%-*s} {T:/%-*s} {T:/%*s} {T:/%*s} {T:/%-*s} "
1620 "{T:/%-*s} {T:/%-*s}", cw.user, "USER", cw.command,
1621 "COMMAND", cw.pid, "PID", cw.fd, "FD", cw.proto,
1622 "PROTO", cw.local_addr, "LOCAL ADDRESS",
1623 cw.foreign_addr, "FOREIGN ADDRESS");
1624 if (opt_A)
1625 xo_emit(" {T:/%-*s}", cw.pcb_kva, "PCB KVA");
1626 if (opt_f)
1627 /* RT_MAXFIBS is 65535. */
1628 xo_emit(" {T:/%*s}", cw.fib, "FIB");
1629 if (opt_I)
1630 xo_emit(" {T:/%-*s}", cw.splice_address,
1631 "SPLICE ADDRESS");
1632 if (opt_i)
1633 xo_emit(" {T:/%*s}", cw.inp_gencnt, "ID");
1634 if (opt_U)
1635 xo_emit(" {T:/%*s}", cw.encaps, "ENCAPS");
1636 if (opt_s) {
1637 if (show_path_state)
1638 xo_emit(" {T:/%-*s}", cw.path_state,
1639 "PATH STATE");
1640 xo_emit(" {T:/%-*s}", cw.conn_state, "CONN STATE");
1641 }
1642 if (opt_b)
1643 xo_emit(" {T:/%-*s}", cw.bblog_state, "BBLOG STATE");
1644 if (opt_S)
1645 xo_emit(" {T:/%-*s}", cw.stack, "STACK");
1646 if (opt_C)
1647 xo_emit(" {T:/%-*s}", cw.cc, "CC");
1648 xo_emit("\n");
1649 }
1650 cap_setpassent(cappwd, 1);
1651 for (xf = files, n = 0; n < nfiles; ++n, ++xf) {
1652 if (xf->xf_data == 0)
1653 continue;
1654 if (opt_j >= 0 && opt_j != getprocjid(xf->xf_pid))
1655 continue;
1656 s = RB_FIND(socks_t, &socks,
1657 &(struct sock){ .socket = xf->xf_data});
1658 if (s != NULL && check_ports(s)) {
1659 xo_open_instance("socket");
1660 s->shown = 1;
1661 if (opt_n ||
1662 (pwd = cap_getpwuid(cappwd, xf->xf_uid)) == NULL)
1663 xo_emit("{:user/%-*lu}", cw.user,
1664 (u_long)xf->xf_uid);
1665 else
1666 xo_emit("{:user/%-*s}", cw.user, pwd->pw_name);
1667 if (!is_xo_style_encoding)
1668 xo_emit(" {:command/%-*.10s}", cw.command,
1669 getprocname(xf->xf_pid));
1670 else
1671 xo_emit(" {:command/%-*s}", cw.command,
1672 getprocname(xf->xf_pid));
1673 xo_emit(" {:pid/%*lu}", cw.pid, (u_long)xf->xf_pid);
1674 xo_emit(" {:fd/%*d}", cw.fd, xf->xf_fd);
1675 display_sock(s, &cw, buf, bufsize);
1676 xo_close_instance("socket");
1677 }
1678 }
1679 if (opt_j >= 0)
1680 goto out;
1681 SLIST_FOREACH(s, &nosocks, socket_list) {
1682 if (!check_ports(s))
1683 continue;
1684 xo_open_instance("socket");
1685 if (!is_xo_style_encoding)
1686 xo_emit("{:user/%-*s} {:command/%-*s} {:pid/%*s}"
1687 " {:fd/%*s}", cw.user, "??", cw.command, "??",
1688 cw.pid, "??", cw.fd, "??");
1689 display_sock(s, &cw, buf, bufsize);
1690 xo_close_instance("socket");
1691 }
1692 RB_FOREACH(s, socks_t, &socks) {
1693 if (s->shown)
1694 continue;
1695 if (!check_ports(s))
1696 continue;
1697 xo_open_instance("socket");
1698 if (!is_xo_style_encoding)
1699 xo_emit("{:user/%-*s} {:command/%-*s} {:pid/%*s}"
1700 " {:fd/%*s}", cw.user, "??", cw.command, "??",
1701 cw.pid, "??", cw.fd, "??");
1702 display_sock(s, &cw, buf, bufsize);
1703 xo_close_instance("socket");
1704 }
1705 out:
1706 xo_close_list("socket");
1707 xo_close_container("sockstat");
1708 if (xo_finish() < 0)
1709 xo_err(1, "stdout");
1710 free(buf);
1711 cap_endpwent(cappwd);
1712 }
1713
1714 static int
set_default_protos(void)1715 set_default_protos(void)
1716 {
1717 struct protoent *prot;
1718 const char *pname;
1719 size_t pindex;
1720
1721 init_protos(default_numprotos);
1722
1723 for (pindex = 0; pindex < default_numprotos; pindex++) {
1724 pname = default_protos[pindex];
1725 prot = cap_getprotobyname(capnetdb, pname);
1726 if (prot == NULL)
1727 xo_err(1, "cap_getprotobyname: %s", pname);
1728 protos[pindex] = prot->p_proto;
1729 }
1730 numprotos = pindex;
1731 return (pindex);
1732 }
1733
1734 /*
1735 * Return the vnet property of the jail, or -1 on error.
1736 */
1737 static int
jail_getvnet(int jid)1738 jail_getvnet(int jid)
1739 {
1740 struct iovec jiov[6];
1741 int vnet;
1742 size_t len = sizeof(vnet);
1743
1744 if (sysctlbyname("kern.features.vimage", &vnet, &len, NULL, 0) != 0)
1745 return (0);
1746
1747 vnet = -1;
1748 jiov[0].iov_base = __DECONST(char *, "jid");
1749 jiov[0].iov_len = sizeof("jid");
1750 jiov[1].iov_base = &jid;
1751 jiov[1].iov_len = sizeof(jid);
1752 jiov[2].iov_base = __DECONST(char *, "vnet");
1753 jiov[2].iov_len = sizeof("vnet");
1754 jiov[3].iov_base = &vnet;
1755 jiov[3].iov_len = sizeof(vnet);
1756 jiov[4].iov_base = __DECONST(char *, "errmsg");
1757 jiov[4].iov_len = sizeof("errmsg");
1758 jiov[5].iov_base = jail_errmsg;
1759 jiov[5].iov_len = JAIL_ERRMSGLEN;
1760 jail_errmsg[0] = '\0';
1761 if (jail_get(jiov, nitems(jiov), 0) < 0) {
1762 if (!jail_errmsg[0])
1763 snprintf(jail_errmsg, JAIL_ERRMSGLEN,
1764 "jail_get: %s", strerror(errno));
1765 return (-1);
1766 }
1767 return (vnet);
1768 }
1769
1770 static void
usage(void)1771 usage(void)
1772 {
1773 xo_error(
1774 "usage: sockstat [--libxo ...] [-46AbCcfIiLlnqSsUuvw] [-j jid] [-p ports]\n"
1775 " [-P protocols]\n");
1776 exit(1);
1777 }
1778
1779 int
main(int argc,char * argv[])1780 main(int argc, char *argv[])
1781 {
1782 cap_channel_t *capcas;
1783 cap_net_limit_t *limit;
1784 const char *pwdcmds[] = { "setpassent", "getpwuid" };
1785 const char *pwdfields[] = { "pw_name" };
1786 int protos_defined = -1;
1787 int o, i, err;
1788
1789 argc = xo_parse_args(argc, argv);
1790 if (argc < 0)
1791 exit(1);
1792 if (xo_get_style(NULL) != XO_STYLE_TEXT &&
1793 xo_get_style(NULL) != XO_STYLE_HTML)
1794 is_xo_style_encoding = true;
1795 opt_j = -1;
1796 while ((o = getopt(argc, argv, "46AbCcfIij:Llnp:P:qSsUuvw")) != -1)
1797 switch (o) {
1798 case '4':
1799 opt_4 = true;
1800 break;
1801 case '6':
1802 opt_6 = true;
1803 break;
1804 case 'A':
1805 opt_A = true;
1806 break;
1807 case 'b':
1808 opt_b = true;
1809 break;
1810 case 'C':
1811 opt_C = true;
1812 break;
1813 case 'c':
1814 opt_c = true;
1815 break;
1816 case 'f':
1817 opt_f = true;
1818 break;
1819 case 'I':
1820 opt_I = true;
1821 break;
1822 case 'i':
1823 opt_i = true;
1824 break;
1825 case 'j':
1826 opt_j = jail_getid(optarg);
1827 if (opt_j < 0)
1828 xo_errx(1, "jail_getid: %s", jail_errmsg);
1829 break;
1830 case 'L':
1831 opt_L = true;
1832 break;
1833 case 'l':
1834 opt_l = true;
1835 break;
1836 case 'n':
1837 opt_n = true;
1838 break;
1839 case 'p':
1840 err = parse_ports(optarg);
1841 switch (err) {
1842 case EINVAL:
1843 xo_errx(1, "syntax error in port range");
1844 break;
1845 case ERANGE:
1846 xo_errx(1, "invalid port number");
1847 break;
1848 }
1849 break;
1850 case 'P':
1851 protos_defined = parse_protos(optarg);
1852 break;
1853 case 'q':
1854 opt_q = true;
1855 break;
1856 case 'S':
1857 opt_S = true;
1858 break;
1859 case 's':
1860 opt_s = true;
1861 break;
1862 case 'U':
1863 opt_U = true;
1864 break;
1865 case 'u':
1866 opt_u = true;
1867 break;
1868 case 'v':
1869 ++opt_v;
1870 break;
1871 case 'w':
1872 opt_w = true;
1873 break;
1874 default:
1875 usage();
1876 }
1877
1878 argc -= optind;
1879 argv += optind;
1880
1881 if (argc > 0)
1882 usage();
1883
1884 if (opt_j > 0) {
1885 switch (jail_getvnet(opt_j)) {
1886 case -1:
1887 xo_errx(2, "jail_getvnet: %s", jail_errmsg);
1888 case JAIL_SYS_NEW:
1889 if (jail_attach(opt_j) < 0)
1890 xo_err(3, "jail_attach()");
1891 /* Set back to -1 for normal output in vnet jail. */
1892 opt_j = -1;
1893 break;
1894 default:
1895 break;
1896 }
1897 }
1898
1899 capcas = cap_init();
1900 if (capcas == NULL)
1901 xo_err(1, "Unable to contact Casper");
1902 if (caph_enter_casper() < 0)
1903 xo_err(1, "Unable to enter capability mode");
1904 capnet = cap_service_open(capcas, "system.net");
1905 if (capnet == NULL)
1906 xo_err(1, "Unable to open system.net service");
1907 capnetdb = cap_service_open(capcas, "system.netdb");
1908 if (capnetdb == NULL)
1909 xo_err(1, "Unable to open system.netdb service");
1910 capsysctl = cap_service_open(capcas, "system.sysctl");
1911 if (capsysctl == NULL)
1912 xo_err(1, "Unable to open system.sysctl service");
1913 cappwd = cap_service_open(capcas, "system.pwd");
1914 if (cappwd == NULL)
1915 xo_err(1, "Unable to open system.pwd service");
1916 cap_close(capcas);
1917 limit = cap_net_limit_init(capnet, CAPNET_ADDR2NAME);
1918 if (limit == NULL)
1919 xo_err(1, "Unable to init cap_net limits");
1920 if (cap_net_limit(limit) < 0)
1921 xo_err(1, "Unable to apply limits");
1922 if (cap_pwd_limit_cmds(cappwd, pwdcmds, nitems(pwdcmds)) < 0)
1923 xo_err(1, "Unable to apply pwd commands limits");
1924 if (cap_pwd_limit_fields(cappwd, pwdfields, nitems(pwdfields)) < 0)
1925 xo_err(1, "Unable to apply pwd commands limits");
1926
1927 if ((!opt_4 && !opt_6) && protos_defined != -1)
1928 opt_4 = opt_6 = true;
1929 if (!opt_4 && !opt_6 && !opt_u)
1930 opt_4 = opt_6 = opt_u = true;
1931 if ((opt_4 || opt_6) && protos_defined == -1)
1932 protos_defined = set_default_protos();
1933 if (!opt_c && !opt_l)
1934 opt_c = opt_l = true;
1935
1936 if (opt_4 || opt_6) {
1937 for (i = 0; i < protos_defined; i++)
1938 if (protos[i] == IPPROTO_SCTP)
1939 gather_sctp();
1940 else
1941 gather_inet(protos[i]);
1942 }
1943
1944 if (opt_u || (protos_defined == -1 && !opt_4 && !opt_6)) {
1945 gather_unix(SOCK_STREAM);
1946 gather_unix(SOCK_DGRAM);
1947 gather_unix(SOCK_SEQPACKET);
1948 }
1949 getfiles();
1950 display();
1951 exit(0);
1952 }
1953