Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 10 Jul 2005 06:50:12 GMT
From:      soc-anders <soc-anders@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 79896 for review
Message-ID:  <200507100650.j6A6oCXF034652@repoman.freebsd.org>

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

Change 79896 by soc-anders@soc-anders_gimli on 2005/07/10 06:49:17

	Interface information now exclusivly uses sysctl to obtain 
	information and if_var.h references have been removed. Certain
	Issues remain:
	* No watchdog timer information is available (drop -t?)
	* Per address if_data information is not available
	* Multicast address are not displayed

Affected files ...

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

Differences ...

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

@@ -47,15 +47,14 @@
 #include <sys/time.h>
 
 #include <net/if.h>
-#include <net/if_var.h>
 #include <net/if_dl.h>
 #include <net/if_types.h>
 #include <net/bridge.h>
 #include <net/ethernet.h>
 #include <netinet/in.h>
-#include <netinet/in_var.h>
+/*#include <netinet/in_var.h>*/
 #include <netipx/ipx.h>
-#include <netipx/ipx_if.h>
+/*#include <netipx/ipx_if.h>*/
 #include <arpa/inet.h>
 
 #include <signal.h>
@@ -68,6 +67,7 @@
 
 #ifdef IFCLEANUP
 #include <net/if_mib.h>
+#include <net/route.h>
 #endif
 
 #include "netstat.h"
@@ -153,19 +153,6 @@
 void
 intpr(int _interval, u_long ifnetaddr, void (*pfunc)(char *))
 {
-	struct ifnet ifnet;
-	struct ifnethead ifnethead;
-	union {
-		struct ifaddr ifa;
-		struct in_ifaddr in;
-#ifdef INET6
-		struct in6_ifaddr in6;
-#endif
-		struct ipx_ifaddr ipx;
-	} ifaddr;
-	u_long ifaddraddr;
-	u_long ifaddrfound;
-	u_long ifnetfound;
 	u_long opackets;
 	u_long ipackets;
 	u_long obytes;
@@ -175,27 +162,36 @@
 	u_long oerrors;
 	u_long ierrors;
 	u_long collisions;
-	short timer;
-	int drops;
+	/*	short timer; */
+	u_long drops;
 	struct sockaddr *sa = NULL;
 	char name[IFNAMSIZ];
 	short network_layer;
 	short link_layer;
 
+	int mib[6] = {CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0};
+	size_t len;
+	char *buf, *cur, *end;
+	struct if_msghdr *ifm;
+	struct ifa_msghdr *ifam;
+	struct sockaddr *addr, *mask, *brd;
+	u_long mtu;
+
 	if (_interval) {
 		sidewaysintpr((unsigned)_interval, ifnetaddr);
 		return;
 	}
-	else if (ifnetaddr == 0) {
-		printf("ifnet: symbol not defined\n");
+
+	if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0)
+		return;
+	if ((buf = malloc(len)) == NULL) {
+		printf("malloc\n");
 		return;
 	}
-
-	if (kread(ifnetaddr, (char *)&ifnethead, sizeof ifnethead))
+	if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
+		free(buf);
 		return;
-	ifnetaddr = (u_long)TAILQ_FIRST(&ifnethead);
-	if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet))
-		return;
+	}
 
 	if (!pfunc) {
 		if (Wflag)
@@ -216,186 +212,206 @@
 			printf(" %s", "Drop");
 		putchar('\n');
 	}
