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
This commit is contained in:
Sam Leffler 2003-04-28 16:37:38 +00:00
parent 1311709a57
commit 4e61f6f1f6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=114164
3 changed files with 120 additions and 3 deletions

View File

@ -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

View File

@ -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 *);

View File

@ -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)