summaryrefslogtreecommitdiffstats
path: root/sbin
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2003-04-28 16:37:38 +0000
committersam <sam@FreeBSD.org>2003-04-28 16:37:38 +0000
commit1e1e2faff9349ae3ff2a353151c0f008eb767008 (patch)
tree8d64b983b644474e55ef4be85ad6afc9522018f1 /sbin
parenta37db6668700646e20198e8605d477205a472821 (diff)
downloadFreeBSD-src-1e1e2faff9349ae3ff2a353151c0f008eb767008.zip
FreeBSD-src-1e1e2faff9349ae3ff2a353151c0f008eb767008.tar.gz
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
Diffstat (limited to 'sbin')
-rw-r--r--sbin/ifconfig/ifconfig.c1
-rw-r--r--sbin/ifconfig/ifconfig.h1
-rw-r--r--sbin/ifconfig/ifmedia.c121
3 files changed, 120 insertions, 3 deletions
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)
OpenPOWER on IntegriCloud