diff options
author | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2000-01-05 11:04:23 +0000 |
---|---|---|
committer | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2000-01-05 11:04:23 +0000 |
commit | 93019139023fdeecae653e53bbbaf9b57355563c (patch) | |
tree | 28753c063958b947bd8e5f94f75ec4fde62db49f /usr.bin/systat | |
parent | dc4781d98ee9a665ec37ad243a9d5f6c104a0742 (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/Makefile | 6 | ||||
-rw-r--r-- | usr.bin/systat/netcmds.c | 112 | ||||
-rw-r--r-- | usr.bin/systat/netstat.c | 175 |
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; |