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.
This commit is contained in:
parent
7a17fd0552
commit
8b0aa988ec
|
@ -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, 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_dictionary_t env0)
|
|||
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_dictionary_t env0)
|
|||
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_dictionary_t env0)
|
|||
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_t n)
|
|||
#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, const void *ifa_data,
|
|||
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);
|
||||
|
|
|
@ -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 media_status)
|
|||
}
|
||||
|
||||
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_state,
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue