From 1e1e2faff9349ae3ff2a353151c0f008eb767008 Mon Sep 17 00:00:00 2001 From: sam Date: Mon, 28 Apr 2003 16:37:38 +0000 Subject: add a "mode" directive to specify the operating mode for multi-mode devices; this is mostly intended for use with multi-mode 802.11 devices that support some combination of 11a, 11b, and 11g --- sbin/ifconfig/ifconfig.c | 1 + sbin/ifconfig/ifconfig.h | 1 + sbin/ifconfig/ifmedia.c | 121 +++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 120 insertions(+), 3 deletions(-) (limited to 'sbin') diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index ff220194..b174c94 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -236,6 +236,7 @@ struct cmd { { "-monitor", -IFF_MONITOR, setifflags }, #ifdef USE_IF_MEDIA { "media", NEXTARG, setmedia }, + { "mode", NEXTARG, setmediamode }, { "mediaopt", NEXTARG, setmediaopt }, { "-mediaopt", NEXTARG, unsetmediaopt }, #endif diff --git a/sbin/ifconfig/ifconfig.h b/sbin/ifconfig/ifconfig.h index a3aa125..7430c69 100644 --- a/sbin/ifconfig/ifconfig.h +++ b/sbin/ifconfig/ifconfig.h @@ -42,6 +42,7 @@ extern int supmedia; struct afswtch; extern void setmedia(const char *, int, int, const struct afswtch *rafp); +extern void setmediamode(const char *, int, int, const struct afswtch *rafp); extern void setmediaopt(const char *, int, int, const struct afswtch *rafp); extern void unsetmediaopt(const char *, int, int, const struct afswtch *rafp); extern void media_status(int s, struct rt_addrinfo *); diff --git a/sbin/ifconfig/ifmedia.c b/sbin/ifconfig/ifmedia.c index e6ab5a4..fe85b14 100644 --- a/sbin/ifconfig/ifmedia.c +++ b/sbin/ifconfig/ifmedia.c @@ -91,6 +91,7 @@ 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); @@ -220,7 +221,7 @@ setmedia(const char *val, int d, int s, const struct afswtch *afp) IFM_TYPE(first_type) | subtype; if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) < 0) - err(1, "SIOCSIFMEDIA"); + err(1, "SIOCSIFMEDIA (media)"); } void @@ -278,7 +279,49 @@ domediaopt(const char *val, int clear, int s) ifr.ifr_media |= options; if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) < 0) - err(1, "SIOCSIFMEDIA"); + err(1, "SIOCSIFMEDIA (mediaopt)"); +} + + +void +setmediamode(const char *val, int d, int s, const struct afswtch *afp) +{ + struct ifmediareq ifmr; + int *mwords, mode; + + (void) memset(&ifmr, 0, sizeof(ifmr)); + (void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name)); + + /* + * 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, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) + err(1, "SIOCGIFMEDIA"); + + 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 (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) + err(1, "SIOCGIFMEDIA"); + + mode = get_media_mode(IFM_TYPE(mwords[0]), val); + + free(mwords); + + strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); + ifr.ifr_media = ifmr.ifm_current; + ifr.ifr_media = (ifmr.ifm_current & ~IFM_MMASK) | IFM_MAKEMODE(mode); + + if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) < 0) + err(1, "SIOCSIFMEDIA (mode)"); } /********************************************************************** @@ -324,6 +367,9 @@ static struct ifmedia_description 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; + static struct ifmedia_description ifm_subtype_shared_descriptions[] = IFM_SUBTYPE_SHARED_DESCRIPTIONS; @@ -342,6 +388,10 @@ struct ifmedia_type_to_subtype { struct ifmedia_description *desc; int alias; } options[3]; + struct { + struct ifmedia_description *desc; + int alias; + } modes[2]; }; /* must be in the same order as IFM_TYPE_DESCRIPTIONS */ @@ -359,6 +409,9 @@ static struct ifmedia_type_to_subtype ifmedia_types_to_subtypes[] = { { &ifm_subtype_ethernet_option_descriptions[0], 0 }, { NULL, 0 }, }, + { + { NULL, 0 }, + }, }, { { @@ -373,6 +426,9 @@ static struct ifmedia_type_to_subtype ifmedia_types_to_subtypes[] = { { &ifm_subtype_tokenring_option_descriptions[0], 0 }, { NULL, 0 }, }, + { + { NULL, 0 }, + }, }, { { @@ -387,6 +443,9 @@ static struct ifmedia_type_to_subtype ifmedia_types_to_subtypes[] = { { &ifm_subtype_fddi_option_descriptions[0], 0 }, { NULL, 0 }, }, + { + { NULL, 0 }, + }, }, { { @@ -401,6 +460,10 @@ static struct ifmedia_type_to_subtype ifmedia_types_to_subtypes[] = { { &ifm_subtype_ieee80211_option_descriptions[0], 0 }, { NULL, 0 }, }, + { + { &ifm_subtype_ieee80211_mode_descriptions[0], 0 }, + { NULL, 0 }, + }, }, }; @@ -425,7 +488,30 @@ get_media_subtype(int type, const char *val) return (rval); } errx(1, "unknown media subtype: %s", val); - /* NOTREACHED */ + /*NOTREACHED*/ +} + +static int +get_media_mode(int type, 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); + } + return -1; } static int @@ -523,6 +609,25 @@ static struct ifmedia_description *get_subtype_desc(int ifmw, 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; + } + } + + return NULL; +} + static void print_media_word(int ifmw, int print_toptype) { @@ -560,6 +665,12 @@ print_media_word(int ifmw, int print_toptype) printf("%s", desc->ifmt_string); + if (print_toptype) { + 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) @@ -609,6 +720,10 @@ print_media_word_ifconfig(int ifmw) got_subtype: 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) -- cgit v1.1