diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2013-11-04 11:33:00 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2013-11-04 15:28:21 +0100 |
commit | af5333e0a02b2295304d4e029b15ee15a4fe2b3a (patch) | |
tree | c5c43680d374f58b487eeeaf18fb7ec6b84ba074 /freebsd/usr.bin | |
parent | BUS_SPACE(9): Use simple memory model for ARM (diff) | |
download | rtems-libbsd-af5333e0a02b2295304d4e029b15ee15a4fe2b3a.tar.bz2 |
Update to FreeBSD 8.4
Diffstat (limited to 'freebsd/usr.bin')
-rw-r--r-- | freebsd/usr.bin/netstat/if.c | 28 | ||||
-rw-r--r-- | freebsd/usr.bin/netstat/inet.c | 78 | ||||
-rw-r--r-- | freebsd/usr.bin/netstat/main.c | 35 | ||||
-rw-r--r-- | freebsd/usr.bin/netstat/netstat.h | 7 | ||||
-rw-r--r-- | freebsd/usr.bin/netstat/route.c | 64 | ||||
-rw-r--r-- | freebsd/usr.bin/netstat/sctp.c | 326 |
6 files changed, 344 insertions, 194 deletions
diff --git a/freebsd/usr.bin/netstat/if.c b/freebsd/usr.bin/netstat/if.c index aaf1fd88..73f74967 100644 --- a/freebsd/usr.bin/netstat/if.c +++ b/freebsd/usr.bin/netstat/if.c @@ -68,6 +68,9 @@ __FBSDID("$FreeBSD$"); #include <err.h> #include <errno.h> #include <libutil.h> +#ifdef INET6 +#include <netdb.h> +#endif #include <signal.h> #include <stdint.h> #include <stdio.h> @@ -84,7 +87,7 @@ static void sidewaysintpr(int, u_long); static void catchalarm(int); #ifdef INET6 -static char ntop_buf[INET6_ADDRSTRLEN]; /* for inet_ntop() */ +static char addr_buf[NI_MAXHOST]; /* for getnameinfo() */ #endif /* @@ -196,7 +199,6 @@ intpr(int interval1, u_long ifnetaddr, void (*pfunc)(char *)) } ifaddr; u_long ifaddraddr; u_long ifaddrfound; - u_long ifnetfound; u_long opackets; u_long ipackets; u_long obytes; @@ -260,7 +262,6 @@ intpr(int interval1, u_long ifnetaddr, void (*pfunc)(char *)) link_layer = 0; if (ifaddraddr == 0) { - ifnetfound = ifnetaddr; if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet) != 0) return; strlcpy(name, ifnet.if_xname, sizeof(name)); @@ -354,13 +355,14 @@ intpr(int interval1, u_long ifnetaddr, void (*pfunc)(char *)) #ifdef INET6 case AF_INET6: sockin6 = (struct sockaddr_in6 *)sa; + in6_fillscopeid(&ifaddr.in6.ia_addr); printf("%-13.13s ", netname6(&ifaddr.in6.ia_addr, &ifaddr.in6.ia_prefixmask.sin6_addr)); - printf("%-17.17s ", - inet_ntop(AF_INET6, - &sockin6->sin6_addr, - ntop_buf, sizeof(ntop_buf))); + in6_fillscopeid(sockin6); + getnameinfo(sa, sa->sa_len, addr_buf, + sizeof(addr_buf), 0, 0, NI_NUMERICHOST); + printf("%-17.17s ", addr_buf); network_layer = 1; break; @@ -409,7 +411,7 @@ intpr(int interval1, u_long ifnetaddr, void (*pfunc)(char *)) n = cp - sa->sa_data + 1; cp = sa->sa_data; hexprint: - while (--n >= 0) + while ((--n >= 0) && (m < 30)) m += printf("%02x%c", *cp++ & 0xff, n > 0 ? ':' : ' '); m = 32 - m; @@ -486,13 +488,13 @@ intpr(int interval1, u_long ifnetaddr, void (*pfunc)(char *)) break; #ifdef INET6 case AF_INET6: + in6_fillscopeid(&msa.in6); + getnameinfo(&msa.sa, msa.sa.sa_len, + addr_buf, sizeof(addr_buf), 0, 0, + NI_NUMERICHOST); printf("%*s %-19.19s(refs: %d)\n", Wflag ? 27 : 25, "", - inet_ntop(AF_INET6, - &msa.in6.sin6_addr, - ntop_buf, - sizeof(ntop_buf)), - ifma.ifma_refcount); + addr_buf, ifma.ifma_refcount); break; #endif /* INET6 */ case AF_LINK: diff --git a/freebsd/usr.bin/netstat/inet.c b/freebsd/usr.bin/netstat/inet.c index 4915a4dd..00b9e27a 100644 --- a/freebsd/usr.bin/netstat/inet.c +++ b/freebsd/usr.bin/netstat/inet.c @@ -403,35 +403,44 @@ protopr(u_long off, const char *name, int af1, int proto) "Current listen queue sizes (qlen/incqlen/maxqlen)"); putchar('\n'); if (Aflag) - printf("%-8.8s ", "Tcpcb"); + printf("%-*s ", 2 * (int)sizeof(void *), "Tcpcb"); if (Lflag) - printf("%-5.5s %-14.14s %-22.22s\n", + printf((Aflag && !Wflag) ? + "%-5.5s %-14.14s %-18.18s" : + "%-5.5s %-14.14s %-22.22s", "Proto", "Listen", "Local Address"); + else if (Tflag) + printf((Aflag && !Wflag) ? + "%-5.5s %-6.6s %-6.6s %-6.6s %-18.18s %s" : + "%-5.5s %-6.6s %-6.6s %-6.6s %-22.22s %s", + "Proto", "Rexmit", "OOORcv", "0-win", + "Local Address", "Foreign Address"); else { printf((Aflag && !Wflag) ? - "%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s" : - "%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s", + "%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s" : + "%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s", "Proto", "Recv-Q", "Send-Q", "Local Address", "Foreign Address"); - if (xflag) - printf("%-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %s\n", - "R-MBUF", "S-MBUF", "R-CLUS", - "S-CLUS", "R-HIWA", "S-HIWA", - "R-LOWA", "S-LOWA", "R-BCNT", - "S-BCNT", "R-BMAX", "S-BMAX", - "(state)"); - else - printf("(state)\n"); + if (!xflag) + printf(" (state)"); } + if (xflag) { + printf(" %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s", + "R-MBUF", "S-MBUF", "R-CLUS", + "S-CLUS", "R-HIWA", "S-HIWA", + "R-LOWA", "S-LOWA", "R-BCNT", + "S-BCNT", "R-BMAX", "S-BMAX"); + } + putchar('\n'); protopr_initialized = 1; } if (Lflag && so->so_qlimit == 0) continue; if (Aflag) { if (istcp) - printf("%8lx ", (u_long)inp->inp_ppcb); + printf("%*lx ", 2 * (int)sizeof(void *), (u_long)inp->inp_ppcb); else - printf("%8lx ", (u_long)so->so_pcb); + printf("%*lx ", 2 * (int)sizeof(void *), (u_long)so->so_pcb); } #ifdef INET6 if ((inp->inp_vflag & INP_IPV6) != 0) @@ -448,6 +457,12 @@ protopr(u_long off, const char *name, int af1, int proto) snprintf(buf1, 15, "%d/%d/%d", so->so_qlen, so->so_incqlen, so->so_qlimit); printf("%-14.14s ", buf1); + } else if (Tflag) { + if (istcp) + printf("%6ju %6ju %6u ", + (uintmax_t)tp->t_sndrexmitpack, + (uintmax_t)tp->t_rcvoopack, + tp->t_sndzerowin); } else { printf("%6u %6u ", so->so_rcv.sb_cc, so->so_snd.sb_cc); } @@ -506,25 +521,15 @@ protopr(u_long off, const char *name, int af1, int proto) #endif /* INET6 */ } if (xflag) { - if (Lflag) - printf("%21s %6u %6u %6u %6u %6u %6u %6u %6u %6u %6u %6u %6u ", - " ", - so->so_rcv.sb_mcnt, so->so_snd.sb_mcnt, - so->so_rcv.sb_ccnt, so->so_snd.sb_ccnt, - so->so_rcv.sb_hiwat, so->so_snd.sb_hiwat, - so->so_rcv.sb_lowat, so->so_snd.sb_lowat, - so->so_rcv.sb_mbcnt, so->so_snd.sb_mbcnt, - so->so_rcv.sb_mbmax, so->so_snd.sb_mbmax); - else - printf("%6u %6u %6u %6u %6u %6u %6u %6u %6u %6u %6u %6u ", - so->so_rcv.sb_mcnt, so->so_snd.sb_mcnt, - so->so_rcv.sb_ccnt, so->so_snd.sb_ccnt, - so->so_rcv.sb_hiwat, so->so_snd.sb_hiwat, - so->so_rcv.sb_lowat, so->so_snd.sb_lowat, - so->so_rcv.sb_mbcnt, so->so_snd.sb_mbcnt, - so->so_rcv.sb_mbmax, so->so_snd.sb_mbmax); + printf("%6u %6u %6u %6u %6u %6u %6u %6u %6u %6u %6u %6u", + so->so_rcv.sb_mcnt, so->so_snd.sb_mcnt, + so->so_rcv.sb_ccnt, so->so_snd.sb_ccnt, + so->so_rcv.sb_hiwat, so->so_snd.sb_hiwat, + so->so_rcv.sb_lowat, so->so_snd.sb_lowat, + so->so_rcv.sb_mbcnt, so->so_snd.sb_mbcnt, + so->so_rcv.sb_mbmax, so->so_snd.sb_mbmax); } - if (istcp && !Lflag) { + if (istcp && !Lflag && !xflag && !Tflag) { if (tp->t_state < 0 || tp->t_state >= TCP_NSTATES) printf("%d", tp->t_state); else { @@ -674,6 +679,9 @@ tcp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) p(tcps_sc_sendcookie, "\t%lu cookie%s sent\n"); p(tcps_sc_recvcookie, "\t%lu cookie%s received\n"); + p(tcps_hc_added, "\t%lu hostcache entrie%s added\n"); + p1a(tcps_hc_bucketoverflow, "\t\t%lu bucket overflow\n"); + p(tcps_sack_recovery_episode, "\t%lu SACK recovery episode%s\n"); p(tcps_sack_rexmits, "\t%lu segment rexmit%s in SACK recovery episodes\n"); @@ -1043,7 +1051,7 @@ icmp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) * Dump IGMP statistics structure (pre 8.x kernel). */ static void -igmp_stats_live_old(u_long off, const char *name) +igmp_stats_live_old(const char *name) { struct oigmpstat oigmpstat, zerostat; size_t len = sizeof(oigmpstat); @@ -1103,7 +1111,7 @@ igmp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) return; } if (len < sizeof(igmpstat)) { - igmp_stats_live_old(off, name); + igmp_stats_live_old(name); return; } } diff --git a/freebsd/usr.bin/netstat/main.c b/freebsd/usr.bin/netstat/main.c index acb256d5..e4e7dce1 100644 --- a/freebsd/usr.bin/netstat/main.c +++ b/freebsd/usr.bin/netstat/main.c @@ -348,10 +348,14 @@ int noutputs = 0; /* how much outputs before we exit */ int numeric_addr; /* show addresses numerically */ int numeric_port; /* show ports numerically */ static int pflag; /* show given protocol */ +#ifndef __rtems__ +int Qflag; /* show netisr information */ +#endif /* __rtems__ */ int rflag; /* show routing tables (or routing stats) */ int sflag; /* show protocol statistics */ int tflag; /* show i/f watchdog timers */ int Wflag; /* wide display */ +int Tflag; /* TCP Information */ int xflag; /* extra information, includes all socket buffer info */ int zflag; /* zero stats */ @@ -431,7 +435,8 @@ main(int argc, char *argv[]) af = AF_UNSPEC; - while ((ch = getopt(argc, argv, "AaBbdf:ghI:iLlM:mN:np:q:rSstuWw:xz")) != -1) + while ((ch = getopt(argc, argv, "AaBbdf:ghI:iLlM:mN:np:Qq:rSTstuWw:xz")) + != -1) switch(ch) { case 'A': Aflag = 1; @@ -517,6 +522,11 @@ main(int argc, char *argv[]) } pflag = 1; break; +#ifndef __rtems__ + case 'Q': + Qflag = 1; + break; +#endif /* __rtems__ */ case 'q': noutputs = atoi(optarg); if (noutputs != 0) @@ -545,6 +555,9 @@ main(int argc, char *argv[]) interval = atoi(optarg); iflag = 1; break; + case 'T': + Tflag = 1; + break; case 'x': xflag = 1; break; @@ -584,6 +597,9 @@ main(int argc, char *argv[]) if (!live) setgid(getgid()); + if (xflag && Tflag) + errx(1, "-x and -T are incompatible, pick one."); + if (Bflag) { if (!live) usage(); @@ -598,6 +614,16 @@ main(int argc, char *argv[]) mbpr(NULL, 0); exit(0); } +#ifndef __rtems__ + if (Qflag) { + if (!live) { + if (kread(0, NULL, 0) == 0) + netisr_stats(kvmd); + } else + netisr_stats(NULL); + exit(0); + } +#endif /* __rtems__ */ #if 0 /* * Keep file descriptors open to avoid overhead @@ -864,8 +890,8 @@ name2protox(const char *name) static void usage(void) { - (void)fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", -"usage: netstat [-AaLnSWx] [-f protocol_family | -p protocol]\n" + (void)fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", +"usage: netstat [-AaLnSTWx] [-f protocol_family | -p protocol]\n" " [-M core] [-N system]", " netstat -i | -I interface [-abdhntW] [-f address_family]\n" " [-M core] [-N system]", @@ -879,6 +905,7 @@ usage(void) " netstat -r [-AanW] [-f address_family] [-M core] [-N system]", " netstat -rs [-s] [-M core] [-N system]", " netstat -g [-W] [-f address_family] [-M core] [-N system]", -" netstat -gs [-s] [-f address_family] [-M core] [-N system]"); +" netstat -gs [-s] [-f address_family] [-M core] [-N system]", +" netstat -Q"); exit(1); } diff --git a/freebsd/usr.bin/netstat/netstat.h b/freebsd/usr.bin/netstat/netstat.h index 9b2db595..69465cf8 100644 --- a/freebsd/usr.bin/netstat/netstat.h +++ b/freebsd/usr.bin/netstat/netstat.h @@ -57,6 +57,7 @@ extern int numeric_port; /* show ports numerically */ extern int rflag; /* show routing tables (or routing stats) */ extern int sflag; /* show protocol statistics */ extern int tflag; /* show i/f watchdog timers */ +extern int Tflag; /* show TCP control block info */ extern int Wflag; /* wide display */ extern int xflag; /* extended display, includes all socket buffer info */ extern int zflag; /* zero stats */ @@ -79,6 +80,9 @@ const char *plural(uintmax_t); const char *plurales(uintmax_t); const char *pluralies(uintmax_t); +struct sockaddr; +struct socket; +struct xsocket; int sotoxsocket(struct socket *, struct xsocket *); void protopr(u_long, const char *, int, int); void tcp_stats(u_long, const char *, int, int); @@ -113,6 +117,7 @@ void mrt6_stats(u_long); struct sockaddr_in6; struct in6_addr; +void in6_fillscopeid(struct sockaddr_in6 *); char *routename6(struct sockaddr_in6 *); const char *netname6(struct sockaddr_in6 *, struct in6_addr *); void inet6print(struct in6_addr *, int, const char *, int); @@ -124,6 +129,8 @@ void pfkey_stats(u_long, const char *, int, int); void mbpr(void *, u_long); +void netisr_stats(void *); + void hostpr(u_long, u_long); void impstats(u_long, u_long); diff --git a/freebsd/usr.bin/netstat/route.c b/freebsd/usr.bin/netstat/route.c index 584ce132..1725c78d 100644 --- a/freebsd/usr.bin/netstat/route.c +++ b/freebsd/usr.bin/netstat/route.c @@ -126,7 +126,6 @@ typedef union { static sa_u pt_u; -static int fibnum; static struct rtentry rtentry; static struct radix_node rnode; static struct radix_mask rmask; @@ -159,8 +158,7 @@ routepr(u_long rtree) { struct radix_node_head **rnhp, *rnh, head; size_t intsize; - int i; - int numfibs; + int fam, fibnum, numfibs; intsize = sizeof(int); if (sysctlbyname("net.my_fibnum", &fibnum, &intsize, NULL, 0) == -1) @@ -198,15 +196,20 @@ routepr(u_long rtree) if (kread((u_long)(rtree), (char *)(rt_tables), (numfibs * (AF_MAX+1) * sizeof(struct radix_node_head *))) != 0) return; - for (i = 0; i <= AF_MAX; i++) { + for (fam = 0; fam <= AF_MAX; fam++) { int tmpfib; - if (i != AF_INET) - tmpfib = 0; - else + + switch (fam) { + case AF_INET6: + case AF_INET: tmpfib = fibnum; + break; + default: + tmpfib = 0; + } rnhp = (struct radix_node_head **)*rt_tables; /* Calculate the in-kernel address. */ - rnhp += tmpfib * (AF_MAX+1) + i; + rnhp += tmpfib * (AF_MAX+1) + fam; /* Read the in kernel rhn pointer. */ if (kget(rnhp, rnh) != 0) continue; @@ -219,16 +222,16 @@ routepr(u_long rtree) /* Read the rnh data. */ if (kget(rnh, head) != 0) continue; - if (i == AF_UNSPEC) { + if (fam == AF_UNSPEC) { if (Aflag && af == 0) { printf("Netmasks:\n"); p_tree(head.rnh_treetop); } - } else if (af == AF_UNSPEC || af == i) { - size_cols(i, head.rnh_treetop); - pr_family(i); + } else if (af == AF_UNSPEC || af == fam) { + size_cols(fam, head.rnh_treetop); + pr_family(fam); do_rtent = 1; - pr_rthdr(i); + pr_rthdr(fam); p_tree(head.rnh_treetop); } } @@ -654,18 +657,8 @@ fmt_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags) case AF_INET6: { struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sa; - struct in6_addr *in6 = &sa6->sin6_addr; - - /* - * XXX: This is a special workaround for KAME kernels. - * sin6_scope_id field of SA should be set in the future. - */ - if (IN6_IS_ADDR_LINKLOCAL(in6) || - IN6_IS_ADDR_MC_LINKLOCAL(in6)) { - /* XXX: override is ok? */ - sa6->sin6_scope_id = (u_int32_t)ntohs(*(u_short *)&in6->s6_addr[2]); - *(u_short *)&in6->s6_addr[2] = 0; - } + + in6_fillscopeid(sa6); if (flags & RTF_HOST) cp = routename6(sa6); @@ -923,6 +916,25 @@ netname(in_addr_t in, u_long mask) #undef NSHIFT #ifdef INET6 +void +in6_fillscopeid(struct sockaddr_in6 *sa6) +{ +#if defined(__KAME__) + /* + * XXX: This is a special workaround for KAME kernels. + * sin6_scope_id field of SA should be set in the future. + */ + if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr) || + IN6_IS_ADDR_MC_NODELOCAL(&sa6->sin6_addr) || + IN6_IS_ADDR_MC_LINKLOCAL(&sa6->sin6_addr)) { + /* XXX: override is ok? */ + sa6->sin6_scope_id = + ntohs(*(u_int16_t *)&sa6->sin6_addr.s6_addr[2]); + sa6->sin6_addr.s6_addr[2] = sa6->sin6_addr.s6_addr[3] = 0; + } +#endif +} + const char * netname6(struct sockaddr_in6 *sa6, struct in6_addr *mask) { @@ -1121,10 +1133,8 @@ ipx_phost(struct sockaddr *sa) struct sockaddr_ipx work; static union ipx_net ipx_zeronet; char *p; - struct ipx_addr in; work = *sipx; - in = work.sipx_addr; work.sipx_addr.x_port = 0; work.sipx_addr.x_net = ipx_zeronet; diff --git a/freebsd/usr.bin/netstat/sctp.c b/freebsd/usr.bin/netstat/sctp.c index d32d28d1..9feca576 100644 --- a/freebsd/usr.bin/netstat/sctp.c +++ b/freebsd/usr.bin/netstat/sctp.c @@ -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,128 @@ 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. + */ +#ifdef INET +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); +} +#endif + +#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) { +#ifdef INET + case AF_INET: + sprintf(line, "%.*s.", Wflag ? 39 : 16, inetname(&address->sin.sin_addr)); + break; +#endif +#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 +272,14 @@ sctp_skip_xinpcb_ifneed(char *buf, const size_t buflen, size_t *offset) } 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 +338,22 @@ sctp_process_tcb(struct xsctp_tcb *xstcb, const char *name, 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 +387,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 +410,115 @@ sctp_process_inpcb(struct xsctp_inpcb *xinpcb, const char *name, } 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 +556,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); @@ -520,7 +615,8 @@ sctp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) memset(&zerostat, 0, len); if (sysctlbyname("net.inet.sctp.stats", &sctpstat, &len, zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { - warn("sysctl: net.inet.sctp.stats"); + if (errno != ENOENT) + warn("sysctl: net.inet.sctp.stats"); return; } } else @@ -563,7 +659,7 @@ sctp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) p(sctps_sendfastretrans, "\t\t%ju fast retransmitted DATA chunk%s\n"); p(sctps_sendmultfastretrans, "\t\t%ju FR'%s that happened more " "than once to same chunk\n"); - p(sctps_sendheartbeat, "\t\t%ju intput HB chunk%s\n"); + p(sctps_sendheartbeat, "\t\t%ju output HB chunk%s\n"); p(sctps_sendecne, "\t\t%ju output ECNE chunk%s\n"); p(sctps_sendauth, "\t\t%ju output AUTH chunk%s\n"); p1a(sctps_senderrors, "\t\t%ju ip_output error counter\n"); |