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 },
|
{ "-monitor", -IFF_MONITOR, setifflags },
|
||||||
#ifdef USE_IF_MEDIA
|
#ifdef USE_IF_MEDIA
|
||||||
{ "media", NEXTARG, setmedia },
|
{ "media", NEXTARG, setmedia },
|
||||||
|
{ "mode", NEXTARG, setmediamode },
|
||||||
{ "mediaopt", NEXTARG, setmediaopt },
|
{ "mediaopt", NEXTARG, setmediaopt },
|
||||||
{ "-mediaopt", NEXTARG, unsetmediaopt },
|
{ "-mediaopt", NEXTARG, unsetmediaopt },
|
||||||
#endif
|
#endif
|
||||||
|
@ -42,6 +42,7 @@ extern int supmedia;
|
|||||||
struct afswtch;
|
struct afswtch;
|
||||||
|
|
||||||
extern void setmedia(const char *, int, int, const struct afswtch *rafp);
|
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 setmediaopt(const char *, int, int, const struct afswtch *rafp);
|
||||||
extern void unsetmediaopt(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 *);
|
extern void media_status(int s, struct rt_addrinfo *);
|
||||||
|
@ -91,6 +91,7 @@
|
|||||||
|
|
||||||
static void domediaopt(const char *, int, int);
|
static void domediaopt(const char *, int, int);
|
||||||
static int get_media_subtype(int, const char *);
|
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 get_media_options(int, const char *);
|
||||||
static int lookup_media_word(struct ifmedia_description *, const char *);
|
static int lookup_media_word(struct ifmedia_description *, const char *);
|
||||||
static void print_media_word(int, int);
|
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;
|
IFM_TYPE(first_type) | subtype;
|
||||||
|
|
||||||
if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) < 0)
|
if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) < 0)
|
||||||
err(1, "SIOCSIFMEDIA");
|
err(1, "SIOCSIFMEDIA (media)");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -278,7 +279,49 @@ domediaopt(const char *val, int clear, int s)
|
|||||||
ifr.ifr_media |= options;
|
ifr.ifr_media |= options;
|
||||||
|
|
||||||
if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) < 0)
|
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[] =
|
static struct ifmedia_description ifm_subtype_ieee80211_option_descriptions[] =
|
||||||
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[] =
|
static struct ifmedia_description ifm_subtype_shared_descriptions[] =
|
||||||
IFM_SUBTYPE_SHARED_DESCRIPTIONS;
|
IFM_SUBTYPE_SHARED_DESCRIPTIONS;
|
||||||
|
|
||||||
@ -342,6 +388,10 @@ struct ifmedia_type_to_subtype {
|
|||||||
struct ifmedia_description *desc;
|
struct ifmedia_description *desc;
|
||||||
int alias;
|
int alias;
|
||||||
} options[3];
|
} options[3];
|
||||||
|
struct {
|
||||||
|
struct ifmedia_description *desc;
|
||||||
|
int alias;
|
||||||
|
} modes[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* must be in the same order as IFM_TYPE_DESCRIPTIONS */
|
/* 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 },
|
{ &ifm_subtype_ethernet_option_descriptions[0], 0 },
|
||||||
{ NULL, 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 },
|
{ &ifm_subtype_tokenring_option_descriptions[0], 0 },
|
||||||
{ NULL, 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 },
|
{ &ifm_subtype_fddi_option_descriptions[0], 0 },
|
||||||
{ NULL, 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 },
|
{ &ifm_subtype_ieee80211_option_descriptions[0], 0 },
|
||||||
{ NULL, 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);
|
return (rval);
|
||||||
}
|
}
|
||||||
errx(1, "unknown media subtype: %s", val);
|
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
|
static int
|
||||||
@ -523,6 +609,25 @@ static struct ifmedia_description *get_subtype_desc(int ifmw,
|
|||||||
return NULL;
|
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
|
static void
|
||||||
print_media_word(int ifmw, int print_toptype)
|
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);
|
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. */
|
/* Find options. */
|
||||||
for (i = 0; ttos->options[i].desc != NULL; i++) {
|
for (i = 0; ttos->options[i].desc != NULL; i++) {
|
||||||
if (ttos->options[i].alias)
|
if (ttos->options[i].alias)
|
||||||
@ -609,6 +720,10 @@ print_media_word_ifconfig(int ifmw)
|
|||||||
got_subtype:
|
got_subtype:
|
||||||
printf("media %s", desc->ifmt_string);
|
printf("media %s", desc->ifmt_string);
|
||||||
|
|
||||||
|
desc = get_mode_desc(ifmw, ttos);
|
||||||
|
if (desc != NULL)
|
||||||
|
printf(" mode %s", desc->ifmt_string);
|
||||||
|
|
||||||
/* Find options. */
|
/* Find options. */
|
||||||
for (i = 0; ttos->options[i].desc != NULL; i++) {
|
for (i = 0; ttos->options[i].desc != NULL; i++) {
|
||||||
if (ttos->options[i].alias)
|
if (ttos->options[i].alias)
|
||||||
|
Loading…
Reference in New Issue
Block a user