summaryrefslogtreecommitdiff
path: root/usr.bin/systat
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
parentdc4781d98ee9a665ec37ad243a9d5f6c104a0742 (diff)
IPv6 support. commands under "netstat" are all IPv6-aware.
const checks in netstat.c.
Diffstat (limited to 'usr.bin/systat')
-rw-r--r--usr.bin/systat/Makefile6
-rw-r--r--usr.bin/systat/netcmds.c112
-rw-r--r--usr.bin/systat/netstat.c175
3 files changed, 243 insertions, 50 deletions
diff --git a/usr.bin/systat/Makefile b/usr.bin/systat/Makefile
index 00f8bca86b0..d3419f344b7 100644
--- a/usr.bin/systat/Makefile
+++ b/usr.bin/systat/Makefile
@@ -1,10 +1,10 @@
-# $OpenBSD: Makefile,v 1.10 1999/10/28 12:09:32 art Exp $
+# $OpenBSD: Makefile,v 1.11 2000/01/05 11:04:21 itojun Exp $
PROG= systat
.PATH: ${.CURDIR}/../../usr.bin/vmstat
-CFLAGS+=-I${.CURDIR}/../../usr.bin/vmstat
+CPPFLAGS+=-I${.CURDIR}/../../usr.bin/vmstat
SRCS= cmds.c cmdtab.c disks.c dkstats.c fetch.c iostat.c keyboard.c \
main.c mbufs.c netcmds.c netstat.c pigs.c swap.c vmstat.c
DPADD= ${LIBCURSES} ${LIBM} ${LIBKVM}
@@ -12,6 +12,8 @@ LDADD= -lcurses -lm -lkvm
BINGRP= kmem
BINMODE=2555
+CPPFLAGS+=-DINET6
+
.include <bsd.prog.mk>
.if (${UVM} == "yes")
diff --git a/usr.bin/systat/netcmds.c b/usr.bin/systat/netcmds.c
index 4190fb822b7..5d9f433e721 100644
--- a/usr.bin/systat/netcmds.c
+++ b/usr.bin/systat/netcmds.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: netcmds.c,v 1.4 1997/06/23 22:21:47 millert Exp $ */
+/* $OpenBSD: netcmds.c,v 1.5 2000/01/05 11:04:22 itojun Exp $ */
/* $NetBSD: netcmds.c,v 1.4 1995/05/21 17:14:38 mycroft Exp $ */
/*-
@@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)netcmds.c 8.1 (Berkeley) 6/6/93";
#endif
-static char rcsid[] = "$OpenBSD: netcmds.c,v 1.4 1997/06/23 22:21:47 millert Exp $";
+static char rcsid[] = "$OpenBSD: netcmds.c,v 1.5 2000/01/05 11:04:22 itojun Exp $";
#endif /* not lint */
/*
@@ -68,7 +68,7 @@ static char rcsid[] = "$OpenBSD: netcmds.c,v 1.4 1997/06/23 22:21:47 millert Exp
#define streq(a,b) (strcmp(a,b)==0)
static struct hitem {
- struct in_addr addr;
+ struct sockaddr_storage addr;
int onoff;
} *hosts;
@@ -79,7 +79,8 @@ static int selectproto __P((char *));
static void showprotos __P((void));
static int selectport __P((long, int));
static void showports __P((void));
-static int selecthost __P((struct in_addr *, int));
+static int addrcmp __P((struct sockaddr *, struct sockaddr *));
+static int selecthost __P((struct sockaddr *, int));
static void showhosts __P((void));
int
@@ -130,8 +131,7 @@ changeitems(args, onoff)
{
register char *cp;
struct servent *sp;
- struct hostent *hp;
- struct in_addr in;
+ struct addrinfo hints, *res0, *res;
cp = strchr(args, '\n');
if (cp)
@@ -152,15 +152,17 @@ changeitems(args, onoff)
selectport(sp->s_port, onoff);
continue;
}
- if (inet_aton(args, &in) == 0) {
- hp = gethostbyname(args);
- if (hp == 0) {
- error("%s: unknown host or port", args);
- continue;
- }
- memcpy(&in, hp->h_addr, hp->h_length);
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ if (getaddrinfo(args, "0", &hints, &res0) != 0) {
+ error("%s: unknown host or port", args);
+ continue;
}
- selecthost(&in, onoff);
+ for (res = res0; res; res = res->ai_next)
+ selecthost(res->ai_addr, onoff);
+ freeaddrinfo(res0);
}
}
@@ -257,13 +259,43 @@ showports()
}
static int
-selecthost(in, onoff)
- struct in_addr *in;
+addrcmp(sa1, sa2)
+ struct sockaddr *sa1;
+ struct sockaddr *sa2;
+{
+ if (sa1->sa_family != sa2->sa_family)
+ return 0;
+ if (sa1->sa_len != sa2->sa_len)
+ return 0;
+ switch (sa1->sa_family) {
+ case AF_INET:
+ if (((struct sockaddr_in *)sa1)->sin_addr.s_addr ==
+ ((struct sockaddr_in *)sa2)->sin_addr.s_addr)
+ return 1;
+ break;
+#ifdef INET6
+ case AF_INET6:
+ if (IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6 *)sa1)->sin6_addr,
+ &((struct sockaddr_in6 *)sa2)->sin6_addr))
+ return 1;
+ break;
+#endif
+ default:
+ if (memcmp(sa1, sa2, sa1->sa_len) == 0)
+ return 1;
+ break;
+ }
+ return 0;
+}
+
+static int
+selecthost(sa, onoff)
+ struct sockaddr *sa;
int onoff;
{
register struct hitem *p;
- if (in == 0) {
+ if (sa == 0) {
if (hosts == 0)
return (0);
free((char *)hosts), hosts = 0;
@@ -271,16 +303,18 @@ selecthost(in, onoff)
return (1);
}
for (p = hosts; p < hosts+nhosts; p++)
- if (p->addr.s_addr == in->s_addr) {
+ if (addrcmp((struct sockaddr *)&p->addr, sa)) {
p->onoff = onoff;
return (0);
}
+ if (sa->sa_len > sizeof(struct sockaddr_storage))
+ return (-1); /*XXX*/
if (nhosts == 0)
hosts = (struct hitem *)malloc(sizeof (*p));
else
hosts = (struct hitem *)realloc(hosts, (nhosts+1)*sizeof (*p));
p = &hosts[nhosts++];
- p->addr = *in;
+ memcpy(&p->addr, sa, sa->sa_len);
p->onoff = onoff;
return (1);
}
@@ -292,10 +326,26 @@ checkhost(inp)
register struct hitem *p;
if (hosts)
- for (p = hosts; p < hosts+nhosts; p++)
- if (p->addr.s_addr == inp->inp_laddr.s_addr ||
- p->addr.s_addr == inp->inp_faddr.s_addr)
- return (p->onoff);
+ for (p = hosts; p < hosts+nhosts; p++) {
+ if (((struct sockaddr *)&p->addr)->sa_family == AF_INET
+ && !(inp->inp_flags & INP_IPV6)) {
+ struct sockaddr_in *sin;
+ sin = (struct sockaddr_in *)&p->addr;
+ if (sin->sin_addr.s_addr == inp->inp_laddr.s_addr ||
+ sin->sin_addr.s_addr == inp->inp_faddr.s_addr)
+ return (p->onoff);
+ }
+#ifdef INET6
+ if (((struct sockaddr *)&p->addr)->sa_family == AF_INET6
+ && (inp->inp_flags & INP_IPV6)) {
+ struct sockaddr_in6 *sin6;
+ sin6 = (struct sockaddr_in6 *)&p->addr;
+ if (IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &inp->inp_laddr6) ||
+ IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &inp->inp_faddr6))
+ return (p->onoff);
+ }
+#endif
+ }
return (1);
}
@@ -303,12 +353,22 @@ static void
showhosts()
{
register struct hitem *p;
- struct hostent *hp;
+ char hbuf[NI_MAXHOST];
+ struct sockaddr *sa;
+ int flags;
+#if 0
+ flags = nflag ? NI_NUMERICHOST : 0;
+#else
+ flags = 0;
+#endif
for (p = hosts; p < hosts+nhosts; p++) {
- hp = gethostbyaddr((char *)&p->addr, sizeof (p->addr), AF_INET);
+ sa = (struct sockaddr *)&p->addr;
+ if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), NULL, 0,
+ flags) != 0)
+ strcpy(hbuf, "(invalid)");
if (!p->onoff)
addch('!');
- printw("%s ", hp ? hp->h_name : inet_ntoa(p->addr));
+ printw("%s ", hbuf);
}
}
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;