1997-05-04 06:22:27 +00:00
|
|
|
/* $NetBSD: ifconfig.c,v 1.34 1997/04/21 01:17:58 lukem Exp $ */
|
1999-08-28 00:22:10 +00:00
|
|
|
/* $FreeBSD$ */
|
1997-05-04 06:22:27 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (c) 1997 Jason R. Thorpe.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
|
|
* must display the following acknowledgement:
|
|
|
|
* This product includes software developed for the NetBSD Project
|
|
|
|
* by Jason R. Thorpe.
|
|
|
|
* 4. The name of the author may not be used to endorse or promote products
|
|
|
|
* derived from this software without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
|
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
|
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
|
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
|
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (c) 1983, 1993
|
|
|
|
* The Regents of the University of California. All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* 4. Neither the name of the University nor the names of its contributors
|
|
|
|
* may be used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/ioctl.h>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <sys/sysctl.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
|
|
|
|
#include <net/if.h>
|
|
|
|
#include <net/if_dl.h>
|
|
|
|
#include <net/if_types.h>
|
|
|
|
#include <net/if_media.h>
|
|
|
|
#include <net/route.h>
|
|
|
|
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <err.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
#include "ifconfig.h"
|
|
|
|
|
2002-04-18 17:14:09 +00:00
|
|
|
static void domediaopt(const char *, int, int);
|
|
|
|
static int get_media_subtype(int, const char *);
|
2003-04-28 16:37:38 +00:00
|
|
|
static int get_media_mode(int, const char *);
|
2002-04-18 17:14:09 +00:00
|
|
|
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);
|
|
|
|
static void print_media_word_ifconfig(int);
|
|
|
|
|
|
|
|
static struct ifmedia_description *get_toptype_desc(int);
|
|
|
|
static struct ifmedia_type_to_subtype *get_toptype_ttos(int);
|
|
|
|
static struct ifmedia_description *get_subtype_desc(int,
|
|
|
|
struct ifmedia_type_to_subtype *ttos);
|
1997-05-04 06:22:27 +00:00
|
|
|
|
2008-04-20 20:35:46 +00:00
|
|
|
#define IFM_OPMODE(x) \
|
|
|
|
((x) & (IFM_IEEE80211_ADHOC | IFM_IEEE80211_HOSTAP | \
|
Implementation of the upcoming Wireless Mesh standard, 802.11s, on the
net80211 wireless stack. This work is based on the March 2009 D3.0 draft
standard. This standard is expected to become final next year.
This includes two main net80211 modules, ieee80211_mesh.c
which deals with peer link management, link metric calculation,
routing table control and mesh configuration and ieee80211_hwmp.c
which deals with the actually routing process on the mesh network.
HWMP is the mandatory routing protocol on by the mesh standard, but
others, such as RA-OLSR, can be implemented.
Authentication and encryption are not implemented.
There are several scripts under tools/tools/net80211/scripts that can be
used to test different mesh network topologies and they also teach you
how to setup a mesh vap (for the impatient: ifconfig wlan0 create
wlandev ... wlanmode mesh).
A new build option is available: IEEE80211_SUPPORT_MESH and it's enabled
by default on GENERIC kernels for i386, amd64, sparc64 and pc98.
Drivers that support mesh networks right now are: ath, ral and mwl.
More information at: http://wiki.freebsd.org/WifiMesh
Please note that this work is experimental. Also, please note that
bridging a mesh vap with another network interface is not yet supported.
Many thanks to the FreeBSD Foundation for sponsoring this project and to
Sam Leffler for his support.
Also, I would like to thank Gateworks Corporation for sending me a
Cambria board which was used during the development of this project.
Reviewed by: sam
Approved by: re (kensmith)
Obtained from: projects/mesh11s
2009-07-11 15:02:45 +00:00
|
|
|
IFM_IEEE80211_IBSS | IFM_IEEE80211_WDS | IFM_IEEE80211_MONITOR | \
|
|
|
|
IFM_IEEE80211_MBSS))
|
2008-04-20 20:35:46 +00:00
|
|
|
#define IFM_IEEE80211_STA 0
|
|
|
|
|
2004-12-08 19:18:07 +00:00
|
|
|
static void
|
2004-12-31 19:46:27 +00:00
|
|
|
media_status(int s)
|
1997-05-04 06:22:27 +00:00
|
|
|
{
|
|
|
|
struct ifmediareq ifmr;
|
|
|
|
int *media_list, i;
|
|
|
|
|
|
|
|
(void) memset(&ifmr, 0, sizeof(ifmr));
|
|
|
|
(void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name));
|
|
|
|
|
|
|
|
if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
|
|
|
|
/*
|
|
|
|
* Interface doesn't support SIOC{G,S}IFMEDIA.
|
|
|
|
*/
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ifmr.ifm_count == 0) {
|
|
|
|
warnx("%s: no media types?", name);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
media_list = (int *)malloc(ifmr.ifm_count * sizeof(int));
|
|
|
|
if (media_list == NULL)
|
|
|
|
err(1, "malloc");
|
|
|
|
ifmr.ifm_ulist = media_list;
|
|
|
|
|
|
|
|
if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0)
|
|
|
|
err(1, "SIOCGIFMEDIA");
|
|
|
|
|
|
|
|
printf("\tmedia: ");
|
2001-05-29 09:13:44 +00:00
|
|
|
print_media_word(ifmr.ifm_current, 1);
|
1997-05-04 06:22:27 +00:00
|
|
|
if (ifmr.ifm_active != ifmr.ifm_current) {
|
|
|
|
putchar(' ');
|
|
|
|
putchar('(');
|
2001-05-29 09:13:44 +00:00
|
|
|
print_media_word(ifmr.ifm_active, 0);
|
1997-05-04 06:22:27 +00:00
|
|
|
putchar(')');
|
|
|
|
}
|
|
|
|
|
2001-05-29 09:13:44 +00:00
|
|
|
putchar('\n');
|
|
|
|
|
1997-05-04 06:22:27 +00:00
|
|
|
if (ifmr.ifm_status & IFM_AVALID) {
|
2001-05-29 09:13:44 +00:00
|
|
|
printf("\tstatus: ");
|
1997-05-04 06:22:27 +00:00
|
|
|
switch (IFM_TYPE(ifmr.ifm_active)) {
|
|
|
|
case IFM_ETHER:
|
2006-08-22 23:49:36 +00:00
|
|
|
case IFM_ATM:
|
1997-05-04 06:22:27 +00:00
|
|
|
if (ifmr.ifm_status & IFM_ACTIVE)
|
|
|
|
printf("active");
|
|
|
|
else
|
|
|
|
printf("no carrier");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IFM_FDDI:
|
|
|
|
case IFM_TOKEN:
|
|
|
|
if (ifmr.ifm_status & IFM_ACTIVE)
|
|
|
|
printf("inserted");
|
|
|
|
else
|
|
|
|
printf("no ring");
|
|
|
|
break;
|
2003-04-29 17:23:23 +00:00
|
|
|
|
2001-05-26 09:27:08 +00:00
|
|
|
case IFM_IEEE80211:
|
2008-04-20 20:35:46 +00:00
|
|
|
if (ifmr.ifm_status & IFM_ACTIVE) {
|
|
|
|
/* NB: only sta mode associates */
|
|
|
|
if (IFM_OPMODE(ifmr.ifm_active) == IFM_IEEE80211_STA)
|
|
|
|
printf("associated");
|
|
|
|
else
|
|
|
|
printf("running");
|
|
|
|
} else
|
2001-05-26 09:27:08 +00:00
|
|
|
printf("no carrier");
|
|
|
|
break;
|
1997-05-04 06:22:27 +00:00
|
|
|
}
|
2001-11-02 02:20:21 +00:00
|
|
|
putchar('\n');
|
1997-05-04 06:22:27 +00:00
|
|
|
}
|
|
|
|
|
2001-05-29 09:13:44 +00:00
|
|
|
if (ifmr.ifm_count > 0 && supmedia) {
|
|
|
|
printf("\tsupported media:\n");
|
1997-05-04 06:22:27 +00:00
|
|
|
for (i = 0; i < ifmr.ifm_count; i++) {
|
2001-05-29 09:13:44 +00:00
|
|
|
printf("\t\t");
|
|
|
|
print_media_word_ifconfig(media_list[i]);
|
|
|
|
putchar('\n');
|
1997-05-04 06:22:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
free(media_list);
|
|
|
|
}
|
|
|
|
|
Update for revised 802.11 support:
o revised channel handling support; ifconfig now queries the kernel to
find the list of available channels and handles channel promotion;
channel attributes can be specified as part of the channel; e.g. 36:a
for channel 36 in 11a (as opposed to turbo A or HT A)
o use channel list to map between freq and IEEE channel #; this eliminates
all knowledge of how the mapping is done and fixes handling of cases
where channels overlap in the IEEE channel # space but are distinct in
the frequency+attributes space (e.g. PSB)
o add new knobs: bgscan, ff (Atheors fast frames), dturbo (Atheros
Dynamic Turbo mode), bgscanidle, bgscanintvl, scanvalid, roam:rssi11a,
roam:rssi11b, roam:rssi11g, roam:rate11a, roam:rate11b, roam:rate11g
(roaming parameters), burst, doth (forthcoming 11h support)
o print contents of WME, ATH, WPA, RSN, information elements with -v option
o print signal strength in dBm
o print noise floor in dBm
o add list txpow to print tx power caps/channel
o change default channel display in status to be more informative
2007-06-11 03:56:33 +00:00
|
|
|
struct ifmediareq *
|
|
|
|
ifmedia_getstate(int s)
|
1997-05-04 06:22:27 +00:00
|
|
|
{
|
2005-01-27 16:40:12 +00:00
|
|
|
static struct ifmediareq *ifmr = NULL;
|
|
|
|
int *mwords;
|
1997-05-04 06:22:27 +00:00
|
|
|
|
2005-01-27 16:40:12 +00:00
|
|
|
if (ifmr == NULL) {
|
|
|
|
ifmr = (struct ifmediareq *)malloc(sizeof(struct ifmediareq));
|
|
|
|
if (ifmr == NULL)
|
|
|
|
err(1, "malloc");
|
|
|
|
|
|
|
|
(void) memset(ifmr, 0, sizeof(struct ifmediareq));
|
|
|
|
(void) strncpy(ifmr->ifm_name, name,
|
|
|
|
sizeof(ifmr->ifm_name));
|
|
|
|
|
|
|
|
ifmr->ifm_count = 0;
|
|
|
|
ifmr->ifm_ulist = NULL;
|
1997-05-04 06:22:27 +00:00
|
|
|
|
|
|
|
/*
|
2005-01-27 16:40:12 +00:00
|
|
|
* 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.
|
1997-05-04 06:22:27 +00:00
|
|
|
*/
|
2005-01-27 16:40:12 +00:00
|
|
|
|
|
|
|
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)
|
1997-05-04 06:22:27 +00:00
|
|
|
err(1, "SIOCGIFMEDIA");
|
|
|
|
}
|
|
|
|
|
2005-01-27 16:40:12 +00:00
|
|
|
return ifmr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
setifmediacallback(int s, void *arg)
|
|
|
|
{
|
|
|
|
struct ifmediareq *ifmr = (struct ifmediareq *)arg;
|
|
|
|
static int did_it = 0;
|
|
|
|
|
|
|
|
if (!did_it) {
|
2006-01-11 22:37:59 +00:00
|
|
|
ifr.ifr_media = ifmr->ifm_current;
|
2005-01-27 16:40:12 +00:00
|
|
|
if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) < 0)
|
|
|
|
err(1, "SIOCSIFMEDIA (media)");
|
|
|
|
free(ifmr->ifm_ulist);
|
|
|
|
free(ifmr);
|
|
|
|
did_it = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
setmedia(const char *val, int d, int s, const struct afswtch *afp)
|
|
|
|
{
|
|
|
|
struct ifmediareq *ifmr;
|
|
|
|
int subtype;
|
|
|
|
|
Update for revised 802.11 support:
o revised channel handling support; ifconfig now queries the kernel to
find the list of available channels and handles channel promotion;
channel attributes can be specified as part of the channel; e.g. 36:a
for channel 36 in 11a (as opposed to turbo A or HT A)
o use channel list to map between freq and IEEE channel #; this eliminates
all knowledge of how the mapping is done and fixes handling of cases
where channels overlap in the IEEE channel # space but are distinct in
the frequency+attributes space (e.g. PSB)
o add new knobs: bgscan, ff (Atheors fast frames), dturbo (Atheros
Dynamic Turbo mode), bgscanidle, bgscanintvl, scanvalid, roam:rssi11a,
roam:rssi11b, roam:rssi11g, roam:rate11a, roam:rate11b, roam:rate11g
(roaming parameters), burst, doth (forthcoming 11h support)
o print contents of WME, ATH, WPA, RSN, information elements with -v option
o print signal strength in dBm
o print noise floor in dBm
o add list txpow to print tx power caps/channel
o change default channel display in status to be more informative
2007-06-11 03:56:33 +00:00
|
|
|
ifmr = ifmedia_getstate(s);
|
1997-05-04 06:22:27 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* We are primarily concerned with the top-level type.
|
|
|
|
* However, "current" may be only IFM_NONE, so we just look
|
|
|
|
* for the top-level type in the first "supported type"
|
|
|
|
* entry.
|
|
|
|
*
|
|
|
|
* (I'm assuming that all supported media types for a given
|
|
|
|
* interface will be the same top-level type..)
|
|
|
|
*/
|
2005-01-27 16:40:12 +00:00
|
|
|
subtype = get_media_subtype(IFM_TYPE(ifmr->ifm_ulist[0]), val);
|
1997-05-04 06:22:27 +00:00
|
|
|
|
|
|
|
strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
|
2011-05-15 12:51:00 +00:00
|
|
|
ifr.ifr_media = (ifmr->ifm_current & IFM_IMASK) |
|
2005-01-27 16:40:12 +00:00
|
|
|
IFM_TYPE(ifmr->ifm_ulist[0]) | subtype;
|
|
|
|
|
|
|
|
ifmr->ifm_current = ifr.ifr_media;
|
|
|
|
callback_register(setifmediacallback, (void *)ifmr);
|
1997-05-04 06:22:27 +00:00
|
|
|
}
|
|
|
|
|
2004-12-08 19:18:07 +00:00
|
|
|
static void
|
2002-04-18 17:14:09 +00:00
|
|
|
setmediaopt(const char *val, int d, int s, const struct afswtch *afp)
|
1997-05-04 06:22:27 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
domediaopt(val, 0, s);
|
|
|
|
}
|
|
|
|
|
2004-12-08 19:18:07 +00:00
|
|
|
static void
|
2002-04-18 17:14:09 +00:00
|
|
|
unsetmediaopt(const char *val, int d, int s, const struct afswtch *afp)
|
1997-05-04 06:22:27 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
domediaopt(val, 1, s);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2002-04-18 17:14:09 +00:00
|
|
|
domediaopt(const char *val, int clear, int s)
|
1997-05-04 06:22:27 +00:00
|
|
|
{
|
2005-01-27 16:40:12 +00:00
|
|
|
struct ifmediareq *ifmr;
|
|
|
|
int options;
|
1997-05-04 06:22:27 +00:00
|
|
|
|
Update for revised 802.11 support:
o revised channel handling support; ifconfig now queries the kernel to
find the list of available channels and handles channel promotion;
channel attributes can be specified as part of the channel; e.g. 36:a
for channel 36 in 11a (as opposed to turbo A or HT A)
o use channel list to map between freq and IEEE channel #; this eliminates
all knowledge of how the mapping is done and fixes handling of cases
where channels overlap in the IEEE channel # space but are distinct in
the frequency+attributes space (e.g. PSB)
o add new knobs: bgscan, ff (Atheors fast frames), dturbo (Atheros
Dynamic Turbo mode), bgscanidle, bgscanintvl, scanvalid, roam:rssi11a,
roam:rssi11b, roam:rssi11g, roam:rate11a, roam:rate11b, roam:rate11g
(roaming parameters), burst, doth (forthcoming 11h support)
o print contents of WME, ATH, WPA, RSN, information elements with -v option
o print signal strength in dBm
o print noise floor in dBm
o add list txpow to print tx power caps/channel
o change default channel display in status to be more informative
2007-06-11 03:56:33 +00:00
|
|
|
ifmr = ifmedia_getstate(s);
|
1997-05-04 06:22:27 +00:00
|
|
|
|
2005-01-27 16:40:12 +00:00
|
|
|
options = get_media_options(IFM_TYPE(ifmr->ifm_ulist[0]), val);
|
1997-05-04 06:22:27 +00:00
|
|
|
|
|
|
|
strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
|
2005-01-27 16:40:12 +00:00
|
|
|
ifr.ifr_media = ifmr->ifm_current;
|
1997-05-04 06:22:27 +00:00
|
|
|
if (clear)
|
|
|
|
ifr.ifr_media &= ~options;
|
2006-12-19 22:50:49 +00:00
|
|
|
else {
|
|
|
|
if (options & IFM_HDX) {
|
|
|
|
ifr.ifr_media &= ~IFM_FDX;
|
|
|
|
options &= ~IFM_HDX;
|
|
|
|
}
|
1997-05-04 06:22:27 +00:00
|
|
|
ifr.ifr_media |= options;
|
2006-12-19 22:50:49 +00:00
|
|
|
}
|
2005-01-27 16:40:12 +00:00
|
|
|
ifmr->ifm_current = ifr.ifr_media;
|
|
|
|
callback_register(setifmediacallback, (void *)ifmr);
|
2003-04-28 16:37:38 +00:00
|
|
|
}
|
|
|
|
|
2007-01-20 00:56:49 +00:00
|
|
|
static void
|
|
|
|
setmediainst(const char *val, int d, int s, const struct afswtch *afp)
|
|
|
|
{
|
|
|
|
struct ifmediareq *ifmr;
|
|
|
|
int inst;
|
|
|
|
|
Update for revised 802.11 support:
o revised channel handling support; ifconfig now queries the kernel to
find the list of available channels and handles channel promotion;
channel attributes can be specified as part of the channel; e.g. 36:a
for channel 36 in 11a (as opposed to turbo A or HT A)
o use channel list to map between freq and IEEE channel #; this eliminates
all knowledge of how the mapping is done and fixes handling of cases
where channels overlap in the IEEE channel # space but are distinct in
the frequency+attributes space (e.g. PSB)
o add new knobs: bgscan, ff (Atheors fast frames), dturbo (Atheros
Dynamic Turbo mode), bgscanidle, bgscanintvl, scanvalid, roam:rssi11a,
roam:rssi11b, roam:rssi11g, roam:rate11a, roam:rate11b, roam:rate11g
(roaming parameters), burst, doth (forthcoming 11h support)
o print contents of WME, ATH, WPA, RSN, information elements with -v option
o print signal strength in dBm
o print noise floor in dBm
o add list txpow to print tx power caps/channel
o change default channel display in status to be more informative
2007-06-11 03:56:33 +00:00
|
|
|
ifmr = ifmedia_getstate(s);
|
2007-01-20 00:56:49 +00:00
|
|
|
|
|
|
|
inst = atoi(val);
|
2009-06-23 23:49:52 +00:00
|
|
|
if (inst < 0 || inst > (int)IFM_INST_MAX)
|
2007-01-20 00:56:49 +00:00
|
|
|
errx(1, "invalid media instance: %s", val);
|
|
|
|
|
|
|
|
strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
|
|
|
|
ifr.ifr_media = (ifmr->ifm_current & ~IFM_IMASK) | inst << IFM_ISHIFT;
|
|
|
|
|
|
|
|
ifmr->ifm_current = ifr.ifr_media;
|
|
|
|
callback_register(setifmediacallback, (void *)ifmr);
|
|
|
|
}
|
2003-04-28 16:37:38 +00:00
|
|
|
|
2004-12-08 19:18:07 +00:00
|
|
|
static void
|
2003-04-28 16:37:38 +00:00
|
|
|
setmediamode(const char *val, int d, int s, const struct afswtch *afp)
|
|
|
|
{
|
2005-01-27 16:40:12 +00:00
|
|
|
struct ifmediareq *ifmr;
|
|
|
|
int mode;
|
2003-04-28 16:37:38 +00:00
|
|
|
|
Update for revised 802.11 support:
o revised channel handling support; ifconfig now queries the kernel to
find the list of available channels and handles channel promotion;
channel attributes can be specified as part of the channel; e.g. 36:a
for channel 36 in 11a (as opposed to turbo A or HT A)
o use channel list to map between freq and IEEE channel #; this eliminates
all knowledge of how the mapping is done and fixes handling of cases
where channels overlap in the IEEE channel # space but are distinct in
the frequency+attributes space (e.g. PSB)
o add new knobs: bgscan, ff (Atheors fast frames), dturbo (Atheros
Dynamic Turbo mode), bgscanidle, bgscanintvl, scanvalid, roam:rssi11a,
roam:rssi11b, roam:rssi11g, roam:rate11a, roam:rate11b, roam:rate11g
(roaming parameters), burst, doth (forthcoming 11h support)
o print contents of WME, ATH, WPA, RSN, information elements with -v option
o print signal strength in dBm
o print noise floor in dBm
o add list txpow to print tx power caps/channel
o change default channel display in status to be more informative
2007-06-11 03:56:33 +00:00
|
|
|
ifmr = ifmedia_getstate(s);
|
2003-04-28 16:37:38 +00:00
|
|
|
|
2005-01-27 16:40:12 +00:00
|
|
|
mode = get_media_mode(IFM_TYPE(ifmr->ifm_ulist[0]), val);
|
2003-04-28 16:37:38 +00:00
|
|
|
|
|
|
|
strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
|
2005-01-27 16:40:12 +00:00
|
|
|
ifr.ifr_media = (ifmr->ifm_current & ~IFM_MMASK) | mode;
|
2003-04-28 16:37:38 +00:00
|
|
|
|
2005-01-27 16:40:12 +00:00
|
|
|
ifmr->ifm_current = ifr.ifr_media;
|
|
|
|
callback_register(setifmediacallback, (void *)ifmr);
|
1997-05-04 06:22:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
|
|
* A good chunk of this is duplicated from sys/net/ifmedia.c
|
|
|
|
**********************************************************************/
|
|
|
|
|
|
|
|
static struct ifmedia_description ifm_type_descriptions[] =
|
|
|
|
IFM_TYPE_DESCRIPTIONS;
|
|
|
|
|
|
|
|
static struct ifmedia_description ifm_subtype_ethernet_descriptions[] =
|
|
|
|
IFM_SUBTYPE_ETHERNET_DESCRIPTIONS;
|
|
|
|
|
|
|
|
static struct ifmedia_description ifm_subtype_ethernet_aliases[] =
|
|
|
|
IFM_SUBTYPE_ETHERNET_ALIASES;
|
|
|
|
|
|
|
|
static struct ifmedia_description ifm_subtype_ethernet_option_descriptions[] =
|
|
|
|
IFM_SUBTYPE_ETHERNET_OPTION_DESCRIPTIONS;
|
|
|
|
|
|
|
|
static struct ifmedia_description ifm_subtype_tokenring_descriptions[] =
|
|
|
|
IFM_SUBTYPE_TOKENRING_DESCRIPTIONS;
|
|
|
|
|
|
|
|
static struct ifmedia_description ifm_subtype_tokenring_aliases[] =
|
|
|
|
IFM_SUBTYPE_TOKENRING_ALIASES;
|
|
|
|
|
|
|
|
static struct ifmedia_description ifm_subtype_tokenring_option_descriptions[] =
|
|
|
|
IFM_SUBTYPE_TOKENRING_OPTION_DESCRIPTIONS;
|
|
|
|
|
|
|
|
static struct ifmedia_description ifm_subtype_fddi_descriptions[] =
|
|
|
|
IFM_SUBTYPE_FDDI_DESCRIPTIONS;
|
|
|
|
|
|
|
|
static struct ifmedia_description ifm_subtype_fddi_aliases[] =
|
|
|
|
IFM_SUBTYPE_FDDI_ALIASES;
|
|
|
|
|
|
|
|
static struct ifmedia_description ifm_subtype_fddi_option_descriptions[] =
|
|
|
|
IFM_SUBTYPE_FDDI_OPTION_DESCRIPTIONS;
|
|
|
|
|
2001-05-26 09:27:08 +00:00
|
|
|
static struct ifmedia_description ifm_subtype_ieee80211_descriptions[] =
|
|
|
|
IFM_SUBTYPE_IEEE80211_DESCRIPTIONS;
|
|
|
|
|
|
|
|
static struct ifmedia_description ifm_subtype_ieee80211_aliases[] =
|
|
|
|
IFM_SUBTYPE_IEEE80211_ALIASES;
|
|
|
|
|
|
|
|
static struct ifmedia_description ifm_subtype_ieee80211_option_descriptions[] =
|
|
|
|
IFM_SUBTYPE_IEEE80211_OPTION_DESCRIPTIONS;
|
|
|
|
|
2003-04-28 16:37:38 +00:00
|
|
|
struct ifmedia_description ifm_subtype_ieee80211_mode_descriptions[] =
|
|
|
|
IFM_SUBTYPE_IEEE80211_MODE_DESCRIPTIONS;
|
|
|
|
|
2003-06-25 15:05:17 +00:00
|
|
|
struct ifmedia_description ifm_subtype_ieee80211_mode_aliases[] =
|
|
|
|
IFM_SUBTYPE_IEEE80211_MODE_ALIASES;
|
|
|
|
|
2003-04-29 17:23:23 +00:00
|
|
|
static struct ifmedia_description ifm_subtype_atm_descriptions[] =
|
|
|
|
IFM_SUBTYPE_ATM_DESCRIPTIONS;
|
|
|
|
|
|
|
|
static struct ifmedia_description ifm_subtype_atm_aliases[] =
|
|
|
|
IFM_SUBTYPE_ATM_ALIASES;
|
|
|
|
|
|
|
|
static struct ifmedia_description ifm_subtype_atm_option_descriptions[] =
|
|
|
|
IFM_SUBTYPE_ATM_OPTION_DESCRIPTIONS;
|
|
|
|
|
1997-05-04 06:22:27 +00:00
|
|
|
static struct ifmedia_description ifm_subtype_shared_descriptions[] =
|
|
|
|
IFM_SUBTYPE_SHARED_DESCRIPTIONS;
|
|
|
|
|
|
|
|
static struct ifmedia_description ifm_subtype_shared_aliases[] =
|
|
|
|
IFM_SUBTYPE_SHARED_ALIASES;
|
|
|
|
|
|
|
|
static struct ifmedia_description ifm_shared_option_descriptions[] =
|
|
|
|
IFM_SHARED_OPTION_DESCRIPTIONS;
|
|
|
|
|
2011-01-05 15:28:30 +00:00
|
|
|
static struct ifmedia_description ifm_shared_option_aliases[] =
|
|
|
|
IFM_SHARED_OPTION_ALIASES;
|
|
|
|
|
1997-05-04 06:22:27 +00:00
|
|
|
struct ifmedia_type_to_subtype {
|
|
|
|
struct {
|
|
|
|
struct ifmedia_description *desc;
|
|
|
|
int alias;
|
|
|
|
} subtypes[5];
|
|
|
|
struct {
|
|
|
|
struct ifmedia_description *desc;
|
|
|
|
int alias;
|
2011-01-05 15:28:30 +00:00
|
|
|
} options[4];
|
2003-04-28 16:37:38 +00:00
|
|
|
struct {
|
|
|
|
struct ifmedia_description *desc;
|
|
|
|
int alias;
|
2003-06-25 15:05:17 +00:00
|
|
|
} modes[3];
|
1997-05-04 06:22:27 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* must be in the same order as IFM_TYPE_DESCRIPTIONS */
|
|
|
|
static struct ifmedia_type_to_subtype ifmedia_types_to_subtypes[] = {
|
|
|
|
{
|
|
|
|
{
|
|
|
|
{ &ifm_subtype_shared_descriptions[0], 0 },
|
|
|
|
{ &ifm_subtype_shared_aliases[0], 1 },
|
|
|
|
{ &ifm_subtype_ethernet_descriptions[0], 0 },
|
|
|
|
{ &ifm_subtype_ethernet_aliases[0], 1 },
|
|
|
|
{ NULL, 0 },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{ &ifm_shared_option_descriptions[0], 0 },
|
2011-01-05 15:28:30 +00:00
|
|
|
{ &ifm_shared_option_aliases[0], 1 },
|
2001-05-26 09:27:08 +00:00
|
|
|
{ &ifm_subtype_ethernet_option_descriptions[0], 0 },
|
1997-05-04 06:22:27 +00:00
|
|
|
{ NULL, 0 },
|
|
|
|
},
|
2003-04-28 16:37:38 +00:00
|
|
|
{
|
|
|
|
{ NULL, 0 },
|
|
|
|
},
|
1997-05-04 06:22:27 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
{
|
|
|
|
{ &ifm_subtype_shared_descriptions[0], 0 },
|
|
|
|
{ &ifm_subtype_shared_aliases[0], 1 },
|
|
|
|
{ &ifm_subtype_tokenring_descriptions[0], 0 },
|
|
|
|
{ &ifm_subtype_tokenring_aliases[0], 1 },
|
|
|
|
{ NULL, 0 },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{ &ifm_shared_option_descriptions[0], 0 },
|
2011-01-05 15:28:30 +00:00
|
|
|
{ &ifm_shared_option_aliases[0], 1 },
|
2001-05-26 09:27:08 +00:00
|
|
|
{ &ifm_subtype_tokenring_option_descriptions[0], 0 },
|
1997-05-04 06:22:27 +00:00
|
|
|
{ NULL, 0 },
|
|
|
|
},
|
2003-04-28 16:37:38 +00:00
|
|
|
{
|
|
|
|
{ NULL, 0 },
|
|
|
|
},
|
1997-05-04 06:22:27 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
{
|
|
|
|
{ &ifm_subtype_shared_descriptions[0], 0 },
|
|
|
|
{ &ifm_subtype_shared_aliases[0], 1 },
|
|
|
|
{ &ifm_subtype_fddi_descriptions[0], 0 },
|
|
|
|
{ &ifm_subtype_fddi_aliases[0], 1 },
|
|
|
|
{ NULL, 0 },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{ &ifm_shared_option_descriptions[0], 0 },
|
2011-01-05 15:28:30 +00:00
|
|
|
{ &ifm_shared_option_aliases[0], 1 },
|
2001-05-26 09:27:08 +00:00
|
|
|
{ &ifm_subtype_fddi_option_descriptions[0], 0 },
|
|
|
|
{ NULL, 0 },
|
|
|
|
},
|
2003-04-28 16:37:38 +00:00
|
|
|
{
|
|
|
|
{ NULL, 0 },
|
|
|
|
},
|
2001-05-26 09:27:08 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
{
|
|
|
|
{ &ifm_subtype_shared_descriptions[0], 0 },
|
|
|
|
{ &ifm_subtype_shared_aliases[0], 1 },
|
|
|
|
{ &ifm_subtype_ieee80211_descriptions[0], 0 },
|
|
|
|
{ &ifm_subtype_ieee80211_aliases[0], 1 },
|
|
|
|
{ NULL, 0 },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{ &ifm_shared_option_descriptions[0], 0 },
|
2011-01-05 15:28:30 +00:00
|
|
|
{ &ifm_shared_option_aliases[0], 1 },
|
2001-05-26 09:27:08 +00:00
|
|
|
{ &ifm_subtype_ieee80211_option_descriptions[0], 0 },
|
1997-05-04 06:22:27 +00:00
|
|
|
{ NULL, 0 },
|
|
|
|
},
|
2003-04-28 16:37:38 +00:00
|
|
|
{
|
|
|
|
{ &ifm_subtype_ieee80211_mode_descriptions[0], 0 },
|
2003-06-25 15:05:17 +00:00
|
|
|
{ &ifm_subtype_ieee80211_mode_aliases[0], 0 },
|
2003-04-28 16:37:38 +00:00
|
|
|
{ NULL, 0 },
|
|
|
|
},
|
1997-05-04 06:22:27 +00:00
|
|
|
},
|
2003-04-29 17:23:23 +00:00
|
|
|
{
|
|
|
|
{
|
|
|
|
{ &ifm_subtype_shared_descriptions[0], 0 },
|
|
|
|
{ &ifm_subtype_shared_aliases[0], 1 },
|
|
|
|
{ &ifm_subtype_atm_descriptions[0], 0 },
|
|
|
|
{ &ifm_subtype_atm_aliases[0], 1 },
|
|
|
|
{ NULL, 0 },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{ &ifm_shared_option_descriptions[0], 0 },
|
2011-01-05 15:28:30 +00:00
|
|
|
{ &ifm_shared_option_aliases[0], 1 },
|
2003-04-29 17:23:23 +00:00
|
|
|
{ &ifm_subtype_atm_option_descriptions[0], 0 },
|
|
|
|
{ NULL, 0 },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{ NULL, 0 },
|
|
|
|
},
|
|
|
|
},
|
1997-05-04 06:22:27 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static int
|
2002-04-18 17:14:09 +00:00
|
|
|
get_media_subtype(int type, const char *val)
|
1997-05-04 06:22:27 +00:00
|
|
|
{
|
|
|
|
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 type 0x%x", type);
|
|
|
|
|
|
|
|
for (i = 0; ttos->subtypes[i].desc != NULL; i++) {
|
|
|
|
rval = lookup_media_word(ttos->subtypes[i].desc, val);
|
|
|
|
if (rval != -1)
|
|
|
|
return (rval);
|
|
|
|
}
|
|
|
|
errx(1, "unknown media subtype: %s", val);
|
2003-04-28 16:37:38 +00:00
|
|
|
/*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;
|
1997-05-04 06:22:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2002-04-18 17:14:09 +00:00
|
|
|
get_media_options(int type, const char *val)
|
1997-05-04 06:22:27 +00:00
|
|
|
{
|
|
|
|
struct ifmedia_description *desc;
|
|
|
|
struct ifmedia_type_to_subtype *ttos;
|
|
|
|
char *optlist, *optptr;
|
|
|
|
int option = 0, i, rval = 0;
|
|
|
|
|
|
|
|
/* We muck with the string, so copy it. */
|
|
|
|
optlist = strdup(val);
|
|
|
|
if (optlist == NULL)
|
|
|
|
err(1, "strdup");
|
|
|
|
|
|
|
|
/* 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 type 0x%x", type);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Look up the options in the user-provided comma-separated
|
|
|
|
* list.
|
|
|
|
*/
|
|
|
|
optptr = optlist;
|
|
|
|
for (; (optptr = strtok(optptr, ",")) != NULL; optptr = NULL) {
|
|
|
|
for (i = 0; ttos->options[i].desc != NULL; i++) {
|
|
|
|
option = lookup_media_word(ttos->options[i].desc, optptr);
|
|
|
|
if (option != -1)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (option == 0)
|
|
|
|
errx(1, "unknown option: %s", optptr);
|
|
|
|
rval |= option;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(optlist);
|
|
|
|
return (rval);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2002-04-18 17:14:09 +00:00
|
|
|
lookup_media_word(struct ifmedia_description *desc, const char *val)
|
1997-05-04 06:22:27 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
for (; desc->ifmt_string != NULL; desc++)
|
|
|
|
if (strcasecmp(desc->ifmt_string, val) == 0)
|
|
|
|
return (desc->ifmt_word);
|
|
|
|
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
|
2002-04-18 17:14:09 +00:00
|
|
|
static struct ifmedia_description *get_toptype_desc(int ifmw)
|
2001-05-29 09:13:44 +00:00
|
|
|
{
|
|
|
|
struct ifmedia_description *desc;
|
|
|
|
|
|
|
|
for (desc = ifm_type_descriptions; desc->ifmt_string != NULL; desc++)
|
|
|
|
if (IFM_TYPE(ifmw) == desc->ifmt_word)
|
|
|
|
break;
|
|
|
|
|
|
|
|
return desc;
|
|
|
|
}
|
|
|
|
|
2002-04-18 17:14:09 +00:00
|
|
|
static struct ifmedia_type_to_subtype *get_toptype_ttos(int ifmw)
|
1997-05-04 06:22:27 +00:00
|
|
|
{
|
|
|
|
struct ifmedia_description *desc;
|
|
|
|
struct ifmedia_type_to_subtype *ttos;
|
|
|
|
|
|
|
|
for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes;
|
|
|
|
desc->ifmt_string != NULL; desc++, ttos++)
|
|
|
|
if (IFM_TYPE(ifmw) == desc->ifmt_word)
|
|
|
|
break;
|
2001-05-29 09:13:44 +00:00
|
|
|
|
|
|
|
return ttos;
|
|
|
|
}
|
|
|
|
|
2002-04-18 17:14:09 +00:00
|
|
|
static struct ifmedia_description *get_subtype_desc(int ifmw,
|
|
|
|
struct ifmedia_type_to_subtype *ttos)
|
2001-05-29 09:13:44 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
struct ifmedia_description *desc;
|
|
|
|
|
|
|
|
for (i = 0; ttos->subtypes[i].desc != NULL; i++) {
|
|
|
|
if (ttos->subtypes[i].alias)
|
|
|
|
continue;
|
|
|
|
for (desc = ttos->subtypes[i].desc;
|
|
|
|
desc->ifmt_string != NULL; desc++) {
|
|
|
|
if (IFM_SUBTYPE(ifmw) == desc->ifmt_word)
|
|
|
|
return desc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2003-04-28 16:37:38 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2001-05-29 09:13:44 +00:00
|
|
|
static void
|
2002-04-18 17:14:09 +00:00
|
|
|
print_media_word(int ifmw, int print_toptype)
|
2001-05-29 09:13:44 +00:00
|
|
|
{
|
|
|
|
struct ifmedia_description *desc;
|
|
|
|
struct ifmedia_type_to_subtype *ttos;
|
|
|
|
int seen_option = 0, i;
|
|
|
|
|
|
|
|
/* Find the top-level interface type. */
|
|
|
|
desc = get_toptype_desc(ifmw);
|
|
|
|
ttos = get_toptype_ttos(ifmw);
|
1997-05-04 06:22:27 +00:00
|
|
|
if (desc->ifmt_string == NULL) {
|
|
|
|
printf("<unknown type>");
|
|
|
|
return;
|
2001-05-29 09:13:44 +00:00
|
|
|
} else if (print_toptype) {
|
|
|
|
printf("%s", desc->ifmt_string);
|
1997-05-04 06:22:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Don't print the top-level type; it's not like we can
|
|
|
|
* change it, or anything.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Find subtype. */
|
2001-05-29 09:13:44 +00:00
|
|
|
desc = get_subtype_desc(ifmw, ttos);
|
2006-08-22 23:49:36 +00:00
|
|
|
if (desc == NULL) {
|
|
|
|
printf("<unknown subtype>");
|
|
|
|
return;
|
|
|
|
}
|
1997-05-04 06:22:27 +00:00
|
|
|
|
2001-05-29 09:13:44 +00:00
|
|
|
if (print_toptype)
|
|
|
|
putchar(' ');
|
|
|
|
|
1997-05-04 06:22:27 +00:00
|
|
|
printf("%s", desc->ifmt_string);
|
|
|
|
|
2003-04-28 16:37:38 +00:00
|
|
|
if (print_toptype) {
|
|
|
|
desc = get_mode_desc(ifmw, ttos);
|
2003-06-25 15:05:17 +00:00
|
|
|
if (desc != NULL && strcasecmp("autoselect", desc->ifmt_string))
|
2003-04-28 16:37:38 +00:00
|
|
|
printf(" mode %s", desc->ifmt_string);
|
|
|
|
}
|
|
|
|
|
1997-05-04 06:22:27 +00:00
|
|
|
/* Find options. */
|
|
|
|
for (i = 0; ttos->options[i].desc != NULL; i++) {
|
|
|
|
if (ttos->options[i].alias)
|
|
|
|
continue;
|
|
|
|
for (desc = ttos->options[i].desc;
|
|
|
|
desc->ifmt_string != NULL; desc++) {
|
|
|
|
if (ifmw & desc->ifmt_word) {
|
|
|
|
if (seen_option == 0)
|
|
|
|
printf(" <");
|
|
|
|
printf("%s%s", seen_option++ ? "," : "",
|
|
|
|
desc->ifmt_string);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
printf("%s", seen_option ? ">" : "");
|
2007-01-20 00:56:49 +00:00
|
|
|
|
2007-01-22 13:42:07 +00:00
|
|
|
if (print_toptype && IFM_INST(ifmw) != 0)
|
2007-01-20 00:56:49 +00:00
|
|
|
printf(" instance %d", IFM_INST(ifmw));
|
1997-05-04 06:22:27 +00:00
|
|
|
}
|
|
|
|
|
2001-05-29 09:13:44 +00:00
|
|
|
static void
|
2002-04-18 17:14:09 +00:00
|
|
|
print_media_word_ifconfig(int ifmw)
|
2001-05-29 09:13:44 +00:00
|
|
|
{
|
|
|
|
struct ifmedia_description *desc;
|
|
|
|
struct ifmedia_type_to_subtype *ttos;
|
2010-11-13 21:03:19 +00:00
|
|
|
int seen_option = 0, i;
|
2001-05-29 09:13:44 +00:00
|
|
|
|
|
|
|
/* Find the top-level interface type. */
|
|
|
|
desc = get_toptype_desc(ifmw);
|
|
|
|
ttos = get_toptype_ttos(ifmw);
|
|
|
|
if (desc->ifmt_string == NULL) {
|
|
|
|
printf("<unknown type>");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Don't print the top-level type; it's not like we can
|
|
|
|
* change it, or anything.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Find subtype. */
|
|
|
|
desc = get_subtype_desc(ifmw, ttos);
|
2006-08-22 23:49:36 +00:00
|
|
|
if (desc == NULL) {
|
|
|
|
printf("<unknown subtype>");
|
|
|
|
return;
|
|
|
|
}
|
2001-05-29 09:13:44 +00:00
|
|
|
|
|
|
|
printf("media %s", desc->ifmt_string);
|
|
|
|
|
2003-04-28 16:37:38 +00:00
|
|
|
desc = get_mode_desc(ifmw, ttos);
|
|
|
|
if (desc != NULL)
|
|
|
|
printf(" mode %s", desc->ifmt_string);
|
|
|
|
|
2001-05-29 09:13:44 +00:00
|
|
|
/* Find options. */
|
|
|
|
for (i = 0; ttos->options[i].desc != NULL; i++) {
|
|
|
|
if (ttos->options[i].alias)
|
|
|
|
continue;
|
|
|
|
for (desc = ttos->options[i].desc;
|
|
|
|
desc->ifmt_string != NULL; desc++) {
|
|
|
|
if (ifmw & desc->ifmt_word) {
|
2010-11-13 21:03:19 +00:00
|
|
|
if (seen_option == 0)
|
|
|
|
printf(" mediaopt ");
|
|
|
|
printf("%s%s", seen_option++ ? "," : "",
|
|
|
|
desc->ifmt_string);
|
2001-05-29 09:13:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-01-20 00:56:49 +00:00
|
|
|
|
2007-01-22 13:42:07 +00:00
|
|
|
if (IFM_INST(ifmw) != 0)
|
|
|
|
printf(" instance %d", IFM_INST(ifmw));
|
2001-05-29 09:13:44 +00:00
|
|
|
}
|
|
|
|
|
1997-05-04 06:22:27 +00:00
|
|
|
/**********************************************************************
|
|
|
|
* ...until here.
|
|
|
|
**********************************************************************/
|
2004-12-08 19:18:07 +00:00
|
|
|
|
|
|
|
static struct cmd media_cmds[] = {
|
|
|
|
DEF_CMD_ARG("media", setmedia),
|
|
|
|
DEF_CMD_ARG("mode", setmediamode),
|
|
|
|
DEF_CMD_ARG("mediaopt", setmediaopt),
|
|
|
|
DEF_CMD_ARG("-mediaopt",unsetmediaopt),
|
2007-01-20 00:56:49 +00:00
|
|
|
DEF_CMD_ARG("inst", setmediainst),
|
|
|
|
DEF_CMD_ARG("instance", setmediainst),
|
2004-12-08 19:18:07 +00:00
|
|
|
};
|
|
|
|
static struct afswtch af_media = {
|
|
|
|
.af_name = "af_media",
|
|
|
|
.af_af = AF_UNSPEC,
|
2004-12-31 19:46:27 +00:00
|
|
|
.af_other_status = media_status,
|
2004-12-08 19:18:07 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static __constructor void
|
|
|
|
ifmedia_ctor(void)
|
|
|
|
{
|
|
|
|
#define N(a) (sizeof(a) / sizeof(a[0]))
|
2009-06-23 23:49:52 +00:00
|
|
|
size_t i;
|
2004-12-08 19:18:07 +00:00
|
|
|
|
|
|
|
for (i = 0; i < N(media_cmds); i++)
|
|
|
|
cmd_register(&media_cmds[i]);
|
|
|
|
af_register(&af_media);
|
|
|
|
#undef N
|
|
|
|
}
|