Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 Jul 2005 22:46:00 GMT
From:      soc-anders <soc-anders@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 80485 for review
Message-ID:  <200507182246.j6IMk0d1092404@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=80485

Change 80485 by soc-anders@soc-anders_gimli on 2005/07/18 22:45:43

	When listing interfaces, the '-I' flag did not work correctly, now it should :)
	Parsing of messages is done in a safer manner.  

Affected files ...

.. //depot/projects/soc2005/ifcleanup/src/src/usr.bin/netstat/if.c#5 edit

Differences ...

==== //depot/projects/soc2005/ifcleanup/src/src/usr.bin/netstat/if.c#5 (text+ko) ====

@@ -60,6 +60,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <err.h>
 
 #define IFCLEANUP
 
@@ -174,7 +175,7 @@
 	struct ifa_msghdr *ifam;
 	struct sockaddr *addr, *mask, *brd;
 	u_long if_mtu;
-	int if_index;
+	int if_index = -1;
 
 	if (_interval) {
 		sidewaysintpr((unsigned)_interval, ifnetaddr);
@@ -232,48 +233,69 @@
 		if (ifm->ifm_type == RTM_IFINFO) {
 			struct sockaddr_dl *sdl;
 			if (!(ifm->ifm_addrs & RTA_IFP)) {
-				printf("Missing IFP\n");
-				exit(1);
+				errx(1, "Interface information missing");
 			}
 			sa = (struct sockaddr *)(cur + sizeof(*ifm));
 			addr = sa;
 			sdl = (struct sockaddr_dl *)sa;
 			strlcpy(name, sdl->sdl_data, sdl->sdl_nlen+1);
 			cur += ifm->ifm_msglen;		      
-			if (interface != 0 && (strcmp(name, interface) != 0)) 
-				continue;			
+			if (interface != 0 && (strcmp(name, interface) != 0)) {
+				if_index = -1;
+				continue;	
+			}		
+			
+			if (pfunc) {
+				(*pfunc)(name);
+				continue;
+			}
+
 			if ((ifm->ifm_flags & IFF_UP) == 0) {
 				cp = index(name, '\0');
 				*cp++ = '*';
 				*cp = '\0';
-			}
+			}			
 			if_mtu = ifm->ifm_data.ifi_mtu;
 			if_index = ifm->ifm_index;
 
 		} else if (ifm->ifm_type == RTM_NEWADDR) {
 			int addrs = ifm->ifm_addrs;
+			char *msgend;
+			int i;
+
+			if (if_index < 0) {
+				cur += ifm->ifm_msglen;
+				continue;
+			}
 			ifam = (struct ifa_msghdr *)cur;
+			msgend = cur + ifm->ifm_msglen;
 			cur += sizeof(*ifam);
-
-			while (addrs != 0) {
+			for (i = 0; addrs != 0 && i < RTAX_MAX && cur < msgend; 
+			     addrs &= ~(1<<i), i++) {
+				if (!(addrs & 1<<i))
+					continue;
 				sa = (struct sockaddr *)cur;
 				cur += SA_SIZE(sa);
 				if (sa->sa_len == 0) 
 					continue;
 				
-				if (addrs & RTA_NETMASK) {
+				switch (1<<i) {
+				case RTA_NETMASK:
 					mask = sa;
-					addrs &= ~RTA_NETMASK;
-				} else if (addrs & RTA_IFA) {
+				break;
+				case RTA_IFA:
 					addr = sa;
-					addrs &= ~RTA_IFA;
-				} else if (addrs & RTA_BRD) {
+					break;
+				case RTA_BRD:
 					brd = sa;
-					addrs &= ~RTA_BRD;
+					break;
+				default:
+					break;
 				}
 			}
+			cur = msgend;
 		} else {
-			printf("Unknown message type: %d\n", ifm->ifm_type);
+			warnx("Unexpected message type: %d\n", ifm->ifm_type);
 			cur += ifm->ifm_msglen;
 			continue;
 		}
@@ -299,7 +321,7 @@
 			drops = ifm->ifm_data.ifi_iqdrops;
 		}
 
-		if (af != AF_UNSPEC && sa->sa_family != af)
+		if (af != AF_UNSPEC && addr->sa_family != af)
 			continue;
 		
 		if (Wflag)
@@ -362,8 +384,8 @@
 			break;
 
 		case AF_APPLETALK:
-			printf("atalk:%-12.12s ",atalk_print(sa,0x10) );
-			printf("%-11.11s  ",atalk_print(sa,0x0b) );
+			printf("atalk:%-12.12s ",atalk_print(addr,0x10) );
+			printf("%-11.11s  ",atalk_print(addr,0x0b) );
 			break;
 		case AF_LINK:
 			{
@@ -377,11 +399,11 @@
 			}
 			goto hexprint;
 		default:
-			m = printf("(%d)", sa->sa_family);
-			for (cp = sa->sa_len + (char *)sa;
-			     --cp > sa->sa_data && (*cp == 0);) {}
-			n = cp - sa->sa_data + 1;
-			cp = sa->sa_data;
+			m = printf("(%d)", addr->sa_family);
+			for (cp = addr->sa_len + (char *)addr;
+			     --cp > addr->sa_data && (*cp == 0);) {}
+			n = cp - addr->sa_data + 1;
+			cp = addr->sa_data;
 		hexprint:
 			while (--n >= 0)
 				m += printf("%02x%c", *cp++ & 0xff,
@@ -469,10 +491,9 @@
 			mib[5] = if_index; 
 			if (sysctl(mib, 6, NULL, &mlen, NULL, 0) < 0)
 				continue;
-			if ((mbuf = malloc(mlen)) == NULL) {
-				printf("malloc\n");
-				exit(1);
-			}
+			if ((mbuf = malloc(mlen)) == NULL) 
+				err(1, NULL);
+
 			if (sysctl(mib, 6, mbuf, &mlen, NULL, 0) < 0) {
 				free(mbuf);
 				continue;
@@ -482,24 +503,33 @@
 			mend = mcur + mlen;
 			while (mcur < mend) {
 				ifmam = (struct ifma_msghdr *)mcur;
+				if (ifmam->ifmam_type != RTM_NEWMADDR) {
+					warnx("Unexpected message type: %d", ifmam->ifmam_type);
+					mcur += ifmam->ifmam_msglen;
+					continue;
+				}
+
 				int addrs = ifmam->ifmam_addrs;
+				int i;
+				char *msgend = mcur + ifmam->ifmam_msglen;
+				
 				mcur += sizeof(*ifmam);
-				while (addrs != 0) {
-					struct sockaddr *tmp = 
-						(struct sockaddr *)mcur;
-					mcur += SA_SIZE(tmp);
-					if (addrs & RTA_GATEWAY)
-						addrs &= ~RTA_GATEWAY;
-					else if (addrs & RTA_IFP) 
-						addrs &= ~RTA_IFP;
-					else if (addrs & RTA_IFA) {
-						bcopy(tmp, &msa, tmp->sa_len);
-						addrs &= ~RTA_IFA;
-					} else {
-						printf("UNEXPECTED: %x\n", addrs);
+
+				for (i = 0; addrs != 0 && i < RTAX_MAX && mcur < msgend;
+				     addrs &= ~(1<<i), i++) {
+					if (!(addrs & 1<<i))
+						continue;
+					sa = (struct sockaddr *)mcur;				       
+					mcur += SA_SIZE(sa);
+
+					if (sa->sa_len == 0)
 						continue;
-					}
+
+					if (1<<i == RTA_IFA)
+						bcopy(sa, &msa, sa->sa_len);					
 				}
+				mcur = msgend;
+
 				fmt = 0;
 				switch (msa.sa.sa_family) {
 				case AF_INET:



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