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:
parent
1311709a57
commit
4e61f6f1f6
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=114164
@ -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
|
||||
|
@ -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 *);
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user