Date: Fri, 19 Mar 2021 13:01:00 GMT From: Ryan Moeller <freqlabs@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: ebee42edc86c - stable/13 - sbin/ifconfig: Get media status with libifconfig Message-ID: <202103191301.12JD10Qp006958@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by freqlabs: URL: https://cgit.FreeBSD.org/src/commit/?id=ebee42edc86c0864d4a9b09ae4dae32cca7a996f commit ebee42edc86c0864d4a9b09ae4dae32cca7a996f Author: Ryan Moeller <freqlabs@FreeBSD.org> AuthorDate: 2021-02-28 20:27:28 +0000 Commit: Ryan Moeller <freqlabs@FreeBSD.org> CommitDate: 2021-03-19 13:00:40 +0000 sbin/ifconfig: Get media status with libifconfig Code deduplication. Reviewed by: kp Differential Revision: https://reviews.freebsd.org/D29030 (cherry picked from commit 2803fa471e77dc8f227fe00bbf075de7feb10022) --- sbin/ifconfig/ifconfig.h | 2 +- sbin/ifconfig/ifieee80211.c | 2 +- sbin/ifconfig/ifmedia.c | 673 ++++++++++++-------------------------------- 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)); } /**********************************************************************
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202103191301.12JD10Qp006958>