-	ifaddraddr = 0;
-	while (ifnetaddr || ifaddraddr) {
+	cur = buf;
+	end = cur + len;
+	while (cur < end) {
 		struct sockaddr_in *sockin;
+		struct sockaddr_in *inmask;
 #ifdef INET6
 		struct sockaddr_in6 *sockin6;
+		struct sockaddr_in6 *in6mask;
 #endif
 		char *cp;
 		int n, m;
 
 		network_layer = 0;
 		link_layer = 0;
+		ifm = (struct if_msghdr *)cur;
+		ifam = NULL;
+
+		if (ifm->ifm_type == RTM_IFINFO) {
+			struct sockaddr_dl *sdl;
+			if (!(ifm->ifm_addrs & RTA_IFP)) {
+				printf("Missing IFP\n");
+				exit(1);
+			}
+			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 ((ifm->ifm_flags & IFF_UP) == 0) {
+				cp = index(name, '\0');
+				*cp++ = '*';
+				*cp = '\0';
+			}
+			mtu = ifm->ifm_data.ifi_mtu;
 
-		if (ifaddraddr == 0) {
-			ifnetfound = ifnetaddr;
-			if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet))
-				return;
-			strlcpy(name, ifnet.if_xname, sizeof(name));
-			ifnetaddr = (u_long)TAILQ_NEXT(&ifnet, if_link);
-			if (interface != 0 && (strcmp(name, interface) != 0))
-				continue;
-			cp = index(name, '\0');
+		} else if (ifm->ifm_type == RTM_NEWADDR) {
+			int addrs = ifm->ifm_addrs;
+			ifam = (struct ifa_msghdr *)cur;
+			cur += sizeof(*ifam);
 
-			if (pfunc) {
-				(*pfunc)(name);
-				continue;
+			while (addrs != 0) {
+				sa = (struct sockaddr *)cur;
+				cur += SA_SIZE(sa);
+				if (sa->sa_len == 0) 
+					continue;
+				
+				if (addrs & RTA_NETMASK) {
+					mask = sa;
+					addrs &= ~RTA_NETMASK;
+				} else if (addrs & RTA_IFA) {
+					addr = sa;
+					addrs &= ~RTA_IFA;
+				} else if (addrs & RTA_BRD) {
+					brd = sa;
+					addrs &= ~RTA_BRD;
+				}
 			}
-
-			if ((ifnet.if_flags&IFF_UP) == 0)
-				*cp++ = '*';
-			*cp = '\0';
-			ifaddraddr = (u_long)TAILQ_FIRST(&ifnet.if_addrhead);
+		} else {
+			printf("Unknown message type: %d\n", ifm->ifm_type);
+			cur += ifm->ifm_msglen;
+			continue;
 		}
-		ifaddrfound = ifaddraddr;
 
 		/*
 		 * Get the interface stats.  These may get
 		 * overriden below on a per-interface basis.
 		 */
-		opackets = ifnet.if_opackets;
-		ipackets = ifnet.if_ipackets;
-		obytes = ifnet.if_obytes;
-		ibytes = ifnet.if_ibytes;
-		omcasts = ifnet.if_omcasts;
-		imcasts = ifnet.if_imcasts;
-		oerrors = ifnet.if_oerrors;
-		ierrors = ifnet.if_ierrors;
-		collisions = ifnet.if_collisions;
-		timer = ifnet.if_timer;
-		drops = ifnet.if_snd.ifq_drops;
+		if (ifm->ifm_type == RTM_IFINFO) {
+			opackets = ifm->ifm_data.ifi_opackets;
+			ipackets = ifm->ifm_data.ifi_ipackets;
+			obytes = ifm->ifm_data.ifi_obytes;
+			ibytes = ifm->ifm_data.ifi_ibytes;
+			omcasts = ifm->ifm_data.ifi_omcasts;
+			imcasts = ifm->ifm_data.ifi_imcasts;
+			oerrors = ifm->ifm_data.ifi_oerrors;
+			ierrors = ifm->ifm_data.ifi_ierrors;
+			collisions = ifm->ifm_data.ifi_collisions;
+			/* IFCLEANUP
+			 * Timer info not available in if_data
+			 * timer = ifnet.if_timer;
+			 */
+			drops = ifm->ifm_data.ifi_iqdrops;
+		}
 
-		if (ifaddraddr == 0) {
-			if (Wflag)
-				printf("%-7.7s", name);
-			else
-				printf("%-5.5s", name);
-			printf(" %5lu ", ifnet.if_mtu);
+		if (af != AF_UNSPEC && sa->sa_family != af)
+			continue;
+		
+		if (Wflag)
+			printf("%-7.7s", name);
+		else
+			printf("%-5.5s", name);
+		printf(" %5lu ", mtu);
+		switch (addr->sa_family) {
+		case AF_UNSPEC:
 			printf("%-13.13s ", "none");
-			printf("%-17.17s ", "none");
-		} else {
-			if (kread(ifaddraddr, (char *)&ifaddr, sizeof ifaddr)) {
-				ifaddraddr = 0;
-				continue;
-			}
-#define CP(x) ((char *)(x))
-			cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) +
-				CP(&ifaddr);
-			sa = (struct sockaddr *)cp;
-			if (af != AF_UNSPEC && sa->sa_family != af) {
-				ifaddraddr =
-				    (u_long)TAILQ_NEXT(&ifaddr.ifa, ifa_link);
-				continue;
-			}
-			if (Wflag)
-				printf("%-7.7s", name);
-			else
-				printf("%-5.5s", name);
-			printf(" %5lu ", ifnet.if_mtu);
-			switch (sa->sa_family) {
-			case AF_UNSPEC:
-				printf("%-13.13s ", "none");
-				printf("%-15.15s ", "none");
-				break;
-			case AF_INET:
-				sockin = (struct sockaddr_in *)sa;
-#ifdef notdef
-				/* can't use inet_makeaddr because kernel
-				 * keeps nets unshifted.
-				 */
-				in = inet_makeaddr(ifaddr.in.ia_subnet,
-					INADDR_ANY);
-				printf("%-13.13s ", netname(in.s_addr,
-				    ifaddr.in.ia_subnetmask));
-#else
-				printf("%-13.13s ",
-				    netname(htonl(ifaddr.in.ia_subnet),
-				    ifaddr.in.ia_subnetmask));
-#endif
-				printf("%-17.17s ",
-				    routename(sockin->sin_addr.s_addr));
+			printf("%-15.15s ", "none");
+			break;
+		case AF_INET:
+			inmask = (struct sockaddr_in *)mask;
+			sockin = (struct sockaddr_in *)addr;
+
+			/* IFCLEANUP
+			 * netname expects a network address and its mask
+			 */
+			printf("%-13.13s ",  
+			       netname(sockin->sin_addr.s_addr &
+				       inmask->sin_addr.s_addr,
+				       ntohl(inmask->sin_addr.s_addr)));
+			printf("%-17.17s ",
+			       routename(sockin->sin_addr.s_addr));
 
-				network_layer = 1;
-				break;
-#ifdef INET6
-			case AF_INET6:
-				sockin6 = (struct sockaddr_in6 *)sa;
-				printf("%-13.13s ",
-				       netname6(&ifaddr.in6.ia_addr,
-						&ifaddr.in6.ia_prefixmask.sin6_addr));
-				printf("%-17.17s ",
-				    inet_ntop(AF_INET6,
-					&sockin6->sin6_addr,
-					ntop_buf, sizeof(ntop_buf)));
+			network_layer = 1;
+			break;
+#ifdef INET6			
+		case AF_INET6:
+			in6mask = (struct sockaddr_in6 *)mask;
+			sockin6 = (struct sockaddr_in6 *)addr;
 
-				network_layer = 1;
-				break;
+			printf("%-13.13s ", 
+			       netname6(sockin6, &in6mask->sin6_addr));
+			printf("%-17.17s ", 
+			       inet_ntop(AF_INET6,
+					 &sockin6->sin6_addr,
+					 ntop_buf, sizeof(ntop_buf)));
+			
+			network_layer = 1;
+			break;
 #endif /*INET6*/
-			case AF_IPX:
-				{
-				struct sockaddr_ipx *sipx =
-					(struct sockaddr_ipx *)sa;
-				u_long net;
-				char netnum[10];
+		case AF_IPX:
+			{
+			struct sockaddr_ipx *sipx =
+				(struct sockaddr_ipx *)addr;
+			u_long net;
+			char netnum[10];
+			
+			*(union ipx_net *) &net = sipx->sipx_addr.x_net;
+			sprintf(netnum, "%lx", (u_long)ntohl(net));
+			printf("ipx:%-8s  ", netnum);
+			/*				printf("ipx:%-8s ", netname(net, 0L)); */
+			printf("%-17s ",
+			       ipx_phost((struct sockaddr *)sipx));
+			}
 
-				*(union ipx_net *) &net = sipx->sipx_addr.x_net;
-				sprintf(netnum, "%lx", (u_long)ntohl(net));
-				printf("ipx:%-8s  ", netnum);
-/*				printf("ipx:%-8s ", netname(net, 0L)); */
-				printf("%-17s ",
-				    ipx_phost((struct sockaddr *)sipx));
-				}
+			network_layer = 1;
+			break;
 
-				network_layer = 1;
-				break;
-
-			case AF_APPLETALK:
-				printf("atalk:%-12.12s ",atalk_print(sa,0x10) );
-				printf("%-11.11s  ",atalk_print(sa,0x0b) );
-				break;
-			case AF_LINK:
-				{
-				struct sockaddr_dl *sdl =
-					(struct sockaddr_dl *)sa;
-				char linknum[10];
-				cp = (char *)LLADDR(sdl);
-				n = sdl->sdl_alen;
-				sprintf(linknum, "<Link#%d>", sdl->sdl_index);
-				m = printf("%-13.13s ", linknum);
-				}
-				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;
-			hexprint:
-				while (--n >= 0)
-					m += printf("%02x%c", *cp++ & 0xff,
+		case AF_APPLETALK:
+			printf("atalk:%-12.12s ",atalk_print(sa,0x10) );
+			printf("%-11.11s  ",atalk_print(sa,0x0b) );
+			break;
+		case AF_LINK:
+			{
+			struct sockaddr_dl *sdl =
+				(struct sockaddr_dl *)addr;
+			char linknum[10];
+			cp = (char *)LLADDR(sdl);
+			n = sdl->sdl_alen;
+			sprintf(linknum, "<Link#%d>", sdl->sdl_index);
+			m = printf("%-13.13s ", linknum);
+			}
+			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;
+		hexprint:
+			while (--n >= 0)
+				m += printf("%02x%c", *cp++ & 0xff,
 						    n > 0 ? ':' : ' ');
-				m = 32 - m;
-				while (m-- > 0)
-					putchar(' ');
-
-				link_layer = 1;
-				break;
-			}
-
-			/*
-			 * Fixup the statistics for interfaces that
-			 * update stats for their network addresses
-			 */
-			if (network_layer) {
-				opackets = ifaddr.in.ia_ifa.if_opackets;
-				ipackets = ifaddr.in.ia_ifa.if_ipackets;
-				obytes = ifaddr.in.ia_ifa.if_obytes;
-				ibytes = ifaddr.in.ia_ifa.if_ibytes;
-			}
-
-			ifaddraddr = (u_long)TAILQ_NEXT(&ifaddr.ifa, ifa_link);
+			m = 32 - m;
+			while (m-- > 0)
+				putchar(' ');
+			
+			link_layer = 1;
+			break;
 		}
+		
+		/*
+		 * Fixup the statistics for interfaces that
+		 * update stats for their network addresses
+		 */
+			
+		/* IFCLEANUP
+		 * Cannot handle this yet; ifa_msghdr does not 
+		 * contain socket if_data info.
+		 */
+		/*
+		  if (network_layer) {
+		  opackets = ifaddr.in.ia_ifa.if_opackets;
+		  ipackets = ifaddr.in.ia_ifa.if_ipackets;
+		  obytes = ifaddr.in.ia_ifa.if_obytes;
+		  ibytes = ifaddr.in.ia_ifa.if_ibytes;
+		  }
+		*/
+		
+	
 
 		show_stat("lu", 8, ipackets, link_layer|network_layer);
 		printf(" ");
@@ -414,15 +430,24 @@
 			printf(" ");
 		}
 		show_stat("lu", 5, collisions, link_layer);
+		/* IFCLEANUP
+		 * timer info not availble in if_data
+		 */
+		/*
 		if (tflag) {
 			printf(" ");
 			show_stat("d", 3, timer, link_layer);
 		}
+		*/
 		if (dflag) {
 			printf(" ");
 			show_stat("d", 3, drops, link_layer);
 		}
 		putchar('\n');
+		/* IFCLEANUP
+		 * Skip mcast for now
+		 */
+#if 0
 		if (aflag && ifaddrfound) {
 			/*
 			 * Print family's multicast addresses
@@ -490,6 +515,7 @@
 				}
 			}
 		}
+#endif /* if 0 */
 	}
 }
 



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