summaryrefslogtreecommitdiffstats
path: root/freebsd/usr.bin
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2013-11-04 11:33:00 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2013-11-04 15:28:21 +0100
commitaf5333e0a02b2295304d4e029b15ee15a4fe2b3a (patch)
treec5c43680d374f58b487eeeaf18fb7ec6b84ba074 /freebsd/usr.bin
parentBUS_SPACE(9): Use simple memory model for ARM (diff)
downloadrtems-libbsd-af5333e0a02b2295304d4e029b15ee15a4fe2b3a.tar.bz2
Update to FreeBSD 8.4
Diffstat (limited to 'freebsd/usr.bin')
-rw-r--r--freebsd/usr.bin/netstat/if.c28
-rw-r--r--freebsd/usr.bin/netstat/inet.c78
-rw-r--r--freebsd/usr.bin/netstat/main.c35
-rw-r--r--freebsd/usr.bin/netstat/netstat.h7
-rw-r--r--freebsd/usr.bin/netstat/route.c64
-rw-r--r--freebsd/usr.bin/netstat/sctp.c326
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");