Module Name:    src
Committed By:   roy
Date:           Wed Oct 14 13:37:14 UTC 2020

Modified Files:
        src/sbin/ifconfig: ifconfig.c media.c media.h

Log Message:
ifconfig: go back to using direct ioctls rather than data from getifaddrs

AF_LINK may not be the first address returned for the interface.
Technically, it *might* not even exist on the interface even though
other families do.
This is likely a driver bug if this really is the case though.

As such it's just easier to use direct ioctls rather than thump around
getifaddrs results. As it stands, the code makes a lot of getifaddrs
calls anyway, so an extra ioctl or two won't break the bank.


To generate a diff of this commit:
cvs rdiff -u -r1.247 -r1.248 src/sbin/ifconfig/ifconfig.c
cvs rdiff -u -r1.12 -r1.13 src/sbin/ifconfig/media.c
cvs rdiff -u -r1.2 -r1.3 src/sbin/ifconfig/media.h

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

Modified files:

Index: src/sbin/ifconfig/ifconfig.c
diff -u src/sbin/ifconfig/ifconfig.c:1.247 src/sbin/ifconfig/ifconfig.c:1.248
--- src/sbin/ifconfig/ifconfig.c:1.247	Mon Sep 28 13:50:22 2020
+++ src/sbin/ifconfig/ifconfig.c	Wed Oct 14 13:37:14 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: ifconfig.c,v 1.247 2020/09/28 13:50:22 roy Exp $	*/
+/*	$NetBSD: ifconfig.c,v 1.248 2020/10/14 13:37:14 roy Exp $	*/
 
 /*-
  * Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc.
@@ -63,7 +63,7 @@
 #ifndef lint
 __COPYRIGHT("@(#) Copyright (c) 1983, 1993\
  The Regents of the University of California.  All rights reserved.");
-__RCSID("$NetBSD: ifconfig.c,v 1.247 2020/09/28 13:50:22 roy Exp $");
+__RCSID("$NetBSD: ifconfig.c,v 1.248 2020/10/14 13:37:14 roy Exp $");
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -135,8 +135,7 @@ static int setlinkstr(prop_dictionary_t,
 static int unsetlinkstr(prop_dictionary_t, prop_dictionary_t);
 static int setifdescr(prop_dictionary_t, prop_dictionary_t);
 static int unsetifdescr(prop_dictionary_t, prop_dictionary_t);
-static void status(const struct sockaddr_dl *, const void *,
-    prop_dictionary_t, prop_dictionary_t);
+static void status(prop_dictionary_t, prop_dictionary_t);
 __dead static void usage(void);
 
 static const struct kwinst ifflagskw[] = {
@@ -850,9 +849,6 @@ void
 printall(const char *ifname, prop_dictionary_t env0)
 {
 	struct ifaddrs *ifap, *ifa;
-	struct ifreq ifr;
-	const struct sockaddr_dl *sdl = NULL;
-	const struct if_data *ifi = NULL;
 	prop_dictionary_t env, oenv;
 	int idx;
 	char *p;
@@ -872,19 +868,8 @@ printall(const char *ifname, prop_dictio
 	p = NULL;
 	idx = 0;
 	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
-		memset(&ifr, 0, sizeof(ifr));
-		estrlcpy(ifr.ifr_name, ifa->ifa_name, sizeof(ifr.ifr_name));
-		if (sizeof(ifr.ifr_addr) >= ifa->ifa_addr->sa_len) {
-			memcpy(&ifr.ifr_addr, ifa->ifa_addr,
-			    ifa->ifa_addr->sa_len);
-		}
-
 		if (ifname != NULL && strcmp(ifname, ifa->ifa_name) != 0)
 			continue;
-		if (ifa->ifa_addr->sa_family == AF_LINK) {
-			sdl = (const struct sockaddr_dl *)ifa->ifa_addr;
-			ifi = (const struct if_data *)ifa->ifa_data;
-		}
 		if (p && strcmp(p, ifa->ifa_name) == 0)
 			continue;
 		if (!prop_dictionary_set_string(env, "if", ifa->ifa_name))
@@ -898,8 +883,7 @@ printall(const char *ifname, prop_dictio
 		if (uflag && (ifa->ifa_flags & IFF_UP) == 0)
 			continue;
 
-		if (sflag && (ifi == NULL ||
-		              ifi->ifi_link_state == LINK_STATE_DOWN))
+		if (sflag && carrier(env) == LINK_STATE_DOWN)
 			continue;
 		idx++;
 		/*
@@ -912,9 +896,7 @@ printall(const char *ifname, prop_dictio
 			continue;
 		}
 
-		status(sdl, ifa->ifa_data, env, oenv);
-		sdl = NULL;
-		ifi = NULL;
+		status(env, oenv);
 	}
 	if (lflag)
 		printf("\n");
@@ -1256,13 +1238,12 @@ print_human_bytes(bool humanize, uint64_
 #define MAX_PRINT_LEN 58	/* XXX need a better way to determine this! */
 
 void
