diff options
author | Sam Leffler <sam@FreeBSD.org> | 2003-04-28 16:37:38 +0000 |
---|---|---|
committer | Sam Leffler <sam@FreeBSD.org> | 2003-04-28 16:37:38 +0000 |
commit | 4e61f6f1f65699ae41ccc1128227895e7a3e9afa (patch) | |
tree | 8d64b983b644474e55ef4be85ad6afc9522018f1 /sbin/ifconfig/ifmedia.c | |
parent | 1311709a57a34b6b2a9169c3bd3a9fc390e009d0 (diff) | |
download | src-4e61f6f1f65699ae41ccc1128227895e7a3e9afa.tar.gz src-4e61f6f1f65699ae41ccc1128227895e7a3e9afa.zip |
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
Notes
Notes:
svn path=/head/; revision=114164
Diffstat (limited to 'sbin/ifconfig/ifmedia.c')
-rw-r--r-- | sbin/ifconfig/ifmedia.c | 121 |
1 files changed, 118 insertions, 3 deletions
diff --git a/sbin/ifconfig/ifmedia.c b/sbin/ifconfig/ifmedia.c index e6ab5a453756..fe85b14444b9 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) |