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