Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 11 Jul 2012 17:25:44 +0000
From:      exxo@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r239272 - soc2012/exxo/freebsd-head/usr.bin/systat
Message-ID:  <20120711172544.6A30C106564A@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: exxo
Date: Wed Jul 11 17:25:43 2012
New Revision: 239272
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=239272

Log:
  Fixing usr.bin/systat

Modified:
  soc2012/exxo/freebsd-head/usr.bin/systat/netcmds.c

Modified: soc2012/exxo/freebsd-head/usr.bin/systat/netcmds.c
==============================================================================
--- soc2012/exxo/freebsd-head/usr.bin/systat/netcmds.c	Wed Jul 11 16:52:25 2012	(r239271)
+++ soc2012/exxo/freebsd-head/usr.bin/systat/netcmds.c	Wed Jul 11 17:25:43 2012	(r239272)
@@ -61,8 +61,14 @@
 
 #define	streq(a,b)	(strcmp(a,b)==0)
 
+union storage_addr {
+	struct in_addr	in;
+	struct in6_addr in6;
+};
+
 static	struct hitem {
-	struct	in_addr addr;
+	union storage_addr addr;
+	int	family;
 	int	onoff;
 } *hosts;
 
@@ -73,7 +79,7 @@
 static void showprotos(void);
 static int selectport(long, int);
 static void showports(void);
-static int selecthost(struct in_addr *, int);
+static int selecthost(union storage_addr *, int, int);
 static void showhosts(void);
 
 int
@@ -96,7 +102,7 @@
 	}
 	if (prefix(cmd, "reset")) {
 		selectproto(0);
-		selecthost(0, 0);
+		selecthost(0, 0, 0);
 		selectport(-1, 0);
 		return (1);
 	}
@@ -126,8 +132,9 @@
 {
 	char *cp, *tmpstr, *tmpstr1;
 	struct servent *sp;
-	struct hostent *hp;
-	struct in_addr in;
+	struct addrinfo hint, *res, *res0;
+	union storage_addr addr;
+	int family = AF_UNSPEC;
 
 	tmpstr = tmpstr1 = strdup(args);
 	cp = strchr(tmpstr1, '\n');
@@ -143,22 +150,46 @@
 			*cp++ = '\0';
 		if (cp - tmpstr1 == 0)
 			break;
+		if (streq(tmpstr1, "-4")) {
+			family = AF_INET;
+			continue;
+		}
+		else if (streq(tmpstr1, "-6")) {
+			family = AF_INET6;
+			continue;
+		}
 		sp = getservbyname(tmpstr1,
 		    protos == TCP ? "tcp" : protos == UDP ? "udp" : 0);
 		if (sp) {
 			selectport(sp->s_port, onoff);
 			continue;
 		}
-		hp = gethostbyname(tmpstr1);
-		if (hp == 0) {
-			in.s_addr = inet_addr(tmpstr1);
-			if ((int)in.s_addr == -1) {
-				error("%s: unknown host or port", tmpstr1);
+		memset(&hint, 0, sizeof(hint));
+		hint.ai_family = family;
+		hint.ai_protocol = (protos == TCP ? IPPROTO_TCP : protos == UDP ? IPPROTO_UDP : 0);
+		hint.ai_flags = AI_ADDRCONFIG;
+		if ( (getaddrinfo(tmpstr1, 0, &hint, &res0))) {
+			error("%s: unknown host or port", tmpstr1);
+			continue;
+		}
+		for (res = res0; res; res = res->ai_next) {
+			switch (res->ai_family) {
+			case AF_INET :
+				memcpy(&addr.in,
+				    &((struct sockaddr_in *)res->ai_addr)->sin_addr,
+				    sizeof(addr.in));
+				break;
+			case AF_INET6 :
+				memcpy(&addr.in6,
+				    &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,
+				    sizeof(addr.in6));
+				break;
+			default :
 				continue;
 			}
-		} else
-			in = *(struct in_addr *)hp->h_addr;
-		selecthost(&in, onoff);
+			selecthost(&addr, res->ai_family, onoff);
+		}
+		freeaddrinfo(res0);
 	}
 	free(tmpstr);
 }
@@ -253,12 +284,15 @@
 	}
 }
 
+#define af4cmp(x, y)	(memcmp(&x.s_addr, &y.s_addr, sizeof(x.s_addr))==0)
+#define af6cmp(x, y)	(memcmp(&x.s6_addr, &y.s6_addr, sizeof(x.s6_addr))==0)
+
 static int
-selecthost(struct in_addr *in, int onoff)
+selecthost(union storage_addr *addr, int family, int onoff)
 {
 	struct hitem *p;
 
-	if (in == 0) {
+	if (addr == 0) {
 		if (hosts == 0)
 			return (0);
 		free((char *)hosts), hosts = 0;
@@ -266,7 +300,9 @@
 		return (1);
 	}
 	for (p = hosts; p < hosts+nhosts; p++)
-		if (p->addr.s_addr == in->s_addr) {
+		if (p->family == family && family == AF_INET ?
+		    af4cmp(p->addr.in, addr->in) : af6cmp(p->addr.in6, addr->in6))
+		{
 			p->onoff = onoff;
 			return (0);
 		}
@@ -275,7 +311,8 @@
 	else
 		hosts = (struct hitem *)realloc(hosts, (nhosts+1)*sizeof (*p));
 	p = &hosts[nhosts++];
-	p->addr = *in;
+	p->addr = *addr;
+	p->family = family;
 	p->onoff = onoff;
 	return (1);
 }
@@ -287,8 +324,11 @@
 
 	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)
+		if (((inp->inp_vflag & INP_IPV4) && p->family == AF_INET &&
+		    (af4cmp(p->addr.in, inp->inp_laddr) || af4cmp(p->addr.in, inp->inp_faddr)))
+		    ||
+		    ((inp->inp_vflag & INP_IPV6) && p->family == AF_INET6 &&
+		    (af6cmp(p->addr.in6, inp->in6p_laddr) || af6cmp(p->addr.in6, inp->in6p_faddr))))
 			return (p->onoff);
 	return (1);
 }
@@ -298,11 +338,27 @@
 {
 	struct hitem *p;
 	struct hostent *hp;
+	const void *host;
+	socklen_t len;
+	char str[INET6_ADDRSTRLEN];
 
 	for (p = hosts; p < hosts+nhosts; p++) {
-		hp = gethostbyaddr((char *)&p->addr, sizeof (p->addr), AF_INET);
+		switch (p->family) {
+		case AF_INET :
+			host = (const void *)&p->addr.in;
+			len = sizeof(p->addr.in);
+			break;
+		case AF_INET6 :
+			host = (const void *)&p->addr.in6;
+			len = sizeof(p->addr.in6);
+			break;
+		default :
+			continue;
+		}
+		hp = gethostbyaddr(host, len, p->family);
 		if (!p->onoff)
 			addch('!');
-		printw("%s ", hp ? hp->h_name : (char *)inet_ntoa(p->addr));
+		printw("%s%s ", hp ? hp->h_name : (char *)inet_ntop(p->family, host, str, INET6_ADDRSTRLEN),
+		    p->family == AF_INET ? "(v4)" : "(v6)");
 	}
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120711172544.6A30C106564A>