1ca007d91SDag-Erling Smørgrav /*- 21de7b4b8SPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 31de7b4b8SPedro F. Giffuni * 4fb2ad9d3SUlrich Spörlein * Copyright (c) 2002 Dag-Erling Coïdan Smørgrav 5ca007d91SDag-Erling Smørgrav * All rights reserved. 6ca007d91SDag-Erling Smørgrav * 7ca007d91SDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without 8ca007d91SDag-Erling Smørgrav * modification, are permitted provided that the following conditions 9ca007d91SDag-Erling Smørgrav * are met: 10ca007d91SDag-Erling Smørgrav * 1. Redistributions of source code must retain the above copyright 11ca007d91SDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer 12ca007d91SDag-Erling Smørgrav * in this position and unchanged. 13ca007d91SDag-Erling Smørgrav * 2. Redistributions in binary form must reproduce the above copyright 14ca007d91SDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer in the 15ca007d91SDag-Erling Smørgrav * documentation and/or other materials provided with the distribution. 16ca007d91SDag-Erling Smørgrav * 3. The name of the author may not be used to endorse or promote products 17ca007d91SDag-Erling Smørgrav * derived from this software without specific prior written permission. 18ca007d91SDag-Erling Smørgrav * 19ca007d91SDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20ca007d91SDag-Erling Smørgrav * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21ca007d91SDag-Erling Smørgrav * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22ca007d91SDag-Erling Smørgrav * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23ca007d91SDag-Erling Smørgrav * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24ca007d91SDag-Erling Smørgrav * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25ca007d91SDag-Erling Smørgrav * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26ca007d91SDag-Erling Smørgrav * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27ca007d91SDag-Erling Smørgrav * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28ca007d91SDag-Erling Smørgrav * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29ca007d91SDag-Erling Smørgrav */ 30ca007d91SDag-Erling Smørgrav 31ca007d91SDag-Erling Smørgrav #include <sys/cdefs.h> 32ca007d91SDag-Erling Smørgrav __FBSDID("$FreeBSD$"); 33ca007d91SDag-Erling Smørgrav 34ca007d91SDag-Erling Smørgrav #include <sys/param.h> 35f1cd4902SRyan Moeller #include <sys/file.h> 36ca007d91SDag-Erling Smørgrav #include <sys/socket.h> 37ca007d91SDag-Erling Smørgrav #include <sys/socketvar.h> 38ca007d91SDag-Erling Smørgrav #include <sys/sysctl.h> 39f1cd4902SRyan Moeller #include <sys/jail.h> 40ca007d91SDag-Erling Smørgrav #include <sys/user.h> 41ca007d91SDag-Erling Smørgrav 42ca007d91SDag-Erling Smørgrav #include <sys/un.h> 430e229f34SGleb Smirnoff #define _WANT_UNPCB 44ca007d91SDag-Erling Smørgrav #include <sys/unpcb.h> 45ca007d91SDag-Erling Smørgrav 4602bd9db0SDag-Erling Smørgrav #include <net/route.h> 4702bd9db0SDag-Erling Smørgrav 48ca007d91SDag-Erling Smørgrav #include <netinet/in.h> 49ca007d91SDag-Erling Smørgrav #include <netinet/in_pcb.h> 50d5b4aa90SMichael Tuexen #include <netinet/sctp.h> 51ca007d91SDag-Erling Smørgrav #include <netinet/tcp.h> 527a5642b3SDag-Erling Smørgrav #define TCPSTATES /* load state names */ 537a5642b3SDag-Erling Smørgrav #include <netinet/tcp_fsm.h> 54ca007d91SDag-Erling Smørgrav #include <netinet/tcp_seq.h> 55ca007d91SDag-Erling Smørgrav #include <netinet/tcp_var.h> 56ca007d91SDag-Erling Smørgrav #include <arpa/inet.h> 57ca007d91SDag-Erling Smørgrav 58ca007d91SDag-Erling Smørgrav #include <ctype.h> 59ca007d91SDag-Erling Smørgrav #include <err.h> 60ca007d91SDag-Erling Smørgrav #include <errno.h> 61de68a320SJamie Gritton #include <jail.h> 62ca007d91SDag-Erling Smørgrav #include <netdb.h> 63ca007d91SDag-Erling Smørgrav #include <pwd.h> 64ca007d91SDag-Erling Smørgrav #include <stdarg.h> 65ca007d91SDag-Erling Smørgrav #include <stdio.h> 66ca007d91SDag-Erling Smørgrav #include <stdlib.h> 67ca007d91SDag-Erling Smørgrav #include <string.h> 68ca007d91SDag-Erling Smørgrav #include <unistd.h> 69ca007d91SDag-Erling Smørgrav 70b8e20e2dSHiroki Sato #define sstosin(ss) ((struct sockaddr_in *)(ss)) 71b8e20e2dSHiroki Sato #define sstosin6(ss) ((struct sockaddr_in6 *)(ss)) 72b8e20e2dSHiroki Sato #define sstosun(ss) ((struct sockaddr_un *)(ss)) 73b8e20e2dSHiroki Sato #define sstosa(ss) ((struct sockaddr *)(ss)) 74b8e20e2dSHiroki Sato 75ca007d91SDag-Erling Smørgrav static int opt_4; /* Show IPv4 sockets */ 76ca007d91SDag-Erling Smørgrav static int opt_6; /* Show IPv6 sockets */ 772ac089d0SMichael Tuexen static int opt_C; /* Show congestion control */ 78ca007d91SDag-Erling Smørgrav static int opt_c; /* Show connected sockets */ 7900feaafdSAndrew Thompson static int opt_j; /* Show specified jail */ 809b6ca892SBruce M Simpson static int opt_L; /* Don't show IPv4 or IPv6 loopback sockets */ 81ca007d91SDag-Erling Smørgrav static int opt_l; /* Show listening sockets */ 82ccdd2b2bSAlexander Motin static int opt_n; /* Don't resolve UIDs to user names */ 83ee0afaa9SEmmanuel Vadot static int opt_q; /* Don't show header */ 84e5cccc35SMichael Tuexen static int opt_S; /* Show protocol stack if applicable */ 857a5642b3SDag-Erling Smørgrav static int opt_s; /* Show protocol state if applicable */ 8649b836f2SMichael Tuexen static int opt_U; /* Show remote UDP encapsulation port number */ 87ca007d91SDag-Erling Smørgrav static int opt_u; /* Show Unix domain sockets */ 88ca007d91SDag-Erling Smørgrav static int opt_v; /* Verbose mode */ 8983f60cb2SMichael Tuexen static int opt_w; /* Wide print area for addresses */ 90ca007d91SDag-Erling Smørgrav 911f3d67aaSGiorgos Keramidas /* 921f3d67aaSGiorgos Keramidas * Default protocols to use if no -P was defined. 931f3d67aaSGiorgos Keramidas */ 94d5b4aa90SMichael Tuexen static const char *default_protos[] = {"sctp", "tcp", "udp", "divert" }; 95b8e20e2dSHiroki Sato static size_t default_numprotos = nitems(default_protos); 961f3d67aaSGiorgos Keramidas 971f3d67aaSGiorgos Keramidas static int *protos; /* protocols to use */ 981f3d67aaSGiorgos Keramidas static size_t numprotos; /* allocated size of protos[] */ 991f3d67aaSGiorgos Keramidas 100ca007d91SDag-Erling Smørgrav static int *ports; 101ca007d91SDag-Erling Smørgrav 102ca007d91SDag-Erling Smørgrav #define INT_BIT (sizeof(int)*CHAR_BIT) 103ca007d91SDag-Erling Smørgrav #define SET_PORT(p) do { ports[p / INT_BIT] |= 1 << (p % INT_BIT); } while (0) 104ca007d91SDag-Erling Smørgrav #define CHK_PORT(p) (ports[p / INT_BIT] & (1 << (p % INT_BIT))) 105ca007d91SDag-Erling Smørgrav 106e6f718c7SMichael Tuexen struct addr { 107e6f718c7SMichael Tuexen struct sockaddr_storage address; 10849b836f2SMichael Tuexen unsigned int encaps_port; 109e389705eSMichael Tuexen int state; 110e6f718c7SMichael Tuexen struct addr *next; 111e6f718c7SMichael Tuexen }; 112e6f718c7SMichael Tuexen 113ca007d91SDag-Erling Smørgrav struct sock { 114f38b68aeSBrooks Davis kvaddr_t socket; 115f38b68aeSBrooks Davis kvaddr_t pcb; 11661149f8dSJilles Tjoelker int shown; 117ca007d91SDag-Erling Smørgrav int vflag; 118ca007d91SDag-Erling Smørgrav int family; 119ca007d91SDag-Erling Smørgrav int proto; 1207a5642b3SDag-Erling Smørgrav int state; 121ca007d91SDag-Erling Smørgrav const char *protoname; 122e5cccc35SMichael Tuexen char stack[TCP_FUNCTION_NAME_LEN_MAX]; 1232ac089d0SMichael Tuexen char cc[TCP_CA_NAME_MAX]; 124e6f718c7SMichael Tuexen struct addr *laddr; 125e6f718c7SMichael Tuexen struct addr *faddr; 126ca007d91SDag-Erling Smørgrav struct sock *next; 127ca007d91SDag-Erling Smørgrav }; 128ca007d91SDag-Erling Smørgrav 129ca007d91SDag-Erling Smørgrav #define HASHSIZE 1009 130ca007d91SDag-Erling Smørgrav static struct sock *sockhash[HASHSIZE]; 131ca007d91SDag-Erling Smørgrav 132ca007d91SDag-Erling Smørgrav static struct xfile *xfiles; 133ca007d91SDag-Erling Smørgrav static int nxfiles; 134ca007d91SDag-Erling Smørgrav 135ca007d91SDag-Erling Smørgrav static int 136ca007d91SDag-Erling Smørgrav xprintf(const char *fmt, ...) 137ca007d91SDag-Erling Smørgrav { 138ca007d91SDag-Erling Smørgrav va_list ap; 139ca007d91SDag-Erling Smørgrav int len; 140ca007d91SDag-Erling Smørgrav 141ca007d91SDag-Erling Smørgrav va_start(ap, fmt); 142ca007d91SDag-Erling Smørgrav len = vprintf(fmt, ap); 143ca007d91SDag-Erling Smørgrav va_end(ap); 144ca007d91SDag-Erling Smørgrav if (len < 0) 145ca007d91SDag-Erling Smørgrav err(1, "printf()"); 146ca007d91SDag-Erling Smørgrav return (len); 147ca007d91SDag-Erling Smørgrav } 148ca007d91SDag-Erling Smørgrav 1491f3d67aaSGiorgos Keramidas static int 1501f3d67aaSGiorgos Keramidas get_proto_type(const char *proto) 1511f3d67aaSGiorgos Keramidas { 1521f3d67aaSGiorgos Keramidas struct protoent *pent; 1531f3d67aaSGiorgos Keramidas 1541f3d67aaSGiorgos Keramidas if (strlen(proto) == 0) 1551f3d67aaSGiorgos Keramidas return (0); 1561f3d67aaSGiorgos Keramidas pent = getprotobyname(proto); 1571f3d67aaSGiorgos Keramidas if (pent == NULL) { 1581f3d67aaSGiorgos Keramidas warn("getprotobyname"); 1591f3d67aaSGiorgos Keramidas return (-1); 1601f3d67aaSGiorgos Keramidas } 1611f3d67aaSGiorgos Keramidas return (pent->p_proto); 1621f3d67aaSGiorgos Keramidas } 1631f3d67aaSGiorgos Keramidas 164b8e20e2dSHiroki Sato static void 165b8e20e2dSHiroki Sato init_protos(int num) 1661f3d67aaSGiorgos Keramidas { 1671f3d67aaSGiorgos Keramidas int proto_count = 0; 1681f3d67aaSGiorgos Keramidas 1691f3d67aaSGiorgos Keramidas if (num > 0) { 1701f3d67aaSGiorgos Keramidas proto_count = num; 1711f3d67aaSGiorgos Keramidas } else { 1721f3d67aaSGiorgos Keramidas /* Find the maximum number of possible protocols. */ 1731f3d67aaSGiorgos Keramidas while (getprotoent() != NULL) 1741f3d67aaSGiorgos Keramidas proto_count++; 1751f3d67aaSGiorgos Keramidas endprotoent(); 1761f3d67aaSGiorgos Keramidas } 1771f3d67aaSGiorgos Keramidas 1781f3d67aaSGiorgos Keramidas if ((protos = malloc(sizeof(int) * proto_count)) == NULL) 1791f3d67aaSGiorgos Keramidas err(1, "malloc"); 1801f3d67aaSGiorgos Keramidas numprotos = proto_count; 1811f3d67aaSGiorgos Keramidas } 1821f3d67aaSGiorgos Keramidas 1831f3d67aaSGiorgos Keramidas static int 1841f3d67aaSGiorgos Keramidas parse_protos(char *protospec) 1851f3d67aaSGiorgos Keramidas { 1861f3d67aaSGiorgos Keramidas char *prot; 1871f3d67aaSGiorgos Keramidas int proto_type, proto_index; 1881f3d67aaSGiorgos Keramidas 1891f3d67aaSGiorgos Keramidas if (protospec == NULL) 1901f3d67aaSGiorgos Keramidas return (-1); 1911f3d67aaSGiorgos Keramidas 1921f3d67aaSGiorgos Keramidas init_protos(0); 1931f3d67aaSGiorgos Keramidas proto_index = 0; 194b8e20e2dSHiroki Sato while ((prot = strsep(&protospec, ",")) != NULL) { 1951f3d67aaSGiorgos Keramidas if (strlen(prot) == 0) 1961f3d67aaSGiorgos Keramidas continue; 1971f3d67aaSGiorgos Keramidas proto_type = get_proto_type(prot); 1981f3d67aaSGiorgos Keramidas if (proto_type != -1) 1991f3d67aaSGiorgos Keramidas protos[proto_index++] = proto_type; 2001f3d67aaSGiorgos Keramidas } 2011f3d67aaSGiorgos Keramidas numprotos = proto_index; 2021f3d67aaSGiorgos Keramidas return (proto_index); 2031f3d67aaSGiorgos Keramidas } 2041f3d67aaSGiorgos Keramidas 205ca007d91SDag-Erling Smørgrav static void 206ca007d91SDag-Erling Smørgrav parse_ports(const char *portspec) 207ca007d91SDag-Erling Smørgrav { 208ca007d91SDag-Erling Smørgrav const char *p, *q; 209ca007d91SDag-Erling Smørgrav int port, end; 210ca007d91SDag-Erling Smørgrav 211ca007d91SDag-Erling Smørgrav if (ports == NULL) 2129efed1e6SRobert Drehmel if ((ports = calloc(65536 / INT_BIT, sizeof(int))) == NULL) 213ca007d91SDag-Erling Smørgrav err(1, "calloc()"); 214ca007d91SDag-Erling Smørgrav p = portspec; 215ca007d91SDag-Erling Smørgrav while (*p != '\0') { 216ca007d91SDag-Erling Smørgrav if (!isdigit(*p)) 217ca007d91SDag-Erling Smørgrav errx(1, "syntax error in port range"); 218ca007d91SDag-Erling Smørgrav for (q = p; *q != '\0' && isdigit(*q); ++q) 219ca007d91SDag-Erling Smørgrav /* nothing */ ; 220ca007d91SDag-Erling Smørgrav for (port = 0; p < q; ++p) 221ca007d91SDag-Erling Smørgrav port = port * 10 + digittoint(*p); 222ca007d91SDag-Erling Smørgrav if (port < 0 || port > 65535) 223ca007d91SDag-Erling Smørgrav errx(1, "invalid port number"); 224ca007d91SDag-Erling Smørgrav SET_PORT(port); 225ca007d91SDag-Erling Smørgrav switch (*p) { 226ca007d91SDag-Erling Smørgrav case '-': 227ca007d91SDag-Erling Smørgrav ++p; 228ca007d91SDag-Erling Smørgrav break; 229ca007d91SDag-Erling Smørgrav case ',': 230ca007d91SDag-Erling Smørgrav ++p; 231ca007d91SDag-Erling Smørgrav /* fall through */ 232ca007d91SDag-Erling Smørgrav case '\0': 233ca007d91SDag-Erling Smørgrav default: 234ca007d91SDag-Erling Smørgrav continue; 235ca007d91SDag-Erling Smørgrav } 236ca007d91SDag-Erling Smørgrav for (q = p; *q != '\0' && isdigit(*q); ++q) 237ca007d91SDag-Erling Smørgrav /* nothing */ ; 238ca007d91SDag-Erling Smørgrav for (end = 0; p < q; ++p) 239ca007d91SDag-Erling Smørgrav end = end * 10 + digittoint(*p); 240ca007d91SDag-Erling Smørgrav if (end < port || end > 65535) 241ca007d91SDag-Erling Smørgrav errx(1, "invalid port number"); 242ca007d91SDag-Erling Smørgrav while (port++ < end) 243ca007d91SDag-Erling Smørgrav SET_PORT(port); 244ca007d91SDag-Erling Smørgrav if (*p == ',') 245ca007d91SDag-Erling Smørgrav ++p; 246ca007d91SDag-Erling Smørgrav } 247ca007d91SDag-Erling Smørgrav } 248ca007d91SDag-Erling Smørgrav 249ca007d91SDag-Erling Smørgrav static void 250b8e20e2dSHiroki Sato sockaddr(struct sockaddr_storage *ss, int af, void *addr, int port) 251ca007d91SDag-Erling Smørgrav { 252ca007d91SDag-Erling Smørgrav struct sockaddr_in *sin4; 253ca007d91SDag-Erling Smørgrav struct sockaddr_in6 *sin6; 254ca007d91SDag-Erling Smørgrav 255b8e20e2dSHiroki Sato bzero(ss, sizeof(*ss)); 256ca007d91SDag-Erling Smørgrav switch (af) { 257ca007d91SDag-Erling Smørgrav case AF_INET: 258b8e20e2dSHiroki Sato sin4 = sstosin(ss); 259b8e20e2dSHiroki Sato sin4->sin_len = sizeof(*sin4); 260ca007d91SDag-Erling Smørgrav sin4->sin_family = af; 261ca007d91SDag-Erling Smørgrav sin4->sin_port = port; 262ca007d91SDag-Erling Smørgrav sin4->sin_addr = *(struct in_addr *)addr; 263ca007d91SDag-Erling Smørgrav break; 264ca007d91SDag-Erling Smørgrav case AF_INET6: 265b8e20e2dSHiroki Sato sin6 = sstosin6(ss); 266b8e20e2dSHiroki Sato sin6->sin6_len = sizeof(*sin6); 267ca007d91SDag-Erling Smørgrav sin6->sin6_family = af; 268ca007d91SDag-Erling Smørgrav sin6->sin6_port = port; 269ca007d91SDag-Erling Smørgrav sin6->sin6_addr = *(struct in6_addr *)addr; 270b8e20e2dSHiroki Sato #define s6_addr16 __u6_addr.__u6_addr16 271b8e20e2dSHiroki Sato if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { 272b8e20e2dSHiroki Sato sin6->sin6_scope_id = 273b8e20e2dSHiroki Sato ntohs(sin6->sin6_addr.s6_addr16[1]); 274b8e20e2dSHiroki Sato sin6->sin6_addr.s6_addr16[1] = 0; 275b8e20e2dSHiroki Sato } 276ca007d91SDag-Erling Smørgrav break; 277ca007d91SDag-Erling Smørgrav default: 278ca007d91SDag-Erling Smørgrav abort(); 279ca007d91SDag-Erling Smørgrav } 280ca007d91SDag-Erling Smørgrav } 281ca007d91SDag-Erling Smørgrav 282ca007d91SDag-Erling Smørgrav static void 283bedcf91dSMichael Tuexen free_socket(struct sock *sock) 284bedcf91dSMichael Tuexen { 285bedcf91dSMichael Tuexen struct addr *cur, *next; 286bedcf91dSMichael Tuexen 287bedcf91dSMichael Tuexen cur = sock->laddr; 288bedcf91dSMichael Tuexen while (cur != NULL) { 289bedcf91dSMichael Tuexen next = cur->next; 290bedcf91dSMichael Tuexen free(cur); 291bedcf91dSMichael Tuexen cur = next; 292bedcf91dSMichael Tuexen } 293bedcf91dSMichael Tuexen cur = sock->faddr; 294bedcf91dSMichael Tuexen while (cur != NULL) { 295bedcf91dSMichael Tuexen next = cur->next; 296bedcf91dSMichael Tuexen free(cur); 297bedcf91dSMichael Tuexen cur = next; 298bedcf91dSMichael Tuexen } 299bedcf91dSMichael Tuexen free(sock); 300bedcf91dSMichael Tuexen } 301bedcf91dSMichael Tuexen 302bedcf91dSMichael Tuexen static void 303d5b4aa90SMichael Tuexen gather_sctp(void) 304d5b4aa90SMichael Tuexen { 305d5b4aa90SMichael Tuexen struct sock *sock; 306d5b4aa90SMichael Tuexen struct addr *laddr, *prev_laddr, *faddr, *prev_faddr; 307d5b4aa90SMichael Tuexen struct xsctp_inpcb *xinpcb; 308d5b4aa90SMichael Tuexen struct xsctp_tcb *xstcb; 309d5b4aa90SMichael Tuexen struct xsctp_raddr *xraddr; 310d5b4aa90SMichael Tuexen struct xsctp_laddr *xladdr; 311d5b4aa90SMichael Tuexen const char *varname; 312d5b4aa90SMichael Tuexen size_t len, offset; 313d5b4aa90SMichael Tuexen char *buf; 314d5b4aa90SMichael Tuexen int hash, vflag; 315d5b4aa90SMichael Tuexen int no_stcb, local_all_loopback, foreign_all_loopback; 316d5b4aa90SMichael Tuexen 317d5b4aa90SMichael Tuexen vflag = 0; 318d5b4aa90SMichael Tuexen if (opt_4) 319d5b4aa90SMichael Tuexen vflag |= INP_IPV4; 320d5b4aa90SMichael Tuexen if (opt_6) 321d5b4aa90SMichael Tuexen vflag |= INP_IPV6; 322d5b4aa90SMichael Tuexen 323d5b4aa90SMichael Tuexen varname = "net.inet.sctp.assoclist"; 324d5b4aa90SMichael Tuexen if (sysctlbyname(varname, 0, &len, 0, 0) < 0) { 325d5b4aa90SMichael Tuexen if (errno != ENOENT) 326d5b4aa90SMichael Tuexen err(1, "sysctlbyname()"); 327d5b4aa90SMichael Tuexen return; 328d5b4aa90SMichael Tuexen } 329d5b4aa90SMichael Tuexen if ((buf = (char *)malloc(len)) == NULL) { 330d5b4aa90SMichael Tuexen err(1, "malloc()"); 331d5b4aa90SMichael Tuexen return; 332d5b4aa90SMichael Tuexen } 333d5b4aa90SMichael Tuexen if (sysctlbyname(varname, buf, &len, 0, 0) < 0) { 334d5b4aa90SMichael Tuexen err(1, "sysctlbyname()"); 335d5b4aa90SMichael Tuexen free(buf); 336d5b4aa90SMichael Tuexen return; 337d5b4aa90SMichael Tuexen } 338d5b4aa90SMichael Tuexen xinpcb = (struct xsctp_inpcb *)(void *)buf; 339d5b4aa90SMichael Tuexen offset = sizeof(struct xsctp_inpcb); 340d5b4aa90SMichael Tuexen while ((offset < len) && (xinpcb->last == 0)) { 341d5b4aa90SMichael Tuexen if ((sock = calloc(1, sizeof *sock)) == NULL) 342d5b4aa90SMichael Tuexen err(1, "malloc()"); 343d5b4aa90SMichael Tuexen sock->socket = xinpcb->socket; 344d5b4aa90SMichael Tuexen sock->proto = IPPROTO_SCTP; 345d5b4aa90SMichael Tuexen sock->protoname = "sctp"; 346c1eb13c7SMichael Tuexen if (xinpcb->maxqlen == 0) 3476414db1bSMichael Tuexen sock->state = SCTP_CLOSED; 3486414db1bSMichael Tuexen else 3496414db1bSMichael Tuexen sock->state = SCTP_LISTEN; 350d5b4aa90SMichael Tuexen if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) { 351d5b4aa90SMichael Tuexen sock->family = AF_INET6; 352edc9c7fcSMichael Tuexen /* 353edc9c7fcSMichael Tuexen * Currently there is no way to distinguish between 354edc9c7fcSMichael Tuexen * IPv6 only sockets or dual family sockets. 355edc9c7fcSMichael Tuexen * So mark it as dual socket. 356edc9c7fcSMichael Tuexen */ 357edc9c7fcSMichael Tuexen sock->vflag = INP_IPV6 | INP_IPV4; 358d5b4aa90SMichael Tuexen } else { 359d5b4aa90SMichael Tuexen sock->family = AF_INET; 360d5b4aa90SMichael Tuexen sock->vflag = INP_IPV4; 361d5b4aa90SMichael Tuexen } 362d5b4aa90SMichael Tuexen prev_laddr = NULL; 363d5b4aa90SMichael Tuexen local_all_loopback = 1; 364d5b4aa90SMichael Tuexen while (offset < len) { 365d5b4aa90SMichael Tuexen xladdr = (struct xsctp_laddr *)(void *)(buf + offset); 366d5b4aa90SMichael Tuexen offset += sizeof(struct xsctp_laddr); 367d5b4aa90SMichael Tuexen if (xladdr->last == 1) 368d5b4aa90SMichael Tuexen break; 369d5b4aa90SMichael Tuexen if ((laddr = calloc(1, sizeof(struct addr))) == NULL) 370d5b4aa90SMichael Tuexen err(1, "malloc()"); 371d5b4aa90SMichael Tuexen switch (xladdr->address.sa.sa_family) { 372d5b4aa90SMichael Tuexen case AF_INET: 373d5b4aa90SMichael Tuexen #define __IN_IS_ADDR_LOOPBACK(pina) \ 374d5b4aa90SMichael Tuexen ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 37527569d01SRenato Botelho if (!__IN_IS_ADDR_LOOPBACK( 37627569d01SRenato Botelho &xladdr->address.sin.sin_addr)) 377d5b4aa90SMichael Tuexen local_all_loopback = 0; 378d5b4aa90SMichael Tuexen #undef __IN_IS_ADDR_LOOPBACK 37927569d01SRenato Botelho sockaddr(&laddr->address, AF_INET, 380d5b4aa90SMichael Tuexen &xladdr->address.sin.sin_addr, 381d5b4aa90SMichael Tuexen htons(xinpcb->local_port)); 382d5b4aa90SMichael Tuexen break; 383d5b4aa90SMichael Tuexen case AF_INET6: 38427569d01SRenato Botelho if (!IN6_IS_ADDR_LOOPBACK( 38527569d01SRenato Botelho &xladdr->address.sin6.sin6_addr)) 386d5b4aa90SMichael Tuexen local_all_loopback = 0; 38727569d01SRenato Botelho sockaddr(&laddr->address, AF_INET6, 388d5b4aa90SMichael Tuexen &xladdr->address.sin6.sin6_addr, 389d5b4aa90SMichael Tuexen htons(xinpcb->local_port)); 390d5b4aa90SMichael Tuexen break; 391d5b4aa90SMichael Tuexen default: 392463a577bSEitan Adler errx(1, "address family %d not supported", 393d5b4aa90SMichael Tuexen xladdr->address.sa.sa_family); 394d5b4aa90SMichael Tuexen } 395d5b4aa90SMichael Tuexen laddr->next = NULL; 396d5b4aa90SMichael Tuexen if (prev_laddr == NULL) 397d5b4aa90SMichael Tuexen sock->laddr = laddr; 398d5b4aa90SMichael Tuexen else 399d5b4aa90SMichael Tuexen prev_laddr->next = laddr; 400d5b4aa90SMichael Tuexen prev_laddr = laddr; 401d5b4aa90SMichael Tuexen } 402d5b4aa90SMichael Tuexen if (sock->laddr == NULL) { 40327569d01SRenato Botelho if ((sock->laddr = 40427569d01SRenato Botelho calloc(1, sizeof(struct addr))) == NULL) 405d5b4aa90SMichael Tuexen err(1, "malloc()"); 406d5b4aa90SMichael Tuexen sock->laddr->address.ss_family = sock->family; 407d5b4aa90SMichael Tuexen if (sock->family == AF_INET) 40827569d01SRenato Botelho sock->laddr->address.ss_len = 40927569d01SRenato Botelho sizeof(struct sockaddr_in); 410d5b4aa90SMichael Tuexen else 41127569d01SRenato Botelho sock->laddr->address.ss_len = 41227569d01SRenato Botelho sizeof(struct sockaddr_in6); 413d5b4aa90SMichael Tuexen local_all_loopback = 0; 414d5b4aa90SMichael Tuexen } 415d5b4aa90SMichael Tuexen if ((sock->faddr = calloc(1, sizeof(struct addr))) == NULL) 416d5b4aa90SMichael Tuexen err(1, "malloc()"); 417d5b4aa90SMichael Tuexen sock->faddr->address.ss_family = sock->family; 418d5b4aa90SMichael Tuexen if (sock->family == AF_INET) 41927569d01SRenato Botelho sock->faddr->address.ss_len = 42027569d01SRenato Botelho sizeof(struct sockaddr_in); 421d5b4aa90SMichael Tuexen else 42227569d01SRenato Botelho sock->faddr->address.ss_len = 42327569d01SRenato Botelho sizeof(struct sockaddr_in6); 424d5b4aa90SMichael Tuexen no_stcb = 1; 425d5b4aa90SMichael Tuexen while (offset < len) { 426d5b4aa90SMichael Tuexen xstcb = (struct xsctp_tcb *)(void *)(buf + offset); 427d5b4aa90SMichael Tuexen offset += sizeof(struct xsctp_tcb); 428bedcf91dSMichael Tuexen if (no_stcb) { 42927569d01SRenato Botelho if (opt_l && (sock->vflag & vflag) && 430d5b4aa90SMichael Tuexen (!opt_L || !local_all_loopback) && 431d5b4aa90SMichael Tuexen ((xinpcb->flags & SCTP_PCB_FLAGS_UDPTYPE) || 432d5b4aa90SMichael Tuexen (xstcb->last == 1))) { 43327569d01SRenato Botelho hash = (int)((uintptr_t)sock->socket % 43427569d01SRenato Botelho HASHSIZE); 435d5b4aa90SMichael Tuexen sock->next = sockhash[hash]; 436d5b4aa90SMichael Tuexen sockhash[hash] = sock; 437bedcf91dSMichael Tuexen } else { 438bedcf91dSMichael Tuexen free_socket(sock); 439bedcf91dSMichael Tuexen } 440d5b4aa90SMichael Tuexen } 441d5b4aa90SMichael Tuexen if (xstcb->last == 1) 442d5b4aa90SMichael Tuexen break; 443d5b4aa90SMichael Tuexen no_stcb = 0; 444d5b4aa90SMichael Tuexen if (opt_c) { 445d5b4aa90SMichael Tuexen if ((sock = calloc(1, sizeof *sock)) == NULL) 446d5b4aa90SMichael Tuexen err(1, "malloc()"); 447d5b4aa90SMichael Tuexen sock->socket = xinpcb->socket; 448d5b4aa90SMichael Tuexen sock->proto = IPPROTO_SCTP; 449d5b4aa90SMichael Tuexen sock->protoname = "sctp"; 4506414db1bSMichael Tuexen sock->state = (int)xstcb->state; 451d5b4aa90SMichael Tuexen if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) { 452d5b4aa90SMichael Tuexen sock->family = AF_INET6; 453edc9c7fcSMichael Tuexen /* 454edc9c7fcSMichael Tuexen * Currently there is no way to distinguish 455edc9c7fcSMichael Tuexen * between IPv6 only sockets or dual family 456edc9c7fcSMichael Tuexen * sockets. So mark it as dual socket. 457edc9c7fcSMichael Tuexen */ 458edc9c7fcSMichael Tuexen sock->vflag = INP_IPV6 | INP_IPV4; 459d5b4aa90SMichael Tuexen } else { 460d5b4aa90SMichael Tuexen sock->family = AF_INET; 461d5b4aa90SMichael Tuexen sock->vflag = INP_IPV4; 462d5b4aa90SMichael Tuexen } 463d5b4aa90SMichael Tuexen } 464d5b4aa90SMichael Tuexen prev_laddr = NULL; 465d5b4aa90SMichael Tuexen local_all_loopback = 1; 466d5b4aa90SMichael Tuexen while (offset < len) { 46727569d01SRenato Botelho xladdr = (struct xsctp_laddr *)(void *)(buf + 46827569d01SRenato Botelho offset); 469d5b4aa90SMichael Tuexen offset += sizeof(struct xsctp_laddr); 470d5b4aa90SMichael Tuexen if (xladdr->last == 1) 471d5b4aa90SMichael Tuexen break; 472d5b4aa90SMichael Tuexen if (!opt_c) 473d5b4aa90SMichael Tuexen continue; 47427569d01SRenato Botelho laddr = calloc(1, sizeof(struct addr)); 47527569d01SRenato Botelho if (laddr == NULL) 476d5b4aa90SMichael Tuexen err(1, "malloc()"); 477d5b4aa90SMichael Tuexen switch (xladdr->address.sa.sa_family) { 478d5b4aa90SMichael Tuexen case AF_INET: 479d5b4aa90SMichael Tuexen #define __IN_IS_ADDR_LOOPBACK(pina) \ 480d5b4aa90SMichael Tuexen ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 48127569d01SRenato Botelho if (!__IN_IS_ADDR_LOOPBACK( 48227569d01SRenato Botelho &xladdr->address.sin.sin_addr)) 483d5b4aa90SMichael Tuexen local_all_loopback = 0; 484d5b4aa90SMichael Tuexen #undef __IN_IS_ADDR_LOOPBACK 48527569d01SRenato Botelho sockaddr(&laddr->address, AF_INET, 486d5b4aa90SMichael Tuexen &xladdr->address.sin.sin_addr, 487d5b4aa90SMichael Tuexen htons(xstcb->local_port)); 488d5b4aa90SMichael Tuexen break; 489d5b4aa90SMichael Tuexen case AF_INET6: 49027569d01SRenato Botelho if (!IN6_IS_ADDR_LOOPBACK( 49127569d01SRenato Botelho &xladdr->address.sin6.sin6_addr)) 492d5b4aa90SMichael Tuexen local_all_loopback = 0; 49327569d01SRenato Botelho sockaddr(&laddr->address, AF_INET6, 494d5b4aa90SMichael Tuexen &xladdr->address.sin6.sin6_addr, 495d5b4aa90SMichael Tuexen htons(xstcb->local_port)); 496d5b4aa90SMichael Tuexen break; 497d5b4aa90SMichael Tuexen default: 49827569d01SRenato Botelho errx(1, 49927569d01SRenato Botelho "address family %d not supported", 500d5b4aa90SMichael Tuexen xladdr->address.sa.sa_family); 501d5b4aa90SMichael Tuexen } 502d5b4aa90SMichael Tuexen laddr->next = NULL; 503d5b4aa90SMichael Tuexen if (prev_laddr == NULL) 504d5b4aa90SMichael Tuexen sock->laddr = laddr; 505d5b4aa90SMichael Tuexen else 506d5b4aa90SMichael Tuexen prev_laddr->next = laddr; 507d5b4aa90SMichael Tuexen prev_laddr = laddr; 508d5b4aa90SMichael Tuexen } 509d5b4aa90SMichael Tuexen prev_faddr = NULL; 510d5b4aa90SMichael Tuexen foreign_all_loopback = 1; 511d5b4aa90SMichael Tuexen while (offset < len) { 51227569d01SRenato Botelho xraddr = (struct xsctp_raddr *)(void *)(buf + 51327569d01SRenato Botelho offset); 514d5b4aa90SMichael Tuexen offset += sizeof(struct xsctp_raddr); 515d5b4aa90SMichael Tuexen if (xraddr->last == 1) 516d5b4aa90SMichael Tuexen break; 517d5b4aa90SMichael Tuexen if (!opt_c) 518d5b4aa90SMichael Tuexen continue; 51927569d01SRenato Botelho faddr = calloc(1, sizeof(struct addr)); 52027569d01SRenato Botelho if (faddr == NULL) 521d5b4aa90SMichael Tuexen err(1, "malloc()"); 522d5b4aa90SMichael Tuexen switch (xraddr->address.sa.sa_family) { 523d5b4aa90SMichael Tuexen case AF_INET: 524d5b4aa90SMichael Tuexen #define __IN_IS_ADDR_LOOPBACK(pina) \ 525d5b4aa90SMichael Tuexen ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 52627569d01SRenato Botelho if (!__IN_IS_ADDR_LOOPBACK( 52727569d01SRenato Botelho &xraddr->address.sin.sin_addr)) 528d5b4aa90SMichael Tuexen foreign_all_loopback = 0; 529d5b4aa90SMichael Tuexen #undef __IN_IS_ADDR_LOOPBACK 53027569d01SRenato Botelho sockaddr(&faddr->address, AF_INET, 531d5b4aa90SMichael Tuexen &xraddr->address.sin.sin_addr, 532d5b4aa90SMichael Tuexen htons(xstcb->remote_port)); 533d5b4aa90SMichael Tuexen break; 534d5b4aa90SMichael Tuexen case AF_INET6: 53527569d01SRenato Botelho if (!IN6_IS_ADDR_LOOPBACK( 53627569d01SRenato Botelho &xraddr->address.sin6.sin6_addr)) 537d5b4aa90SMichael Tuexen foreign_all_loopback = 0; 53827569d01SRenato Botelho sockaddr(&faddr->address, AF_INET6, 539d5b4aa90SMichael Tuexen &xraddr->address.sin6.sin6_addr, 540d5b4aa90SMichael Tuexen htons(xstcb->remote_port)); 541d5b4aa90SMichael Tuexen break; 542d5b4aa90SMichael Tuexen default: 54327569d01SRenato Botelho errx(1, 54427569d01SRenato Botelho "address family %d not supported", 545d5b4aa90SMichael Tuexen xraddr->address.sa.sa_family); 546d5b4aa90SMichael Tuexen } 54749b836f2SMichael Tuexen faddr->encaps_port = xraddr->encaps_port; 548e389705eSMichael Tuexen faddr->state = xraddr->state; 549d5b4aa90SMichael Tuexen faddr->next = NULL; 550d5b4aa90SMichael Tuexen if (prev_faddr == NULL) 551d5b4aa90SMichael Tuexen sock->faddr = faddr; 552d5b4aa90SMichael Tuexen else 553d5b4aa90SMichael Tuexen prev_faddr->next = faddr; 554d5b4aa90SMichael Tuexen prev_faddr = faddr; 555d5b4aa90SMichael Tuexen } 556bedcf91dSMichael Tuexen if (opt_c) { 557edc9c7fcSMichael Tuexen if ((sock->vflag & vflag) && 558edc9c7fcSMichael Tuexen (!opt_L || 55927569d01SRenato Botelho !(local_all_loopback || 56027569d01SRenato Botelho foreign_all_loopback))) { 56127569d01SRenato Botelho hash = (int)((uintptr_t)sock->socket % 56227569d01SRenato Botelho HASHSIZE); 563d5b4aa90SMichael Tuexen sock->next = sockhash[hash]; 564d5b4aa90SMichael Tuexen sockhash[hash] = sock; 565bedcf91dSMichael Tuexen } else { 566bedcf91dSMichael Tuexen free_socket(sock); 567bedcf91dSMichael Tuexen } 568d5b4aa90SMichael Tuexen } 569d5b4aa90SMichael Tuexen } 570d5b4aa90SMichael Tuexen xinpcb = (struct xsctp_inpcb *)(void *)(buf + offset); 571d5b4aa90SMichael Tuexen offset += sizeof(struct xsctp_inpcb); 572d5b4aa90SMichael Tuexen } 573d5b4aa90SMichael Tuexen free(buf); 574d5b4aa90SMichael Tuexen } 575d5b4aa90SMichael Tuexen 576d5b4aa90SMichael Tuexen static void 577ca007d91SDag-Erling Smørgrav gather_inet(int proto) 578ca007d91SDag-Erling Smørgrav { 579ca007d91SDag-Erling Smørgrav struct xinpgen *xig, *exig; 580ca007d91SDag-Erling Smørgrav struct xinpcb *xip; 581bf40d2caSGleb Smirnoff struct xtcpcb *xtp = NULL; 582ca007d91SDag-Erling Smørgrav struct xsocket *so; 583ca007d91SDag-Erling Smørgrav struct sock *sock; 584e6f718c7SMichael Tuexen struct addr *laddr, *faddr; 585ca007d91SDag-Erling Smørgrav const char *varname, *protoname; 586ca007d91SDag-Erling Smørgrav size_t len, bufsize; 587ca007d91SDag-Erling Smørgrav void *buf; 5886eb1d5baSMichael Tuexen int hash, retry, vflag; 589ca007d91SDag-Erling Smørgrav 5906eb1d5baSMichael Tuexen vflag = 0; 591ca007d91SDag-Erling Smørgrav if (opt_4) 592ca007d91SDag-Erling Smørgrav vflag |= INP_IPV4; 593ca007d91SDag-Erling Smørgrav if (opt_6) 594ca007d91SDag-Erling Smørgrav vflag |= INP_IPV6; 595ca007d91SDag-Erling Smørgrav 596ca007d91SDag-Erling Smørgrav switch (proto) { 597ca007d91SDag-Erling Smørgrav case IPPROTO_TCP: 598ca007d91SDag-Erling Smørgrav varname = "net.inet.tcp.pcblist"; 599ca007d91SDag-Erling Smørgrav protoname = "tcp"; 600ca007d91SDag-Erling Smørgrav break; 601ca007d91SDag-Erling Smørgrav case IPPROTO_UDP: 602ca007d91SDag-Erling Smørgrav varname = "net.inet.udp.pcblist"; 603ca007d91SDag-Erling Smørgrav protoname = "udp"; 604ca007d91SDag-Erling Smørgrav break; 6052cfbdf89SRuslan Ermilov case IPPROTO_DIVERT: 6062cfbdf89SRuslan Ermilov varname = "net.inet.divert.pcblist"; 6072cfbdf89SRuslan Ermilov protoname = "div"; 6082cfbdf89SRuslan Ermilov break; 609ca007d91SDag-Erling Smørgrav default: 6101f3d67aaSGiorgos Keramidas errx(1, "protocol %d not supported", proto); 611ca007d91SDag-Erling Smørgrav } 612ca007d91SDag-Erling Smørgrav 613ca007d91SDag-Erling Smørgrav buf = NULL; 614ca007d91SDag-Erling Smørgrav bufsize = 8192; 615ca007d91SDag-Erling Smørgrav retry = 5; 616ca007d91SDag-Erling Smørgrav do { 617ca007d91SDag-Erling Smørgrav for (;;) { 618ca007d91SDag-Erling Smørgrav if ((buf = realloc(buf, bufsize)) == NULL) 619ca007d91SDag-Erling Smørgrav err(1, "realloc()"); 620ca007d91SDag-Erling Smørgrav len = bufsize; 621ca007d91SDag-Erling Smørgrav if (sysctlbyname(varname, buf, &len, NULL, 0) == 0) 622ca007d91SDag-Erling Smørgrav break; 6234b2a3d41SRuslan Ermilov if (errno == ENOENT) 6244b2a3d41SRuslan Ermilov goto out; 625003e7e49SMikolaj Golub if (errno != ENOMEM || len != bufsize) 626ca007d91SDag-Erling Smørgrav err(1, "sysctlbyname()"); 627ca007d91SDag-Erling Smørgrav bufsize *= 2; 628ca007d91SDag-Erling Smørgrav } 629ca007d91SDag-Erling Smørgrav xig = (struct xinpgen *)buf; 6306dbe8d53SRobert Drehmel exig = (struct xinpgen *)(void *) 6316dbe8d53SRobert Drehmel ((char *)buf + len - sizeof *exig); 632ca007d91SDag-Erling Smørgrav if (xig->xig_len != sizeof *xig || 633ca007d91SDag-Erling Smørgrav exig->xig_len != sizeof *exig) 634ca007d91SDag-Erling Smørgrav errx(1, "struct xinpgen size mismatch"); 635ca007d91SDag-Erling Smørgrav } while (xig->xig_gen != exig->xig_gen && retry--); 636ca007d91SDag-Erling Smørgrav 637ca007d91SDag-Erling Smørgrav if (xig->xig_gen != exig->xig_gen && opt_v) 638ca007d91SDag-Erling Smørgrav warnx("warning: data may be inconsistent"); 639ca007d91SDag-Erling Smørgrav 640ca007d91SDag-Erling Smørgrav for (;;) { 6416dbe8d53SRobert Drehmel xig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len); 642ca007d91SDag-Erling Smørgrav if (xig >= exig) 643ca007d91SDag-Erling Smørgrav break; 644ca007d91SDag-Erling Smørgrav switch (proto) { 645ca007d91SDag-Erling Smørgrav case IPPROTO_TCP: 646cc65eb4eSGleb Smirnoff xtp = (struct xtcpcb *)xig; 647cc65eb4eSGleb Smirnoff xip = &xtp->xt_inp; 648b8e20e2dSHiroki Sato if (xtp->xt_len != sizeof(*xtp)) { 649ca007d91SDag-Erling Smørgrav warnx("struct xtcpcb size mismatch"); 650ca007d91SDag-Erling Smørgrav goto out; 651ca007d91SDag-Erling Smørgrav } 652cc65eb4eSGleb Smirnoff protoname = xtp->t_flags & TF_TOE ? "toe" : "tcp"; 653ca007d91SDag-Erling Smørgrav break; 654ca007d91SDag-Erling Smørgrav case IPPROTO_UDP: 6552cfbdf89SRuslan Ermilov case IPPROTO_DIVERT: 656cc65eb4eSGleb Smirnoff xip = (struct xinpcb *)xig; 657b8e20e2dSHiroki Sato if (xip->xi_len != sizeof(*xip)) { 658ca007d91SDag-Erling Smørgrav warnx("struct xinpcb size mismatch"); 659ca007d91SDag-Erling Smørgrav goto out; 660ca007d91SDag-Erling Smørgrav } 661ca007d91SDag-Erling Smørgrav break; 662ca007d91SDag-Erling Smørgrav default: 6631f3d67aaSGiorgos Keramidas errx(1, "protocol %d not supported", proto); 664ca007d91SDag-Erling Smørgrav } 665cc65eb4eSGleb Smirnoff so = &xip->xi_socket; 666cc65eb4eSGleb Smirnoff if ((xip->inp_vflag & vflag) == 0) 667ca007d91SDag-Erling Smørgrav continue; 668cc65eb4eSGleb Smirnoff if (xip->inp_vflag & INP_IPV4) { 669cc65eb4eSGleb Smirnoff if ((xip->inp_fport == 0 && !opt_l) || 670cc65eb4eSGleb Smirnoff (xip->inp_fport != 0 && !opt_c)) 6711e6690e5SDag-Erling Smørgrav continue; 6729b6ca892SBruce M Simpson #define __IN_IS_ADDR_LOOPBACK(pina) \ 6739b6ca892SBruce M Simpson ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 6749b6ca892SBruce M Simpson if (opt_L && 675cc65eb4eSGleb Smirnoff (__IN_IS_ADDR_LOOPBACK(&xip->inp_faddr) || 676cc65eb4eSGleb Smirnoff __IN_IS_ADDR_LOOPBACK(&xip->inp_laddr))) 6779b6ca892SBruce M Simpson continue; 6789b6ca892SBruce M Simpson #undef __IN_IS_ADDR_LOOPBACK 679cc65eb4eSGleb Smirnoff } else if (xip->inp_vflag & INP_IPV6) { 680cc65eb4eSGleb Smirnoff if ((xip->inp_fport == 0 && !opt_l) || 681cc65eb4eSGleb Smirnoff (xip->inp_fport != 0 && !opt_c)) 6821e6690e5SDag-Erling Smørgrav continue; 6839b6ca892SBruce M Simpson if (opt_L && 684cc65eb4eSGleb Smirnoff (IN6_IS_ADDR_LOOPBACK(&xip->in6p_faddr) || 685cc65eb4eSGleb Smirnoff IN6_IS_ADDR_LOOPBACK(&xip->in6p_laddr))) 6869b6ca892SBruce M Simpson continue; 6871e6690e5SDag-Erling Smørgrav } else { 6881e6690e5SDag-Erling Smørgrav if (opt_v) 689cc65eb4eSGleb Smirnoff warnx("invalid vflag 0x%x", xip->inp_vflag); 6901e6690e5SDag-Erling Smørgrav continue; 6911e6690e5SDag-Erling Smørgrav } 692b8e20e2dSHiroki Sato if ((sock = calloc(1, sizeof(*sock))) == NULL) 693ca007d91SDag-Erling Smørgrav err(1, "malloc()"); 694e6f718c7SMichael Tuexen if ((laddr = calloc(1, sizeof *laddr)) == NULL) 695e6f718c7SMichael Tuexen err(1, "malloc()"); 696e6f718c7SMichael Tuexen if ((faddr = calloc(1, sizeof *faddr)) == NULL) 697e6f718c7SMichael Tuexen err(1, "malloc()"); 698ca007d91SDag-Erling Smørgrav sock->socket = so->xso_so; 699ca007d91SDag-Erling Smørgrav sock->proto = proto; 700cc65eb4eSGleb Smirnoff if (xip->inp_vflag & INP_IPV4) { 701ca007d91SDag-Erling Smørgrav sock->family = AF_INET; 702e6f718c7SMichael Tuexen sockaddr(&laddr->address, sock->family, 703cc65eb4eSGleb Smirnoff &xip->inp_laddr, xip->inp_lport); 704e6f718c7SMichael Tuexen sockaddr(&faddr->address, sock->family, 705cc65eb4eSGleb Smirnoff &xip->inp_faddr, xip->inp_fport); 706cc65eb4eSGleb Smirnoff } else if (xip->inp_vflag & INP_IPV6) { 707ca007d91SDag-Erling Smørgrav sock->family = AF_INET6; 708e6f718c7SMichael Tuexen sockaddr(&laddr->address, sock->family, 709cc65eb4eSGleb Smirnoff &xip->in6p_laddr, xip->inp_lport); 710e6f718c7SMichael Tuexen sockaddr(&faddr->address, sock->family, 711cc65eb4eSGleb Smirnoff &xip->in6p_faddr, xip->inp_fport); 712ca007d91SDag-Erling Smørgrav } 713*9e644c23SMichael Tuexen if (proto == IPPROTO_TCP) 714*9e644c23SMichael Tuexen faddr->encaps_port = xtp->xt_encaps_port; 715e6f718c7SMichael Tuexen laddr->next = NULL; 716e6f718c7SMichael Tuexen faddr->next = NULL; 717e6f718c7SMichael Tuexen sock->laddr = laddr; 718e6f718c7SMichael Tuexen sock->faddr = faddr; 719cc65eb4eSGleb Smirnoff sock->vflag = xip->inp_vflag; 720e5cccc35SMichael Tuexen if (proto == IPPROTO_TCP) { 721cc65eb4eSGleb Smirnoff sock->state = xtp->t_state; 722e5cccc35SMichael Tuexen memcpy(sock->stack, xtp->xt_stack, 723e5cccc35SMichael Tuexen TCP_FUNCTION_NAME_LEN_MAX); 7242ac089d0SMichael Tuexen memcpy(sock->cc, xtp->xt_cc, TCP_CA_NAME_MAX); 725e5cccc35SMichael Tuexen } 726ca007d91SDag-Erling Smørgrav sock->protoname = protoname; 727ca007d91SDag-Erling Smørgrav hash = (int)((uintptr_t)sock->socket % HASHSIZE); 728ca007d91SDag-Erling Smørgrav sock->next = sockhash[hash]; 729ca007d91SDag-Erling Smørgrav sockhash[hash] = sock; 730ca007d91SDag-Erling Smørgrav } 731ca007d91SDag-Erling Smørgrav out: 732ca007d91SDag-Erling Smørgrav free(buf); 733ca007d91SDag-Erling Smørgrav } 734ca007d91SDag-Erling Smørgrav 735ca007d91SDag-Erling Smørgrav static void 736ca007d91SDag-Erling Smørgrav gather_unix(int proto) 737ca007d91SDag-Erling Smørgrav { 738ca007d91SDag-Erling Smørgrav struct xunpgen *xug, *exug; 739ca007d91SDag-Erling Smørgrav struct xunpcb *xup; 740ca007d91SDag-Erling Smørgrav struct sock *sock; 741e6f718c7SMichael Tuexen struct addr *laddr, *faddr; 742ca007d91SDag-Erling Smørgrav const char *varname, *protoname; 743ca007d91SDag-Erling Smørgrav size_t len, bufsize; 744ca007d91SDag-Erling Smørgrav void *buf; 745ca007d91SDag-Erling Smørgrav int hash, retry; 746ca007d91SDag-Erling Smørgrav 747ca007d91SDag-Erling Smørgrav switch (proto) { 748ca007d91SDag-Erling Smørgrav case SOCK_STREAM: 749ca007d91SDag-Erling Smørgrav varname = "net.local.stream.pcblist"; 750ca007d91SDag-Erling Smørgrav protoname = "stream"; 751ca007d91SDag-Erling Smørgrav break; 752ca007d91SDag-Erling Smørgrav case SOCK_DGRAM: 753ca007d91SDag-Erling Smørgrav varname = "net.local.dgram.pcblist"; 754ca007d91SDag-Erling Smørgrav protoname = "dgram"; 755ca007d91SDag-Erling Smørgrav break; 756b8e20e2dSHiroki Sato case SOCK_SEQPACKET: 757b8e20e2dSHiroki Sato varname = "net.local.seqpacket.pcblist"; 758b8e20e2dSHiroki Sato protoname = "seqpac"; 759b8e20e2dSHiroki Sato break; 760ca007d91SDag-Erling Smørgrav default: 761ca007d91SDag-Erling Smørgrav abort(); 762ca007d91SDag-Erling Smørgrav } 763ca007d91SDag-Erling Smørgrav buf = NULL; 764ca007d91SDag-Erling Smørgrav bufsize = 8192; 765ca007d91SDag-Erling Smørgrav retry = 5; 766ca007d91SDag-Erling Smørgrav do { 767ca007d91SDag-Erling Smørgrav for (;;) { 768ca007d91SDag-Erling Smørgrav if ((buf = realloc(buf, bufsize)) == NULL) 769ca007d91SDag-Erling Smørgrav err(1, "realloc()"); 770ca007d91SDag-Erling Smørgrav len = bufsize; 771ca007d91SDag-Erling Smørgrav if (sysctlbyname(varname, buf, &len, NULL, 0) == 0) 772ca007d91SDag-Erling Smørgrav break; 773003e7e49SMikolaj Golub if (errno != ENOMEM || len != bufsize) 774ca007d91SDag-Erling Smørgrav err(1, "sysctlbyname()"); 775ca007d91SDag-Erling Smørgrav bufsize *= 2; 776ca007d91SDag-Erling Smørgrav } 777ca007d91SDag-Erling Smørgrav xug = (struct xunpgen *)buf; 7786dbe8d53SRobert Drehmel exug = (struct xunpgen *)(void *) 779b8e20e2dSHiroki Sato ((char *)buf + len - sizeof(*exug)); 780b8e20e2dSHiroki Sato if (xug->xug_len != sizeof(*xug) || 781b8e20e2dSHiroki Sato exug->xug_len != sizeof(*exug)) { 782ca007d91SDag-Erling Smørgrav warnx("struct xinpgen size mismatch"); 783ca007d91SDag-Erling Smørgrav goto out; 784ca007d91SDag-Erling Smørgrav } 785ca007d91SDag-Erling Smørgrav } while (xug->xug_gen != exug->xug_gen && retry--); 786ca007d91SDag-Erling Smørgrav 787ca007d91SDag-Erling Smørgrav if (xug->xug_gen != exug->xug_gen && opt_v) 788ca007d91SDag-Erling Smørgrav warnx("warning: data may be inconsistent"); 789ca007d91SDag-Erling Smørgrav 790ca007d91SDag-Erling Smørgrav for (;;) { 7916dbe8d53SRobert Drehmel xug = (struct xunpgen *)(void *)((char *)xug + xug->xug_len); 792ca007d91SDag-Erling Smørgrav if (xug >= exug) 793ca007d91SDag-Erling Smørgrav break; 794ca007d91SDag-Erling Smørgrav xup = (struct xunpcb *)xug; 795b8e20e2dSHiroki Sato if (xup->xu_len != sizeof(*xup)) { 796ca007d91SDag-Erling Smørgrav warnx("struct xunpcb size mismatch"); 797ca007d91SDag-Erling Smørgrav goto out; 798ca007d91SDag-Erling Smørgrav } 799f38b68aeSBrooks Davis if ((xup->unp_conn == 0 && !opt_l) || 800f38b68aeSBrooks Davis (xup->unp_conn != 0 && !opt_c)) 8011e6690e5SDag-Erling Smørgrav continue; 802b8e20e2dSHiroki Sato if ((sock = calloc(1, sizeof(*sock))) == NULL) 803ca007d91SDag-Erling Smørgrav err(1, "malloc()"); 804e6f718c7SMichael Tuexen if ((laddr = calloc(1, sizeof *laddr)) == NULL) 805e6f718c7SMichael Tuexen err(1, "malloc()"); 806e6f718c7SMichael Tuexen if ((faddr = calloc(1, sizeof *faddr)) == NULL) 807e6f718c7SMichael Tuexen err(1, "malloc()"); 808ca007d91SDag-Erling Smørgrav sock->socket = xup->xu_socket.xso_so; 809ca007d91SDag-Erling Smørgrav sock->pcb = xup->xu_unpp; 810ca007d91SDag-Erling Smørgrav sock->proto = proto; 811ca007d91SDag-Erling Smørgrav sock->family = AF_UNIX; 812ca007d91SDag-Erling Smørgrav sock->protoname = protoname; 8130e229f34SGleb Smirnoff if (xup->xu_addr.sun_family == AF_UNIX) 814e6f718c7SMichael Tuexen laddr->address = 8156dbe8d53SRobert Drehmel *(struct sockaddr_storage *)(void *)&xup->xu_addr; 816f38b68aeSBrooks Davis else if (xup->unp_conn != 0) 817f38b68aeSBrooks Davis *(kvaddr_t*)&(faddr->address) = xup->unp_conn; 818e6f718c7SMichael Tuexen laddr->next = NULL; 819e6f718c7SMichael Tuexen faddr->next = NULL; 820e6f718c7SMichael Tuexen sock->laddr = laddr; 821e6f718c7SMichael Tuexen sock->faddr = faddr; 822ca007d91SDag-Erling Smørgrav hash = (int)((uintptr_t)sock->socket % HASHSIZE); 823ca007d91SDag-Erling Smørgrav sock->next = sockhash[hash]; 824ca007d91SDag-Erling Smørgrav sockhash[hash] = sock; 825ca007d91SDag-Erling Smørgrav } 826ca007d91SDag-Erling Smørgrav out: 827ca007d91SDag-Erling Smørgrav free(buf); 828ca007d91SDag-Erling Smørgrav } 829ca007d91SDag-Erling Smørgrav 830ca007d91SDag-Erling Smørgrav static void 831ca007d91SDag-Erling Smørgrav getfiles(void) 832ca007d91SDag-Erling Smørgrav { 833003e7e49SMikolaj Golub size_t len, olen; 834ca007d91SDag-Erling Smørgrav 835b8e20e2dSHiroki Sato olen = len = sizeof(*xfiles); 836003e7e49SMikolaj Golub if ((xfiles = malloc(len)) == NULL) 837ca007d91SDag-Erling Smørgrav err(1, "malloc()"); 838ca007d91SDag-Erling Smørgrav while (sysctlbyname("kern.file", xfiles, &len, 0, 0) == -1) { 839003e7e49SMikolaj Golub if (errno != ENOMEM || len != olen) 840ca007d91SDag-Erling Smørgrav err(1, "sysctlbyname()"); 841003e7e49SMikolaj Golub olen = len *= 2; 842ca007d91SDag-Erling Smørgrav if ((xfiles = realloc(xfiles, len)) == NULL) 843ca007d91SDag-Erling Smørgrav err(1, "realloc()"); 844ca007d91SDag-Erling Smørgrav } 845b8e20e2dSHiroki Sato if (len > 0 && xfiles->xf_size != sizeof(*xfiles)) 846ca007d91SDag-Erling Smørgrav errx(1, "struct xfile size mismatch"); 847b8e20e2dSHiroki Sato nxfiles = len / sizeof(*xfiles); 848ca007d91SDag-Erling Smørgrav } 849ca007d91SDag-Erling Smørgrav 850ca007d91SDag-Erling Smørgrav static int 851baa7f281SMichael Tuexen printaddr(struct sockaddr_storage *ss) 852ca007d91SDag-Erling Smørgrav { 853ca007d91SDag-Erling Smørgrav struct sockaddr_un *sun; 854b8e20e2dSHiroki Sato char addrstr[NI_MAXHOST] = { '\0', '\0' }; 855b8e20e2dSHiroki Sato int error, off, port = 0; 856ca007d91SDag-Erling Smørgrav 857baa7f281SMichael Tuexen switch (ss->ss_family) { 858ca007d91SDag-Erling Smørgrav case AF_INET: 859b8e20e2dSHiroki Sato if (inet_lnaof(sstosin(ss)->sin_addr) == INADDR_ANY) 860ca007d91SDag-Erling Smørgrav addrstr[0] = '*'; 861b8e20e2dSHiroki Sato port = ntohs(sstosin(ss)->sin_port); 862ca007d91SDag-Erling Smørgrav break; 863ca007d91SDag-Erling Smørgrav case AF_INET6: 864b8e20e2dSHiroki Sato if (IN6_IS_ADDR_UNSPECIFIED(&sstosin6(ss)->sin6_addr)) 865ca007d91SDag-Erling Smørgrav addrstr[0] = '*'; 866b8e20e2dSHiroki Sato port = ntohs(sstosin6(ss)->sin6_port); 867ca007d91SDag-Erling Smørgrav break; 868ca007d91SDag-Erling Smørgrav case AF_UNIX: 869b8e20e2dSHiroki Sato sun = sstosun(ss); 870ca007d91SDag-Erling Smørgrav off = (int)((char *)&sun->sun_path - (char *)sun); 871ca007d91SDag-Erling Smørgrav return (xprintf("%.*s", sun->sun_len - off, sun->sun_path)); 872ca007d91SDag-Erling Smørgrav } 873b8e20e2dSHiroki Sato if (addrstr[0] == '\0') { 874b8e20e2dSHiroki Sato error = getnameinfo(sstosa(ss), ss->ss_len, addrstr, 875b8e20e2dSHiroki Sato sizeof(addrstr), NULL, 0, NI_NUMERICHOST); 876b8e20e2dSHiroki Sato if (error) 877b8e20e2dSHiroki Sato errx(1, "getnameinfo()"); 878b8e20e2dSHiroki Sato } 879ca007d91SDag-Erling Smørgrav if (port == 0) 880ca007d91SDag-Erling Smørgrav return xprintf("%s:*", addrstr); 881ca007d91SDag-Erling Smørgrav else 882ca007d91SDag-Erling Smørgrav return xprintf("%s:%d", addrstr, port); 883ca007d91SDag-Erling Smørgrav } 884ca007d91SDag-Erling Smørgrav 885ca007d91SDag-Erling Smørgrav static const char * 886ca007d91SDag-Erling Smørgrav getprocname(pid_t pid) 887ca007d91SDag-Erling Smørgrav { 888ca007d91SDag-Erling Smørgrav static struct kinfo_proc proc; 889ca007d91SDag-Erling Smørgrav size_t len; 890ca007d91SDag-Erling Smørgrav int mib[4]; 891ca007d91SDag-Erling Smørgrav 892ca007d91SDag-Erling Smørgrav mib[0] = CTL_KERN; 893ca007d91SDag-Erling Smørgrav mib[1] = KERN_PROC; 894ca007d91SDag-Erling Smørgrav mib[2] = KERN_PROC_PID; 895ca007d91SDag-Erling Smørgrav mib[3] = (int)pid; 896b8e20e2dSHiroki Sato len = sizeof(proc); 897b8e20e2dSHiroki Sato if (sysctl(mib, nitems(mib), &proc, &len, NULL, 0) == -1) { 89848c513e0SMaxim Konovalov /* Do not warn if the process exits before we get its name. */ 89948c513e0SMaxim Konovalov if (errno != ESRCH) 900ca007d91SDag-Erling Smørgrav warn("sysctl()"); 901ca007d91SDag-Erling Smørgrav return ("??"); 902ca007d91SDag-Erling Smørgrav } 903f487a6a8SEd Maste return (proc.ki_comm); 904ca007d91SDag-Erling Smørgrav } 905ca007d91SDag-Erling Smørgrav 906ae94787dSMaxime Henrion static int 90700feaafdSAndrew Thompson getprocjid(pid_t pid) 90800feaafdSAndrew Thompson { 90900feaafdSAndrew Thompson static struct kinfo_proc proc; 91000feaafdSAndrew Thompson size_t len; 91100feaafdSAndrew Thompson int mib[4]; 91200feaafdSAndrew Thompson 91300feaafdSAndrew Thompson mib[0] = CTL_KERN; 91400feaafdSAndrew Thompson mib[1] = KERN_PROC; 91500feaafdSAndrew Thompson mib[2] = KERN_PROC_PID; 91600feaafdSAndrew Thompson mib[3] = (int)pid; 917b8e20e2dSHiroki Sato len = sizeof(proc); 918b8e20e2dSHiroki Sato if (sysctl(mib, nitems(mib), &proc, &len, NULL, 0) == -1) { 91900feaafdSAndrew Thompson /* Do not warn if the process exits before we get its jid. */ 92000feaafdSAndrew Thompson if (errno != ESRCH) 92100feaafdSAndrew Thompson warn("sysctl()"); 92200feaafdSAndrew Thompson return (-1); 92300feaafdSAndrew Thompson } 92400feaafdSAndrew Thompson return (proc.ki_jid); 92500feaafdSAndrew Thompson } 92600feaafdSAndrew Thompson 92700feaafdSAndrew Thompson static int 928ae94787dSMaxime Henrion check_ports(struct sock *s) 929ae94787dSMaxime Henrion { 930ae94787dSMaxime Henrion int port; 931e6f718c7SMichael Tuexen struct addr *addr; 932ae94787dSMaxime Henrion 933ae94787dSMaxime Henrion if (ports == NULL) 934ae94787dSMaxime Henrion return (1); 935ae94787dSMaxime Henrion if ((s->family != AF_INET) && (s->family != AF_INET6)) 936ae94787dSMaxime Henrion return (1); 937e6f718c7SMichael Tuexen for (addr = s->laddr; addr != NULL; addr = addr->next) { 938b8e20e2dSHiroki Sato if (s->family == AF_INET) 939b8e20e2dSHiroki Sato port = ntohs(sstosin(&addr->address)->sin_port); 940ae94787dSMaxime Henrion else 941b8e20e2dSHiroki Sato port = ntohs(sstosin6(&addr->address)->sin6_port); 942ae94787dSMaxime Henrion if (CHK_PORT(port)) 943ae94787dSMaxime Henrion return (1); 944e6f718c7SMichael Tuexen } 945e6f718c7SMichael Tuexen for (addr = s->faddr; addr != NULL; addr = addr->next) { 946b8e20e2dSHiroki Sato if (s->family == AF_INET) 947b8e20e2dSHiroki Sato port = ntohs(sstosin(&addr->address)->sin_port); 948ae94787dSMaxime Henrion else 949b8e20e2dSHiroki Sato port = ntohs(sstosin6(&addr->address)->sin6_port); 950ae94787dSMaxime Henrion if (CHK_PORT(port)) 951ae94787dSMaxime Henrion return (1); 952e6f718c7SMichael Tuexen } 953ae94787dSMaxime Henrion return (0); 954ae94787dSMaxime Henrion } 955ae94787dSMaxime Henrion 9566414db1bSMichael Tuexen static const char * 957e389705eSMichael Tuexen sctp_conn_state(int state) 9586414db1bSMichael Tuexen { 9596414db1bSMichael Tuexen switch (state) { 9606414db1bSMichael Tuexen case SCTP_CLOSED: 9616414db1bSMichael Tuexen return "CLOSED"; 9626414db1bSMichael Tuexen break; 9636414db1bSMichael Tuexen case SCTP_BOUND: 9646414db1bSMichael Tuexen return "BOUND"; 9656414db1bSMichael Tuexen break; 9666414db1bSMichael Tuexen case SCTP_LISTEN: 9676414db1bSMichael Tuexen return "LISTEN"; 9686414db1bSMichael Tuexen break; 9696414db1bSMichael Tuexen case SCTP_COOKIE_WAIT: 9706414db1bSMichael Tuexen return "COOKIE_WAIT"; 9716414db1bSMichael Tuexen break; 9726414db1bSMichael Tuexen case SCTP_COOKIE_ECHOED: 9736414db1bSMichael Tuexen return "COOKIE_ECHOED"; 9746414db1bSMichael Tuexen break; 9756414db1bSMichael Tuexen case SCTP_ESTABLISHED: 9766414db1bSMichael Tuexen return "ESTABLISHED"; 9776414db1bSMichael Tuexen break; 9786414db1bSMichael Tuexen case SCTP_SHUTDOWN_SENT: 9796414db1bSMichael Tuexen return "SHUTDOWN_SENT"; 9806414db1bSMichael Tuexen break; 9816414db1bSMichael Tuexen case SCTP_SHUTDOWN_RECEIVED: 9826414db1bSMichael Tuexen return "SHUTDOWN_RECEIVED"; 9836414db1bSMichael Tuexen break; 9846414db1bSMichael Tuexen case SCTP_SHUTDOWN_ACK_SENT: 9856414db1bSMichael Tuexen return "SHUTDOWN_ACK_SENT"; 9866414db1bSMichael Tuexen break; 9876414db1bSMichael Tuexen case SCTP_SHUTDOWN_PENDING: 9886414db1bSMichael Tuexen return "SHUTDOWN_PENDING"; 9896414db1bSMichael Tuexen break; 9906414db1bSMichael Tuexen default: 9916414db1bSMichael Tuexen return "UNKNOWN"; 9926414db1bSMichael Tuexen break; 9936414db1bSMichael Tuexen } 9946414db1bSMichael Tuexen } 9956414db1bSMichael Tuexen 996e389705eSMichael Tuexen static const char * 997e389705eSMichael Tuexen sctp_path_state(int state) 998e389705eSMichael Tuexen { 999e389705eSMichael Tuexen switch (state) { 1000e389705eSMichael Tuexen case SCTP_UNCONFIRMED: 1001e389705eSMichael Tuexen return "UNCONFIRMED"; 1002e389705eSMichael Tuexen break; 1003e389705eSMichael Tuexen case SCTP_ACTIVE: 1004e389705eSMichael Tuexen return "ACTIVE"; 1005e389705eSMichael Tuexen break; 1006e389705eSMichael Tuexen case SCTP_INACTIVE: 1007e389705eSMichael Tuexen return "INACTIVE"; 1008e389705eSMichael Tuexen break; 1009e389705eSMichael Tuexen default: 1010e389705eSMichael Tuexen return "UNKNOWN"; 1011e389705eSMichael Tuexen break; 1012e389705eSMichael Tuexen } 1013e389705eSMichael Tuexen } 1014e389705eSMichael Tuexen 1015ca007d91SDag-Erling Smørgrav static void 101661149f8dSJilles Tjoelker displaysock(struct sock *s, int pos) 1017ca007d91SDag-Erling Smørgrav { 1018f38b68aeSBrooks Davis kvaddr_t p; 101949b836f2SMichael Tuexen int hash, first, offset; 1020e6f718c7SMichael Tuexen struct addr *laddr, *faddr; 102181091202SMichael Tuexen struct sock *s_tmp; 1022ca007d91SDag-Erling Smørgrav 1023ca007d91SDag-Erling Smørgrav while (pos < 29) 1024ca007d91SDag-Erling Smørgrav pos += xprintf(" "); 1025ca007d91SDag-Erling Smørgrav pos += xprintf("%s", s->protoname); 1026ca007d91SDag-Erling Smørgrav if (s->vflag & INP_IPV4) 1027ca007d91SDag-Erling Smørgrav pos += xprintf("4"); 1028ca007d91SDag-Erling Smørgrav if (s->vflag & INP_IPV6) 1029ca007d91SDag-Erling Smørgrav pos += xprintf("6"); 1030edc9c7fcSMichael Tuexen if (s->vflag & (INP_IPV4 | INP_IPV6)) 1031edc9c7fcSMichael Tuexen pos += xprintf(" "); 1032e6f718c7SMichael Tuexen laddr = s->laddr; 1033e6f718c7SMichael Tuexen faddr = s->faddr; 10344e13a5b0SMichael Tuexen first = 1; 1035e6f718c7SMichael Tuexen while (laddr != NULL || faddr != NULL) { 103683f60cb2SMichael Tuexen offset = 36; 103783f60cb2SMichael Tuexen while (pos < offset) 1038ca007d91SDag-Erling Smørgrav pos += xprintf(" "); 1039ca007d91SDag-Erling Smørgrav switch (s->family) { 1040ca007d91SDag-Erling Smørgrav case AF_INET: 1041ca007d91SDag-Erling Smørgrav case AF_INET6: 1042e6f718c7SMichael Tuexen if (laddr != NULL) { 1043e6f718c7SMichael Tuexen pos += printaddr(&laddr->address); 104409bbda21SMaxim Konovalov if (s->family == AF_INET6 && pos >= 58) 104509bbda21SMaxim Konovalov pos += xprintf(" "); 1046e6f718c7SMichael Tuexen } 104783f60cb2SMichael Tuexen offset += opt_w ? 46 : 22; 104883f60cb2SMichael Tuexen while (pos < offset) 1049ca007d91SDag-Erling Smørgrav pos += xprintf(" "); 1050e6f718c7SMichael Tuexen if (faddr != NULL) 1051e6f718c7SMichael Tuexen pos += printaddr(&faddr->address); 105283f60cb2SMichael Tuexen offset += opt_w ? 46 : 22; 1053ca007d91SDag-Erling Smørgrav break; 1054ca007d91SDag-Erling Smørgrav case AF_UNIX: 1055e6f718c7SMichael Tuexen if ((laddr == NULL) || (faddr == NULL)) 1056e6f718c7SMichael Tuexen errx(1, "laddr = %p or faddr = %p is NULL", 1057e6f718c7SMichael Tuexen (void *)laddr, (void *)faddr); 1058ca007d91SDag-Erling Smørgrav /* server */ 1059e6f718c7SMichael Tuexen if (laddr->address.ss_len > 0) { 1060e6f718c7SMichael Tuexen pos += printaddr(&laddr->address); 1061ca007d91SDag-Erling Smørgrav break; 1062ca007d91SDag-Erling Smørgrav } 1063ca007d91SDag-Erling Smørgrav /* client */ 1064f38b68aeSBrooks Davis p = *(kvaddr_t*)&(faddr->address); 1065f38b68aeSBrooks Davis if (p == 0) { 1066b4eb37c6SJohn-Mark Gurney pos += xprintf("(not connected)"); 106783f60cb2SMichael Tuexen offset += opt_w ? 92 : 44; 1068b4eb37c6SJohn-Mark Gurney break; 1069b4eb37c6SJohn-Mark Gurney } 1070b4eb37c6SJohn-Mark Gurney pos += xprintf("-> "); 1071ca007d91SDag-Erling Smørgrav for (hash = 0; hash < HASHSIZE; ++hash) { 107281091202SMichael Tuexen for (s_tmp = sockhash[hash]; 107381091202SMichael Tuexen s_tmp != NULL; 107481091202SMichael Tuexen s_tmp = s_tmp->next) 107581091202SMichael Tuexen if (s_tmp->pcb == p) 1076ca007d91SDag-Erling Smørgrav break; 107781091202SMichael Tuexen if (s_tmp != NULL) 1078ca007d91SDag-Erling Smørgrav break; 1079ca007d91SDag-Erling Smørgrav } 108027569d01SRenato Botelho if (s_tmp == NULL || s_tmp->laddr == NULL || 108181091202SMichael Tuexen s_tmp->laddr->address.ss_len == 0) 1082ca007d91SDag-Erling Smørgrav pos += xprintf("??"); 1083ca007d91SDag-Erling Smørgrav else 108481091202SMichael Tuexen pos += printaddr(&s_tmp->laddr->address); 108583f60cb2SMichael Tuexen offset += opt_w ? 92 : 44; 1086ca007d91SDag-Erling Smørgrav break; 1087ca007d91SDag-Erling Smørgrav default: 1088ca007d91SDag-Erling Smørgrav abort(); 1089ca007d91SDag-Erling Smørgrav } 109049b836f2SMichael Tuexen if (opt_U) { 109149b836f2SMichael Tuexen if (faddr != NULL && 1092*9e644c23SMichael Tuexen ((s->proto == IPPROTO_SCTP && 109349b836f2SMichael Tuexen s->state != SCTP_CLOSED && 109449b836f2SMichael Tuexen s->state != SCTP_BOUND && 1095*9e644c23SMichael Tuexen s->state != SCTP_LISTEN) || 1096*9e644c23SMichael Tuexen (s->proto == IPPROTO_TCP && 1097*9e644c23SMichael Tuexen s->state != TCPS_CLOSED && 1098*9e644c23SMichael Tuexen s->state != TCPS_LISTEN))) { 109949b836f2SMichael Tuexen while (pos < offset) 110049b836f2SMichael Tuexen pos += xprintf(" "); 110149b836f2SMichael Tuexen pos += xprintf("%u", 110249b836f2SMichael Tuexen ntohs(faddr->encaps_port)); 110349b836f2SMichael Tuexen } 110449b836f2SMichael Tuexen offset += 7; 110549b836f2SMichael Tuexen } 1106e389705eSMichael Tuexen if (opt_s) { 1107e389705eSMichael Tuexen if (faddr != NULL && 1108e389705eSMichael Tuexen s->proto == IPPROTO_SCTP && 1109e389705eSMichael Tuexen s->state != SCTP_CLOSED && 1110e389705eSMichael Tuexen s->state != SCTP_BOUND && 1111e389705eSMichael Tuexen s->state != SCTP_LISTEN) { 1112e389705eSMichael Tuexen while (pos < offset) 1113e389705eSMichael Tuexen pos += xprintf(" "); 1114e389705eSMichael Tuexen pos += xprintf("%s", 1115e389705eSMichael Tuexen sctp_path_state(faddr->state)); 1116e389705eSMichael Tuexen } 1117e389705eSMichael Tuexen offset += 13; 1118e389705eSMichael Tuexen } 1119e5cccc35SMichael Tuexen if (first) { 112049b836f2SMichael Tuexen if (opt_s) { 112149b836f2SMichael Tuexen if (s->proto == IPPROTO_SCTP || 112249b836f2SMichael Tuexen s->proto == IPPROTO_TCP) { 112349b836f2SMichael Tuexen while (pos < offset) 11244e13a5b0SMichael Tuexen pos += xprintf(" "); 11256414db1bSMichael Tuexen switch (s->proto) { 11266414db1bSMichael Tuexen case IPPROTO_SCTP: 1127e5cccc35SMichael Tuexen pos += xprintf("%s", 1128e389705eSMichael Tuexen sctp_conn_state(s->state)); 11296414db1bSMichael Tuexen break; 11306414db1bSMichael Tuexen case IPPROTO_TCP: 1131e5cccc35SMichael Tuexen if (s->state >= 0 && 1132e5cccc35SMichael Tuexen s->state < TCP_NSTATES) 113349b836f2SMichael Tuexen pos += xprintf("%s", 1134e5cccc35SMichael Tuexen tcpstates[s->state]); 11354e13a5b0SMichael Tuexen else 11364e13a5b0SMichael Tuexen pos += xprintf("?"); 11376414db1bSMichael Tuexen break; 11386414db1bSMichael Tuexen } 11394e13a5b0SMichael Tuexen } 114049b836f2SMichael Tuexen offset += 13; 114149b836f2SMichael Tuexen } 11422ac089d0SMichael Tuexen if (opt_S) { 11432ac089d0SMichael Tuexen if (s->proto == IPPROTO_TCP) { 114449b836f2SMichael Tuexen while (pos < offset) 1145e5cccc35SMichael Tuexen pos += xprintf(" "); 11462ac089d0SMichael Tuexen pos += xprintf("%.*s", 11472ac089d0SMichael Tuexen TCP_FUNCTION_NAME_LEN_MAX, 1148e5cccc35SMichael Tuexen s->stack); 1149e5cccc35SMichael Tuexen } 11502ac089d0SMichael Tuexen offset += TCP_FUNCTION_NAME_LEN_MAX + 1; 11512ac089d0SMichael Tuexen } 11522ac089d0SMichael Tuexen if (opt_C) { 11532ac089d0SMichael Tuexen if (s->proto == IPPROTO_TCP) { 11542ac089d0SMichael Tuexen while (pos < offset) 11552ac089d0SMichael Tuexen pos += xprintf(" "); 11562ac089d0SMichael Tuexen xprintf("%.*s", TCP_CA_NAME_MAX, s->cc); 11572ac089d0SMichael Tuexen } 11582ac089d0SMichael Tuexen offset += TCP_CA_NAME_MAX + 1; 11592ac089d0SMichael Tuexen } 1160e5cccc35SMichael Tuexen } 1161e6f718c7SMichael Tuexen if (laddr != NULL) 1162e6f718c7SMichael Tuexen laddr = laddr->next; 1163e6f718c7SMichael Tuexen if (faddr != NULL) 1164e6f718c7SMichael Tuexen faddr = faddr->next; 1165e6f718c7SMichael Tuexen if ((laddr != NULL) || (faddr != NULL)) { 1166e6f718c7SMichael Tuexen xprintf("\n"); 1167e6f718c7SMichael Tuexen pos = 0; 1168e6f718c7SMichael Tuexen } 11694e13a5b0SMichael Tuexen first = 0; 1170e6f718c7SMichael Tuexen } 11714e13a5b0SMichael Tuexen xprintf("\n"); 1172ca007d91SDag-Erling Smørgrav } 117361149f8dSJilles Tjoelker 117461149f8dSJilles Tjoelker static void 117561149f8dSJilles Tjoelker display(void) 117661149f8dSJilles Tjoelker { 117761149f8dSJilles Tjoelker struct passwd *pwd; 117861149f8dSJilles Tjoelker struct xfile *xf; 117961149f8dSJilles Tjoelker struct sock *s; 118061149f8dSJilles Tjoelker int hash, n, pos; 118161149f8dSJilles Tjoelker 1182ee0afaa9SEmmanuel Vadot if (opt_q != 1) { 118383f60cb2SMichael Tuexen printf("%-8s %-10s %-5s %-2s %-6s %-*s %-*s", 118461149f8dSJilles Tjoelker "USER", "COMMAND", "PID", "FD", "PROTO", 118583f60cb2SMichael Tuexen opt_w ? 45 : 21, "LOCAL ADDRESS", 118683f60cb2SMichael Tuexen opt_w ? 45 : 21, "FOREIGN ADDRESS"); 118749b836f2SMichael Tuexen if (opt_U) 118849b836f2SMichael Tuexen printf(" %-6s", "ENCAPS"); 1189e389705eSMichael Tuexen if (opt_s) { 1190e389705eSMichael Tuexen printf(" %-12s", "PATH STATE"); 1191e389705eSMichael Tuexen printf(" %-12s", "CONN STATE"); 1192e389705eSMichael Tuexen } 1193e5cccc35SMichael Tuexen if (opt_S) 11942ac089d0SMichael Tuexen printf(" %-*.*s", TCP_FUNCTION_NAME_LEN_MAX, 11952ac089d0SMichael Tuexen TCP_FUNCTION_NAME_LEN_MAX, "STACK"); 11962ac089d0SMichael Tuexen if (opt_C) 11972ac089d0SMichael Tuexen printf(" %-.*s", TCP_CA_NAME_MAX, "CC"); 11987a5642b3SDag-Erling Smørgrav printf("\n"); 1199ee0afaa9SEmmanuel Vadot } 120061149f8dSJilles Tjoelker setpassent(1); 120161149f8dSJilles Tjoelker for (xf = xfiles, n = 0; n < nxfiles; ++n, ++xf) { 1202f38b68aeSBrooks Davis if (xf->xf_data == 0) 120361149f8dSJilles Tjoelker continue; 120400feaafdSAndrew Thompson if (opt_j >= 0 && opt_j != getprocjid(xf->xf_pid)) 120500feaafdSAndrew Thompson continue; 120661149f8dSJilles Tjoelker hash = (int)((uintptr_t)xf->xf_data % HASHSIZE); 12077e80c6b0SMichael Tuexen for (s = sockhash[hash]; s != NULL; s = s->next) { 1208f38b68aeSBrooks Davis if (s->socket != xf->xf_data) 120961149f8dSJilles Tjoelker continue; 121061149f8dSJilles Tjoelker if (!check_ports(s)) 121161149f8dSJilles Tjoelker continue; 121261149f8dSJilles Tjoelker s->shown = 1; 121361149f8dSJilles Tjoelker pos = 0; 1214ccdd2b2bSAlexander Motin if (opt_n || (pwd = getpwuid(xf->xf_uid)) == NULL) 121561149f8dSJilles Tjoelker pos += xprintf("%lu ", (u_long)xf->xf_uid); 121661149f8dSJilles Tjoelker else 121761149f8dSJilles Tjoelker pos += xprintf("%s ", pwd->pw_name); 121861149f8dSJilles Tjoelker while (pos < 9) 121961149f8dSJilles Tjoelker pos += xprintf(" "); 122061149f8dSJilles Tjoelker pos += xprintf("%.10s", getprocname(xf->xf_pid)); 122161149f8dSJilles Tjoelker while (pos < 20) 122261149f8dSJilles Tjoelker pos += xprintf(" "); 122361149f8dSJilles Tjoelker pos += xprintf("%lu ", (u_long)xf->xf_pid); 122461149f8dSJilles Tjoelker while (pos < 26) 122561149f8dSJilles Tjoelker pos += xprintf(" "); 122661149f8dSJilles Tjoelker pos += xprintf("%d ", xf->xf_fd); 122761149f8dSJilles Tjoelker displaysock(s, pos); 122861149f8dSJilles Tjoelker } 12297e80c6b0SMichael Tuexen } 123000feaafdSAndrew Thompson if (opt_j >= 0) 123100feaafdSAndrew Thompson return; 123261149f8dSJilles Tjoelker for (hash = 0; hash < HASHSIZE; hash++) { 123361149f8dSJilles Tjoelker for (s = sockhash[hash]; s != NULL; s = s->next) { 123461149f8dSJilles Tjoelker if (s->shown) 123561149f8dSJilles Tjoelker continue; 123661149f8dSJilles Tjoelker if (!check_ports(s)) 123761149f8dSJilles Tjoelker continue; 123861149f8dSJilles Tjoelker pos = 0; 123961149f8dSJilles Tjoelker pos += xprintf("%-8s %-10s %-5s %-2s ", 124061149f8dSJilles Tjoelker "?", "?", "?", "?"); 124161149f8dSJilles Tjoelker displaysock(s, pos); 124261149f8dSJilles Tjoelker } 124361149f8dSJilles Tjoelker } 1244ca007d91SDag-Erling Smørgrav } 1245ca007d91SDag-Erling Smørgrav 1246f1cd4902SRyan Moeller static int 1247f1cd4902SRyan Moeller set_default_protos(void) 12481f3d67aaSGiorgos Keramidas { 12491f3d67aaSGiorgos Keramidas struct protoent *prot; 12501f3d67aaSGiorgos Keramidas const char *pname; 12511f3d67aaSGiorgos Keramidas size_t pindex; 12521f3d67aaSGiorgos Keramidas 12531f3d67aaSGiorgos Keramidas init_protos(default_numprotos); 12541f3d67aaSGiorgos Keramidas 12551f3d67aaSGiorgos Keramidas for (pindex = 0; pindex < default_numprotos; pindex++) { 12561f3d67aaSGiorgos Keramidas pname = default_protos[pindex]; 12571f3d67aaSGiorgos Keramidas prot = getprotobyname(pname); 12581f3d67aaSGiorgos Keramidas if (prot == NULL) 12591f3d67aaSGiorgos Keramidas err(1, "getprotobyname: %s", pname); 12601f3d67aaSGiorgos Keramidas protos[pindex] = prot->p_proto; 12611f3d67aaSGiorgos Keramidas } 12621f3d67aaSGiorgos Keramidas numprotos = pindex; 12631f3d67aaSGiorgos Keramidas return (pindex); 12641f3d67aaSGiorgos Keramidas } 12651f3d67aaSGiorgos Keramidas 1266f1cd4902SRyan Moeller /* 1267f1cd4902SRyan Moeller * Return the vnet property of the jail, or -1 on error. 1268f1cd4902SRyan Moeller */ 1269f1cd4902SRyan Moeller static int 1270f1cd4902SRyan Moeller jail_getvnet(int jid) 1271f1cd4902SRyan Moeller { 1272f1cd4902SRyan Moeller struct iovec jiov[6]; 1273f1cd4902SRyan Moeller int vnet; 1274f1cd4902SRyan Moeller 1275f1cd4902SRyan Moeller vnet = -1; 1276f1cd4902SRyan Moeller jiov[0].iov_base = __DECONST(char *, "jid"); 1277f1cd4902SRyan Moeller jiov[0].iov_len = sizeof("jid"); 1278f1cd4902SRyan Moeller jiov[1].iov_base = &jid; 1279f1cd4902SRyan Moeller jiov[1].iov_len = sizeof(jid); 1280f1cd4902SRyan Moeller jiov[2].iov_base = __DECONST(char *, "vnet"); 1281f1cd4902SRyan Moeller jiov[2].iov_len = sizeof("vnet"); 1282f1cd4902SRyan Moeller jiov[3].iov_base = &vnet; 1283f1cd4902SRyan Moeller jiov[3].iov_len = sizeof(vnet); 1284f1cd4902SRyan Moeller jiov[4].iov_base = __DECONST(char *, "errmsg"); 1285f1cd4902SRyan Moeller jiov[4].iov_len = sizeof("errmsg"); 1286f1cd4902SRyan Moeller jiov[5].iov_base = jail_errmsg; 1287f1cd4902SRyan Moeller jiov[5].iov_len = JAIL_ERRMSGLEN; 1288f1cd4902SRyan Moeller jail_errmsg[0] = '\0'; 1289f1cd4902SRyan Moeller if (jail_get(jiov, nitems(jiov), 0) < 0) { 1290f1cd4902SRyan Moeller if (!jail_errmsg[0]) 1291f1cd4902SRyan Moeller snprintf(jail_errmsg, JAIL_ERRMSGLEN, 1292f1cd4902SRyan Moeller "jail_get: %s", strerror(errno)); 1293f1cd4902SRyan Moeller return (-1); 1294f1cd4902SRyan Moeller } 1295f1cd4902SRyan Moeller return (vnet); 1296f1cd4902SRyan Moeller } 1297f1cd4902SRyan Moeller 1298ca007d91SDag-Erling Smørgrav static void 1299ca007d91SDag-Erling Smørgrav usage(void) 1300ca007d91SDag-Erling Smørgrav { 13011f3d67aaSGiorgos Keramidas fprintf(stderr, 130283f60cb2SMichael Tuexen "usage: sockstat [-46cLlSsUuvw] [-j jid] [-p ports] [-P protocols]\n"); 1303ca007d91SDag-Erling Smørgrav exit(1); 1304ca007d91SDag-Erling Smørgrav } 1305ca007d91SDag-Erling Smørgrav 1306ca007d91SDag-Erling Smørgrav int 1307ca007d91SDag-Erling Smørgrav main(int argc, char *argv[]) 1308ca007d91SDag-Erling Smørgrav { 13091f3d67aaSGiorgos Keramidas int protos_defined = -1; 13101f3d67aaSGiorgos Keramidas int o, i; 1311ca007d91SDag-Erling Smørgrav 131200feaafdSAndrew Thompson opt_j = -1; 1313ccdd2b2bSAlexander Motin while ((o = getopt(argc, argv, "46Ccj:Llnp:P:qSsUuvw")) != -1) 1314ca007d91SDag-Erling Smørgrav switch (o) { 1315ca007d91SDag-Erling Smørgrav case '4': 1316ca007d91SDag-Erling Smørgrav opt_4 = 1; 1317ca007d91SDag-Erling Smørgrav break; 1318ca007d91SDag-Erling Smørgrav case '6': 1319ca007d91SDag-Erling Smørgrav opt_6 = 1; 1320ca007d91SDag-Erling Smørgrav break; 13212ac089d0SMichael Tuexen case 'C': 13222ac089d0SMichael Tuexen opt_C = 1; 13232ac089d0SMichael Tuexen break; 1324ca007d91SDag-Erling Smørgrav case 'c': 1325ca007d91SDag-Erling Smørgrav opt_c = 1; 1326ca007d91SDag-Erling Smørgrav break; 132700feaafdSAndrew Thompson case 'j': 1328de68a320SJamie Gritton opt_j = jail_getid(optarg); 1329de68a320SJamie Gritton if (opt_j < 0) 1330de68a320SJamie Gritton errx(1, "%s", jail_errmsg); 133100feaafdSAndrew Thompson break; 13329b6ca892SBruce M Simpson case 'L': 13339b6ca892SBruce M Simpson opt_L = 1; 13349b6ca892SBruce M Simpson break; 1335ca007d91SDag-Erling Smørgrav case 'l': 1336ca007d91SDag-Erling Smørgrav opt_l = 1; 1337ca007d91SDag-Erling Smørgrav break; 1338ccdd2b2bSAlexander Motin case 'n': 1339ccdd2b2bSAlexander Motin opt_n = 1; 1340ccdd2b2bSAlexander Motin break; 1341ca007d91SDag-Erling Smørgrav case 'p': 1342ca007d91SDag-Erling Smørgrav parse_ports(optarg); 1343ca007d91SDag-Erling Smørgrav break; 13441f3d67aaSGiorgos Keramidas case 'P': 13451f3d67aaSGiorgos Keramidas protos_defined = parse_protos(optarg); 13461f3d67aaSGiorgos Keramidas break; 1347ee0afaa9SEmmanuel Vadot case 'q': 1348ee0afaa9SEmmanuel Vadot opt_q = 1; 134962de7037SEmmanuel Vadot break; 1350e5cccc35SMichael Tuexen case 'S': 1351e5cccc35SMichael Tuexen opt_S = 1; 1352e5cccc35SMichael Tuexen break; 13537a5642b3SDag-Erling Smørgrav case 's': 13547a5642b3SDag-Erling Smørgrav opt_s = 1; 13557a5642b3SDag-Erling Smørgrav break; 135649b836f2SMichael Tuexen case 'U': 135749b836f2SMichael Tuexen opt_U = 1; 135849b836f2SMichael Tuexen break; 1359ca007d91SDag-Erling Smørgrav case 'u': 1360ca007d91SDag-Erling Smørgrav opt_u = 1; 1361ca007d91SDag-Erling Smørgrav break; 1362ca007d91SDag-Erling Smørgrav case 'v': 1363ca007d91SDag-Erling Smørgrav ++opt_v; 1364ca007d91SDag-Erling Smørgrav break; 136583f60cb2SMichael Tuexen case 'w': 136683f60cb2SMichael Tuexen opt_w = 1; 136783f60cb2SMichael Tuexen break; 1368ca007d91SDag-Erling Smørgrav default: 1369ca007d91SDag-Erling Smørgrav usage(); 1370ca007d91SDag-Erling Smørgrav } 1371ca007d91SDag-Erling Smørgrav 1372ca007d91SDag-Erling Smørgrav argc -= optind; 1373ca007d91SDag-Erling Smørgrav argv += optind; 1374ca007d91SDag-Erling Smørgrav 1375ca007d91SDag-Erling Smørgrav if (argc > 0) 1376ca007d91SDag-Erling Smørgrav usage(); 1377ca007d91SDag-Erling Smørgrav 1378f1cd4902SRyan Moeller if (opt_j > 0) { 1379f1cd4902SRyan Moeller switch (jail_getvnet(opt_j)) { 1380f1cd4902SRyan Moeller case -1: 1381f1cd4902SRyan Moeller errx(2, "%s", jail_errmsg); 1382f1cd4902SRyan Moeller case JAIL_SYS_NEW: 1383f1cd4902SRyan Moeller if (jail_attach(opt_j) < 0) 1384ae37905bSRyan Moeller err(3, "jail_attach()"); 1385f1cd4902SRyan Moeller /* Set back to -1 for normal output in vnet jail. */ 1386f1cd4902SRyan Moeller opt_j = -1; 1387f1cd4902SRyan Moeller break; 1388f1cd4902SRyan Moeller default: 1389f1cd4902SRyan Moeller break; 1390f1cd4902SRyan Moeller } 1391f1cd4902SRyan Moeller } 1392f1cd4902SRyan Moeller 1393d2d77d2aSGiorgos Keramidas if ((!opt_4 && !opt_6) && protos_defined != -1) 13941f3d67aaSGiorgos Keramidas opt_4 = opt_6 = 1; 1395d2d77d2aSGiorgos Keramidas if (!opt_4 && !opt_6 && !opt_u) 1396d2d77d2aSGiorgos Keramidas opt_4 = opt_6 = opt_u = 1; 1397d2d77d2aSGiorgos Keramidas if ((opt_4 || opt_6) && protos_defined == -1) 1398d2d77d2aSGiorgos Keramidas protos_defined = set_default_protos(); 1399ca007d91SDag-Erling Smørgrav if (!opt_c && !opt_l) 1400ca007d91SDag-Erling Smørgrav opt_c = opt_l = 1; 1401ca007d91SDag-Erling Smørgrav 1402ca007d91SDag-Erling Smørgrav if (opt_4 || opt_6) { 14031f3d67aaSGiorgos Keramidas for (i = 0; i < protos_defined; i++) 1404d5b4aa90SMichael Tuexen if (protos[i] == IPPROTO_SCTP) 1405d5b4aa90SMichael Tuexen gather_sctp(); 1406d5b4aa90SMichael Tuexen else 14071f3d67aaSGiorgos Keramidas gather_inet(protos[i]); 1408ca007d91SDag-Erling Smørgrav } 14091f3d67aaSGiorgos Keramidas 14101f3d67aaSGiorgos Keramidas if (opt_u || (protos_defined == -1 && !opt_4 && !opt_6)) { 1411ca007d91SDag-Erling Smørgrav gather_unix(SOCK_STREAM); 1412ca007d91SDag-Erling Smørgrav gather_unix(SOCK_DGRAM); 1413b8e20e2dSHiroki Sato gather_unix(SOCK_SEQPACKET); 1414ca007d91SDag-Erling Smørgrav } 1415ca007d91SDag-Erling Smørgrav getfiles(); 1416ca007d91SDag-Erling Smørgrav display(); 1417ca007d91SDag-Erling Smørgrav exit(0); 1418ca007d91SDag-Erling Smørgrav } 1419