-status(const struct sockaddr_dl *sdl, const void *ifa_data,
-    prop_dictionary_t env, prop_dictionary_t oenv)
+status(prop_dictionary_t env, prop_dictionary_t oenv)
 {
-	const struct if_data *ifi = ifa_data;
 	status_func_t *status_f;
 	statistics_func_t *statistics_f;
 	struct ifdatareq ifdr;
+	struct if_data *ifi;
 	struct ifreq ifr;
 	struct ifdrv ifdrv;
 	char fbuf[BUFSIZ];
@@ -1351,18 +1332,16 @@ status(const struct sockaddr_dl *sdl, co
 		free(p);
 	}
 
-	media_status(sdl->sdl_type, ifi->ifi_link_state, env, oenv);
+	media_status(env, oenv);
 
 	if (!vflag && !zflag)
 		goto proto_status;
 
 	/* We already have if_data from SIOCGIFDATA in ifa_data. */
-	if (zflag) {
-		estrlcpy(ifdr.ifdr_name, ifname, sizeof(ifdr.ifdr_name));
-		if (prog_ioctl(s, SIOCZIFDATA, &ifdr) == -1)
-			err(EXIT_FAILURE, "SIOCZIFDATA");
-		ifi = &ifdr.ifdr_data;
-	}
+	estrlcpy(ifdr.ifdr_name, ifname, sizeof(ifdr.ifdr_name));
+	if (prog_ioctl(s, zflag ? SIOCZIFDATA : SIOCGIFDATA, &ifdr) == -1)
+		err(EXIT_FAILURE, zflag ? "SIOCZIFDATA" : "SIOCGIFDATA");
+	ifi = &ifdr.ifdr_data;
 
 	print_plural("\tinput: ", ifi->ifi_ipackets, "packet");
 	print_human_bytes(hflag, ifi->ifi_ibytes);

Index: src/sbin/ifconfig/media.c
diff -u src/sbin/ifconfig/media.c:1.12 src/sbin/ifconfig/media.c:1.13
--- src/sbin/ifconfig/media.c:1.12	Mon Oct  5 17:29:22 2020
+++ src/sbin/ifconfig/media.c	Wed Oct 14 13:37:14 2020
@@ -1,6 +1,6 @@
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: media.c,v 1.12 2020/10/05 17:29:22 roy Exp $");
+__RCSID("$NetBSD: media.c,v 1.13 2020/10/14 13:37:14 roy Exp $");
 #endif /* not lint */
 
 #include <assert.h>
@@ -395,8 +395,7 @@ print_media_status(int media_type, int m
 }
 
 void
-media_status(int media_type, int link_state,
-    prop_dictionary_t env, prop_dictionary_t oenv)
+media_status(prop_dictionary_t env, prop_dictionary_t oenv)
 {
 	struct ifmediareq ifmr;
 	int af, i, s;
@@ -416,11 +415,17 @@ media_status(int media_type, int link_st
 	estrlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name));
 
 	if (prog_ioctl(s, SIOCGIFMEDIA, &ifmr) == -1) {
+		struct ifdatareq ifdr = { .ifdr_data.ifi_link_state = 0 };
+		struct if_data *ifi = &ifdr.ifdr_data;
+
 		/*
 		 * Interface doesn't support SIOC{G,S}IFMEDIA.
 		 */
-		if (link_state != LINK_STATE_UNKNOWN)
-			print_link_status(media_type, link_state);
+		if (direct_ioctl(env, SIOCGIFDATA, &ifdr) == -1)
+			err(EXIT_FAILURE, "%s: SIOCGIFDATA", __func__);
+
+		if (ifi->ifi_link_state != LINK_STATE_UNKNOWN)
+			print_link_status(ifi->ifi_type, ifi->ifi_link_state);
 		return;
 	}
 

Index: src/sbin/ifconfig/media.h
diff -u src/sbin/ifconfig/media.h:1.2 src/sbin/ifconfig/media.h:1.3
--- src/sbin/ifconfig/media.h:1.2	Tue Sep 22 14:14:17 2020
+++ src/sbin/ifconfig/media.h	Wed Oct 14 13:37:14 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: media.h,v 1.2 2020/09/22 14:14:17 roy Exp $	*/
+/*	$NetBSD: media.h,v 1.3 2020/10/14 13:37:14 roy Exp $	*/
 
 #ifndef	_IFCONFIG_MEDIA_H
 #define	_IFCONFIG_MEDIA_H
@@ -11,6 +11,6 @@ extern struct pkw kwmedia;
 
 void	print_media_word(int, const char *);
 void	process_media_commands(prop_dictionary_t);
-void	media_status(int, int, prop_dictionary_t, prop_dictionary_t);
+void	media_status(prop_dictionary_t, prop_dictionary_t);
 
 #endif	/* _IFCONFIG_MEDIA_H */

Reply via email to