]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.bin/sockstat/sockstat.c
zfs: merge openzfs/zfs@3522f57b6 (zfs-2.1-release) to stable/13
[FreeBSD/FreeBSD.git] / usr.bin / sockstat / sockstat.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2002 Dag-Erling Coïdan 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/cdefs.h>
32 __FBSDID("$FreeBSD$");
33
34 #include <sys/param.h>
35 #include <sys/file.h>
36 #include <sys/socket.h>
37 #include <sys/socketvar.h>
38 #include <sys/sysctl.h>
39 #include <sys/jail.h>
40 #include <sys/user.h>
41
42 #include <sys/un.h>
43 #define _WANT_UNPCB
44 #include <sys/unpcb.h>
45
46 #include <net/route.h>
47
48 #include <netinet/in.h>
49 #include <netinet/in_pcb.h>
50 #include <netinet/sctp.h>
51 #include <netinet/tcp.h>
52 #define TCPSTATES /* load state names */
53 #include <netinet/tcp_fsm.h>
54 #include <netinet/tcp_seq.h>
55 #include <netinet/tcp_var.h>
56 #include <arpa/inet.h>
57
58 #include <ctype.h>
59 #include <err.h>
60 #include <errno.h>
61 #include <jail.h>
62 #include <netdb.h>
63 #include <pwd.h>
64 #include <stdarg.h>
65 #include <stdio.h>
66 #include <stdlib.h>
67 #include <string.h>
68 #include <unistd.h>
69
70 #define sstosin(ss)     ((struct sockaddr_in *)(ss))
71 #define sstosin6(ss)    ((struct sockaddr_in6 *)(ss))
72 #define sstosun(ss)     ((struct sockaddr_un *)(ss))
73 #define sstosa(ss)      ((struct sockaddr *)(ss))
74
75 static int       opt_4;         /* Show IPv4 sockets */
76 static int       opt_6;         /* Show IPv6 sockets */
77 static int       opt_C;         /* Show congestion control */
78 static int       opt_c;         /* Show connected sockets */
79 static int       opt_j;         /* Show specified jail */
80 static int       opt_L;         /* Don't show IPv4 or IPv6 loopback sockets */
81 static int       opt_l;         /* Show listening sockets */
82 static int       opt_n;         /* Don't resolve UIDs to user names */
83 static int       opt_q;         /* Don't show header */
84 static int       opt_S;         /* Show protocol stack if applicable */
85 static int       opt_s;         /* Show protocol state if applicable */
86 static int       opt_U;         /* Show remote UDP encapsulation port number */
87 static int       opt_u;         /* Show Unix domain sockets */
88 static int       opt_v;         /* Verbose mode */
89 static int       opt_w;         /* Wide print area for addresses */
90
91 /*
92  * Default protocols to use if no -P was defined.
93  */
94 static const char *default_protos[] = {"sctp", "tcp", "udp", "divert" };
95 static size_t      default_numprotos = nitems(default_protos);
96
97 static int      *protos;        /* protocols to use */
98 static size_t    numprotos;     /* allocated size of protos[] */
99
100 static int      *ports;
101
102 #define INT_BIT (sizeof(int)*CHAR_BIT)
103 #define SET_PORT(p) do { ports[p / INT_BIT] |= 1 << (p % INT_BIT); } while (0)
104 #define CHK_PORT(p) (ports[p / INT_BIT] & (1 << (p % INT_BIT)))
105
106 struct addr {
107         struct sockaddr_storage address;
108         unsigned int encaps_port;
109         int state;
110         struct addr *next;
111 };
112
113 struct sock {
114         kvaddr_t socket;
115         kvaddr_t pcb;
116         int shown;
117         int vflag;
118         int family;
119         int proto;
120         int state;
121         const char *protoname;
122         char stack[TCP_FUNCTION_NAME_LEN_MAX];
123         char cc[TCP_CA_NAME_MAX];
124         struct addr *laddr;
125         struct addr *faddr;
126         struct sock *next;
127 };
128
129 #define HASHSIZE 1009
130 static struct sock *sockhash[HASHSIZE];
131
132 static struct xfile *xfiles;
133 static int nxfiles;
134
135 static int
136 xprintf(const char *fmt, ...)
137 {
138         va_list ap;
139         int len;
140
141         va_start(ap, fmt);
142         len = vprintf(fmt, ap);
143         va_end(ap);
144         if (len < 0)
145                 err(1, "printf()");
146         return (len);
147 }
148
149 static int
150 get_proto_type(const char *proto)
151 {
152         struct protoent *pent;
153
154         if (strlen(proto) == 0)
155                 return (0);
156         pent = getprotobyname(proto);
157         if (pent == NULL) {
158                 warn("getprotobyname");
159                 return (-1);
160         }
161         return (pent->p_proto);
162 }
163
164 static void
165 init_protos(int num)
166 {
167         int proto_count = 0;
168
169         if (num > 0) {
170                 proto_count = num;
171         } else {
172                 /* Find the maximum number of possible protocols. */
173                 while (getprotoent() != NULL)
174                         proto_count++;
175                 endprotoent();
176         }
177
178         if ((protos = malloc(sizeof(int) * proto_count)) == NULL)
179                 err(1, "malloc");
180         numprotos = proto_count;
181 }
182
183 static int
184 parse_protos(char *protospec)
185 {
186         char *prot;
187         int proto_type, proto_index;
188
189         if (protospec == NULL)
190                 return (-1);
191
192         init_protos(0);
193         proto_index = 0;
194         while ((prot = strsep(&protospec, ",")) != NULL) {
195                 if (strlen(prot) == 0)
196                         continue;
197                 proto_type = get_proto_type(prot);
198                 if (proto_type != -1)
199                         protos[proto_index++] = proto_type;
200         }
201         numprotos = proto_index;
202         return (proto_index);
203 }
204
205 static void
206 parse_ports(const char *portspec)
207 {
208         const char *p, *q;
209         int port, end;
210
211         if (ports == NULL)
212                 if ((ports = calloc(65536 / INT_BIT, sizeof(int))) == NULL)
213                         err(1, "calloc()");
214         p = portspec;
215         while (*p != '\0') {
216                 if (!isdigit(*p))
217                         errx(1, "syntax error in port range");
218                 for (q = p; *q != '\0' && isdigit(*q); ++q)
219                         /* nothing */ ;
220                 for (port = 0; p < q; ++p)
221                         port = port * 10 + digittoint(*p);
222                 if (port < 0 || port > 65535)
223                         errx(1, "invalid port number");
224                 SET_PORT(port);
225                 switch (*p) {
226                 case '-':
227                         ++p;
228                         break;
229                 case ',':
230                         ++p;
231                         /* fall through */
232                 case '\0':
233                 default:
234                         continue;
235                 }
236                 for (q = p; *q != '\0' && isdigit(*q); ++q)
237                         /* nothing */ ;
238                 for (end = 0; p < q; ++p)
239                         end = end * 10 + digittoint(*p);
240                 if (end < port || end > 65535)
241                         errx(1, "invalid port number");
242                 while (port++ < end)
243                         SET_PORT(port);
244                 if (*p == ',')
245                         ++p;
246         }
247 }
248
249 static void
250 sockaddr(struct sockaddr_storage *ss, int af, void *addr, int port)
251 {
252         struct sockaddr_in *sin4;
253         struct sockaddr_in6 *sin6;
254
255         bzero(ss, sizeof(*ss));
256         switch (af) {
257         case AF_INET:
258                 sin4 = sstosin(ss);
259                 sin4->sin_len = sizeof(*sin4);
260                 sin4->sin_family = af;
261                 sin4->sin_port = port;
262                 sin4->sin_addr = *(struct in_addr *)addr;
263                 break;
264         case AF_INET6:
265                 sin6 = sstosin6(ss);
266                 sin6->sin6_len = sizeof(*sin6);
267                 sin6->sin6_family = af;
268                 sin6->sin6_port = port;
269                 sin6->sin6_addr = *(struct in6_addr *)addr;
270 #define s6_addr16       __u6_addr.__u6_addr16
271                 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
272                         sin6->sin6_scope_id =
273                             ntohs(sin6->sin6_addr.s6_addr16[1]);
274                         sin6->sin6_addr.s6_addr16[1] = 0;
275                 }
276                 break;
277         default:
278                 abort();
279         }
280 }
281
282 static void
283 free_socket(struct sock *sock)
284 {
285         struct addr *cur, *next;
286
287         cur = sock->laddr;
288         while (cur != NULL) {
289                 next = cur->next;
290                 free(cur);
291                 cur = next;
292         }
293         cur = sock->faddr;
294         while (cur != NULL) {
295                 next = cur->next;
296                 free(cur);
297                 cur = next;
298         }
299         free(sock);
300 }
301
302 static void
303 gather_sctp(void)
304 {
305         struct sock *sock;
306         struct addr *laddr, *prev_laddr, *faddr, *prev_faddr;
307         struct xsctp_inpcb *xinpcb;
308         struct xsctp_tcb *xstcb;
309         struct xsctp_raddr *xraddr;
310         struct xsctp_laddr *xladdr;
311         const char *varname;
312         size_t len, offset;
313         char *buf;
314         int hash, vflag;
315         int no_stcb, local_all_loopback, foreign_all_loopback;
316
317         vflag = 0;
318         if (opt_4)
319                 vflag |= INP_IPV4;
320         if (opt_6)
321                 vflag |= INP_IPV6;
322
323         varname = "net.inet.sctp.assoclist";
324         if (sysctlbyname(varname, 0, &len, 0, 0) < 0) {
325                 if (errno != ENOENT)
326                         err(1, "sysctlbyname()");
327                 return;
328         }
329         if ((buf = (char *)malloc(len)) == NULL) {
330                 err(1, "malloc()");
331                 return;
332         }
333         if (sysctlbyname(varname, buf, &len, 0, 0) < 0) {
334                 err(1, "sysctlbyname()");
335                 free(buf);
336                 return;
337         }
338         xinpcb = (struct xsctp_inpcb *)(void *)buf;
339         offset = sizeof(struct xsctp_inpcb);
340         while ((offset < len) && (xinpcb->last == 0)) {
341                 if ((sock = calloc(1, sizeof *sock)) == NULL)
342                         err(1, "malloc()");
343                 sock->socket = xinpcb->socket;
344                 sock->proto = IPPROTO_SCTP;
345                 sock->protoname = "sctp";
346                 if (xinpcb->maxqlen == 0)
347                         sock->state = SCTP_CLOSED;
348                 else
349                         sock->state = SCTP_LISTEN;
350                 if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) {
351                         sock->family = AF_INET6;
352                         /*
353                          * Currently there is no way to distinguish between
354                          * IPv6 only sockets or dual family sockets.
355                          * So mark it as dual socket.
356                          */
357                         sock->vflag = INP_IPV6 | INP_IPV4;
358                 } else {
359                         sock->family = AF_INET;
360                         sock->vflag = INP_IPV4;
361                 }
362                 prev_laddr = NULL;
363                 local_all_loopback = 1;
364                 while (offset < len) {
365                         xladdr = (struct xsctp_laddr *)(void *)(buf + offset);
366                         offset += sizeof(struct xsctp_laddr);
367                         if (xladdr->last == 1)
368                                 break;
369                         if ((laddr = calloc(1, sizeof(struct addr))) == NULL)
370                                 err(1, "malloc()");
371                         switch (xladdr->address.sa.sa_family) {
372                         case AF_INET:
373 #define __IN_IS_ADDR_LOOPBACK(pina) \
374         ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
375                                 if (!__IN_IS_ADDR_LOOPBACK(
376                                     &xladdr->address.sin.sin_addr))
377                                         local_all_loopback = 0;
378 #undef  __IN_IS_ADDR_LOOPBACK
379                                 sockaddr(&laddr->address, AF_INET,
380                                     &xladdr->address.sin.sin_addr,
381                                     htons(xinpcb->local_port));
382                                 break;
383                         case AF_INET6:
384                                 if (!IN6_IS_ADDR_LOOPBACK(
385                                     &xladdr->address.sin6.sin6_addr))
386                                         local_all_loopback = 0;
387                                 sockaddr(&laddr->address, AF_INET6,
388                                     &xladdr->address.sin6.sin6_addr,
389                                     htons(xinpcb->local_port));
390                                 break;
391                         default:
392                                 errx(1, "address family %d not supported",
393                                     xladdr->address.sa.sa_family);
394                         }
395                         laddr->next = NULL;
396                         if (prev_laddr == NULL)
397                                 sock->laddr = laddr;
398                         else
399                                 prev_laddr->next = laddr;
400                         prev_laddr = laddr;
401                 }
402                 if (sock->laddr == NULL) {
403                         if ((sock->laddr =
404                             calloc(1, sizeof(struct addr))) == NULL)
405                                 err(1, "malloc()");
406                         sock->laddr->address.ss_family = sock->family;
407                         if (sock->family == AF_INET)
408                                 sock->laddr->address.ss_len =
409                                     sizeof(struct sockaddr_in);
410                         else
411                                 sock->laddr->address.ss_len =
412                                     sizeof(struct sockaddr_in6);
413                         local_all_loopback = 0;
414                 }
415                 if ((sock->faddr = calloc(1, sizeof(struct addr))) == NULL)
416                         err(1, "malloc()");
417                 sock->faddr->address.ss_family = sock->family;
418                 if (sock->family == AF_INET)
419                         sock->faddr->address.ss_len =
420                             sizeof(struct sockaddr_in);
421                 else
422                         sock->faddr->address.ss_len =
423                             sizeof(struct sockaddr_in6);
424                 no_stcb = 1;
425                 while (offset < len) {
426                         xstcb = (struct xsctp_tcb *)(void *)(buf + offset);
427                         offset += sizeof(struct xsctp_tcb);
428                         if (no_stcb) {
429                                 if (opt_l && (sock->vflag & vflag) &&
430                                     (!opt_L || !local_all_loopback) &&
431                                     ((xinpcb->flags & SCTP_PCB_FLAGS_UDPTYPE) ||
432                                      (xstcb->last == 1))) {
433                                         hash = (int)((uintptr_t)sock->socket %
434                                             HASHSIZE);
435                                         sock->next = sockhash[hash];
436                                         sockhash[hash] = sock;
437                                 } else {
438                                         free_socket(sock);
439                                 }
440                         }
441                         if (xstcb->last == 1)
442                                 break;
443                         no_stcb = 0;
444                         if (opt_c) {
445                                 if ((sock = calloc(1, sizeof *sock)) == NULL)
446                                         err(1, "malloc()");
447                                 sock->socket = xinpcb->socket;
448                                 sock->proto = IPPROTO_SCTP;
449                                 sock->protoname = "sctp";
450                                 sock->state = (int)xstcb->state;
451                                 if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) {
452                                         sock->family = AF_INET6;
453                                 /*
454                                  * Currently there is no way to distinguish
455                                  * between IPv6 only sockets or dual family
456                                  *  sockets. So mark it as dual socket.
457                                  */
458                                         sock->vflag = INP_IPV6 | INP_IPV4;
459                                 } else {
460                                         sock->family = AF_INET;
461                                         sock->vflag = INP_IPV4;
462                                 }
463                         }
464                         prev_laddr = NULL;
465                         local_all_loopback = 1;
466                         while (offset < len) {
467                                 xladdr = (struct xsctp_laddr *)(void *)(buf +
468                                     offset);
469                                 offset += sizeof(struct xsctp_laddr);
470                                 if (xladdr->last == 1)
471                                         break;
472                                 if (!opt_c)
473                                         continue;
474                                 laddr = calloc(1, sizeof(struct addr));
475                                 if (laddr == NULL)
476                                         err(1, "malloc()");
477                                 switch (xladdr->address.sa.sa_family) {
478                                 case AF_INET:
479 #define __IN_IS_ADDR_LOOPBACK(pina) \
480         ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
481                                         if (!__IN_IS_ADDR_LOOPBACK(
482                                             &xladdr->address.sin.sin_addr))
483                                                 local_all_loopback = 0;
484 #undef  __IN_IS_ADDR_LOOPBACK
485                                         sockaddr(&laddr->address, AF_INET,
486                                             &xladdr->address.sin.sin_addr,
487                                             htons(xstcb->local_port));
488                                         break;
489                                 case AF_INET6:
490                                         if (!IN6_IS_ADDR_LOOPBACK(
491                                             &xladdr->address.sin6.sin6_addr))
492                                                 local_all_loopback = 0;
493                                         sockaddr(&laddr->address, AF_INET6,
494                                             &xladdr->address.sin6.sin6_addr,
495                                             htons(xstcb->local_port));
496                                         break;
497                                 default:
498                                         errx(1,
499                                             "address family %d not supported",
500                                             xladdr->address.sa.sa_family);
501                                 }
502                                 laddr->next = NULL;
503                                 if (prev_laddr == NULL)
504                                         sock->laddr = laddr;
505                                 else
506                                         prev_laddr->next = laddr;
507                                 prev_laddr = laddr;
508                         }
509                         prev_faddr = NULL;
510                         foreign_all_loopback = 1;
511                         while (offset < len) {
512                                 xraddr = (struct xsctp_raddr *)(void *)(buf +
513                                     offset);
514                                 offset += sizeof(struct xsctp_raddr);
515                                 if (xraddr->last == 1)
516                                         break;
517                                 if (!opt_c)
518                                         continue;
519                                 faddr = calloc(1, sizeof(struct addr));
520                                 if (faddr == NULL)
521                                         err(1, "malloc()");
522                                 switch (xraddr->address.sa.sa_family) {
523                                 case AF_INET:
524 #define __IN_IS_ADDR_LOOPBACK(pina) \
525         ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
526                                         if (!__IN_IS_ADDR_LOOPBACK(
527                                             &xraddr->address.sin.sin_addr))
528                                                 foreign_all_loopback = 0;
529 #undef  __IN_IS_ADDR_LOOPBACK
530                                         sockaddr(&faddr->address, AF_INET,
531                                             &xraddr->address.sin.sin_addr,
532                                             htons(xstcb->remote_port));
533                                         break;
534                                 case AF_INET6:
535                                         if (!IN6_IS_ADDR_LOOPBACK(
536                                             &xraddr->address.sin6.sin6_addr))
537                                                 foreign_all_loopback = 0;
538                                         sockaddr(&faddr->address, AF_INET6,
539                                             &xraddr->address.sin6.sin6_addr,
540                                             htons(xstcb->remote_port));
541                                         break;
542                                 default:
543                                         errx(1,
544                                             "address family %d not supported",
545                                             xraddr->address.sa.sa_family);
546                                 }
547                                 faddr->encaps_port = xraddr->encaps_port;
548                                 faddr->state = xraddr->state;
549                                 faddr->next = NULL;
550                                 if (prev_faddr == NULL)
551                                         sock->faddr = faddr;
552                                 else
553                                         prev_faddr->next = faddr;
554                                 prev_faddr = faddr;
555                         }
556                         if (opt_c) {
557                                 if ((sock->vflag & vflag) &&
558                                     (!opt_L ||
559                                      !(local_all_loopback ||
560                                      foreign_all_loopback))) {
561                                         hash = (int)((uintptr_t)sock->socket %
562                                             HASHSIZE);
563                                         sock->next = sockhash[hash];
564                                         sockhash[hash] = sock;
565                                 } else {
566                                         free_socket(sock);
567                                 }
568                         }
569                 }
570                 xinpcb = (struct xsctp_inpcb *)(void *)(buf + offset);
571                 offset += sizeof(struct xsctp_inpcb);
572         }
573         free(buf);
574 }
575
576 static void
577 gather_inet(int proto)
578 {
579         struct xinpgen *xig, *exig;
580         struct xinpcb *xip;
581         struct xtcpcb *xtp = NULL;
582         struct xsocket *so;
583         struct sock *sock;
584         struct addr *laddr, *faddr;
585         const char *varname, *protoname;
586         size_t len, bufsize;
587         void *buf;
588         int hash, retry, vflag;
589
590         vflag = 0;
591         if (opt_4)
592                 vflag |= INP_IPV4;
593         if (opt_6)
594                 vflag |= INP_IPV6;
595
596         switch (proto) {
597         case IPPROTO_TCP:
598                 varname = "net.inet.tcp.pcblist";
599                 protoname = "tcp";
600                 break;
601         case IPPROTO_UDP:
602                 varname = "net.inet.udp.pcblist";
603                 protoname = "udp";
604                 break;
605         case IPPROTO_DIVERT:
606                 varname = "net.inet.divert.pcblist";
607                 protoname = "div";
608                 break;
609         default:
610                 errx(1, "protocol %d not supported", proto);
611         }
612
613         buf = NULL;
614         bufsize = 8192;
615         retry = 5;
616         do {
617                 for (;;) {
618                         if ((buf = realloc(buf, bufsize)) == NULL)
619                                 err(1, "realloc()");
620                         len = bufsize;
621                         if (sysctlbyname(varname, buf, &len, NULL, 0) == 0)
622                                 break;
623                         if (errno == ENOENT)
624                                 goto out;
625                         if (errno != ENOMEM || len != bufsize)
626                                 err(1, "sysctlbyname()");
627                         bufsize *= 2;
628                 }
629                 xig = (struct xinpgen *)buf;
630                 exig = (struct xinpgen *)(void *)
631                     ((char *)buf + len - sizeof *exig);
632                 if (xig->xig_len != sizeof *xig ||
633                     exig->xig_len != sizeof *exig)
634                         errx(1, "struct xinpgen size mismatch");
635         } while (xig->xig_gen != exig->xig_gen && retry--);
636
637         if (xig->xig_gen != exig->xig_gen && opt_v)
638                 warnx("warning: data may be inconsistent");
639
640         for (;;) {
641                 xig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len);
642                 if (xig >= exig)
643                         break;
644                 switch (proto) {
645                 case IPPROTO_TCP:
646                         xtp = (struct xtcpcb *)xig;
647                         xip = &xtp->xt_inp;
648                         if (xtp->xt_len != sizeof(*xtp)) {
649                                 warnx("struct xtcpcb size mismatch");
650                                 goto out;
651                         }
652                         protoname = xtp->t_flags & TF_TOE ? "toe" : "tcp";
653                         break;
654                 case IPPROTO_UDP:
655                 case IPPROTO_DIVERT:
656                         xip = (struct xinpcb *)xig;
657                         if (xip->xi_len != sizeof(*xip)) {
658                                 warnx("struct xinpcb size mismatch");
659                                 goto out;
660                         }
661                         break;
662                 default:
663                         errx(1, "protocol %d not supported", proto);
664                 }
665                 so = &xip->xi_socket;
666                 if ((xip->inp_vflag & vflag) == 0)
667                         continue;
668                 if (xip->inp_vflag & INP_IPV4) {
669                         if ((xip->inp_fport == 0 && !opt_l) ||
670                             (xip->inp_fport != 0 && !opt_c))
671                                 continue;
672 #define __IN_IS_ADDR_LOOPBACK(pina) \
673         ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
674                         if (opt_L &&
675                             (__IN_IS_ADDR_LOOPBACK(&xip->inp_faddr) ||
676                              __IN_IS_ADDR_LOOPBACK(&xip->inp_laddr)))
677                                 continue;
678 #undef  __IN_IS_ADDR_LOOPBACK
679                 } else if (xip->inp_vflag & INP_IPV6) {
680                         if ((xip->inp_fport == 0 && !opt_l) ||
681                             (xip->inp_fport != 0 && !opt_c))
682                                 continue;
683                         if (opt_L &&
684                             (IN6_IS_ADDR_LOOPBACK(&xip->in6p_faddr) ||
685                              IN6_IS_ADDR_LOOPBACK(&xip->in6p_laddr)))
686                                 continue;
687                 } else {
688                         if (opt_v)
689                                 warnx("invalid vflag 0x%x", xip->inp_vflag);
690                         continue;
691                 }
692                 if ((sock = calloc(1, sizeof(*sock))) == NULL)
693                         err(1, "malloc()");
694                 if ((laddr = calloc(1, sizeof *laddr)) == NULL)
695                         err(1, "malloc()");
696                 if ((faddr = calloc(1, sizeof *faddr)) == NULL)
697                         err(1, "malloc()");
698                 sock->socket = so->xso_so;
699                 sock->proto = proto;
700                 if (xip->inp_vflag & INP_IPV4) {
701                         sock->family = AF_INET;
702                         sockaddr(&laddr->address, sock->family,
703                             &xip->inp_laddr, xip->inp_lport);
704                         sockaddr(&faddr->address, sock->family,
705                             &xip->inp_faddr, xip->inp_fport);
706                 } else if (xip->inp_vflag & INP_IPV6) {
707                         sock->family = AF_INET6;
708                         sockaddr(&laddr->address, sock->family,
709                             &xip->in6p_laddr, xip->inp_lport);
710                         sockaddr(&faddr->address, sock->family,
711                             &xip->in6p_faddr, xip->inp_fport);
712                 }
713                 if (proto == IPPROTO_TCP)
714                         faddr->encaps_port = xtp->xt_encaps_port;
715                 laddr->next = NULL;
716                 faddr->next = NULL;
717                 sock->laddr = laddr;
718                 sock->faddr = faddr;
719                 sock->vflag = xip->inp_vflag;
720                 if (proto == IPPROTO_TCP) {
721                         sock->state = xtp->t_state;
722                         memcpy(sock->stack, xtp->xt_stack,
723                             TCP_FUNCTION_NAME_LEN_MAX);
724                         memcpy(sock->cc, xtp->xt_cc, TCP_CA_NAME_MAX);
725                 }
726                 sock->protoname = protoname;
727                 hash = (int)((uintptr_t)sock->socket % HASHSIZE);
728                 sock->next = sockhash[hash];
729                 sockhash[hash] = sock;
730         }
731 out:
732         free(buf);
733 }
734
735 static void
736 gather_unix(int proto)
737 {
738         struct xunpgen *xug, *exug;
739         struct xunpcb *xup;
740         struct sock *sock;
741         struct addr *laddr, *faddr;
742         const char *varname, *protoname;
743         size_t len, bufsize;
744         void *buf;
745         int hash, retry;
746
747         switch (proto) {
748         case SOCK_STREAM:
749                 varname = "net.local.stream.pcblist";
750                 protoname = "stream";
751                 break;
752         case SOCK_DGRAM:
753                 varname = "net.local.dgram.pcblist";
754                 protoname = "dgram";
755                 break;
756         case SOCK_SEQPACKET:
757                 varname = "net.local.seqpacket.pcblist";
758                 protoname = "seqpac";
759                 break;
760         default:
761                 abort();
762         }
763         buf = NULL;
764         bufsize = 8192;
765         retry = 5;
766         do {
767                 for (;;) {
768                         if ((buf = realloc(buf, bufsize)) == NULL)
769                                 err(1, "realloc()");
770                         len = bufsize;
771                         if (sysctlbyname(varname, buf, &len, NULL, 0) == 0)
772                                 break;
773                         if (errno != ENOMEM || len != bufsize)
774                                 err(1, "sysctlbyname()");
775                         bufsize *= 2;
776                 }
777                 xug = (struct xunpgen *)buf;
778                 exug = (struct xunpgen *)(void *)
779                     ((char *)buf + len - sizeof(*exug));
780                 if (xug->xug_len != sizeof(*xug) ||
781                     exug->xug_len != sizeof(*exug)) {
782                         warnx("struct xinpgen size mismatch");
783                         goto out;
784                 }
785         } while (xug->xug_gen != exug->xug_gen && retry--);
786
787         if (xug->xug_gen != exug->xug_gen && opt_v)
788                 warnx("warning: data may be inconsistent");
789
790         for (;;) {
791                 xug = (struct xunpgen *)(void *)((char *)xug + xug->xug_len);
792                 if (xug >= exug)
793                         break;
794                 xup = (struct xunpcb *)xug;
795                 if (xup->xu_len != sizeof(*xup)) {
796                         warnx("struct xunpcb size mismatch");
797                         goto out;
798                 }
799                 if ((xup->unp_conn == 0 && !opt_l) ||
800                     (xup->unp_conn != 0 && !opt_c))
801                         continue;
802                 if ((sock = calloc(1, sizeof(*sock))) == NULL)
803                         err(1, "malloc()");
804                 if ((laddr = calloc(1, sizeof *laddr)) == NULL)
805                         err(1, "malloc()");
806                 if ((faddr = calloc(1, sizeof *faddr)) == NULL)
807                         err(1, "malloc()");
808                 sock->socket = xup->xu_socket.xso_so;
809                 sock->pcb = xup->xu_unpp;
810                 sock->proto = proto;
811                 sock->family = AF_UNIX;
812                 sock->protoname = protoname;
813                 if (xup->xu_addr.sun_family == AF_UNIX)
814                         laddr->address =
815                             *(struct sockaddr_storage *)(void *)&xup->xu_addr;
816                 else if (xup->unp_conn != 0)
817                         *(kvaddr_t*)&(faddr->address) = xup->unp_conn;
818                 laddr->next = NULL;
819                 faddr->next = NULL;
820                 sock->laddr = laddr;
821                 sock->faddr = faddr;
822                 hash = (int)((uintptr_t)sock->socket % HASHSIZE);
823                 sock->next = sockhash[hash];
824                 sockhash[hash] = sock;
825         }
826 out:
827         free(buf);
828 }
829
830 static void
831 getfiles(void)
832 {
833         size_t len, olen;
834
835         olen = len = sizeof(*xfiles);
836         if ((xfiles = malloc(len)) == NULL)
837                 err(1, "malloc()");
838         while (sysctlbyname("kern.file", xfiles, &len, 0, 0) == -1) {
839                 if (errno != ENOMEM || len != olen)
840                         err(1, "sysctlbyname()");
841                 olen = len *= 2;
842                 if ((xfiles = realloc(xfiles, len)) == NULL)
843                         err(1, "realloc()");
844         }
845         if (len > 0 && xfiles->xf_size != sizeof(*xfiles))
846                 errx(1, "struct xfile size mismatch");
847         nxfiles = len / sizeof(*xfiles);
848 }
849
850 static int
851 printaddr(struct sockaddr_storage *ss)
852 {
853         struct sockaddr_un *sun;
854         char addrstr[NI_MAXHOST] = { '\0', '\0' };
855         int error, off, port = 0;
856
857         switch (ss->ss_family) {
858         case AF_INET:
859                 if (inet_lnaof(sstosin(ss)->sin_addr) == INADDR_ANY)
860                         addrstr[0] = '*';
861                 port = ntohs(sstosin(ss)->sin_port);
862                 break;
863         case AF_INET6:
864                 if (IN6_IS_ADDR_UNSPECIFIED(&sstosin6(ss)->sin6_addr))
865                         addrstr[0] = '*';
866                 port = ntohs(sstosin6(ss)->sin6_port);
867                 break;
868         case AF_UNIX:
869                 sun = sstosun(ss);
870                 off = (int)((char *)&sun->sun_path - (char *)sun);
871                 return (xprintf("%.*s", sun->sun_len - off, sun->sun_path));
872         }
873         if (addrstr[0] == '\0') {
874                 error = getnameinfo(sstosa(ss), ss->ss_len, addrstr,
875                     sizeof(addrstr), NULL, 0, NI_NUMERICHOST);
876                 if (error)
877                         errx(1, "getnameinfo()");
878         }
879         if (port == 0)
880                 return xprintf("%s:*", addrstr);
881         else
882                 return xprintf("%s:%d", addrstr, port);
883 }
884
885 static const char *
886 getprocname(pid_t pid)
887 {
888         static struct kinfo_proc proc;
889         size_t len;
890         int mib[4];
891
892         mib[0] = CTL_KERN;
893         mib[1] = KERN_PROC;
894         mib[2] = KERN_PROC_PID;
895         mib[3] = (int)pid;
896         len = sizeof(proc);
897         if (sysctl(mib, nitems(mib), &proc, &len, NULL, 0) == -1) {
898                 /* Do not warn if the process exits before we get its name. */
899                 if (errno != ESRCH)
900                         warn("sysctl()");
901                 return ("??");
902         }
903         return (proc.ki_comm);
904 }
905
906 static int
907 getprocjid(pid_t pid)
908 {
909         static struct kinfo_proc proc;
910         size_t len;
911         int mib[4];
912
913         mib[0] = CTL_KERN;
914         mib[1] = KERN_PROC;
915         mib[2] = KERN_PROC_PID;
916         mib[3] = (int)pid;
917         len = sizeof(proc);
918         if (sysctl(mib, nitems(mib), &proc, &len, NULL, 0) == -1) {
919                 /* Do not warn if the process exits before we get its jid. */
920                 if (errno != ESRCH)
921                         warn("sysctl()");
922                 return (-1);
923         }
924         return (proc.ki_jid);
925 }
926
927 static int
928 check_ports(struct sock *s)
929 {
930         int port;
931         struct addr *addr;
932
933         if (ports == NULL)
934                 return (1);
935         if ((s->family != AF_INET) && (s->family != AF_INET6))
936                 return (1);
937         for (addr = s->laddr; addr != NULL; addr = addr->next) {
938                 if (s->family == AF_INET)
939                         port = ntohs(sstosin(&addr->address)->sin_port);
940                 else
941                         port = ntohs(sstosin6(&addr->address)->sin6_port);
942                 if (CHK_PORT(port))
943                         return (1);
944         }
945         for (addr = s->faddr; addr != NULL; addr = addr->next) {
946                 if (s->family == AF_INET)
947                         port = ntohs(sstosin(&addr->address)->sin_port);
948                 else
949                         port = ntohs(sstosin6(&addr->address)->sin6_port);
950                 if (CHK_PORT(port))
951                         return (1);
952         }
953         return (0);
954 }
955
956 static const char *
957 sctp_conn_state(int state)
958 {
959         switch (state) {
960         case SCTP_CLOSED:
961                 return "CLOSED";
962                 break;
963         case SCTP_BOUND:
964                 return "BOUND";
965                 break;
966         case SCTP_LISTEN:
967                 return "LISTEN";
968                 break;
969         case SCTP_COOKIE_WAIT:
970                 return "COOKIE_WAIT";
971                 break;
972         case SCTP_COOKIE_ECHOED:
973                 return "COOKIE_ECHOED";
974                 break;
975         case SCTP_ESTABLISHED:
976                 return "ESTABLISHED";
977                 break;
978         case SCTP_SHUTDOWN_SENT:
979                 return "SHUTDOWN_SENT";
980                 break;
981         case SCTP_SHUTDOWN_RECEIVED:
982                 return "SHUTDOWN_RECEIVED";
983                 break;
984         case SCTP_SHUTDOWN_ACK_SENT:
985                 return "SHUTDOWN_ACK_SENT";
986                 break;
987         case SCTP_SHUTDOWN_PENDING:
988                 return "SHUTDOWN_PENDING";
989                 break;
990         default:
991                 return "UNKNOWN";
992                 break;
993         }
994 }
995
996 static const char *
997 sctp_path_state(int state)
998 {
999         switch (state) {
1000         case SCTP_UNCONFIRMED:
1001                 return "UNCONFIRMED";
1002                 break;
1003         case SCTP_ACTIVE:
1004                 return "ACTIVE";
1005                 break;
1006         case SCTP_INACTIVE:
1007                 return "INACTIVE";
1008                 break;
1009         default:
1010                 return "UNKNOWN";
1011                 break;
1012         }
1013 }
1014
1015 static void
1016 displaysock(struct sock *s, int pos)
1017 {
1018         kvaddr_t p;
1019         int hash, first, offset;
1020         struct addr *laddr, *faddr;
1021         struct sock *s_tmp;
1022
1023         while (pos < 29)
1024                 pos += xprintf(" ");
1025         pos += xprintf("%s", s->protoname);
1026         if (s->vflag & INP_IPV4)
1027                 pos += xprintf("4");
1028         if (s->vflag & INP_IPV6)
1029                 pos += xprintf("6");
1030         if (s->vflag & (INP_IPV4 | INP_IPV6))
1031                 pos += xprintf(" ");
1032         laddr = s->laddr;
1033         faddr = s->faddr;
1034         first = 1;
1035         while (laddr != NULL || faddr != NULL) {
1036                 offset = 36;
1037                 while (pos < offset)
1038                         pos += xprintf(" ");
1039                 switch (s->family) {
1040                 case AF_INET:
1041                 case AF_INET6:
1042                         if (laddr != NULL) {
1043                                 pos += printaddr(&laddr->address);
1044                                 if (s->family == AF_INET6 && pos >= 58)
1045                                         pos += xprintf(" ");
1046                         }
1047                         offset += opt_w ? 46 : 22;
1048                         while (pos < offset)
1049                                 pos += xprintf(" ");
1050                         if (faddr != NULL)
1051                                 pos += printaddr(&faddr->address);
1052                         offset += opt_w ? 46 : 22;
1053                         break;
1054                 case AF_UNIX:
1055                         if ((laddr == NULL) || (faddr == NULL))
1056                                 errx(1, "laddr = %p or faddr = %p is NULL",
1057                                     (void *)laddr, (void *)faddr);
1058                         /* server */
1059                         if (laddr->address.ss_len > 0) {
1060                                 pos += printaddr(&laddr->address);
1061                                 break;
1062                         }
1063                         /* client */
1064                         p = *(kvaddr_t*)&(faddr->address);
1065                         if (p == 0) {
1066                                 pos += xprintf("(not connected)");
1067                                 offset += opt_w ? 92 : 44;
1068                                 break;
1069                         }
1070                         pos += xprintf("-> ");
1071                         for (hash = 0; hash < HASHSIZE; ++hash) {
1072                                 for (s_tmp = sockhash[hash];
1073                                     s_tmp != NULL;
1074                                     s_tmp = s_tmp->next)
1075                                         if (s_tmp->pcb == p)
1076                                                 break;
1077                                 if (s_tmp != NULL)
1078                                         break;
1079                         }
1080                         if (s_tmp == NULL || s_tmp->laddr == NULL ||
1081                             s_tmp->laddr->address.ss_len == 0)
1082                                 pos += xprintf("??");
1083                         else
1084                                 pos += printaddr(&s_tmp->laddr->address);
1085                         offset += opt_w ? 92 : 44;
1086                         break;
1087                 default:
1088                         abort();
1089                 }
1090                 if (opt_U) {
1091                         if (faddr != NULL &&
1092                             ((s->proto == IPPROTO_SCTP &&
1093                               s->state != SCTP_CLOSED &&
1094                               s->state != SCTP_BOUND &&
1095                               s->state != SCTP_LISTEN) ||
1096                              (s->proto == IPPROTO_TCP &&
1097                               s->state != TCPS_CLOSED &&
1098                               s->state != TCPS_LISTEN))) {
1099                                 while (pos < offset)
1100                                         pos += xprintf(" ");
1101                                 pos += xprintf("%u",
1102                                     ntohs(faddr->encaps_port));
1103                         }
1104                         offset += 7;
1105                 }
1106                 if (opt_s) {
1107                         if (faddr != NULL &&
1108                             s->proto == IPPROTO_SCTP &&
1109                             s->state != SCTP_CLOSED &&
1110                             s->state != SCTP_BOUND &&
1111                             s->state != SCTP_LISTEN) {
1112                                 while (pos < offset)
1113                                         pos += xprintf(" ");
1114                                 pos += xprintf("%s",
1115                                     sctp_path_state(faddr->state));
1116                         }
1117                         offset += 13;
1118                 }
1119                 if (first) {
1120                         if (opt_s) {
1121                                 if (s->proto == IPPROTO_SCTP ||
1122                                     s->proto == IPPROTO_TCP) {
1123                                         while (pos < offset)
1124                                                 pos += xprintf(" ");
1125                                         switch (s->proto) {
1126                                         case IPPROTO_SCTP:
1127                                                 pos += xprintf("%s",
1128                                                     sctp_conn_state(s->state));
1129                                                 break;
1130                                         case IPPROTO_TCP:
1131                                                 if (s->state >= 0 &&
1132                                                     s->state < TCP_NSTATES)
1133                                                         pos += xprintf("%s",
1134                                                             tcpstates[s->state]);
1135                                                 else
1136                                                         pos += xprintf("?");
1137                                                 break;
1138                                         }
1139                                 }
1140                                 offset += 13;
1141                         }
1142                         if (opt_S) {
1143                                 if (s->proto == IPPROTO_TCP) {
1144                                         while (pos < offset)
1145                                                 pos += xprintf(" ");
1146                                         pos += xprintf("%.*s",
1147                                             TCP_FUNCTION_NAME_LEN_MAX,
1148                                             s->stack);
1149                                 }
1150                                 offset += TCP_FUNCTION_NAME_LEN_MAX + 1;
1151                         }
1152                         if (opt_C) {
1153                                 if (s->proto == IPPROTO_TCP) {
1154                                         while (pos < offset)
1155                                                 pos += xprintf(" ");
1156                                         xprintf("%.*s", TCP_CA_NAME_MAX, s->cc);
1157                                 }
1158                                 offset += TCP_CA_NAME_MAX + 1;
1159                         }
1160                 }
1161                 if (laddr != NULL)
1162                         laddr = laddr->next;
1163                 if (faddr != NULL)
1164                         faddr = faddr->next;
1165                 if ((laddr != NULL) || (faddr != NULL)) {
1166                         xprintf("\n");
1167                         pos = 0;
1168                 }
1169                 first = 0;
1170         }
1171         xprintf("\n");
1172 }
1173
1174 static void
1175 display(void)
1176 {
1177         struct passwd *pwd;
1178         struct xfile *xf;
1179         struct sock *s;
1180         int hash, n, pos;
1181
1182         if (opt_q != 1) {
1183                 printf("%-8s %-10s %-5s %-2s %-6s %-*s %-*s",
1184                     "USER", "COMMAND", "PID", "FD", "PROTO",
1185                     opt_w ? 45 : 21, "LOCAL ADDRESS",
1186                     opt_w ? 45 : 21, "FOREIGN ADDRESS");
1187                 if (opt_U)
1188                         printf(" %-6s", "ENCAPS");
1189                 if (opt_s) {
1190                         printf(" %-12s", "PATH STATE");
1191                         printf(" %-12s", "CONN STATE");
1192                 }
1193                 if (opt_S)
1194                         printf(" %-*.*s", TCP_FUNCTION_NAME_LEN_MAX,
1195                             TCP_FUNCTION_NAME_LEN_MAX, "STACK");
1196                 if (opt_C)
1197                         printf(" %-.*s", TCP_CA_NAME_MAX, "CC");
1198                 printf("\n");
1199         }
1200         setpassent(1);
1201         for (xf = xfiles, n = 0; n < nxfiles; ++n, ++xf) {
1202                 if (xf->xf_data == 0)
1203                         continue;
1204                 if (opt_j >= 0 && opt_j != getprocjid(xf->xf_pid))
1205                         continue;
1206                 hash = (int)((uintptr_t)xf->xf_data % HASHSIZE);
1207                 for (s = sockhash[hash]; s != NULL; s = s->next) {
1208                         if (s->socket != xf->xf_data)
1209                                 continue;
1210                         if (!check_ports(s))
1211                                 continue;
1212                         s->shown = 1;
1213                         pos = 0;
1214                         if (opt_n || (pwd = getpwuid(xf->xf_uid)) == NULL)
1215                                 pos += xprintf("%lu ", (u_long)xf->xf_uid);
1216                         else
1217                                 pos += xprintf("%s ", pwd->pw_name);
1218                         while (pos < 9)
1219                                 pos += xprintf(" ");
1220                         pos += xprintf("%.10s", getprocname(xf->xf_pid));
1221                         while (pos < 20)
1222                                 pos += xprintf(" ");
1223                         pos += xprintf("%lu ", (u_long)xf->xf_pid);
1224                         while (pos < 26)
1225                                 pos += xprintf(" ");
1226                         pos += xprintf("%d ", xf->xf_fd);
1227                         displaysock(s, pos);
1228                 }
1229         }
1230         if (opt_j >= 0)
1231                 return;
1232         for (hash = 0; hash < HASHSIZE; hash++) {
1233                 for (s = sockhash[hash]; s != NULL; s = s->next) {
1234                         if (s->shown)
1235                                 continue;
1236                         if (!check_ports(s))
1237                                 continue;
1238                         pos = 0;
1239                         pos += xprintf("%-8s %-10s %-5s %-2s ",
1240                             "?", "?", "?", "?");
1241                         displaysock(s, pos);
1242                 }
1243         }
1244 }
1245
1246 static int
1247 set_default_protos(void)
1248 {
1249         struct protoent *prot;
1250         const char *pname;
1251         size_t pindex;
1252
1253         init_protos(default_numprotos);
1254
1255         for (pindex = 0; pindex < default_numprotos; pindex++) {
1256                 pname = default_protos[pindex];
1257                 prot = getprotobyname(pname);
1258                 if (prot == NULL)
1259                         err(1, "getprotobyname: %s", pname);
1260                 protos[pindex] = prot->p_proto;
1261         }
1262         numprotos = pindex;
1263         return (pindex);
1264 }
1265
1266 /*
1267  * Return the vnet property of the jail, or -1 on error.
1268  */
1269 static int
1270 jail_getvnet(int jid)
1271 {
1272         struct iovec jiov[6];
1273         int vnet;
1274
1275         vnet = -1;
1276         jiov[0].iov_base = __DECONST(char *, "jid");
1277         jiov[0].iov_len = sizeof("jid");
1278         jiov[1].iov_base = &jid;
1279         jiov[1].iov_len = sizeof(jid);
1280         jiov[2].iov_base = __DECONST(char *, "vnet");
1281         jiov[2].iov_len = sizeof("vnet");
1282         jiov[3].iov_base = &vnet;
1283         jiov[3].iov_len = sizeof(vnet);
1284         jiov[4].iov_base = __DECONST(char *, "errmsg");
1285         jiov[4].iov_len = sizeof("errmsg");
1286         jiov[5].iov_base = jail_errmsg;
1287         jiov[5].iov_len = JAIL_ERRMSGLEN;
1288         jail_errmsg[0] = '\0';
1289         if (jail_get(jiov, nitems(jiov), 0) < 0) {
1290                 if (!jail_errmsg[0])
1291                         snprintf(jail_errmsg, JAIL_ERRMSGLEN,
1292                             "jail_get: %s", strerror(errno));
1293                 return (-1);
1294         }
1295         return (vnet);
1296 }
1297
1298 static void
1299 usage(void)
1300 {
1301         fprintf(stderr,
1302             "usage: sockstat [-46cLlSsUuvw] [-j jid] [-p ports] [-P protocols]\n");
1303         exit(1);
1304 }
1305
1306 int
1307 main(int argc, char *argv[])
1308 {
1309         int protos_defined = -1;
1310         int o, i;
1311
1312         opt_j = -1;
1313         while ((o = getopt(argc, argv, "46Ccj:Llnp:P:qSsUuvw")) != -1)
1314                 switch (o) {
1315                 case '4':
1316                         opt_4 = 1;
1317                         break;
1318                 case '6':
1319                         opt_6 = 1;
1320                         break;
1321                 case 'C':
1322                         opt_C = 1;
1323                         break;
1324                 case 'c':
1325                         opt_c = 1;
1326                         break;
1327                 case 'j':
1328                         opt_j = jail_getid(optarg);
1329                         if (opt_j < 0)
1330                                 errx(1, "%s", jail_errmsg);
1331                         break;
1332                 case 'L':
1333                         opt_L = 1;
1334                         break;
1335                 case 'l':
1336                         opt_l = 1;
1337                         break;
1338                 case 'n':
1339                         opt_n = 1;
1340                         break;
1341                 case 'p':
1342                         parse_ports(optarg);
1343                         break;
1344                 case 'P':
1345                         protos_defined = parse_protos(optarg);
1346                         break;
1347                 case 'q':
1348                         opt_q = 1;
1349                         break;
1350                 case 'S':
1351                         opt_S = 1;
1352                         break;
1353                 case 's':
1354                         opt_s = 1;
1355                         break;
1356                 case 'U':
1357                         opt_U = 1;
1358                         break;
1359                 case 'u':
1360                         opt_u = 1;
1361                         break;
1362                 case 'v':
1363                         ++opt_v;
1364                         break;
1365                 case 'w':
1366                         opt_w = 1;
1367                         break;
1368                 default:
1369                         usage();
1370                 }
1371
1372         argc -= optind;
1373         argv += optind;
1374
1375         if (argc > 0)
1376                 usage();
1377
1378         if (opt_j > 0) {
1379                 switch (jail_getvnet(opt_j)) {
1380                 case -1:
1381                         errx(2, "%s", jail_errmsg);
1382                 case JAIL_SYS_NEW:
1383                         if (jail_attach(opt_j) < 0)
1384                                 err(3, "jail_attach()");
1385                         /* Set back to -1 for normal output in vnet jail. */
1386                         opt_j = -1;
1387                         break;
1388                 default:
1389                         break;
1390                 }
1391         }
1392
1393         if ((!opt_4 && !opt_6) && protos_defined != -1)
1394                 opt_4 = opt_6 = 1;
1395         if (!opt_4 && !opt_6 && !opt_u)
1396                 opt_4 = opt_6 = opt_u = 1;
1397         if ((opt_4 || opt_6) && protos_defined == -1)
1398                 protos_defined = set_default_protos();
1399         if (!opt_c && !opt_l)
1400                 opt_c = opt_l = 1;
1401
1402         if (opt_4 || opt_6) {
1403                 for (i = 0; i < protos_defined; i++)
1404                         if (protos[i] == IPPROTO_SCTP)
1405                                 gather_sctp();
1406                         else
1407                                 gather_inet(protos[i]);
1408         }
1409
1410         if (opt_u || (protos_defined == -1 && !opt_4 && !opt_6)) {
1411                 gather_unix(SOCK_STREAM);
1412                 gather_unix(SOCK_DGRAM);
1413                 gather_unix(SOCK_SEQPACKET);
1414         }
1415         getfiles();
1416         display();
1417         exit(0);
1418 }