2 * Copyright (c) 2002 Dag-Erling Coïdan Smørgrav
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/param.h>
33 #include <sys/socket.h>
34 #include <sys/socketvar.h>
35 #include <sys/sysctl.h>
40 #include <sys/unpcb.h>
42 #include <net/route.h>
44 #include <netinet/in.h>
45 #include <netinet/in_pcb.h>
46 #include <netinet/sctp.h>
47 #include <netinet/tcp.h>
48 #define TCPSTATES /* load state names */
49 #include <netinet/tcp_fsm.h>
50 #include <netinet/tcp_seq.h>
51 #include <netinet/tcp_var.h>
52 #include <arpa/inet.h>
65 #define sstosin(ss) ((struct sockaddr_in *)(ss))
66 #define sstosin6(ss) ((struct sockaddr_in6 *)(ss))
67 #define sstosun(ss) ((struct sockaddr_un *)(ss))
68 #define sstosa(ss) ((struct sockaddr *)(ss))
70 static int opt_4; /* Show IPv4 sockets */
71 static int opt_6; /* Show IPv6 sockets */
72 static int opt_c; /* Show connected sockets */
73 static int opt_j; /* Show specified jail */
74 static int opt_L; /* Don't show IPv4 or IPv6 loopback sockets */
75 static int opt_l; /* Show listening sockets */
76 static int opt_s; /* Show protocol state if applicable */
77 static int opt_u; /* Show Unix domain sockets */
78 static int opt_v; /* Verbose mode */
81 * Default protocols to use if no -P was defined.
83 static const char *default_protos[] = {"sctp", "tcp", "udp", "divert" };
84 static size_t default_numprotos = nitems(default_protos);
86 static int *protos; /* protocols to use */
87 static size_t numprotos; /* allocated size of protos[] */
91 #define INT_BIT (sizeof(int)*CHAR_BIT)
92 #define SET_PORT(p) do { ports[p / INT_BIT] |= 1 << (p % INT_BIT); } while (0)
93 #define CHK_PORT(p) (ports[p / INT_BIT] & (1 << (p % INT_BIT)))
96 struct sockaddr_storage address;
108 const char *protoname;
114 #define HASHSIZE 1009
115 static struct sock *sockhash[HASHSIZE];
117 static struct xfile *xfiles;
121 xprintf(const char *fmt, ...)
127 len = vprintf(fmt, ap);
135 get_proto_type(const char *proto)
137 struct protoent *pent;
139 if (strlen(proto) == 0)
141 pent = getprotobyname(proto);
143 warn("getprotobyname");
146 return (pent->p_proto);
157 /* Find the maximum number of possible protocols. */
158 while (getprotoent() != NULL)
163 if ((protos = malloc(sizeof(int) * proto_count)) == NULL)
165 numprotos = proto_count;
169 parse_protos(char *protospec)
172 int proto_type, proto_index;
174 if (protospec == NULL)
179 while ((prot = strsep(&protospec, ",")) != NULL) {
180 if (strlen(prot) == 0)
182 proto_type = get_proto_type(prot);
183 if (proto_type != -1)
184 protos[proto_index++] = proto_type;
186 numprotos = proto_index;
187 return (proto_index);
191 parse_ports(const char *portspec)
197 if ((ports = calloc(65536 / INT_BIT, sizeof(int))) == NULL)
202 errx(1, "syntax error in port range");
203 for (q = p; *q != '\0' && isdigit(*q); ++q)
205 for (port = 0; p < q; ++p)
206 port = port * 10 + digittoint(*p);
207 if (port < 0 || port > 65535)
208 errx(1, "invalid port number");
221 for (q = p; *q != '\0' && isdigit(*q); ++q)
223 for (end = 0; p < q; ++p)
224 end = end * 10 + digittoint(*p);
225 if (end < port || end > 65535)
226 errx(1, "invalid port number");
235 sockaddr(struct sockaddr_storage *ss, int af, void *addr, int port)
237 struct sockaddr_in *sin4;
238 struct sockaddr_in6 *sin6;
240 bzero(ss, sizeof(*ss));
244 sin4->sin_len = sizeof(*sin4);
245 sin4->sin_family = af;
246 sin4->sin_port = port;
247 sin4->sin_addr = *(struct in_addr *)addr;
251 sin6->sin6_len = sizeof(*sin6);
252 sin6->sin6_family = af;
253 sin6->sin6_port = port;
254 sin6->sin6_addr = *(struct in6_addr *)addr;
255 #define s6_addr16 __u6_addr.__u6_addr16
256 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
257 sin6->sin6_scope_id =
258 ntohs(sin6->sin6_addr.s6_addr16[1]);
259 sin6->sin6_addr.s6_addr16[1] = 0;
268 free_socket(struct sock *sock)
270 struct addr *cur, *next;
273 while (cur != NULL) {
279 while (cur != NULL) {
291 struct addr *laddr, *prev_laddr, *faddr, *prev_faddr;
292 struct xsctp_inpcb *xinpcb;
293 struct xsctp_tcb *xstcb;
294 struct xsctp_raddr *xraddr;
295 struct xsctp_laddr *xladdr;
300 int no_stcb, local_all_loopback, foreign_all_loopback;
308 varname = "net.inet.sctp.assoclist";
309 if (sysctlbyname(varname, 0, &len, 0, 0) < 0) {
311 err(1, "sysctlbyname()");
314 if ((buf = (char *)malloc(len)) == NULL) {
318 if (sysctlbyname(varname, buf, &len, 0, 0) < 0) {
319 err(1, "sysctlbyname()");
323 xinpcb = (struct xsctp_inpcb *)(void *)buf;
324 offset = sizeof(struct xsctp_inpcb);
325 while ((offset < len) && (xinpcb->last == 0)) {
326 if ((sock = calloc(1, sizeof *sock)) == NULL)
328 sock->socket = xinpcb->socket;
329 sock->proto = IPPROTO_SCTP;
330 sock->protoname = "sctp";
331 if (xinpcb->maxqlen == 0)
332 sock->state = SCTP_CLOSED;
334 sock->state = SCTP_LISTEN;
335 if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) {
336 sock->family = AF_INET6;
338 * Currently there is no way to distinguish between
339 * IPv6 only sockets or dual family sockets.
340 * So mark it as dual socket.
342 sock->vflag = INP_IPV6 | INP_IPV4;
344 sock->family = AF_INET;
345 sock->vflag = INP_IPV4;
348 local_all_loopback = 1;
349 while (offset < len) {
350 xladdr = (struct xsctp_laddr *)(void *)(buf + offset);
351 offset += sizeof(struct xsctp_laddr);
352 if (xladdr->last == 1)
354 if ((laddr = calloc(1, sizeof(struct addr))) == NULL)
356 switch (xladdr->address.sa.sa_family) {
358 #define __IN_IS_ADDR_LOOPBACK(pina) \
359 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
360 if (!__IN_IS_ADDR_LOOPBACK(
361 &xladdr->address.sin.sin_addr))
362 local_all_loopback = 0;
363 #undef __IN_IS_ADDR_LOOPBACK
364 sockaddr(&laddr->address, AF_INET,
365 &xladdr->address.sin.sin_addr,
366 htons(xinpcb->local_port));
369 if (!IN6_IS_ADDR_LOOPBACK(
370 &xladdr->address.sin6.sin6_addr))
371 local_all_loopback = 0;
372 sockaddr(&laddr->address, AF_INET6,
373 &xladdr->address.sin6.sin6_addr,
374 htons(xinpcb->local_port));
377 errx(1, "address family %d not supported",
378 xladdr->address.sa.sa_family);
381 if (prev_laddr == NULL)
384 prev_laddr->next = laddr;
387 if (sock->laddr == NULL) {
389 calloc(1, sizeof(struct addr))) == NULL)
391 sock->laddr->address.ss_family = sock->family;
392 if (sock->family == AF_INET)
393 sock->laddr->address.ss_len =
394 sizeof(struct sockaddr_in);
396 sock->laddr->address.ss_len =
397 sizeof(struct sockaddr_in6);
398 local_all_loopback = 0;
400 if ((sock->faddr = calloc(1, sizeof(struct addr))) == NULL)
402 sock->faddr->address.ss_family = sock->family;
403 if (sock->family == AF_INET)
404 sock->faddr->address.ss_len =
405 sizeof(struct sockaddr_in);
407 sock->faddr->address.ss_len =
408 sizeof(struct sockaddr_in6);
410 while (offset < len) {
411 xstcb = (struct xsctp_tcb *)(void *)(buf + offset);
412 offset += sizeof(struct xsctp_tcb);
414 if (opt_l && (sock->vflag & vflag) &&
415 (!opt_L || !local_all_loopback) &&
416 ((xinpcb->flags & SCTP_PCB_FLAGS_UDPTYPE) ||
417 (xstcb->last == 1))) {
418 hash = (int)((uintptr_t)sock->socket %
420 sock->next = sockhash[hash];
421 sockhash[hash] = sock;
426 if (xstcb->last == 1)
430 if ((sock = calloc(1, sizeof *sock)) == NULL)
432 sock->socket = xinpcb->socket;
433 sock->proto = IPPROTO_SCTP;
434 sock->protoname = "sctp";
435 sock->state = (int)xstcb->state;
436 if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) {
437 sock->family = AF_INET6;
439 * Currently there is no way to distinguish
440 * between IPv6 only sockets or dual family
441 * sockets. So mark it as dual socket.
443 sock->vflag = INP_IPV6 | INP_IPV4;
445 sock->family = AF_INET;
446 sock->vflag = INP_IPV4;
450 local_all_loopback = 1;
451 while (offset < len) {
452 xladdr = (struct xsctp_laddr *)(void *)(buf +
454 offset += sizeof(struct xsctp_laddr);
455 if (xladdr->last == 1)
459 laddr = calloc(1, sizeof(struct addr));
462 switch (xladdr->address.sa.sa_family) {
464 #define __IN_IS_ADDR_LOOPBACK(pina) \
465 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
466 if (!__IN_IS_ADDR_LOOPBACK(
467 &xladdr->address.sin.sin_addr))
468 local_all_loopback = 0;
469 #undef __IN_IS_ADDR_LOOPBACK
470 sockaddr(&laddr->address, AF_INET,
471 &xladdr->address.sin.sin_addr,
472 htons(xstcb->local_port));
475 if (!IN6_IS_ADDR_LOOPBACK(
476 &xladdr->address.sin6.sin6_addr))
477 local_all_loopback = 0;
478 sockaddr(&laddr->address, AF_INET6,
479 &xladdr->address.sin6.sin6_addr,
480 htons(xstcb->local_port));
484 "address family %d not supported",
485 xladdr->address.sa.sa_family);
488 if (prev_laddr == NULL)
491 prev_laddr->next = laddr;
495 foreign_all_loopback = 1;
496 while (offset < len) {
497 xraddr = (struct xsctp_raddr *)(void *)(buf +
499 offset += sizeof(struct xsctp_raddr);
500 if (xraddr->last == 1)
504 faddr = calloc(1, sizeof(struct addr));
507 switch (xraddr->address.sa.sa_family) {
509 #define __IN_IS_ADDR_LOOPBACK(pina) \
510 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
511 if (!__IN_IS_ADDR_LOOPBACK(
512 &xraddr->address.sin.sin_addr))
513 foreign_all_loopback = 0;
514 #undef __IN_IS_ADDR_LOOPBACK
515 sockaddr(&faddr->address, AF_INET,
516 &xraddr->address.sin.sin_addr,
517 htons(xstcb->remote_port));
520 if (!IN6_IS_ADDR_LOOPBACK(
521 &xraddr->address.sin6.sin6_addr))
522 foreign_all_loopback = 0;
523 sockaddr(&faddr->address, AF_INET6,
524 &xraddr->address.sin6.sin6_addr,
525 htons(xstcb->remote_port));
529 "address family %d not supported",
530 xraddr->address.sa.sa_family);
533 if (prev_faddr == NULL)
536 prev_faddr->next = faddr;
540 if ((sock->vflag & vflag) &&
542 !(local_all_loopback ||
543 foreign_all_loopback))) {
544 hash = (int)((uintptr_t)sock->socket %
546 sock->next = sockhash[hash];
547 sockhash[hash] = sock;
553 xinpcb = (struct xsctp_inpcb *)(void *)(buf + offset);
554 offset += sizeof(struct xsctp_inpcb);
560 gather_inet(int proto)
562 struct xinpgen *xig, *exig;
564 struct xtcpcb *xtp = NULL;
567 struct addr *laddr, *faddr;
568 const char *varname, *protoname;
571 int hash, retry, vflag;
581 varname = "net.inet.tcp.pcblist";
585 varname = "net.inet.udp.pcblist";
589 varname = "net.inet.divert.pcblist";
593 errx(1, "protocol %d not supported", proto);
601 if ((buf = realloc(buf, bufsize)) == NULL)
604 if (sysctlbyname(varname, buf, &len, NULL, 0) == 0)
608 if (errno != ENOMEM || len != bufsize)
609 err(1, "sysctlbyname()");
612 xig = (struct xinpgen *)buf;
613 exig = (struct xinpgen *)(void *)
614 ((char *)buf + len - sizeof *exig);
615 if (xig->xig_len != sizeof *xig ||
616 exig->xig_len != sizeof *exig)
617 errx(1, "struct xinpgen size mismatch");
618 } while (xig->xig_gen != exig->xig_gen && retry--);
620 if (xig->xig_gen != exig->xig_gen && opt_v)
621 warnx("warning: data may be inconsistent");
624 xig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len);
629 xtp = (struct xtcpcb *)xig;
631 if (xtp->xt_len != sizeof(*xtp)) {
632 warnx("struct xtcpcb size mismatch");
635 protoname = xtp->t_flags & TF_TOE ? "toe" : "tcp";
639 xip = (struct xinpcb *)xig;
640 if (xip->xi_len != sizeof(*xip)) {
641 warnx("struct xinpcb size mismatch");
646 errx(1, "protocol %d not supported", proto);
648 so = &xip->xi_socket;
649 if ((xip->inp_vflag & vflag) == 0)
651 if (xip->inp_vflag & INP_IPV4) {
652 if ((xip->inp_fport == 0 && !opt_l) ||
653 (xip->inp_fport != 0 && !opt_c))
655 #define __IN_IS_ADDR_LOOPBACK(pina) \
656 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
658 (__IN_IS_ADDR_LOOPBACK(&xip->inp_faddr) ||
659 __IN_IS_ADDR_LOOPBACK(&xip->inp_laddr)))
661 #undef __IN_IS_ADDR_LOOPBACK
662 } else if (xip->inp_vflag & INP_IPV6) {
663 if ((xip->inp_fport == 0 && !opt_l) ||
664 (xip->inp_fport != 0 && !opt_c))
667 (IN6_IS_ADDR_LOOPBACK(&xip->in6p_faddr) ||
668 IN6_IS_ADDR_LOOPBACK(&xip->in6p_laddr)))
672 warnx("invalid vflag 0x%x", xip->inp_vflag);
675 if ((sock = calloc(1, sizeof(*sock))) == NULL)
677 if ((laddr = calloc(1, sizeof *laddr)) == NULL)
679 if ((faddr = calloc(1, sizeof *faddr)) == NULL)
681 sock->socket = so->xso_so;
683 if (xip->inp_vflag & INP_IPV4) {
684 sock->family = AF_INET;
685 sockaddr(&laddr->address, sock->family,
686 &xip->inp_laddr, xip->inp_lport);
687 sockaddr(&faddr->address, sock->family,
688 &xip->inp_faddr, xip->inp_fport);
689 } else if (xip->inp_vflag & INP_IPV6) {
690 sock->family = AF_INET6;
691 sockaddr(&laddr->address, sock->family,
692 &xip->in6p_laddr, xip->inp_lport);
693 sockaddr(&faddr->address, sock->family,
694 &xip->in6p_faddr, xip->inp_fport);
700 sock->vflag = xip->inp_vflag;
701 if (proto == IPPROTO_TCP)
702 sock->state = xtp->t_state;
703 sock->protoname = protoname;
704 hash = (int)((uintptr_t)sock->socket % HASHSIZE);
705 sock->next = sockhash[hash];
706 sockhash[hash] = sock;
713 gather_unix(int proto)
715 struct xunpgen *xug, *exug;
718 struct addr *laddr, *faddr;
719 const char *varname, *protoname;
726 varname = "net.local.stream.pcblist";
727 protoname = "stream";
730 varname = "net.local.dgram.pcblist";
734 varname = "net.local.seqpacket.pcblist";
735 protoname = "seqpac";
745 if ((buf = realloc(buf, bufsize)) == NULL)
748 if (sysctlbyname(varname, buf, &len, NULL, 0) == 0)
750 if (errno != ENOMEM || len != bufsize)
751 err(1, "sysctlbyname()");
754 xug = (struct xunpgen *)buf;
755 exug = (struct xunpgen *)(void *)
756 ((char *)buf + len - sizeof(*exug));
757 if (xug->xug_len != sizeof(*xug) ||
758 exug->xug_len != sizeof(*exug)) {
759 warnx("struct xinpgen size mismatch");
762 } while (xug->xug_gen != exug->xug_gen && retry--);
764 if (xug->xug_gen != exug->xug_gen && opt_v)
765 warnx("warning: data may be inconsistent");
768 xug = (struct xunpgen *)(void *)((char *)xug + xug->xug_len);
771 xup = (struct xunpcb *)xug;
772 if (xup->xu_len != sizeof(*xup)) {
773 warnx("struct xunpcb size mismatch");
776 if ((xup->xu_unp.unp_conn == NULL && !opt_l) ||
777 (xup->xu_unp.unp_conn != NULL && !opt_c))
779 if ((sock = calloc(1, sizeof(*sock))) == NULL)
781 if ((laddr = calloc(1, sizeof *laddr)) == NULL)
783 if ((faddr = calloc(1, sizeof *faddr)) == NULL)
785 sock->socket = xup->xu_socket.xso_so;
786 sock->pcb = xup->xu_unpp;
788 sock->family = AF_UNIX;
789 sock->protoname = protoname;
790 if (xup->xu_unp.unp_addr != NULL)
792 *(struct sockaddr_storage *)(void *)&xup->xu_addr;
793 else if (xup->xu_unp.unp_conn != NULL)
794 *(void **)&(faddr->address) = xup->xu_unp.unp_conn;
799 hash = (int)((uintptr_t)sock->socket % HASHSIZE);
800 sock->next = sockhash[hash];
801 sockhash[hash] = sock;
812 olen = len = sizeof(*xfiles);
813 if ((xfiles = malloc(len)) == NULL)
815 while (sysctlbyname("kern.file", xfiles, &len, 0, 0) == -1) {
816 if (errno != ENOMEM || len != olen)
817 err(1, "sysctlbyname()");
819 if ((xfiles = realloc(xfiles, len)) == NULL)
822 if (len > 0 && xfiles->xf_size != sizeof(*xfiles))
823 errx(1, "struct xfile size mismatch");
824 nxfiles = len / sizeof(*xfiles);
828 printaddr(struct sockaddr_storage *ss)
830 struct sockaddr_un *sun;
831 char addrstr[NI_MAXHOST] = { '\0', '\0' };
832 int error, off, port = 0;
834 switch (ss->ss_family) {
836 if (inet_lnaof(sstosin(ss)->sin_addr) == INADDR_ANY)
838 port = ntohs(sstosin(ss)->sin_port);
841 if (IN6_IS_ADDR_UNSPECIFIED(&sstosin6(ss)->sin6_addr))
843 port = ntohs(sstosin6(ss)->sin6_port);
847 off = (int)((char *)&sun->sun_path - (char *)sun);
848 return (xprintf("%.*s", sun->sun_len - off, sun->sun_path));
850 if (addrstr[0] == '\0') {
851 error = getnameinfo(sstosa(ss), ss->ss_len, addrstr,
852 sizeof(addrstr), NULL, 0, NI_NUMERICHOST);
854 errx(1, "getnameinfo()");
857 return xprintf("%s:*", addrstr);
859 return xprintf("%s:%d", addrstr, port);
863 getprocname(pid_t pid)
865 static struct kinfo_proc proc;
871 mib[2] = KERN_PROC_PID;
874 if (sysctl(mib, nitems(mib), &proc, &len, NULL, 0) == -1) {
875 /* Do not warn if the process exits before we get its name. */
880 return (proc.ki_comm);
884 getprocjid(pid_t pid)
886 static struct kinfo_proc proc;
892 mib[2] = KERN_PROC_PID;
895 if (sysctl(mib, nitems(mib), &proc, &len, NULL, 0) == -1) {
896 /* Do not warn if the process exits before we get its jid. */
901 return (proc.ki_jid);
905 check_ports(struct sock *s)
912 if ((s->family != AF_INET) && (s->family != AF_INET6))
914 for (addr = s->laddr; addr != NULL; addr = addr->next) {
915 if (s->family == AF_INET)
916 port = ntohs(sstosin(&addr->address)->sin_port);
918 port = ntohs(sstosin6(&addr->address)->sin6_port);
922 for (addr = s->faddr; addr != NULL; addr = addr->next) {
923 if (s->family == AF_INET)
924 port = ntohs(sstosin(&addr->address)->sin_port);
926 port = ntohs(sstosin6(&addr->address)->sin6_port);
934 sctp_state(int state)
946 case SCTP_COOKIE_WAIT:
947 return "COOKIE_WAIT";
949 case SCTP_COOKIE_ECHOED:
950 return "COOKIE_ECHOED";
952 case SCTP_ESTABLISHED:
953 return "ESTABLISHED";
955 case SCTP_SHUTDOWN_SENT:
956 return "SHUTDOWN_SENT";
958 case SCTP_SHUTDOWN_RECEIVED:
959 return "SHUTDOWN_RECEIVED";
961 case SCTP_SHUTDOWN_ACK_SENT:
962 return "SHUTDOWN_ACK_SENT";
964 case SCTP_SHUTDOWN_PENDING:
965 return "SHUTDOWN_PENDING";
974 displaysock(struct sock *s, int pos)
978 struct addr *laddr, *faddr;
983 pos += xprintf("%s", s->protoname);
984 if (s->vflag & INP_IPV4)
986 if (s->vflag & INP_IPV6)
988 if (s->vflag & (INP_IPV4 | INP_IPV6))
993 while (laddr != NULL || faddr != NULL) {
1000 pos += printaddr(&laddr->address);
1001 if (s->family == AF_INET6 && pos >= 58)
1002 pos += xprintf(" ");
1005 pos += xprintf(" ");
1007 pos += printaddr(&faddr->address);
1010 if ((laddr == NULL) || (faddr == NULL))
1011 errx(1, "laddr = %p or faddr = %p is NULL",
1012 (void *)laddr, (void *)faddr);
1014 if (laddr->address.ss_len > 0) {
1015 pos += printaddr(&laddr->address);
1019 p = *(void **)&(faddr->address);
1021 pos += xprintf("(not connected)");
1024 pos += xprintf("-> ");
1025 for (hash = 0; hash < HASHSIZE; ++hash) {
1026 for (s_tmp = sockhash[hash];
1028 s_tmp = s_tmp->next)
1029 if (s_tmp->pcb == p)
1034 if (s_tmp == NULL || s_tmp->laddr == NULL ||
1035 s_tmp->laddr->address.ss_len == 0)
1036 pos += xprintf("??");
1038 pos += printaddr(&s_tmp->laddr->address);
1043 if (first && opt_s &&
1044 (s->proto == IPPROTO_SCTP || s->proto == IPPROTO_TCP)) {
1046 pos += xprintf(" ");
1049 pos += xprintf("%s", sctp_state(s->state));
1052 if (s->state >= 0 && s->state < TCP_NSTATES)
1054 xprintf("%s", tcpstates[s->state]);
1056 pos += xprintf("?");
1061 laddr = laddr->next;
1063 faddr = faddr->next;
1064 if ((laddr != NULL) || (faddr != NULL)) {
1081 printf("%-8s %-10s %-5s %-2s %-6s %-21s %-21s",
1082 "USER", "COMMAND", "PID", "FD", "PROTO",
1083 "LOCAL ADDRESS", "FOREIGN ADDRESS");
1085 printf(" %-12s", "STATE");
1088 for (xf = xfiles, n = 0; n < nxfiles; ++n, ++xf) {
1089 if (xf->xf_data == NULL)
1091 if (opt_j >= 0 && opt_j != getprocjid(xf->xf_pid))
1093 hash = (int)((uintptr_t)xf->xf_data % HASHSIZE);
1094 for (s = sockhash[hash]; s != NULL; s = s->next) {
1095 if ((void *)s->socket != xf->xf_data)
1097 if (!check_ports(s))
1101 if ((pwd = getpwuid(xf->xf_uid)) == NULL)
1102 pos += xprintf("%lu ", (u_long)xf->xf_uid);
1104 pos += xprintf("%s ", pwd->pw_name);
1106 pos += xprintf(" ");
1107 pos += xprintf("%.10s", getprocname(xf->xf_pid));
1109 pos += xprintf(" ");
1110 pos += xprintf("%lu ", (u_long)xf->xf_pid);
1112 pos += xprintf(" ");
1113 pos += xprintf("%d ", xf->xf_fd);
1114 displaysock(s, pos);
1119 for (hash = 0; hash < HASHSIZE; hash++) {
1120 for (s = sockhash[hash]; s != NULL; s = s->next) {
1123 if (!check_ports(s))
1126 pos += xprintf("%-8s %-10s %-5s %-2s ",
1127 "?", "?", "?", "?");
1128 displaysock(s, pos);
1133 static int set_default_protos(void)
1135 struct protoent *prot;
1139 init_protos(default_numprotos);
1141 for (pindex = 0; pindex < default_numprotos; pindex++) {
1142 pname = default_protos[pindex];
1143 prot = getprotobyname(pname);
1145 err(1, "getprotobyname: %s", pname);
1146 protos[pindex] = prot->p_proto;
1156 "usage: sockstat [-46cLlsu] [-j jid] [-p ports] [-P protocols]\n");
1161 main(int argc, char *argv[])
1163 int protos_defined = -1;
1167 while ((o = getopt(argc, argv, "46cj:Llp:P:suv")) != -1)
1179 opt_j = atoi(optarg);
1188 parse_ports(optarg);
1191 protos_defined = parse_protos(optarg);
1212 if ((!opt_4 && !opt_6) && protos_defined != -1)
1214 if (!opt_4 && !opt_6 && !opt_u)
1215 opt_4 = opt_6 = opt_u = 1;
1216 if ((opt_4 || opt_6) && protos_defined == -1)
1217 protos_defined = set_default_protos();
1218 if (!opt_c && !opt_l)
1221 if (opt_4 || opt_6) {
1222 for (i = 0; i < protos_defined; i++)
1223 if (protos[i] == IPPROTO_SCTP)
1226 gather_inet(protos[i]);
1229 if (opt_u || (protos_defined == -1 && !opt_4 && !opt_6)) {
1230 gather_unix(SOCK_STREAM);
1231 gather_unix(SOCK_DGRAM);
1232 gather_unix(SOCK_SEQPACKET);