Module Name:    src
Committed By:   msaitoh
Date:           Mon Sep  5 00:18:25 UTC 2022

Modified Files:
        src/usr.bin/netstat: if.c

Log Message:
Get if_data correctly when kvm is used.


To generate a diff of this commit:
cvs rdiff -u -r1.99 -r1.100 src/usr.bin/netstat/if.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/netstat/if.c
diff -u src/usr.bin/netstat/if.c:1.99 src/usr.bin/netstat/if.c:1.100
--- src/usr.bin/netstat/if.c:1.99	Fri Sep  2 06:25:43 2022
+++ src/usr.bin/netstat/if.c	Mon Sep  5 00:18:25 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: if.c,v 1.99 2022/09/02 06:25:43 msaitoh Exp $	*/
+/*	$NetBSD: if.c,v 1.100 2022/09/05 00:18:25 msaitoh Exp $	*/
 
 /*
  * Copyright (c) 1983, 1988, 1993
@@ -34,7 +34,7 @@
 #if 0
 static char sccsid[] = "from: @(#)if.c	8.2 (Berkeley) 2/21/94";
 #else
-__RCSID("$NetBSD: if.c,v 1.99 2022/09/02 06:25:43 msaitoh Exp $");
+__RCSID("$NetBSD: if.c,v 1.100 2022/09/05 00:18:25 msaitoh Exp $");
 #endif
 #endif /* not lint */
 
@@ -287,27 +287,15 @@ union ifaddr_u {
 };
 
 static void
-ifnet_to_ifdata_kvm(const struct ifnet * const ifp, struct if_data * const ifd)
+ifname_to_ifdata(int s, const char *ifname, struct if_data * const ifd)
 {
+	struct ifdatareq ifdr;
 
-	/*
-	 * Interface statistics are no longer kept in struct ifnet,
-	 * and thus an if_data is no longer embedded in struct ifnet.
-	 * We cannot read stats via kvm without chasing per-cpu data,
-	 * and maybe someday we could do that.  But for now, this is
-	 * what we have.
-	 *
-	 * Just copy the fields that do exist.
-	 */
 	memset(ifd, 0, sizeof(*ifd));
-	ifd->ifi_type = ifp->if_type;
-	ifd->ifi_addrlen = ifp->if_addrlen;
-	ifd->ifi_hdrlen = ifp->if_hdrlen;
-	ifd->ifi_link_state = ifp->if_link_state;
-	ifd->ifi_mtu = ifp->if_mtu;
-	ifd->ifi_metric = ifp->if_metric;
-	ifd->ifi_baudrate = ifp->if_baudrate;
-	ifd->ifi_lastchange = ifp->if_lastchange;
+	strlcpy(ifdr.ifdr_name, ifname, sizeof(ifdr.ifdr_name));
+	if (ioctl(s, SIOCGIFDATA, &ifdr) != 0)
+		return;
+	memcpy(ifd, &ifdr.ifdr_data, sizeof(ifdr.ifdr_data));
 }
 
 static void
@@ -319,6 +307,7 @@ intpr_kvm(u_long ifnetaddr, void (*pfunc
 	u_long ifaddraddr;
 	struct ifnet_head ifhead;	/* TAILQ_HEAD */
 	char name[IFNAMSIZ + 1];	/* + 1 for `*' */
+	int s;
 
 	if (ifnetaddr == 0) {
 		printf("ifnet: symbol not defined\n");
@@ -334,6 +323,9 @@ intpr_kvm(u_long ifnetaddr, void (*pfunc
 		return;
 	ifnetaddr = (u_long)ifhead.tqh_first;
 
+	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+		return;
+
 	intpr_header();
 
 	ifaddraddr = 0;
@@ -382,13 +374,13 @@ intpr_kvm(u_long ifnetaddr, void (*pfunc
 			cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) +
 			    CP(&ifaddr);
 			sa = (struct sockaddr *)cp;
-			ifnet_to_ifdata_kvm(&ifnet, &ifd);
+			ifname_to_ifdata(s, name, &ifd);
 			print_addr(ifnet.if_index, sa, (void *)&ifaddr,
 			    &ifd, &ifnet);
 		}
 		ifaddraddr = (u_long)ifaddr.ifa.ifa_list.tqe_next;
 	}
-
+	close(s);
 }
 
 static void
@@ -816,6 +808,7 @@ sidewaysintpr_kvm(unsigned interval, u_l
 	unsigned line;
 	struct iftot *lastif, *sum, *interesting;
 	struct ifnet_head ifhead;	/* TAILQ_HEAD */
+	int s;
 
 	set_lines();
 
@@ -828,6 +821,9 @@ sidewaysintpr_kvm(unsigned interval, u_l
 		return;
 	firstifnet = (u_long)ifhead.tqh_first;
 
+	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+		return;
+
 	lastif = iftot;
 	sum = iftot + MAXIF - 1;
 	total = sum - 1;
@@ -930,7 +926,7 @@ loop:
 			off = 0;
 			continue;
 		}
-		ifnet_to_ifdata_kvm(&ifnet, &ifd);
+		ifname_to_ifdata(s, ip->ift_name, &ifd);
 		if (ip == interesting) {
 			if (bflag) {
 				char humbuf[HUMBUF_SIZE];

Reply via email to