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);
136 get_proto_type(const char *proto)
138 struct protoent *pent;
140 if (strlen(proto) == 0)
142 pent = getprotobyname(proto);
144 warn("getprotobyname");
147 return (pent->p_proto);
159 /* Find the maximum number of possible protocols. */
160 while (getprotoent() != NULL)
165 if ((protos = malloc(sizeof(int) * proto_count)) == NULL)
167 numprotos = proto_count;
172 parse_protos(char *protospec)
175 int proto_type, proto_index;
177 if (protospec == NULL)
182 while ((prot = strsep(&protospec, ",")) != NULL) {
183 if (strlen(prot) == 0)
185 proto_type = get_proto_type(prot);
186 if (proto_type != -1)
187 protos[proto_index++] = proto_type;
189 numprotos = proto_index;
190 return (proto_index);
195 parse_ports(const char *portspec)
201 if ((ports = calloc(65536 / INT_BIT, sizeof(int))) == NULL)
206 errx(1, "syntax error in port range");
207 for (q = p; *q != '\0' && isdigit(*q); ++q)
209 for (port = 0; p < q; ++p)
210 port = port * 10 + digittoint(*p);
211 if (port < 0 || port > 65535)
212 errx(1, "invalid port number");
225 for (q = p; *q != '\0' && isdigit(*q); ++q)
227 for (end = 0; p < q; ++p)
228 end = end * 10 + digittoint(*p);
229 if (end < port || end > 65535)
230 errx(1, "invalid port number");
239 sockaddr(struct sockaddr_storage *ss, int af, void *addr, int port)
241 struct sockaddr_in *sin4;
242 struct sockaddr_in6 *sin6;
244 bzero(ss, sizeof(*ss));
248 sin4->sin_len = sizeof(*sin4);
249 sin4->sin_family = af;
250 sin4->sin_port = port;
251 sin4->sin_addr = *(struct in_addr *)addr;
255 sin6->sin6_len = sizeof(*sin6);
256 sin6->sin6_family = af;
257 sin6->sin6_port = port;
258 sin6->sin6_addr = *(struct in6_addr *)addr;
259 #define s6_addr16 __u6_addr.__u6_addr16
260 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
261 sin6->sin6_scope_id =
262 ntohs(sin6->sin6_addr.s6_addr16[1]);
263 sin6->sin6_addr.s6_addr16[1] = 0;
272 free_socket(struct sock *sock)
274 struct addr *cur, *next;
277 while (cur != NULL) {
283 while (cur != NULL) {
295 struct addr *laddr, *prev_laddr, *faddr, *prev_faddr;
296 struct xsctp_inpcb *xinpcb;
297 struct xsctp_tcb *xstcb;
298 struct xsctp_raddr *xraddr;
299 struct xsctp_laddr *xladdr;
304 int no_stcb, local_all_loopback, foreign_all_loopback;
312 varname = "net.inet.sctp.assoclist";
313 if (sysctlbyname(varname, 0, &len, 0, 0) < 0) {
315 err(1, "sysctlbyname()");
318 if ((buf = (char *)malloc(len)) == NULL) {
322 if (sysctlbyname(varname, buf, &len, 0, 0) < 0) {
323 err(1, "sysctlbyname()");
327 xinpcb = (struct xsctp_inpcb *)(void *)buf;
328 offset = sizeof(struct xsctp_inpcb);
329 while ((offset < len) && (xinpcb->last == 0)) {
330 if ((sock = calloc(1, sizeof *sock)) == NULL)
332 sock->socket = xinpcb->socket;
333 sock->proto = IPPROTO_SCTP;
334 sock->protoname = "sctp";
335 if (xinpcb->maxqlen == 0)
336 sock->state = SCTP_CLOSED;
338 sock->state = SCTP_LISTEN;
339 if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) {
340 sock->family = AF_INET6;
342 * Currently there is no way to distinguish between
343 * IPv6 only sockets or dual family sockets.
344 * So mark it as dual socket.
346 sock->vflag = INP_IPV6 | INP_IPV4;
348 sock->family = AF_INET;
349 sock->vflag = INP_IPV4;
352 local_all_loopback = 1;
353 while (offset < len) {
354 xladdr = (struct xsctp_laddr *)(void *)(buf + offset);
355 offset += sizeof(struct xsctp_laddr);
356 if (xladdr->last == 1)
358 if ((laddr = calloc(1, sizeof(struct addr))) == NULL)
360 switch (xladdr->address.sa.sa_family) {
362 #define __IN_IS_ADDR_LOOPBACK(pina) \
363 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
364 if (!__IN_IS_ADDR_LOOPBACK(&xladdr->address.sin.sin_addr))
365 local_all_loopback = 0;
366 #undef __IN_IS_ADDR_LOOPBACK
367 sockaddr(&laddr->address,
369 &xladdr->address.sin.sin_addr,
370 htons(xinpcb->local_port));
373 if (!IN6_IS_ADDR_LOOPBACK(&xladdr->address.sin6.sin6_addr))
374 local_all_loopback = 0;
375 sockaddr(&laddr->address,
377 &xladdr->address.sin6.sin6_addr,
378 htons(xinpcb->local_port));
381 errx(1, "address family %d not supported",
382 xladdr->address.sa.sa_family);
385 if (prev_laddr == NULL)
388 prev_laddr->next = laddr;
391 if (sock->laddr == NULL) {
392 if ((sock->laddr = calloc(1, sizeof(struct addr))) == NULL)
394 sock->laddr->address.ss_family = sock->family;
395 if (sock->family == AF_INET)
396 sock->laddr->address.ss_len = sizeof(struct sockaddr_in);
398 sock->laddr->address.ss_len = sizeof(struct sockaddr_in6);
399 local_all_loopback = 0;
401 if ((sock->faddr = calloc(1, sizeof(struct addr))) == NULL)
403 sock->faddr->address.ss_family = sock->family;
404 if (sock->family == AF_INET)
405 sock->faddr->address.ss_len = sizeof(struct sockaddr_in);
407 sock->faddr->address.ss_len = sizeof(struct sockaddr_in6);
409 while (offset < len) {
410 xstcb = (struct xsctp_tcb *)(void *)(buf + offset);
411 offset += sizeof(struct xsctp_tcb);
414 (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 % HASHSIZE);
419 sock->next = sockhash[hash];
420 sockhash[hash] = sock;
425 if (xstcb->last == 1)
429 if ((sock = calloc(1, sizeof *sock)) == NULL)
431 sock->socket = xinpcb->socket;
432 sock->proto = IPPROTO_SCTP;
433 sock->protoname = "sctp";
434 sock->state = (int)xstcb->state;
435 if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) {
436 sock->family = AF_INET6;
438 * Currently there is no way to distinguish
439 * between IPv6 only sockets or dual family
440 * sockets. So mark it as dual socket.
442 sock->vflag = INP_IPV6 | INP_IPV4;
444 sock->family = AF_INET;
445 sock->vflag = INP_IPV4;
449 local_all_loopback = 1;
450 while (offset < len) {
451 xladdr = (struct xsctp_laddr *)(void *)(buf + offset);
452 offset += sizeof(struct xsctp_laddr);
453 if (xladdr->last == 1)
457 if ((laddr = calloc(1, sizeof(struct addr))) == NULL)
459 switch (xladdr->address.sa.sa_family) {
461 #define __IN_IS_ADDR_LOOPBACK(pina) \
462 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
463 if (!__IN_IS_ADDR_LOOPBACK(&xladdr->address.sin.sin_addr))
464 local_all_loopback = 0;
465 #undef __IN_IS_ADDR_LOOPBACK
466 sockaddr(&laddr->address,
468 &xladdr->address.sin.sin_addr,
469 htons(xstcb->local_port));
472 if (!IN6_IS_ADDR_LOOPBACK(&xladdr->address.sin6.sin6_addr))
473 local_all_loopback = 0;
474 sockaddr(&laddr->address,
476 &xladdr->address.sin6.sin6_addr,
477 htons(xstcb->local_port));
480 errx(1, "address family %d not supported",
481 xladdr->address.sa.sa_family);
484 if (prev_laddr == NULL)
487 prev_laddr->next = laddr;
491 foreign_all_loopback = 1;
492 while (offset < len) {
493 xraddr = (struct xsctp_raddr *)(void *)(buf + offset);
494 offset += sizeof(struct xsctp_raddr);
495 if (xraddr->last == 1)
499 if ((faddr = calloc(1, sizeof(struct addr))) == NULL)
501 switch (xraddr->address.sa.sa_family) {
503 #define __IN_IS_ADDR_LOOPBACK(pina) \
504 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
505 if (!__IN_IS_ADDR_LOOPBACK(&xraddr->address.sin.sin_addr))
506 foreign_all_loopback = 0;
507 #undef __IN_IS_ADDR_LOOPBACK
508 sockaddr(&faddr->address,
510 &xraddr->address.sin.sin_addr,
511 htons(xstcb->remote_port));
514 if (!IN6_IS_ADDR_LOOPBACK(&xraddr->address.sin6.sin6_addr))
515 foreign_all_loopback = 0;
516 sockaddr(&faddr->address,
518 &xraddr->address.sin6.sin6_addr,
519 htons(xstcb->remote_port));
522 errx(1, "address family %d not supported",
523 xraddr->address.sa.sa_family);
526 if (prev_faddr == NULL)
529 prev_faddr->next = faddr;
533 if ((sock->vflag & vflag) &&
535 !(local_all_loopback || foreign_all_loopback))) {
536 hash = (int)((uintptr_t)sock->socket % HASHSIZE);
537 sock->next = sockhash[hash];
538 sockhash[hash] = sock;
544 xinpcb = (struct xsctp_inpcb *)(void *)(buf + offset);
545 offset += sizeof(struct xsctp_inpcb);
551 gather_inet(int proto)
553 struct xinpgen *xig, *exig;
559 struct addr *laddr, *faddr;
560 const char *varname, *protoname;
563 int hash, retry, vflag;
573 varname = "net.inet.tcp.pcblist";
577 varname = "net.inet.udp.pcblist";
581 varname = "net.inet.divert.pcblist";
585 errx(1, "protocol %d not supported", proto);
593 if ((buf = realloc(buf, bufsize)) == NULL)
596 if (sysctlbyname(varname, buf, &len, NULL, 0) == 0)
600 if (errno != ENOMEM || len != bufsize)
601 err(1, "sysctlbyname()");
604 xig = (struct xinpgen *)buf;
605 exig = (struct xinpgen *)(void *)
606 ((char *)buf + len - sizeof *exig);
607 if (xig->xig_len != sizeof *xig ||
608 exig->xig_len != sizeof *exig)
609 errx(1, "struct xinpgen size mismatch");
610 } while (xig->xig_gen != exig->xig_gen && retry--);
612 if (xig->xig_gen != exig->xig_gen && opt_v)
613 warnx("warning: data may be inconsistent");
616 xig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len);
619 xip = (struct xinpcb *)xig;
620 xtp = (struct xtcpcb *)xig;
623 if (xtp->xt_len != sizeof(*xtp)) {
624 warnx("struct xtcpcb size mismatch");
628 so = &xtp->xt_socket;
629 protoname = xtp->xt_tp.t_flags & TF_TOE ? "toe" : "tcp";
633 if (xip->xi_len != sizeof(*xip)) {
634 warnx("struct xinpcb size mismatch");
638 so = &xip->xi_socket;
641 errx(1, "protocol %d not supported", proto);
643 if ((inp->inp_vflag & vflag) == 0)
645 if (inp->inp_vflag & INP_IPV4) {
646 if ((inp->inp_fport == 0 && !opt_l) ||
647 (inp->inp_fport != 0 && !opt_c))
649 #define __IN_IS_ADDR_LOOPBACK(pina) \
650 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
652 (__IN_IS_ADDR_LOOPBACK(&inp->inp_faddr) ||
653 __IN_IS_ADDR_LOOPBACK(&inp->inp_laddr)))
655 #undef __IN_IS_ADDR_LOOPBACK
656 } else if (inp->inp_vflag & INP_IPV6) {
657 if ((inp->inp_fport == 0 && !opt_l) ||
658 (inp->inp_fport != 0 && !opt_c))
661 (IN6_IS_ADDR_LOOPBACK(&inp->in6p_faddr) ||
662 IN6_IS_ADDR_LOOPBACK(&inp->in6p_laddr)))
666 warnx("invalid vflag 0x%x", inp->inp_vflag);
669 if ((sock = calloc(1, sizeof(*sock))) == NULL)
671 if ((laddr = calloc(1, sizeof *laddr)) == NULL)
673 if ((faddr = calloc(1, sizeof *faddr)) == NULL)
675 sock->socket = so->xso_so;
677 if (inp->inp_vflag & INP_IPV4) {
678 sock->family = AF_INET;
679 sockaddr(&laddr->address, sock->family,
680 &inp->inp_laddr, inp->inp_lport);
681 sockaddr(&faddr->address, sock->family,
682 &inp->inp_faddr, inp->inp_fport);
683 } else if (inp->inp_vflag & INP_IPV6) {
684 sock->family = AF_INET6;
685 sockaddr(&laddr->address, sock->family,
686 &inp->in6p_laddr, inp->inp_lport);
687 sockaddr(&faddr->address, sock->family,
688 &inp->in6p_faddr, inp->inp_fport);
694 sock->vflag = inp->inp_vflag;
695 if (proto == IPPROTO_TCP)
696 sock->state = xtp->xt_tp.t_state;
697 sock->protoname = protoname;
698 hash = (int)((uintptr_t)sock->socket % HASHSIZE);
699 sock->next = sockhash[hash];
700 sockhash[hash] = sock;
707 gather_unix(int proto)
709 struct xunpgen *xug, *exug;
712 struct addr *laddr, *faddr;
713 const char *varname, *protoname;
720 varname = "net.local.stream.pcblist";
721 protoname = "stream";
724 varname = "net.local.dgram.pcblist";
728 varname = "net.local.seqpacket.pcblist";
729 protoname = "seqpac";
739 if ((buf = realloc(buf, bufsize)) == NULL)
742 if (sysctlbyname(varname, buf, &len, NULL, 0) == 0)
744 if (errno != ENOMEM || len != bufsize)
745 err(1, "sysctlbyname()");
748 xug = (struct xunpgen *)buf;
749 exug = (struct xunpgen *)(void *)
750 ((char *)buf + len - sizeof(*exug));
751 if (xug->xug_len != sizeof(*xug) ||
752 exug->xug_len != sizeof(*exug)) {
753 warnx("struct xinpgen size mismatch");
756 } while (xug->xug_gen != exug->xug_gen && retry--);
758 if (xug->xug_gen != exug->xug_gen && opt_v)
759 warnx("warning: data may be inconsistent");
762 xug = (struct xunpgen *)(void *)((char *)xug + xug->xug_len);
765 xup = (struct xunpcb *)xug;
766 if (xup->xu_len != sizeof(*xup)) {
767 warnx("struct xunpcb size mismatch");
770 if ((xup->xu_unp.unp_conn == NULL && !opt_l) ||
771 (xup->xu_unp.unp_conn != NULL && !opt_c))
773 if ((sock = calloc(1, sizeof(*sock))) == NULL)
775 if ((laddr = calloc(1, sizeof *laddr)) == NULL)
777 if ((faddr = calloc(1, sizeof *faddr)) == NULL)
779 sock->socket = xup->xu_socket.xso_so;
780 sock->pcb = xup->xu_unpp;
782 sock->family = AF_UNIX;
783 sock->protoname = protoname;
784 if (xup->xu_unp.unp_addr != NULL)
786 *(struct sockaddr_storage *)(void *)&xup->xu_addr;
787 else if (xup->xu_unp.unp_conn != NULL)
788 *(void **)&(faddr->address) = xup->xu_unp.unp_conn;
793 hash = (int)((uintptr_t)sock->socket % HASHSIZE);
794 sock->next = sockhash[hash];
795 sockhash[hash] = sock;
806 olen = len = sizeof(*xfiles);
807 if ((xfiles = malloc(len)) == NULL)
809 while (sysctlbyname("kern.file", xfiles, &len, 0, 0) == -1) {
810 if (errno != ENOMEM || len != olen)
811 err(1, "sysctlbyname()");
813 if ((xfiles = realloc(xfiles, len)) == NULL)
816 if (len > 0 && xfiles->xf_size != sizeof(*xfiles))
817 errx(1, "struct xfile size mismatch");
818 nxfiles = len / sizeof(*xfiles);
822 printaddr(struct sockaddr_storage *ss)
824 struct sockaddr_un *sun;
825 char addrstr[NI_MAXHOST] = { '\0', '\0' };
826 int error, off, port = 0;
828 switch (ss->ss_family) {
830 if (inet_lnaof(sstosin(ss)->sin_addr) == INADDR_ANY)
832 port = ntohs(sstosin(ss)->sin_port);
835 if (IN6_IS_ADDR_UNSPECIFIED(&sstosin6(ss)->sin6_addr))
837 port = ntohs(sstosin6(ss)->sin6_port);
841 off = (int)((char *)&sun->sun_path - (char *)sun);
842 return (xprintf("%.*s", sun->sun_len - off, sun->sun_path));
844 if (addrstr[0] == '\0') {
845 error = getnameinfo(sstosa(ss), ss->ss_len, addrstr,
846 sizeof(addrstr), NULL, 0, NI_NUMERICHOST);
848 errx(1, "getnameinfo()");
851 return xprintf("%s:*", addrstr);
853 return xprintf("%s:%d", addrstr, port);
857 getprocname(pid_t pid)
859 static struct kinfo_proc proc;
865 mib[2] = KERN_PROC_PID;
868 if (sysctl(mib, nitems(mib), &proc, &len, NULL, 0) == -1) {
869 /* Do not warn if the process exits before we get its name. */
874 return (proc.ki_comm);
878 getprocjid(pid_t pid)
880 static struct kinfo_proc proc;
886 mib[2] = KERN_PROC_PID;
889 if (sysctl(mib, nitems(mib), &proc, &len, NULL, 0) == -1) {
890 /* Do not warn if the process exits before we get its jid. */
895 return (proc.ki_jid);
899 check_ports(struct sock *s)
906 if ((s->family != AF_INET) && (s->family != AF_INET6))
908 for (addr = s->laddr; addr != NULL; addr = addr->next) {
909 if (s->family == AF_INET)
910 port = ntohs(sstosin(&addr->address)->sin_port);
912 port = ntohs(sstosin6(&addr->address)->sin6_port);
916 for (addr = s->faddr; addr != NULL; addr = addr->next) {
917 if (s->family == AF_INET)
918 port = ntohs(sstosin(&addr->address)->sin_port);
920 port = ntohs(sstosin6(&addr->address)->sin6_port);
928 sctp_state(int state)
940 case SCTP_COOKIE_WAIT:
941 return "COOKIE_WAIT";
943 case SCTP_COOKIE_ECHOED:
944 return "COOKIE_ECHOED";
946 case SCTP_ESTABLISHED:
947 return "ESTABLISHED";
949 case SCTP_SHUTDOWN_SENT:
950 return "SHUTDOWN_SENT";
952 case SCTP_SHUTDOWN_RECEIVED:
953 return "SHUTDOWN_RECEIVED";
955 case SCTP_SHUTDOWN_ACK_SENT:
956 return "SHUTDOWN_ACK_SENT";
958 case SCTP_SHUTDOWN_PENDING:
959 return "SHUTDOWN_PENDING";
968 displaysock(struct sock *s, int pos)
972 struct addr *laddr, *faddr;
977 pos += xprintf("%s", s->protoname);
978 if (s->vflag & INP_IPV4)
980 if (s->vflag & INP_IPV6)
982 if (s->vflag & (INP_IPV4 | INP_IPV6))
987 while (laddr != NULL || faddr != NULL) {
994 pos += printaddr(&laddr->address);
995 if (s->family == AF_INET6 && pos >= 58)
1001 pos += printaddr(&faddr->address);
1004 if ((laddr == NULL) || (faddr == NULL))
1005 errx(1, "laddr = %p or faddr = %p is NULL",
1006 (void *)laddr, (void *)faddr);
1008 if (laddr->address.ss_len > 0) {
1009 pos += printaddr(&laddr->address);
1013 p = *(void **)&(faddr->address);
1015 pos += xprintf("(not connected)");
1018 pos += xprintf("-> ");
1019 for (hash = 0; hash < HASHSIZE; ++hash) {
1020 for (s_tmp = sockhash[hash];
1022 s_tmp = s_tmp->next)
1023 if (s_tmp->pcb == p)
1028 if (s_tmp == NULL ||
1029 s_tmp->laddr == NULL ||
1030 s_tmp->laddr->address.ss_len == 0)
1031 pos += xprintf("??");
1033 pos += printaddr(&s_tmp->laddr->address);
1038 if (first && opt_s &&
1039 (s->proto == IPPROTO_SCTP || s->proto == IPPROTO_TCP)) {
1041 pos += xprintf(" ");
1044 pos += xprintf("%s", sctp_state(s->state));
1047 if (s->state >= 0 && s->state < TCP_NSTATES)
1049 xprintf("%s", tcpstates[s->state]);
1051 pos += xprintf("?");
1056 laddr = laddr->next;
1058 faddr = faddr->next;
1059 if ((laddr != NULL) || (faddr != NULL)) {
1076 printf("%-8s %-10s %-5s %-2s %-6s %-21s %-21s",
1077 "USER", "COMMAND", "PID", "FD", "PROTO",
1078 "LOCAL ADDRESS", "FOREIGN ADDRESS");
1080 printf(" %-12s", "STATE");
1083 for (xf = xfiles, n = 0; n < nxfiles; ++n, ++xf) {
1084 if (xf->xf_data == NULL)
1086 if (opt_j >= 0 && opt_j != getprocjid(xf->xf_pid))
1088 hash = (int)((uintptr_t)xf->xf_data % HASHSIZE);
1089 for (s = sockhash[hash]; s != NULL; s = s->next) {
1090 if ((void *)s->socket != xf->xf_data)
1092 if (!check_ports(s))
1096 if ((pwd = getpwuid(xf->xf_uid)) == NULL)
1097 pos += xprintf("%lu ", (u_long)xf->xf_uid);
1099 pos += xprintf("%s ", pwd->pw_name);
1101 pos += xprintf(" ");
1102 pos += xprintf("%.10s", getprocname(xf->xf_pid));
1104 pos += xprintf(" ");
1105 pos += xprintf("%lu ", (u_long)xf->xf_pid);
1107 pos += xprintf(" ");
1108 pos += xprintf("%d ", xf->xf_fd);
1109 displaysock(s, pos);
1114 for (hash = 0; hash < HASHSIZE; hash++) {
1115 for (s = sockhash[hash]; s != NULL; s = s->next) {
1118 if (!check_ports(s))
1121 pos += xprintf("%-8s %-10s %-5s %-2s ",
1122 "?", "?", "?", "?");
1123 displaysock(s, pos);
1128 static int set_default_protos(void)
1130 struct protoent *prot;
1134 init_protos(default_numprotos);
1136 for (pindex = 0; pindex < default_numprotos; pindex++) {
1137 pname = default_protos[pindex];
1138 prot = getprotobyname(pname);
1140 err(1, "getprotobyname: %s", pname);
1141 protos[pindex] = prot->p_proto;
1152 "usage: sockstat [-46cLlsu] [-j jid] [-p ports] [-P protocols]\n");
1157 main(int argc, char *argv[])
1159 int protos_defined = -1;
1163 while ((o = getopt(argc, argv, "46cj:Llp:P:suv")) != -1)
1175 opt_j = atoi(optarg);
1184 parse_ports(optarg);
1187 protos_defined = parse_protos(optarg);
1208 if ((!opt_4 && !opt_6) && protos_defined != -1)
1210 if (!opt_4 && !opt_6 && !opt_u)
1211 opt_4 = opt_6 = opt_u = 1;
1212 if ((opt_4 || opt_6) && protos_defined == -1)
1213 protos_defined = set_default_protos();
1214 if (!opt_c && !opt_l)
1217 if (opt_4 || opt_6) {
1218 for (i = 0; i < protos_defined; i++)
1219 if (protos[i] == IPPROTO_SCTP)
1222 gather_inet(protos[i]);
1225 if (opt_u || (protos_defined == -1 && !opt_4 && !opt_6)) {
1226 gather_unix(SOCK_STREAM);
1227 gather_unix(SOCK_DGRAM);
1228 gather_unix(SOCK_SEQPACKET);