From owner-svn-src-stable@FreeBSD.ORG Fri Feb 10 22:31:47 2012 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 81DD31065678; Fri, 10 Feb 2012 22:31:47 +0000 (UTC) (envelope-from tuexen@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 6E37B8FC18; Fri, 10 Feb 2012 22:31:47 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q1AMVlDp098947; Fri, 10 Feb 2012 22:31:47 GMT (envelope-from tuexen@svn.freebsd.org) Received: (from tuexen@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q1AMVlBp098945; Fri, 10 Feb 2012 22:31:47 GMT (envelope-from tuexen@svn.freebsd.org) Message-Id: <201202102231.q1AMVlBp098945@svn.freebsd.org> From: Michael Tuexen Date: Fri, 10 Feb 2012 22:31:47 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r231455 - in stable/8/usr.bin: chpass netstat su X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 10 Feb 2012 22:31:47 -0000 Author: tuexen Date: Fri Feb 10 22:31:47 2012 New Revision: 231455 URL: http://svn.freebsd.org/changeset/base/231455 Log: MFC r224271: Fix the following bugs related to the SCTP support of netstat: * Correctly handle -a. * -A isn't supported. * Show all closed 1-to-1 and 1-to-many style sockets. * Show all listening 1-to-many style sockets. * Use consistent formatting for -W. Modified: stable/8/usr.bin/netstat/sctp.c (contents, props changed) Directory Properties: stable/8/usr.bin/ (props changed) stable/8/usr.bin/apply/ (props changed) stable/8/usr.bin/ar/ (props changed) stable/8/usr.bin/awk/ (props changed) stable/8/usr.bin/biff/ (props changed) stable/8/usr.bin/c89/ (props changed) stable/8/usr.bin/c99/ (props changed) stable/8/usr.bin/calendar/ (props changed) stable/8/usr.bin/catman/ (props changed) stable/8/usr.bin/checknr/ (props changed) stable/8/usr.bin/chpass/Makefile (props changed) stable/8/usr.bin/column/ (props changed) stable/8/usr.bin/comm/ (props changed) stable/8/usr.bin/compress/ (props changed) stable/8/usr.bin/cpio/ (props changed) stable/8/usr.bin/cpuset/ (props changed) stable/8/usr.bin/csup/ (props changed) stable/8/usr.bin/du/ (props changed) stable/8/usr.bin/ee/ (props changed) stable/8/usr.bin/enigma/ (props changed) stable/8/usr.bin/fetch/ (props changed) stable/8/usr.bin/find/ (props changed) stable/8/usr.bin/finger/ (props changed) stable/8/usr.bin/fold/ (props changed) stable/8/usr.bin/fstat/ (props changed) stable/8/usr.bin/gcore/ (props changed) stable/8/usr.bin/getopt/ (props changed) stable/8/usr.bin/gzip/ (props changed) stable/8/usr.bin/hexdump/ (props changed) stable/8/usr.bin/indent/ (props changed) stable/8/usr.bin/ipcs/ (props changed) stable/8/usr.bin/jot/ (props changed) stable/8/usr.bin/kdump/ (props changed) stable/8/usr.bin/killall/ (props changed) stable/8/usr.bin/ktrace/ (props changed) stable/8/usr.bin/lastcomm/ (props changed) stable/8/usr.bin/ldd/ (props changed) stable/8/usr.bin/less/ (props changed) stable/8/usr.bin/lex/ (props changed) stable/8/usr.bin/limits/ (props changed) stable/8/usr.bin/locale/ (props changed) stable/8/usr.bin/locate/ (props changed) stable/8/usr.bin/lock/ (props changed) stable/8/usr.bin/lockf/ (props changed) stable/8/usr.bin/logger/ (props changed) stable/8/usr.bin/look/ (props changed) stable/8/usr.bin/m4/ (props changed) stable/8/usr.bin/mail/ (props changed) stable/8/usr.bin/make/ (props changed) stable/8/usr.bin/makewhatis/ (props changed) stable/8/usr.bin/minigzip/ (props changed) stable/8/usr.bin/ncal/ (props changed) stable/8/usr.bin/netstat/ (props changed) stable/8/usr.bin/netstat/Makefile (props changed) stable/8/usr.bin/netstat/atalk.c (props changed) stable/8/usr.bin/netstat/bpf.c (props changed) stable/8/usr.bin/netstat/if.c (props changed) stable/8/usr.bin/netstat/inet.c (props changed) stable/8/usr.bin/netstat/inet6.c (props changed) stable/8/usr.bin/netstat/ipsec.c (props changed) stable/8/usr.bin/netstat/ipx.c (props changed) stable/8/usr.bin/netstat/main.c (props changed) stable/8/usr.bin/netstat/mbuf.c (props changed) stable/8/usr.bin/netstat/mroute.c (props changed) stable/8/usr.bin/netstat/mroute6.c (props changed) stable/8/usr.bin/netstat/netgraph.c (props changed) stable/8/usr.bin/netstat/netisr.c (props changed) stable/8/usr.bin/netstat/netstat.1 (props changed) stable/8/usr.bin/netstat/netstat.h (props changed) stable/8/usr.bin/netstat/pfkey.c (props changed) stable/8/usr.bin/netstat/route.c (props changed) stable/8/usr.bin/netstat/unix.c (props changed) stable/8/usr.bin/newgrp/ (props changed) stable/8/usr.bin/nfsstat/ (props changed) stable/8/usr.bin/pathchk/ (props changed) stable/8/usr.bin/perror/ (props changed) stable/8/usr.bin/printf/ (props changed) stable/8/usr.bin/procstat/ (props changed) stable/8/usr.bin/rlogin/ (props changed) stable/8/usr.bin/rpcgen/ (props changed) stable/8/usr.bin/rpcinfo/ (props changed) stable/8/usr.bin/rs/ (props changed) stable/8/usr.bin/ruptime/ (props changed) stable/8/usr.bin/script/ (props changed) stable/8/usr.bin/sed/ (props changed) stable/8/usr.bin/showmount/ (props changed) stable/8/usr.bin/sockstat/ (props changed) stable/8/usr.bin/split/ (props changed) stable/8/usr.bin/stat/ (props changed) stable/8/usr.bin/su/ (props changed) stable/8/usr.bin/su/Makefile (props changed) stable/8/usr.bin/su/su.1 (props changed) stable/8/usr.bin/su/su.c (props changed) stable/8/usr.bin/systat/ (props changed) stable/8/usr.bin/tail/ (props changed) stable/8/usr.bin/tar/ (props changed) stable/8/usr.bin/tftp/ (props changed) stable/8/usr.bin/tip/ (props changed) stable/8/usr.bin/top/ (props changed) stable/8/usr.bin/touch/ (props changed) stable/8/usr.bin/tr/ (props changed) stable/8/usr.bin/truss/ (props changed) stable/8/usr.bin/uname/ (props changed) stable/8/usr.bin/unifdef/ (props changed) stable/8/usr.bin/uniq/ (props changed) stable/8/usr.bin/unzip/ (props changed) stable/8/usr.bin/usbhidaction/ (props changed) stable/8/usr.bin/usbhidctl/ (props changed) stable/8/usr.bin/uudecode/ (props changed) stable/8/usr.bin/vmstat/ (props changed) stable/8/usr.bin/w/ (props changed) stable/8/usr.bin/wall/ (props changed) stable/8/usr.bin/whois/ (props changed) stable/8/usr.bin/xargs/ (props changed) stable/8/usr.bin/xinstall/ (props changed) stable/8/usr.bin/xlint/ (props changed) stable/8/usr.bin/xz/ (props changed) stable/8/usr.bin/yacc/ (props changed) Modified: stable/8/usr.bin/netstat/sctp.c ============================================================================== --- stable/8/usr.bin/netstat/sctp.c Fri Feb 10 22:29:41 2012 (r231454) +++ stable/8/usr.bin/netstat/sctp.c Fri Feb 10 22:31:47 2012 (r231455) @@ -1,5 +1,6 @@ /*- * Copyright (c) 2001-2007, by Weongyo Jeong. All rights reserved. + * Copyright (c) 2011, by Michael Tuexen. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -63,7 +64,6 @@ __FBSDID("$FreeBSD$"); #ifdef SCTP -void inetprint(struct in_addr *, int, const char *, int); static void sctp_statesprint(uint32_t state); #define NETSTAT_SCTP_STATES_CLOSED 0x0 @@ -102,6 +102,124 @@ struct xraddr_entry { LIST_ENTRY(xraddr_entry) xraddr_entries; }; +/* + * Construct an Internet address representation. + * If numeric_addr has been supplied, give + * numeric value, otherwise try for symbolic name. + */ +static char * +inetname(struct in_addr *inp) +{ + char *cp; + static char line[MAXHOSTNAMELEN]; + struct hostent *hp; + struct netent *np; + + cp = 0; + if (!numeric_addr && inp->s_addr != INADDR_ANY) { + int net = inet_netof(*inp); + int lna = inet_lnaof(*inp); + + if (lna == INADDR_ANY) { + np = getnetbyaddr(net, AF_INET); + if (np) + cp = np->n_name; + } + if (cp == 0) { + hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET); + if (hp) { + cp = hp->h_name; + trimdomain(cp, strlen(cp)); + } + } + } + if (inp->s_addr == INADDR_ANY) + strcpy(line, "*"); + else if (cp) { + strlcpy(line, cp, sizeof(line)); + } else { + inp->s_addr = ntohl(inp->s_addr); +#define C(x) ((u_int)((x) & 0xff)) + sprintf(line, "%u.%u.%u.%u", C(inp->s_addr >> 24), + C(inp->s_addr >> 16), C(inp->s_addr >> 8), C(inp->s_addr)); + inp->s_addr = htonl(inp->s_addr); + } + return (line); +} + +#ifdef INET6 +static char ntop_buf[INET6_ADDRSTRLEN]; + +static char * +inet6name(struct in6_addr *in6p) +{ + char *cp; + static char line[50]; + struct hostent *hp; + static char domain[MAXHOSTNAMELEN]; + static int first = 1; + + if (first && !numeric_addr) { + first = 0; + if (gethostname(domain, MAXHOSTNAMELEN) == 0 && + (cp = index(domain, '.'))) + (void) strcpy(domain, cp + 1); + else + domain[0] = 0; + } + cp = 0; + if (!numeric_addr && !IN6_IS_ADDR_UNSPECIFIED(in6p)) { + hp = gethostbyaddr((char *)in6p, sizeof(*in6p), AF_INET6); + if (hp) { + if ((cp = index(hp->h_name, '.')) && + !strcmp(cp + 1, domain)) + *cp = 0; + cp = hp->h_name; + } + } + if (IN6_IS_ADDR_UNSPECIFIED(in6p)) + strcpy(line, "*"); + else if (cp) + strcpy(line, cp); + else + sprintf(line, "%s", + inet_ntop(AF_INET6, (void *)in6p, ntop_buf, + sizeof(ntop_buf))); + return (line); +} +#endif + +static void +sctp_print_address(union sctp_sockstore *address, int port, int num_port) +{ + struct servent *sp = 0; + char line[80], *cp; + int width; + + switch (address->sa.sa_family) { + case AF_INET: + sprintf(line, "%.*s.", Wflag ? 39 : 16, inetname(&address->sin.sin_addr)); + break; +#ifdef INET6 + case AF_INET6: + sprintf(line, "%.*s.", Wflag ? 39 : 16, inet6name(&address->sin6.sin6_addr)); + break; +#endif + default: + sprintf(line, "%.*s.", Wflag ? 39 : 16, ""); + break; + } + cp = index(line, '\0'); + if (!num_port && port) + sp = getservbyport((int)port, "sctp"); + if (sp || port == 0) + sprintf(cp, "%.15s ", sp ? sp->s_name : "*"); + else + sprintf(cp, "%d ", ntohs((u_short)port)); + width = Wflag ? 45 : 22; + printf("%-*.*s ", width, width, line); +} + static int sctp_skip_xinpcb_ifneed(char *buf, const size_t buflen, size_t *offset) { @@ -150,18 +268,14 @@ sctp_skip_xinpcb_ifneed(char *buf, const } static void -sctp_process_tcb(struct xsctp_tcb *xstcb, const char *name, +sctp_process_tcb(struct xsctp_tcb *xstcb, char *buf, const size_t buflen, size_t *offset, int *indent) { int i, xl_total = 0, xr_total = 0, x_max; - struct sockaddr *sa; struct xsctp_raddr *xraddr; struct xsctp_laddr *xladdr; struct xladdr_entry *prev_xl = NULL, *xl = NULL, *xl_tmp; struct xraddr_entry *prev_xr = NULL, *xr = NULL, *xr_tmp; -#ifdef INET6 - struct sockaddr_in6 *in6; -#endif LIST_INIT(&xladdr_head); LIST_INIT(&xraddr_head); @@ -220,38 +334,22 @@ sctp_process_tcb(struct xsctp_tcb *xstcb x_max = (xl_total > xr_total) ? xl_total : xr_total; for (i = 0; i < x_max; i++) { if (((*indent == 0) && i > 0) || *indent > 0) - printf("%-11s ", " "); + printf("%-12s ", " "); if (xl != NULL) { - sa = &(xl->xladdr->address.sa); - if ((sa->sa_family) == AF_INET) - inetprint(&((struct sockaddr_in *)sa)->sin_addr, - htons(xstcb->local_port), - name, numeric_port); -#ifdef INET6 - else { - in6 = (struct sockaddr_in6 *)sa; - inet6print(&in6->sin6_addr, - htons(xstcb->local_port), - name, numeric_port); + sctp_print_address(&(xl->xladdr->address), + htons(xstcb->local_port), numeric_port); + } else { + if (Wflag) { + printf("%-45s ", " "); + } else { + printf("%-22s ", " "); } -#endif } if (xr != NULL && !Lflag) { - sa = &(xr->xraddr->address.sa); - if ((sa->sa_family) == AF_INET) - inetprint(&((struct sockaddr_in *)sa)->sin_addr, - htons(xstcb->remote_port), - name, numeric_port); -#ifdef INET6 - else { - in6 = (struct sockaddr_in6 *)sa; - inet6print(&in6->sin6_addr, - htons(xstcb->remote_port), - name, numeric_port); - } -#endif + sctp_print_address(&(xr->xraddr->address), + htons(xstcb->remote_port), numeric_port); } if (xl != NULL) @@ -285,53 +383,21 @@ out: } } -#ifdef SCTP_DEBUG -uint32_t sctp_pdup[64]; -int sctp_pcnt = 0; -#endif - static void -sctp_process_inpcb(struct xsctp_inpcb *xinpcb, const char *name, +sctp_process_inpcb(struct xsctp_inpcb *xinpcb, char *buf, const size_t buflen, size_t *offset) { - int offset_backup, indent = 0, xladdr_total = 0, is_listening = 0; + int indent = 0, xladdr_total = 0, is_listening = 0; static int first = 1; - char *tname; + char *tname, *pname; struct xsctp_tcb *xstcb; struct xsctp_laddr *xladdr; - struct sockaddr *sa; -#ifdef INET6 - struct sockaddr_in6 *in6; -#endif + size_t offset_laddr; + int process_closed; - if ((xinpcb->flags & SCTP_PCB_FLAGS_TCPTYPE) == - SCTP_PCB_FLAGS_TCPTYPE && xinpcb->maxqlen > 0) + if (xinpcb->maxqlen > 0) is_listening = 1; - if (!Lflag && !is_listening && - !(xinpcb->flags & SCTP_PCB_FLAGS_CONNECTED)) { -#ifdef SCTP_DEBUG - int i, found = 0; - - for (i = 0; i < sctp_pcnt; i++) { - if (sctp_pdup[i] == xinpcb->flags) { - found = 1; - break; - } - } - if (!found) { - sctp_pdup[sctp_pcnt++] = xinpcb->flags; - if (sctp_pcnt >= 64) - sctp_pcnt = 0; - printf("[0x%08x]", xinpcb->flags); - } -#endif - offset_backup = *offset; - if (!sctp_skip_xinpcb_ifneed(buf, buflen, offset)) - return; - *offset = offset_backup; - } - if (first) { if (!Lflag) { printf("Active SCTP associations"); @@ -340,90 +406,115 @@ sctp_process_inpcb(struct xsctp_inpcb *x } else printf("Current listen queue sizes (qlen/maxqlen)"); putchar('\n'); - if (Aflag) - printf("%-8.8s ", "Socket"); if (Lflag) - printf("%-5.5s %-5.5s %-8.8s %-22.22s\n", + printf("%-6.6s %-5.5s %-8.8s %-22.22s\n", "Proto", "Type", "Listen", "Local Address"); else - printf((Aflag && !Wflag) ? - "%-5.5s %-5.5s %-18.18s %-18.18s %s\n" : - "%-5.5s %-5.5s %-22.22s %-22.22s %s\n", - "Proto", "Type", - "Local Address", "Foreign Address", - "(state)"); + if (Wflag) + printf("%-6.6s %-5.5s %-45.45s %-45.45s %s\n", + "Proto", "Type", + "Local Address", "Foreign Address", + "(state)"); + else + printf("%-6.6s %-5.5s %-22.22s %-22.22s %s\n", + "Proto", "Type", + "Local Address", "Foreign Address", + "(state)"); first = 0; } - if (Lflag && xinpcb->maxqlen == 0) { + xladdr = (struct xsctp_laddr *)(buf + *offset); + if (Lflag && !is_listening) { (int)sctp_skip_xinpcb_ifneed(buf, buflen, offset); return; } - if (Aflag) - printf("%8lx ", (u_long)xinpcb); - printf("%-5.5s ", name); + if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) { + /* Can't distinguish between sctp46 and sctp6 */ + pname = "sctp46"; + } else { + pname = "sctp4"; + } if (xinpcb->flags & SCTP_PCB_FLAGS_TCPTYPE) tname = "1to1"; else if (xinpcb->flags & SCTP_PCB_FLAGS_UDPTYPE) tname = "1toN"; else - return; - - printf("%-5.5s ", tname); + tname = "????"; if (Lflag) { char buf1[9]; snprintf(buf1, 9, "%hu/%hu", xinpcb->qlen, xinpcb->maxqlen); + printf("%-6.6s %-5.5s ", pname, tname); printf("%-8.8s ", buf1); } - /* - * process the local address. This routine are used for Lflag. - */ + + offset_laddr = *offset; + process_closed = 0; +retry: while (*offset < buflen) { xladdr = (struct xsctp_laddr *)(buf + *offset); *offset += sizeof(struct xsctp_laddr); - if (xladdr->last == 1) + if (xladdr->last) { + if (aflag && !Lflag && (xladdr_total == 0) && process_closed) { + printf("%-6.6s %-5.5s ", pname, tname); + if (Wflag) { + printf("%-91.91s CLOSED", " "); + } else { + printf("%-45.45s CLOSED", " "); + } + } + if (process_closed || is_listening) { + putchar('\n'); + } break; + } - if (!Lflag && !is_listening) + if (!Lflag && !is_listening && !process_closed) continue; - if (xladdr_total != 0) + if (xladdr_total == 0) { + printf("%-6.6s %-5.5s ", pname, tname); + } else { putchar('\n'); - if (xladdr_total > 0) printf((Lflag) ? - "%-20.20s " : "%-11.11s ", " "); - - sa = &(xladdr->address.sa); - if ((sa->sa_family) == AF_INET) - inetprint(&((struct sockaddr_in *)sa)->sin_addr, - htons(xinpcb->local_port), name, numeric_port); -#ifdef INET6 - else { - in6 = (struct sockaddr_in6 *)sa; - inet6print(&in6->sin6_addr, - htons(xinpcb->local_port), name, numeric_port); + "%-21.21s " : "%-12.12s ", " "); + } + sctp_print_address(&(xladdr->address), + htons(xinpcb->local_port), numeric_port); + if (aflag && !Lflag && xladdr_total == 0) { + if (Wflag) { + if (process_closed) { + printf("%-45.45s CLOSED", " "); + } else { + printf("%-45.45s LISTEN", " "); + } + } else { + if (process_closed) { + printf("%-22.22s CLOSED", " "); + } else { + printf("%-22.22s LISTEN", " "); + } + } } -#endif - - if (!Lflag && xladdr_total == 0 && is_listening == 1) - printf("%-22.22s LISTEN", " "); - xladdr_total++; } xstcb = (struct xsctp_tcb *)(buf + *offset); *offset += sizeof(struct xsctp_tcb); + if (aflag && (xladdr_total == 0) && xstcb->last && !process_closed) { + process_closed = 1; + *offset = offset_laddr; + goto retry; + } while (xstcb->last == 0 && *offset < buflen) { - sctp_process_tcb(xstcb, name, buf, buflen, offset, &indent); + printf("%-6.6s %-5.5s ", pname, tname); + sctp_process_tcb(xstcb, buf, buflen, offset, &indent); indent++; xstcb = (struct xsctp_tcb *)(buf + *offset); *offset += sizeof(struct xsctp_tcb); } - - putchar('\n'); } /* @@ -461,7 +552,7 @@ sctp_protopr(u_long off __unused, xinpcb = (struct xsctp_inpcb *)(buf + offset); offset += sizeof(struct xsctp_inpcb); while (xinpcb->last == 0 && offset < len) { - sctp_process_inpcb(xinpcb, name, buf, (const size_t)len, + sctp_process_inpcb(xinpcb, buf, (const size_t)len, &offset); xinpcb = (struct xsctp_inpcb *)(buf + offset);