aboutsummaryrefslogtreecommitdiff
path: root/sbin/ifconfig
diff options
context:
space:
mode:
authorRyan Moeller <freqlabs@FreeBSD.org>2021-02-28 20:27:28 +0000
committerRyan Moeller <freqlabs@FreeBSD.org>2021-03-05 09:15:55 +0000
commit2803fa471e77dc8f227fe00bbf075de7feb10022 (patch)
tree2b5012a9e11c3d0b66d4df49387ae21e6b1e4fe3 /sbin/ifconfig
parentc4ba4aa547184ab401204096cdad9def4ab37964 (diff)
downloadsrc-2803fa471e77dc8f227fe00bbf075de7feb10022.tar.gz
src-2803fa471e77dc8f227fe00bbf075de7feb10022.zip
sbin/ifconfig: Get media status with libifconfig
Code deduplication. Reviewed by: kp MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D29030
Diffstat (limited to 'sbin/ifconfig')
-rw-r--r--sbin/ifconfig/ifconfig.h2
-rw-r--r--sbin/ifconfig/ifieee80211.c2
-rw-r--r--sbin/ifconfig/ifmedia.c673
3 files changed, 176 insertions, 501 deletions
diff --git a/sbin/ifconfig/ifconfig.h b/sbin/ifconfig/ifconfig.h
index 61b1137b47ba..ea541c5e9257 100644
--- a/sbin/ifconfig/ifconfig.h
+++ b/sbin/ifconfig/ifconfig.h
@@ -161,7 +161,7 @@ void sfp_status(int s, struct ifreq *ifr, int verbose);
* XXX expose this so modules that neeed to know of any pending
* operations on ifmedia can avoid cmd line ordering confusion.
*/
-struct ifmediareq *ifmedia_getstate(int s);
+struct ifmediareq *ifmedia_getstate(void);
void print_vhid(const struct ifaddrs *, const char *);
diff --git a/sbin/ifconfig/ifieee80211.c b/sbin/ifconfig/ifieee80211.c
index bb406469829a..cfaf163f5930 100644
--- a/sbin/ifconfig/ifieee80211.c
+++ b/sbin/ifconfig/ifieee80211.c
@@ -239,7 +239,7 @@ getchaninfo(int s)
if (get80211(s, IEEE80211_IOC_CHANINFO, chaninfo,
IEEE80211_CHANINFO_SIZE(MAXCHAN)) < 0)
err(1, "unable to get channel information");
- ifmr = ifmedia_getstate(s);
+ ifmr = ifmedia_getstate();
gethtconf(s);
getvhtconf(s);
}
diff --git a/sbin/ifconfig/ifmedia.c b/sbin/ifconfig/ifmedia.c
index cd3600df454c..66eb40254889 100644
--- a/sbin/ifconfig/ifmedia.c
+++ b/sbin/ifconfig/ifmedia.c
@@ -86,201 +86,103 @@
#include <string.h>
#include <unistd.h>
+#include <libifconfig.h>
+
#include "ifconfig.h"
-static void domediaopt(const char *, int, int);
-static int get_media_subtype(int, const char *);
-static int get_media_mode(int, const char *);
-static int get_media_options(int, const char *);
-static int lookup_media_word(struct ifmedia_description *, const char *);
-static void print_media_word(int, int);
-static void print_media_word_ifconfig(int);
-
-static struct ifmedia_description *get_toptype_desc(int);
-static struct ifmedia_type_to_subtype *get_toptype_ttos(int);
-static struct ifmedia_description *get_subtype_desc(int,
- struct ifmedia_type_to_subtype *ttos);
-
-#define IFM_OPMODE(x) \
- ((x) & (IFM_IEEE80211_ADHOC | IFM_IEEE80211_HOSTAP | \
- IFM_IEEE80211_IBSS | IFM_IEEE80211_WDS | IFM_IEEE80211_MONITOR | \
- IFM_IEEE80211_MBSS))
-#define IFM_IEEE80211_STA 0
+static void domediaopt(const char *, bool, int);
+static ifmedia_t get_media_subtype(ifmedia_t, const char *);
+static ifmedia_t get_media_mode(ifmedia_t, const char *);
+static ifmedia_t get_media_options(ifmedia_t, const char *);
+static void print_media(ifmedia_t, bool);
+static void print_media_ifconfig(ifmedia_t);
static void
media_status(int s)
{
- struct ifmediareq ifmr;
- struct ifdownreason ifdr;
- int *media_list, i;
- bool no_carrier, xmedia;
-
- (void) memset(&ifmr, 0, sizeof(ifmr));
- (void) strlcpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name));
- xmedia = true;
+ struct ifmediareq *ifmr;
- /*
- * Check if interface supports extended media types.
- */
- if (ioctl(s, SIOCGIFXMEDIA, (caddr_t)&ifmr) < 0)
- xmedia = false;
- if (!xmedia && ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
- /*
- * Interface doesn't support SIOC{G,S}IFMEDIA.
- */
+ if (ifconfig_media_get_mediareq(lifh, name, &ifmr) == -1)
return;
- }
- if (ifmr.ifm_count == 0) {
+ if (ifmr->ifm_count == 0) {
warnx("%s: no media types?", name);
- return;
- }
-
- media_list = (int *)malloc(ifmr.ifm_count * sizeof(int));
- if (media_list == NULL)
- err(1, "malloc");
- ifmr.ifm_ulist = media_list;
-
- if (xmedia) {
- if (ioctl(s, SIOCGIFXMEDIA, (caddr_t)&ifmr) < 0)
- err(1, "SIOCGIFXMEDIA");
- } else {
- if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0)
- err(1, "SIOCGIFMEDIA");
+ goto free;
}
printf("\tmedia: ");
- print_media_word(ifmr.ifm_current, 1);
- if (ifmr.ifm_active != ifmr.ifm_current) {
+ print_media(ifmr->ifm_current, true);
+ if (ifmr->ifm_active != ifmr->ifm_current) {
putchar(' ');
putchar('(');
- print_media_word(ifmr.ifm_active, 0);
+ print_media(ifmr->ifm_active, false);
putchar(')');
}
putchar('\n');
- if (ifmr.ifm_status & IFM_AVALID) {
- no_carrier = false;
- printf("\tstatus: ");
- switch (IFM_TYPE(ifmr.ifm_active)) {
- case IFM_ETHER:
- case IFM_ATM:
- if (ifmr.ifm_status & IFM_ACTIVE)
- printf("active");
- else
- no_carrier = true;
- break;
-
- case IFM_IEEE80211:
- if (ifmr.ifm_status & IFM_ACTIVE) {
- /* NB: only sta mode associates */
- if (IFM_OPMODE(ifmr.ifm_active) == IFM_IEEE80211_STA)
- printf("associated");
- else
- printf("running");
- } else
- no_carrier = true;
- break;
- }
- if (no_carrier) {
- printf("no carrier");
- memset(&ifdr, 0, sizeof(ifdr));
- strlcpy(ifdr.ifdr_name, name, sizeof(ifdr.ifdr_name));
- if (ioctl(s, SIOCGIFDOWNREASON, (caddr_t)&ifdr) == 0) {
- switch (ifdr.ifdr_reason) {
- case IFDR_REASON_MSG:
- printf(" (%s)", ifdr.ifdr_msg);
- break;
- case IFDR_REASON_VENDOR:
- printf(" (vendor code %d)",
- ifdr.ifdr_vendor);
- break;
- default:
- break;
- }
+ if (ifmr->ifm_status & IFM_AVALID) {
+ struct ifdownreason ifdr;
+ const char *status;
+
+ status = ifconfig_media_get_status(ifmr);
+ printf("\tstatus: %s", status);
+ if (strcmp(status, "no carrier") == 0 &&
+ ifconfig_media_get_downreason(lifh, name, &ifdr) == 0) {
+ switch (ifdr.ifdr_reason) {
+ case IFDR_REASON_MSG:
+ printf(" (%s)", ifdr.ifdr_msg);
+ break;
+ case IFDR_REASON_VENDOR:
+ printf(" (vendor code %d)",
+ ifdr.ifdr_vendor);
+ break;
+ default:
+ break;
}
}
putchar('\n');
}
- if (ifmr.ifm_count > 0 && supmedia) {
+ if (supmedia) {
printf("\tsupported media:\n");
- for (i = 0; i < ifmr.ifm_count; i++) {
+ for (size_t i = 0; i < ifmr->ifm_count; ++i) {
printf("\t\t");
- print_media_word_ifconfig(media_list[i]);
+ print_media_ifconfig(ifmr->ifm_ulist[i]);
putchar('\n');
}
}
-
- free(media_list);
+free:
+ free(ifmr);
}
struct ifmediareq *
-ifmedia_getstate(int s)
+ifmedia_getstate(void)
{
- static struct ifmediareq *ifmr = NULL;
- int *mwords;
- int xmedia = 1;
-
- if (ifmr == NULL) {
- ifmr = (struct ifmediareq *)malloc(sizeof(struct ifmediareq));
- if (ifmr == NULL)
- err(1, "malloc");
-
- (void) memset(ifmr, 0, sizeof(struct ifmediareq));
- (void) strlcpy(ifmr->ifm_name, name,
- sizeof(ifmr->ifm_name));
-
- ifmr->ifm_count = 0;
- ifmr->ifm_ulist = NULL;
-
- /*
- * We must go through the motions of reading all
- * supported media because we need to know both
- * the current media type and the top-level type.
- */
-
- if (ioctl(s, SIOCGIFXMEDIA, (caddr_t)ifmr) < 0) {
- xmedia = 0;
- }
- if (xmedia == 0 && ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0) {
- err(1, "SIOCGIFMEDIA");
- }
+ static struct ifmediareq *ifmr;
- if (ifmr->ifm_count == 0)
- errx(1, "%s: no media types?", name);
-
- mwords = (int *)malloc(ifmr->ifm_count * sizeof(int));
- if (mwords == NULL)
- err(1, "malloc");
-
- ifmr->ifm_ulist = mwords;
- if (xmedia) {
- if (ioctl(s, SIOCGIFXMEDIA, (caddr_t)ifmr) < 0)
- err(1, "SIOCGIFXMEDIA");
- } else {
- if (ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0)
- err(1, "SIOCGIFMEDIA");
- }
- }
+ if (ifconfig_media_get_mediareq(lifh, name, &ifmr) == -1)
+ errc(1, ifconfig_err_errno(lifh),
+ "%s: ifconfig_media_get_mediareq", name);
- return ifmr;
+ if (ifmr->ifm_count == 0)
+ errx(1, "%s: no media types?", name);
+
+ return (ifmr);
}
static void
setifmediacallback(int s, void *arg)
{
struct ifmediareq *ifmr = (struct ifmediareq *)arg;
- static int did_it = 0;
+ static bool did_it = false;
if (!did_it) {
ifr.ifr_media = ifmr->ifm_current;
if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) < 0)
err(1, "SIOCSIFMEDIA (media)");
- free(ifmr->ifm_ulist);
free(ifmr);
- did_it = 1;
+ did_it = true;
}
}
@@ -290,7 +192,7 @@ setmedia(const char *val, int d, int s, const struct afswtch *afp)
struct ifmediareq *ifmr;
int subtype;
- ifmr = ifmedia_getstate(s);
+ ifmr = ifmedia_getstate();
/*
* We are primarily concerned with the top-level type.
@@ -301,7 +203,7 @@ setmedia(const char *val, int d, int s, const struct afswtch *afp)
* (I'm assuming that all supported media types for a given
* interface will be the same top-level type..)
*/
- subtype = get_media_subtype(IFM_TYPE(ifmr->ifm_ulist[0]), val);
+ subtype = get_media_subtype(ifmr->ifm_ulist[0], val);
strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
ifr.ifr_media = (ifmr->ifm_current & IFM_IMASK) |
@@ -315,25 +217,25 @@ static void
setmediaopt(const char *val, int d, int s, const struct afswtch *afp)
{
- domediaopt(val, 0, s);
+ domediaopt(val, false, s);
}
static void
unsetmediaopt(const char *val, int d, int s, const struct afswtch *afp)
{
- domediaopt(val, 1, s);
+ domediaopt(val, true, s);
}
static void
-domediaopt(const char *val, int clear, int s)
+domediaopt(const char *val, bool clear, int s)
{
struct ifmediareq *ifmr;
- int options;
+ ifmedia_t options;
- ifmr = ifmedia_getstate(s);
+ ifmr = ifmedia_getstate();
- options = get_media_options(IFM_TYPE(ifmr->ifm_ulist[0]), val);
+ options = get_media_options(ifmr->ifm_ulist[0], val);
strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
ifr.ifr_media = ifmr->ifm_current;
@@ -356,7 +258,7 @@ setmediainst(const char *val, int d, int s, const struct afswtch *afp)
struct ifmediareq *ifmr;
int inst;
- ifmr = ifmedia_getstate(s);
+ ifmr = ifmedia_getstate();
inst = atoi(val);
if (inst < 0 || inst > (int)IFM_INST_MAX)
@@ -375,9 +277,9 @@ setmediamode(const char *val, int d, int s, const struct afswtch *afp)
struct ifmediareq *ifmr;
int mode;
- ifmr = ifmedia_getstate(s);
+ ifmr = ifmedia_getstate();
- mode = get_media_mode(IFM_TYPE(ifmr->ifm_ulist[0]), val);
+ mode = get_media_mode(ifmr->ifm_ulist[0], val);
strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
ifr.ifr_media = (ifmr->ifm_current & ~IFM_MMASK) | mode;
@@ -386,320 +288,112 @@ setmediamode(const char *val, int d, int s, const struct afswtch *afp)
callback_register(setifmediacallback, (void *)ifmr);
}
-/**********************************************************************
- * A good chunk of this is duplicated from sys/net/if_media.c
- **********************************************************************/
-
-static struct ifmedia_description ifm_type_descriptions[] =
- IFM_TYPE_DESCRIPTIONS;
-
-static struct ifmedia_description ifm_subtype_ethernet_descriptions[] =
- IFM_SUBTYPE_ETHERNET_DESCRIPTIONS;
-
-static struct ifmedia_description ifm_subtype_ethernet_aliases[] =
- IFM_SUBTYPE_ETHERNET_ALIASES;
-
-static struct ifmedia_description ifm_subtype_ethernet_option_descriptions[] =
- IFM_SUBTYPE_ETHERNET_OPTION_DESCRIPTIONS;
-
-static struct ifmedia_description ifm_subtype_ieee80211_descriptions[] =
- IFM_SUBTYPE_IEEE80211_DESCRIPTIONS;
-
-static struct ifmedia_description ifm_subtype_ieee80211_aliases[] =
- IFM_SUBTYPE_IEEE80211_ALIASES;
-
-static struct ifmedia_description ifm_subtype_ieee80211_option_descriptions[] =
- IFM_SUBTYPE_IEEE80211_OPTION_DESCRIPTIONS;
-
-struct ifmedia_description ifm_subtype_ieee80211_mode_descriptions[] =
- IFM_SUBTYPE_IEEE80211_MODE_DESCRIPTIONS;
-
-struct ifmedia_description ifm_subtype_ieee80211_mode_aliases[] =
- IFM_SUBTYPE_IEEE80211_MODE_ALIASES;
-
-static struct ifmedia_description ifm_subtype_atm_descriptions[] =
- IFM_SUBTYPE_ATM_DESCRIPTIONS;
-
-static struct ifmedia_description ifm_subtype_atm_aliases[] =
- IFM_SUBTYPE_ATM_ALIASES;
-
-static struct ifmedia_description ifm_subtype_atm_option_descriptions[] =
- IFM_SUBTYPE_ATM_OPTION_DESCRIPTIONS;
-
-static struct ifmedia_description ifm_subtype_shared_descriptions[] =
- IFM_SUBTYPE_SHARED_DESCRIPTIONS;
-
-static struct ifmedia_description ifm_subtype_shared_aliases[] =
- IFM_SUBTYPE_SHARED_ALIASES;
-
-static struct ifmedia_description ifm_shared_option_descriptions[] =
- IFM_SHARED_OPTION_DESCRIPTIONS;
-
-static struct ifmedia_description ifm_shared_option_aliases[] =
- IFM_SHARED_OPTION_ALIASES;
-
-struct ifmedia_type_to_subtype {
- struct {
- struct ifmedia_description *desc;
- int alias;
- } subtypes[5];
- struct {
- struct ifmedia_description *desc;
- int alias;
- } options[4];
- struct {
- struct ifmedia_description *desc;
- int alias;
- } modes[3];
-};
-
-/* must be in the same order as IFM_TYPE_DESCRIPTIONS */
-static struct ifmedia_type_to_subtype ifmedia_types_to_subtypes[] = {
- {
- {
- { &ifm_subtype_shared_descriptions[0], 0 },
- { &ifm_subtype_shared_aliases[0], 1 },
- { &ifm_subtype_ethernet_descriptions[0], 0 },
- { &ifm_subtype_ethernet_aliases[0], 1 },
- { NULL, 0 },
- },
- {
- { &ifm_shared_option_descriptions[0], 0 },
- { &ifm_shared_option_aliases[0], 1 },
- { &ifm_subtype_ethernet_option_descriptions[0], 0 },
- { NULL, 0 },
- },
- {
- { NULL, 0 },
- },
- },
- {
- {
- { &ifm_subtype_shared_descriptions[0], 0 },
- { &ifm_subtype_shared_aliases[0], 1 },
- { &ifm_subtype_ieee80211_descriptions[0], 0 },
- { &ifm_subtype_ieee80211_aliases[0], 1 },
- { NULL, 0 },
- },
- {
- { &ifm_shared_option_descriptions[0], 0 },
- { &ifm_shared_option_aliases[0], 1 },
- { &ifm_subtype_ieee80211_option_descriptions[0], 0 },
- { NULL, 0 },
- },
- {
- { &ifm_subtype_ieee80211_mode_descriptions[0], 0 },
- { &ifm_subtype_ieee80211_mode_aliases[0], 0 },
- { NULL, 0 },
- },
- },
- {
- {
- { &ifm_subtype_shared_descriptions[0], 0 },
- { &ifm_subtype_shared_aliases[0], 1 },
- { &ifm_subtype_atm_descriptions[0], 0 },
- { &ifm_subtype_atm_aliases[0], 1 },
- { NULL, 0 },
- },
- {
- { &ifm_shared_option_descriptions[0], 0 },
- { &ifm_shared_option_aliases[0], 1 },
- { &ifm_subtype_atm_option_descriptions[0], 0 },
- { NULL, 0 },
- },
- {
- { NULL, 0 },
- },
- },
-};
-
-static int
-get_media_subtype(int type, const char *val)
+static ifmedia_t
+get_media_subtype(ifmedia_t media, const char *val)
{
- struct ifmedia_description *desc;
- struct ifmedia_type_to_subtype *ttos;
- int rval, i;
-
- /* Find the top-level interface type. */
- for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes;
- desc->ifmt_string != NULL; desc++, ttos++)
- if (type == desc->ifmt_word)
- break;
- if (desc->ifmt_string == NULL)
- errx(1, "unknown media type 0x%x", type);
-
- for (i = 0; ttos->subtypes[i].desc != NULL; i++) {
- rval = lookup_media_word(ttos->subtypes[i].desc, val);
- if (rval != -1)
- return (rval);
+ ifmedia_t subtype;
+
+ subtype = ifconfig_media_lookup_subtype(media, val);
+ if (subtype != INVALID_IFMEDIA)
+ return (subtype);
+ switch (errno) {
+ case EINVAL:
+ errx(EXIT_FAILURE, "unknown media type 0x%x", media);
+ case ENOENT:
+ errx(EXIT_FAILURE, "unknown media subtype: %s", val);
+ default:
+ err(EXIT_FAILURE, "ifconfig_media_lookup_subtype");
}
- errx(1, "unknown media subtype: %s", val);
/*NOTREACHED*/
}
-static int
-get_media_mode(int type, const char *val)
+static ifmedia_t
+get_media_mode(ifmedia_t media, const char *val)
{
- struct ifmedia_description *desc;
- struct ifmedia_type_to_subtype *ttos;
- int rval, i;
-
- /* Find the top-level interface type. */
- for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes;
- desc->ifmt_string != NULL; desc++, ttos++)
- if (type == desc->ifmt_word)
- break;
- if (desc->ifmt_string == NULL)
- errx(1, "unknown media mode 0x%x", type);
-
- for (i = 0; ttos->modes[i].desc != NULL; i++) {
- rval = lookup_media_word(ttos->modes[i].desc, val);
- if (rval != -1)
- return (rval);
+ ifmedia_t mode;
+
+ mode = ifconfig_media_lookup_mode(media, val);
+ if (mode != INVALID_IFMEDIA)
+ return (mode);
+ switch (errno) {
+ case EINVAL:
+ errx(EXIT_FAILURE, "unknown media type 0x%x", media);
+ case ENOENT:
+ return (INVALID_IFMEDIA);
+ default:
+ err(EXIT_FAILURE, "ifconfig_media_lookup_subtype");
}
- return -1;
+ /*NOTREACHED*/
}
-static int
-get_media_options(int type, const char *val)
+static ifmedia_t
+get_media_options(ifmedia_t media, const char *val)
{
- struct ifmedia_description *desc;
- struct ifmedia_type_to_subtype *ttos;
- char *optlist, *optptr;
- int option, i, rval = 0;
-
- /* We muck with the string, so copy it. */
- optlist = strdup(val);
- if (optlist == NULL)
- err(1, "strdup");
-
- /* Find the top-level interface type. */
- for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes;
- desc->ifmt_string != NULL; desc++, ttos++)
- if (type == desc->ifmt_word)
- break;
- if (desc->ifmt_string == NULL)
- errx(1, "unknown media type 0x%x", type);
+ ifmedia_t *options;
+ const char **optnames;
+ char *opts, *opt;
+ size_t nopts;
+ int rval;
/*
- * Look up the options in the user-provided comma-separated
- * list.
+ * We muck with the string, so copy it.
*/
- optptr = optlist;
- for (; (optptr = strtok(optptr, ",")) != NULL; optptr = NULL) {
- option = -1;
- for (i = 0; ttos->options[i].desc != NULL; i++) {
- option = lookup_media_word(ttos->options[i].desc, optptr);
- if (option != -1)
- break;
- }
- if (option == -1)
- errx(1, "unknown option: %s", optptr);
- rval |= option;
- }
-
- free(optlist);
- return (rval);
-}
-
-static int
-lookup_media_word(struct ifmedia_description *desc, const char *val)
-{
-
- for (; desc->ifmt_string != NULL; desc++)
- if (strcasecmp(desc->ifmt_string, val) == 0)
- return (desc->ifmt_word);
-
- return (-1);
-}
-
-static struct ifmedia_description *get_toptype_desc(int ifmw)
-{
- struct ifmedia_description *desc;
-
- for (desc = ifm_type_descriptions; desc->ifmt_string != NULL; desc++)
- if (IFM_TYPE(ifmw) == desc->ifmt_word)
- break;
+ opts = strdup(val);
+ if (opts == NULL)
+ err(EXIT_FAILURE, "strdup");
- return desc;
-}
-
-static struct ifmedia_type_to_subtype *get_toptype_ttos(int ifmw)
-{
- struct ifmedia_description *desc;
- struct ifmedia_type_to_subtype *ttos;
-
- for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes;
- desc->ifmt_string != NULL; desc++, ttos++)
- if (IFM_TYPE(ifmw) == desc->ifmt_word)
- break;
-
- return ttos;
-}
-
-static struct ifmedia_description *get_subtype_desc(int ifmw,
- struct ifmedia_type_to_subtype *ttos)
-{
- int i;
- struct ifmedia_description *desc;
-
- for (i = 0; ttos->subtypes[i].desc != NULL; i++) {
- if (ttos->subtypes[i].alias)
- continue;
- for (desc = ttos->subtypes[i].desc;
- desc->ifmt_string != NULL; desc++) {
- if (IFM_SUBTYPE(ifmw) == desc->ifmt_word)
- return desc;
- }
+ /*
+ * Split the comma-delimited list into separate strings.
+ */
+ nopts = 0;
+ for (opt = opts; (opt = strtok(opt, ",")) != NULL; opt = NULL)
+ ++nopts;
+ if (nopts == 0) {
+ free(opts);
+ return (0);
}
-
- return NULL;
-}
-
-static struct ifmedia_description *get_mode_desc(int ifmw,
- struct ifmedia_type_to_subtype *ttos)
-{
- int i;
- struct ifmedia_description *desc;
-
- for (i = 0; ttos->modes[i].desc != NULL; i++) {
- if (ttos->modes[i].alias)
- continue;
- for (desc = ttos->modes[i].desc;
- desc->ifmt_string != NULL; desc++) {
- if (IFM_MODE(ifmw) == desc->ifmt_word)
- return desc;
- }
+ optnames = calloc(nopts, sizeof(*optnames));
+ if (optnames == NULL)
+ err(EXIT_FAILURE, "calloc");
+ opt = opts;
+ for (size_t i = 0; i < nopts; ++i) {
+ optnames[i] = opt;
+ opt = strchr(opt, '\0') + 1;
}
- return NULL;
+ /*
+ * Look up the options in the user-provided list.
+ */
+ options = ifconfig_media_lookup_options(media, optnames, nopts);
+ if (options == NULL)
+ err(EXIT_FAILURE, "ifconfig_media_lookup_options");
+ rval = 0;
+ for (size_t i = 0; i < nopts; ++i) {
+ if (options[i] == INVALID_IFMEDIA)
+ errx(EXIT_FAILURE, "unknown option: %s", optnames[i]);
+ rval |= options[i];
+ }
+ free(options);
+ free(optnames);
+ free(opts);
+ return (rval);
}
static void
-print_media_word(int ifmw, int print_toptype)
+print_media(ifmedia_t media, bool print_toptype)
{
- struct ifmedia_description *desc;
- struct ifmedia_type_to_subtype *ttos;
- int seen_option = 0, i;
-
- /* Find the top-level interface type. */
- desc = get_toptype_desc(ifmw);
- ttos = get_toptype_ttos(ifmw);
- if (desc->ifmt_string == NULL) {
+ const char *val, **options;
+
+ val = ifconfig_media_get_type(media);
+ if (val == NULL) {
printf("<unknown type>");
return;
} else if (print_toptype) {
- printf("%s", desc->ifmt_string);
+ printf("%s", val);
}
- /*
- * Don't print the top-level type; it's not like we can
- * change it, or anything.
- */
-
- /* Find subtype. */
- desc = get_subtype_desc(ifmw, ttos);
- if (desc == NULL) {
+ val = ifconfig_media_get_subtype(media);
+ if (val == NULL) {
printf("<unknown subtype>");
return;
}
@@ -707,45 +401,34 @@ print_media_word(int ifmw, int print_toptype)
if (print_toptype)
putchar(' ');
- printf("%s", desc->ifmt_string);
+ printf("%s", val);
if (print_toptype) {
- desc = get_mode_desc(ifmw, ttos);
- if (desc != NULL && strcasecmp("autoselect", desc->ifmt_string))
- printf(" mode %s", desc->ifmt_string);
+ val = ifconfig_media_get_mode(media);
+ if (val != NULL && strcasecmp("autoselect", val) != 0)
+ printf(" mode %s", val);
}
- /* Find options. */
- for (i = 0; ttos->options[i].desc != NULL; i++) {
- if (ttos->options[i].alias)
- continue;
- for (desc = ttos->options[i].desc;
- desc->ifmt_string != NULL; desc++) {
- if (ifmw & desc->ifmt_word) {
- if (seen_option == 0)
- printf(" <");
- printf("%s%s", seen_option++ ? "," : "",
- desc->ifmt_string);
- }
- }
+ options = ifconfig_media_get_options(media);
+ if (options != NULL && options[0] != NULL) {
+ printf(" <%s", options[0]);
+ for (size_t i = 1; options[i] != NULL; ++i)
+ printf(",%s", options[i]);
+ printf(">");
}
- printf("%s", seen_option ? ">" : "");
+ free(options);
- if (print_toptype && IFM_INST(ifmw) != 0)
- printf(" instance %d", IFM_INST(ifmw));
+ if (print_toptype && IFM_INST(media) != 0)
+ printf(" instance %d", IFM_INST(media));
}
static void
-print_media_word_ifconfig(int ifmw)
+print_media_ifconfig(ifmedia_t media)
{
- struct ifmedia_description *desc;
- struct ifmedia_type_to_subtype *ttos;
- int seen_option = 0, i;
-
- /* Find the top-level interface type. */
- desc = get_toptype_desc(ifmw);
- ttos = get_toptype_ttos(ifmw);
- if (desc->ifmt_string == NULL) {
+ const char *val, **options;
+
+ val = ifconfig_media_get_type(media);
+ if (val == NULL) {
printf("<unknown type>");
return;
}
@@ -755,36 +438,28 @@ print_media_word_ifconfig(int ifmw)
* change it, or anything.
*/
- /* Find subtype. */
- desc = get_subtype_desc(ifmw, ttos);
- if (desc == NULL) {
+ val = ifconfig_media_get_subtype(media);
+ if (val == NULL) {
printf("<unknown subtype>");
return;
}
- printf("media %s", desc->ifmt_string);
-
- desc = get_mode_desc(ifmw, ttos);
- if (desc != NULL)
- printf(" mode %s", desc->ifmt_string);
-
- /* Find options. */
- for (i = 0; ttos->options[i].desc != NULL; i++) {
- if (ttos->options[i].alias)
- continue;
- for (desc = ttos->options[i].desc;
- desc->ifmt_string != NULL; desc++) {
- if (ifmw & desc->ifmt_word) {
- if (seen_option == 0)
- printf(" mediaopt ");
- printf("%s%s", seen_option++ ? "," : "",
- desc->ifmt_string);
- }
- }
+ printf("media %s", val);
+
+ val = ifconfig_media_get_mode(media);
+ if (val != NULL)
+ printf(" mode %s", val);
+
+ options = ifconfig_media_get_options(media);
+ if (options != NULL && options[0] != NULL) {
+ printf(" mediaopt %s", options[0]);
+ for (size_t i = 1; options[i] != NULL; ++i)
+ printf(",%s", options[i]);
}
+ free(options);
- if (IFM_INST(ifmw) != 0)
- printf(" instance %d", IFM_INST(ifmw));
+ if (IFM_INST(media) != 0)
+ printf(" instance %d", IFM_INST(media));
}
/**********************************************************************