summaryrefslogtreecommitdiff
path: root/usr.bin/systat/netstat.c
diff options
context:
space:
mode:
authorJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2000-01-05 11:04:23 +0000
committerJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2000-01-05 11:04:23 +0000
commit93019139023fdeecae653e53bbbaf9b57355563c (patch)
tree28753c063958b947bd8e5f94f75ec4fde62db49f /usr.bin/systat/netstat.c
parentdc4781d98ee9a665ec37ad243a9d5f6c104a0742 (diff)
IPv6 support. commands under "netstat" are all IPv6-aware.
const checks in netstat.c.
Diffstat (limited to 'usr.bin/systat/netstat.c')
-rw-r--r--usr.bin/systat/netstat.c175
1 files changed, 153 insertions, 22 deletions
diff --git a/usr.bin/systat/netstat.c b/usr.bin/systat/netstat.c
index e78ab44d8ac..74692837e0b 100644
--- a/usr.bin/systat/netstat.c
+++ b/usr.bin/systat/netstat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: netstat.c,v 1.11 1999/12/08 10:50:04 angelos Exp $ */
+/* $OpenBSD: netstat.c,v 1.12 2000/01/05 11:04:22 itojun Exp $ */
/* $NetBSD: netstat.c,v 1.3 1995/06/18 23:53:07 cgd Exp $ */
/*-
@@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)netstat.c 8.1 (Berkeley) 6/6/93";
#endif
-static char rcsid[] = "$OpenBSD: netstat.c,v 1.11 1999/12/08 10:50:04 angelos Exp $";
+static char rcsid[] = "$OpenBSD: netstat.c,v 1.12 2000/01/05 11:04:22 itojun Exp $";
#endif /* not lint */
/*
@@ -79,8 +79,12 @@ static char rcsid[] = "$OpenBSD: netstat.c,v 1.11 1999/12/08 10:50:04 angelos Ex
#include "extern.h"
static void enter __P((struct inpcb *, struct socket *, int, char *));
-static char *inetname __P((struct in_addr));
+static const char *inetname __P((struct in_addr));
static void inetprint __P((struct in_addr *, int, char *));
+#ifdef INET6
+static const char *inet6name __P((struct in6_addr *));
+static void inet6print __P((struct in6_addr *, int, char *));
+#endif
#define streq(a,b) (strcmp(a,b)==0)
#define YMAX(w) ((w)->_maxy-1)
@@ -95,6 +99,7 @@ opennetstat()
struct netinfo {
struct netinfo *nif_forw, *nif_prev;
+ int nif_family;
short nif_line; /* line on screen */
short nif_seen; /* 0 when not present in list */
short nif_flags;
@@ -103,8 +108,14 @@ struct netinfo {
short nif_state; /* tcp state */
char *nif_proto; /* protocol */
struct in_addr nif_laddr; /* local address */
+#ifdef INET6
+ struct in6_addr nif_laddr6; /* local address */
+#endif
long nif_lport; /* local port */
struct in_addr nif_faddr; /* foreign address */
+#ifdef INET6
+ struct in6_addr nif_faddr6; /* foreign address */
+#endif
long nif_fport; /* foreign port */
long nif_rcvcc; /* rcv buffer character count */
long nif_sndcc; /* snd buffer character count */
@@ -117,8 +128,6 @@ static struct {
static int aflag = 0;
static int nflag = 0;
static int lastrow = 1;
-static void enter(), inetprint();
-static char *inetname();
void
closenetstat(w)
@@ -211,8 +220,21 @@ printf("prev = %x, head = %x, next = %x, inpcb...prev = %x\n", prev, head, next,
prev = next;
next = inpcb.inp_queue.cqe_next;
- if (!aflag && inet_lnaof(inpcb.inp_laddr) == INADDR_ANY)
+#ifndef INET6
+ if (inpcb.inp_flags & INP_IPV6)
continue;
+#endif
+
+ if (!aflag) {
+ if (!(inpcb.inp_flags & INP_IPV6)
+ && inet_lnaof(inpcb.inp_laddr) == INADDR_ANY)
+ continue;
+#ifdef INET6
+ if ((inpcb.inp_flags & INP_IPV6)
+ && IN6_IS_ADDR_UNSPECIFIED(&inpcb.inp_laddr6))
+ continue;
+#endif
+ }
if (nhosts && !checkhost(&inpcb))
continue;
if (nports && !checkport(&inpcb))
@@ -247,17 +269,36 @@ enter(inp, so, state, proto)
* will appear as ``not seen'' in the kernel
* data structures.
*/
- for (p = netcb.nif_forw;
- p != (struct netinfo *)&netcb;
- p = p->nif_forw) {
+ for (p = netcb.nif_forw; p != (struct netinfo *)&netcb; p = p->nif_forw) {
+#ifdef INET6
+ if (p->nif_family == AF_INET && (inp->inp_flags & INP_IPV6))
+ continue;
+ if (p->nif_family == AF_INET6 && !(inp->inp_flags & INP_IPV6))
+ continue;
+#endif
if (!streq(proto, p->nif_proto))
continue;
- if (p->nif_lport != inp->inp_lport ||
- p->nif_laddr.s_addr != inp->inp_laddr.s_addr)
+ if (p->nif_family == AF_INET) {
+ if (p->nif_lport != inp->inp_lport ||
+ p->nif_laddr.s_addr != inp->inp_laddr.s_addr)
+ continue;
+ if (p->nif_faddr.s_addr == inp->inp_faddr.s_addr &&
+ p->nif_fport == inp->inp_fport)
+ break;
+
+ }
+#ifdef INET6
+ else if (p->nif_family == AF_INET6) {
+ if (p->nif_lport != inp->inp_lport ||
+ !IN6_ARE_ADDR_EQUAL(&p->nif_laddr6, &inp->inp_laddr6))
+ continue;
+ if (IN6_ARE_ADDR_EQUAL(&p->nif_faddr, &inp->inp_faddr) &&
+ p->nif_fport == inp->inp_fport)
+ break;
+ }
+#endif
+ else
continue;
- if (p->nif_faddr.s_addr == inp->inp_faddr.s_addr &&
- p->nif_fport == inp->inp_fport)
- break;
}
if (p == (struct netinfo *)&netcb) {
if ((p = malloc(sizeof(*p))) == NULL) {
@@ -269,12 +310,23 @@ enter(inp, so, state, proto)
netcb.nif_forw->nif_prev = p;
netcb.nif_forw = p;
p->nif_line = -1;
- p->nif_laddr = inp->inp_laddr;
p->nif_lport = inp->inp_lport;
- p->nif_faddr = inp->inp_faddr;
p->nif_fport = inp->inp_fport;
p->nif_proto = proto;
p->nif_flags = NIF_LACHG|NIF_FACHG;
+#ifdef INET6
+ if (inp->inp_flags & INP_IPV6) {
+ p->nif_laddr6 = inp->inp_laddr6;
+ p->nif_faddr6 = inp->inp_faddr6;
+ p->nif_family = AF_INET6;
+ }
+ else
+#endif
+ {
+ p->nif_laddr = inp->inp_laddr;
+ p->nif_faddr = inp->inp_faddr;
+ p->nif_family = AF_INET;
+ }
}
p->nif_rcvcc = so->so_rcv.sb_cc;
p->nif_sndcc = so->so_snd.sb_cc;
@@ -339,9 +391,7 @@ shownetstat()
/*
* Update existing connections and add new ones.
*/
- for (p = netcb.nif_forw;
- p != (struct netinfo *)&netcb;
- p = p->nif_forw) {
+ for (p = netcb.nif_forw; p != (struct netinfo *)&netcb; p = p->nif_forw) {
if (p->nif_line == -1) {
/*
* Add a new entry if possible.
@@ -353,15 +403,41 @@ shownetstat()
}
if (p->nif_flags & NIF_LACHG) {
wmove(wnd, p->nif_line, LADDR);
- inetprint(&p->nif_laddr, p->nif_lport, p->nif_proto);
+ switch (p->nif_family) {
+ case AF_INET:
+ inetprint(&p->nif_laddr, p->nif_lport,
+ p->nif_proto);
+ break;
+#ifdef INET6
+ case AF_INET6:
+ inet6print(&p->nif_laddr6, p->nif_lport,
+ p->nif_proto);
+ break;
+#endif
+ }
p->nif_flags &= ~NIF_LACHG;
}
if (p->nif_flags & NIF_FACHG) {
wmove(wnd, p->nif_line, FADDR);
- inetprint(&p->nif_faddr, p->nif_fport, p->nif_proto);
+ switch (p->nif_family) {
+ case AF_INET:
+ inetprint(&p->nif_faddr, p->nif_fport,
+ p->nif_proto);
+ break;
+#ifdef INET6
+ case AF_INET6:
+ inet6print(&p->nif_faddr6, p->nif_fport,
+ p->nif_proto);
+ break;
+#endif
+ }
p->nif_flags &= ~NIF_FACHG;
}
mvwaddstr(wnd, p->nif_line, PROTO, p->nif_proto);
+#ifdef INET6
+ if (p->nif_family == AF_INET6)
+ waddstr(wnd, "6");
+#endif
mvwprintw(wnd, p->nif_line, RCVCC, "%6d", p->nif_rcvcc);
mvwprintw(wnd, p->nif_line, SNDCC, "%6d", p->nif_sndcc);
if (streq(p->nif_proto, "tcp"))
@@ -410,12 +486,41 @@ inetprint(in, port, proto)
waddstr(wnd, line);
}
+#ifdef INET6
+static void
+inet6print(in6, port, proto)
+ register struct in6_addr *in6;
+ int port;
+ char *proto;
+{
+ struct servent *sp = 0;
+ char line[80], *cp;
+
+ snprintf(line, sizeof line, "%.*s.", 16, inet6name(in6));
+ cp = strchr(line, '\0');
+ if (!nflag && port)
+ sp = getservbyport(port, proto);
+ if (sp || port == 0)
+ snprintf(cp, sizeof line - strlen(cp), "%.8s",
+ sp ? sp->s_name : "*");
+ else
+ snprintf(cp, sizeof line - strlen(cp), "%d",
+ ntohs((u_short)port));
+ /* pad to full column to clear any garbage */
+ cp = strchr(line, '\0');
+ while (cp - line < 22 && cp - line < sizeof line-1)
+ *cp++ = ' ';
+ *cp = '\0';
+ waddstr(wnd, line);
+}
+#endif
+
/*
* Construct an Internet address representation.
* If the nflag has been supplied, give
* numeric value, otherwise try for symbolic name.
*/
-static char *
+static const char *
inetname(in)
struct in_addr in;
{
@@ -454,6 +559,32 @@ inetname(in)
return (line);
}
+#ifdef INET6
+static const char *
+inet6name(in6)
+ struct in6_addr *in6;
+{
+ static char line[NI_MAXHOST];
+ struct sockaddr_in6 sin6;
+ int flags;
+
+ if (nflag)
+ flags = NI_NUMERICHOST;
+ else
+ flags = 0;
+ if (IN6_IS_ADDR_UNSPECIFIED(in6))
+ return "*";
+ memset(&sin6, 0, sizeof(sin6));
+ sin6.sin6_family = AF_INET6;
+ sin6.sin6_len = sizeof(struct sockaddr_in6);
+ sin6.sin6_addr = *in6;
+ if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
+ line, sizeof(line), NULL, 0, flags) == 0)
+ return line;
+ return "?";
+}
+#endif
+
int
cmdnetstat(cmd, args)
char *cmd, *args;