ifmedia.c revision 114232
125450Speter/* $NetBSD: ifconfig.c,v 1.34 1997/04/21 01:17:58 lukem Exp $ */ 250476Speter/* $FreeBSD: head/sbin/ifconfig/ifmedia.c 114232 2003-04-29 17:23:23Z harti $ */ 325450Speter 425450Speter/* 525450Speter * Copyright (c) 1997 Jason R. Thorpe. 625450Speter * All rights reserved. 725450Speter * 825450Speter * Redistribution and use in source and binary forms, with or without 925450Speter * modification, are permitted provided that the following conditions 1025450Speter * are met: 1125450Speter * 1. Redistributions of source code must retain the above copyright 1225450Speter * notice, this list of conditions and the following disclaimer. 1325450Speter * 2. Redistributions in binary form must reproduce the above copyright 1425450Speter * notice, this list of conditions and the following disclaimer in the 1525450Speter * documentation and/or other materials provided with the distribution. 1625450Speter * 3. All advertising materials mentioning features or use of this software 1725450Speter * must display the following acknowledgement: 1825450Speter * This product includes software developed for the NetBSD Project 1925450Speter * by Jason R. Thorpe. 2025450Speter * 4. The name of the author may not be used to endorse or promote products 2125450Speter * derived from this software without specific prior written permission. 2225450Speter * 2325450Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2425450Speter * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2525450Speter * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2625450Speter * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2725450Speter * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 2825450Speter * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 2925450Speter * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 3025450Speter * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 3125450Speter * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3225450Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3325450Speter * SUCH DAMAGE. 3425450Speter */ 3525450Speter 3625450Speter/* 3725450Speter * Copyright (c) 1983, 1993 3825450Speter * The Regents of the University of California. All rights reserved. 3925450Speter * 4025450Speter * Redistribution and use in source and binary forms, with or without 4125450Speter * modification, are permitted provided that the following conditions 4225450Speter * are met: 4325450Speter * 1. Redistributions of source code must retain the above copyright 4425450Speter * notice, this list of conditions and the following disclaimer. 4525450Speter * 2. Redistributions in binary form must reproduce the above copyright 4625450Speter * notice, this list of conditions and the following disclaimer in the 4725450Speter * documentation and/or other materials provided with the distribution. 4825450Speter * 3. All advertising materials mentioning features or use of this software 4925450Speter * must display the following acknowledgement: 5025450Speter * This product includes software developed by the University of 5125450Speter * California, Berkeley and its contributors. 5225450Speter * 4. Neither the name of the University nor the names of its contributors 5325450Speter * may be used to endorse or promote products derived from this software 5425450Speter * without specific prior written permission. 5525450Speter * 5625450Speter * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 5725450Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 5825450Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 5925450Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 6025450Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 6125450Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 6225450Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 6325450Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 6425450Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 6525450Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 6625450Speter * SUCH DAMAGE. 6725450Speter */ 6825450Speter 6925450Speter#include <sys/param.h> 7025450Speter#include <sys/ioctl.h> 7125450Speter#include <sys/socket.h> 7225450Speter#include <sys/sysctl.h> 7325450Speter#include <sys/time.h> 7425450Speter 7525450Speter#include <net/if.h> 7625450Speter#include <net/if_dl.h> 7725450Speter#include <net/if_types.h> 7825450Speter#include <net/if_media.h> 7925450Speter#include <net/route.h> 8025450Speter 8125450Speter#include <ctype.h> 8225450Speter#include <err.h> 8325450Speter#include <errno.h> 8425450Speter#include <fcntl.h> 8525450Speter#include <stdio.h> 8625450Speter#include <stdlib.h> 8725450Speter#include <string.h> 8825450Speter#include <unistd.h> 8925450Speter 9025450Speter#include "ifconfig.h" 9125450Speter 9295005Simpstatic void domediaopt(const char *, int, int); 9395005Simpstatic int get_media_subtype(int, const char *); 94114164Ssamstatic int get_media_mode(int, const char *); 9595005Simpstatic int get_media_options(int, const char *); 9695005Simpstatic int lookup_media_word(struct ifmedia_description *, const char *); 9795005Simpstatic void print_media_word(int, int); 9895005Simpstatic void print_media_word_ifconfig(int); 9925450Speter 10095005Simpstatic struct ifmedia_description *get_toptype_desc(int); 10195005Simpstatic struct ifmedia_type_to_subtype *get_toptype_ttos(int); 10295005Simpstatic struct ifmedia_description *get_subtype_desc(int, 10395005Simp struct ifmedia_type_to_subtype *ttos); 10477385Sphk 10525450Spetervoid 10695005Simpmedia_status(int s, struct rt_addrinfo *info __unused) 10725450Speter{ 10825450Speter struct ifmediareq ifmr; 10925450Speter int *media_list, i; 11025450Speter 11125450Speter (void) memset(&ifmr, 0, sizeof(ifmr)); 11225450Speter (void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name)); 11325450Speter 11425450Speter if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) { 11525450Speter /* 11625450Speter * Interface doesn't support SIOC{G,S}IFMEDIA. 11725450Speter */ 11825450Speter return; 11925450Speter } 12025450Speter 12125450Speter if (ifmr.ifm_count == 0) { 12225450Speter warnx("%s: no media types?", name); 12325450Speter return; 12425450Speter } 12525450Speter 12625450Speter media_list = (int *)malloc(ifmr.ifm_count * sizeof(int)); 12725450Speter if (media_list == NULL) 12825450Speter err(1, "malloc"); 12925450Speter ifmr.ifm_ulist = media_list; 13025450Speter 13125450Speter if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) 13225450Speter err(1, "SIOCGIFMEDIA"); 13325450Speter 13425450Speter printf("\tmedia: "); 13577385Sphk print_media_word(ifmr.ifm_current, 1); 13625450Speter if (ifmr.ifm_active != ifmr.ifm_current) { 13725450Speter putchar(' '); 13825450Speter putchar('('); 13977385Sphk print_media_word(ifmr.ifm_active, 0); 14025450Speter putchar(')'); 14125450Speter } 14225450Speter 14377385Sphk putchar('\n'); 14477385Sphk 14525450Speter if (ifmr.ifm_status & IFM_AVALID) { 14677385Sphk printf("\tstatus: "); 14725450Speter switch (IFM_TYPE(ifmr.ifm_active)) { 14825450Speter case IFM_ETHER: 14925450Speter if (ifmr.ifm_status & IFM_ACTIVE) 15025450Speter printf("active"); 15125450Speter else 15225450Speter printf("no carrier"); 15325450Speter break; 15425450Speter 15525450Speter case IFM_FDDI: 15625450Speter case IFM_TOKEN: 15725450Speter if (ifmr.ifm_status & IFM_ACTIVE) 15825450Speter printf("inserted"); 15925450Speter else 16025450Speter printf("no ring"); 16125450Speter break; 162114232Sharti 163114232Sharti case IFM_ATM: 164114232Sharti if (ifmr.ifm_status & IFM_ACTIVE) 165114232Sharti printf("active"); 166114232Sharti else 167114232Sharti printf("no carrier"); 168114232Sharti break; 169114232Sharti 17077217Sphk case IFM_IEEE80211: 17177217Sphk /* XXX: Different value for adhoc? */ 17277217Sphk if (ifmr.ifm_status & IFM_ACTIVE) 17377217Sphk printf("associated"); 17477217Sphk else 17577217Sphk printf("no carrier"); 17677217Sphk break; 17725450Speter } 17885853Syar putchar('\n'); 17925450Speter } 18025450Speter 18177385Sphk if (ifmr.ifm_count > 0 && supmedia) { 18277385Sphk printf("\tsupported media:\n"); 18325450Speter for (i = 0; i < ifmr.ifm_count; i++) { 18477385Sphk printf("\t\t"); 18577385Sphk print_media_word_ifconfig(media_list[i]); 18677385Sphk putchar('\n'); 18725450Speter } 18825450Speter } 18925450Speter 19025450Speter free(media_list); 19125450Speter} 19225450Speter 19325450Spetervoid 19495005Simpsetmedia(const char *val, int d, int s, const struct afswtch *afp) 19525450Speter{ 19625450Speter struct ifmediareq ifmr; 19725450Speter int first_type, subtype; 19825450Speter 19925450Speter (void) memset(&ifmr, 0, sizeof(ifmr)); 20025450Speter (void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name)); 20125450Speter 20225450Speter ifmr.ifm_count = 1; 20325450Speter ifmr.ifm_ulist = &first_type; 20425450Speter if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) { 20525450Speter /* 20625450Speter * If we get E2BIG, the kernel is telling us 20725450Speter * that there are more, so we can ignore it. 20825450Speter */ 20925450Speter if (errno != E2BIG) 21025450Speter err(1, "SIOCGIFMEDIA"); 21125450Speter } 21225450Speter 21325450Speter if (ifmr.ifm_count == 0) 21425450Speter errx(1, "%s: no media types?", name); 21525450Speter 21625450Speter /* 21725450Speter * We are primarily concerned with the top-level type. 21825450Speter * However, "current" may be only IFM_NONE, so we just look 21925450Speter * for the top-level type in the first "supported type" 22025450Speter * entry. 22125450Speter * 22225450Speter * (I'm assuming that all supported media types for a given 22325450Speter * interface will be the same top-level type..) 22425450Speter */ 22525450Speter subtype = get_media_subtype(IFM_TYPE(first_type), val); 22625450Speter 22725450Speter strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 22825450Speter ifr.ifr_media = (ifmr.ifm_current & ~(IFM_NMASK|IFM_TMASK)) | 22925450Speter IFM_TYPE(first_type) | subtype; 23025450Speter 23125450Speter if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) < 0) 232114164Ssam err(1, "SIOCSIFMEDIA (media)"); 23325450Speter} 23425450Speter 23525450Spetervoid 23695005Simpsetmediaopt(const char *val, int d, int s, const struct afswtch *afp) 23725450Speter{ 23825450Speter 23925450Speter domediaopt(val, 0, s); 24025450Speter} 24125450Speter 24225450Spetervoid 24395005Simpunsetmediaopt(const char *val, int d, int s, const struct afswtch *afp) 24425450Speter{ 24525450Speter 24625450Speter domediaopt(val, 1, s); 24725450Speter} 24825450Speter 24925450Speterstatic void 25095005Simpdomediaopt(const char *val, int clear, int s) 25125450Speter{ 25225450Speter struct ifmediareq ifmr; 25325450Speter int *mwords, options; 25425450Speter 25525450Speter (void) memset(&ifmr, 0, sizeof(ifmr)); 25625450Speter (void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name)); 25725450Speter 25825450Speter /* 25925450Speter * We must go through the motions of reading all 26025450Speter * supported media because we need to know both 26125450Speter * the current media type and the top-level type. 26225450Speter */ 26325450Speter 26425450Speter if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) 26525450Speter err(1, "SIOCGIFMEDIA"); 26625450Speter 26725450Speter if (ifmr.ifm_count == 0) 26825450Speter errx(1, "%s: no media types?", name); 26925450Speter 27025450Speter mwords = (int *)malloc(ifmr.ifm_count * sizeof(int)); 27125450Speter if (mwords == NULL) 27225450Speter err(1, "malloc"); 27325450Speter 27425450Speter ifmr.ifm_ulist = mwords; 27525450Speter if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) 27625450Speter err(1, "SIOCGIFMEDIA"); 27725450Speter 27825450Speter options = get_media_options(IFM_TYPE(mwords[0]), val); 27925450Speter 28025450Speter free(mwords); 28125450Speter 28225450Speter strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 28325450Speter ifr.ifr_media = ifmr.ifm_current; 28425450Speter if (clear) 28525450Speter ifr.ifr_media &= ~options; 28625450Speter else 28725450Speter ifr.ifr_media |= options; 28825450Speter 28925450Speter if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) < 0) 290114164Ssam err(1, "SIOCSIFMEDIA (mediaopt)"); 29125450Speter} 29225450Speter 293114164Ssam 294114164Ssamvoid 295114164Ssamsetmediamode(const char *val, int d, int s, const struct afswtch *afp) 296114164Ssam{ 297114164Ssam struct ifmediareq ifmr; 298114164Ssam int *mwords, mode; 299114164Ssam 300114164Ssam (void) memset(&ifmr, 0, sizeof(ifmr)); 301114164Ssam (void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name)); 302114164Ssam 303114164Ssam /* 304114164Ssam * We must go through the motions of reading all 305114164Ssam * supported media because we need to know both 306114164Ssam * the current media type and the top-level type. 307114164Ssam */ 308114164Ssam 309114164Ssam if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) 310114164Ssam err(1, "SIOCGIFMEDIA"); 311114164Ssam 312114164Ssam if (ifmr.ifm_count == 0) 313114164Ssam errx(1, "%s: no media types?", name); 314114164Ssam 315114164Ssam mwords = (int *)malloc(ifmr.ifm_count * sizeof(int)); 316114164Ssam if (mwords == NULL) 317114164Ssam err(1, "malloc"); 318114164Ssam 319114164Ssam ifmr.ifm_ulist = mwords; 320114164Ssam if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) 321114164Ssam err(1, "SIOCGIFMEDIA"); 322114164Ssam 323114164Ssam mode = get_media_mode(IFM_TYPE(mwords[0]), val); 324114164Ssam 325114164Ssam free(mwords); 326114164Ssam 327114164Ssam strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 328114164Ssam ifr.ifr_media = ifmr.ifm_current; 329114164Ssam ifr.ifr_media = (ifmr.ifm_current & ~IFM_MMASK) | IFM_MAKEMODE(mode); 330114164Ssam 331114164Ssam if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) < 0) 332114164Ssam err(1, "SIOCSIFMEDIA (mode)"); 333114164Ssam} 334114164Ssam 33525450Speter/********************************************************************** 33625450Speter * A good chunk of this is duplicated from sys/net/ifmedia.c 33725450Speter **********************************************************************/ 33825450Speter 33925450Speterstatic struct ifmedia_description ifm_type_descriptions[] = 34025450Speter IFM_TYPE_DESCRIPTIONS; 34125450Speter 34225450Speterstatic struct ifmedia_description ifm_subtype_ethernet_descriptions[] = 34325450Speter IFM_SUBTYPE_ETHERNET_DESCRIPTIONS; 34425450Speter 34525450Speterstatic struct ifmedia_description ifm_subtype_ethernet_aliases[] = 34625450Speter IFM_SUBTYPE_ETHERNET_ALIASES; 34725450Speter 34825450Speterstatic struct ifmedia_description ifm_subtype_ethernet_option_descriptions[] = 34925450Speter IFM_SUBTYPE_ETHERNET_OPTION_DESCRIPTIONS; 35025450Speter 35125450Speterstatic struct ifmedia_description ifm_subtype_tokenring_descriptions[] = 35225450Speter IFM_SUBTYPE_TOKENRING_DESCRIPTIONS; 35325450Speter 35425450Speterstatic struct ifmedia_description ifm_subtype_tokenring_aliases[] = 35525450Speter IFM_SUBTYPE_TOKENRING_ALIASES; 35625450Speter 35725450Speterstatic struct ifmedia_description ifm_subtype_tokenring_option_descriptions[] = 35825450Speter IFM_SUBTYPE_TOKENRING_OPTION_DESCRIPTIONS; 35925450Speter 36025450Speterstatic struct ifmedia_description ifm_subtype_fddi_descriptions[] = 36125450Speter IFM_SUBTYPE_FDDI_DESCRIPTIONS; 36225450Speter 36325450Speterstatic struct ifmedia_description ifm_subtype_fddi_aliases[] = 36425450Speter IFM_SUBTYPE_FDDI_ALIASES; 36525450Speter 36625450Speterstatic struct ifmedia_description ifm_subtype_fddi_option_descriptions[] = 36725450Speter IFM_SUBTYPE_FDDI_OPTION_DESCRIPTIONS; 36825450Speter 36977217Sphkstatic struct ifmedia_description ifm_subtype_ieee80211_descriptions[] = 37077217Sphk IFM_SUBTYPE_IEEE80211_DESCRIPTIONS; 37177217Sphk 37277217Sphkstatic struct ifmedia_description ifm_subtype_ieee80211_aliases[] = 37377217Sphk IFM_SUBTYPE_IEEE80211_ALIASES; 37477217Sphk 37577217Sphkstatic struct ifmedia_description ifm_subtype_ieee80211_option_descriptions[] = 37677217Sphk IFM_SUBTYPE_IEEE80211_OPTION_DESCRIPTIONS; 37777217Sphk 378114164Ssamstruct ifmedia_description ifm_subtype_ieee80211_mode_descriptions[] = 379114164Ssam IFM_SUBTYPE_IEEE80211_MODE_DESCRIPTIONS; 380114164Ssam 381114232Shartistatic struct ifmedia_description ifm_subtype_atm_descriptions[] = 382114232Sharti IFM_SUBTYPE_ATM_DESCRIPTIONS; 383114232Sharti 384114232Shartistatic struct ifmedia_description ifm_subtype_atm_aliases[] = 385114232Sharti IFM_SUBTYPE_ATM_ALIASES; 386114232Sharti 387114232Shartistatic struct ifmedia_description ifm_subtype_atm_option_descriptions[] = 388114232Sharti IFM_SUBTYPE_ATM_OPTION_DESCRIPTIONS; 389114232Sharti 39025450Speterstatic struct ifmedia_description ifm_subtype_shared_descriptions[] = 39125450Speter IFM_SUBTYPE_SHARED_DESCRIPTIONS; 39225450Speter 39325450Speterstatic struct ifmedia_description ifm_subtype_shared_aliases[] = 39425450Speter IFM_SUBTYPE_SHARED_ALIASES; 39525450Speter 39625450Speterstatic struct ifmedia_description ifm_shared_option_descriptions[] = 39725450Speter IFM_SHARED_OPTION_DESCRIPTIONS; 39825450Speter 39925450Speterstruct ifmedia_type_to_subtype { 40025450Speter struct { 40125450Speter struct ifmedia_description *desc; 40225450Speter int alias; 40325450Speter } subtypes[5]; 40425450Speter struct { 40525450Speter struct ifmedia_description *desc; 40625450Speter int alias; 40725450Speter } options[3]; 408114164Ssam struct { 409114164Ssam struct ifmedia_description *desc; 410114164Ssam int alias; 411114164Ssam } modes[2]; 41225450Speter}; 41325450Speter 41425450Speter/* must be in the same order as IFM_TYPE_DESCRIPTIONS */ 41525450Speterstatic struct ifmedia_type_to_subtype ifmedia_types_to_subtypes[] = { 41625450Speter { 41725450Speter { 41825450Speter { &ifm_subtype_shared_descriptions[0], 0 }, 41925450Speter { &ifm_subtype_shared_aliases[0], 1 }, 42025450Speter { &ifm_subtype_ethernet_descriptions[0], 0 }, 42125450Speter { &ifm_subtype_ethernet_aliases[0], 1 }, 42225450Speter { NULL, 0 }, 42325450Speter }, 42425450Speter { 42525450Speter { &ifm_shared_option_descriptions[0], 0 }, 42677217Sphk { &ifm_subtype_ethernet_option_descriptions[0], 0 }, 42725450Speter { NULL, 0 }, 42825450Speter }, 429114164Ssam { 430114164Ssam { NULL, 0 }, 431114164Ssam }, 43225450Speter }, 43325450Speter { 43425450Speter { 43525450Speter { &ifm_subtype_shared_descriptions[0], 0 }, 43625450Speter { &ifm_subtype_shared_aliases[0], 1 }, 43725450Speter { &ifm_subtype_tokenring_descriptions[0], 0 }, 43825450Speter { &ifm_subtype_tokenring_aliases[0], 1 }, 43925450Speter { NULL, 0 }, 44025450Speter }, 44125450Speter { 44225450Speter { &ifm_shared_option_descriptions[0], 0 }, 44377217Sphk { &ifm_subtype_tokenring_option_descriptions[0], 0 }, 44425450Speter { NULL, 0 }, 44525450Speter }, 446114164Ssam { 447114164Ssam { NULL, 0 }, 448114164Ssam }, 44925450Speter }, 45025450Speter { 45125450Speter { 45225450Speter { &ifm_subtype_shared_descriptions[0], 0 }, 45325450Speter { &ifm_subtype_shared_aliases[0], 1 }, 45425450Speter { &ifm_subtype_fddi_descriptions[0], 0 }, 45525450Speter { &ifm_subtype_fddi_aliases[0], 1 }, 45625450Speter { NULL, 0 }, 45725450Speter }, 45825450Speter { 45925450Speter { &ifm_shared_option_descriptions[0], 0 }, 46077217Sphk { &ifm_subtype_fddi_option_descriptions[0], 0 }, 46125450Speter { NULL, 0 }, 46225450Speter }, 463114164Ssam { 464114164Ssam { NULL, 0 }, 465114164Ssam }, 46625450Speter }, 46777217Sphk { 46877217Sphk { 46977217Sphk { &ifm_subtype_shared_descriptions[0], 0 }, 47077217Sphk { &ifm_subtype_shared_aliases[0], 1 }, 47177217Sphk { &ifm_subtype_ieee80211_descriptions[0], 0 }, 47277217Sphk { &ifm_subtype_ieee80211_aliases[0], 1 }, 47377217Sphk { NULL, 0 }, 47477217Sphk }, 47577217Sphk { 47677217Sphk { &ifm_shared_option_descriptions[0], 0 }, 47777217Sphk { &ifm_subtype_ieee80211_option_descriptions[0], 0 }, 47877217Sphk { NULL, 0 }, 47977217Sphk }, 480114164Ssam { 481114164Ssam { &ifm_subtype_ieee80211_mode_descriptions[0], 0 }, 482114164Ssam { NULL, 0 }, 483114164Ssam }, 48477217Sphk }, 485114232Sharti { 486114232Sharti { 487114232Sharti { &ifm_subtype_shared_descriptions[0], 0 }, 488114232Sharti { &ifm_subtype_shared_aliases[0], 1 }, 489114232Sharti { &ifm_subtype_atm_descriptions[0], 0 }, 490114232Sharti { &ifm_subtype_atm_aliases[0], 1 }, 491114232Sharti { NULL, 0 }, 492114232Sharti }, 493114232Sharti { 494114232Sharti { &ifm_shared_option_descriptions[0], 0 }, 495114232Sharti { &ifm_subtype_atm_option_descriptions[0], 0 }, 496114232Sharti { NULL, 0 }, 497114232Sharti }, 498114232Sharti { 499114232Sharti { NULL, 0 }, 500114232Sharti }, 501114232Sharti }, 50225450Speter}; 50325450Speter 50425450Speterstatic int 50595005Simpget_media_subtype(int type, const char *val) 50625450Speter{ 50725450Speter struct ifmedia_description *desc; 50825450Speter struct ifmedia_type_to_subtype *ttos; 50925450Speter int rval, i; 51025450Speter 51125450Speter /* Find the top-level interface type. */ 51225450Speter for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; 51325450Speter desc->ifmt_string != NULL; desc++, ttos++) 51425450Speter if (type == desc->ifmt_word) 51525450Speter break; 51625450Speter if (desc->ifmt_string == NULL) 51725450Speter errx(1, "unknown media type 0x%x", type); 51825450Speter 51925450Speter for (i = 0; ttos->subtypes[i].desc != NULL; i++) { 52025450Speter rval = lookup_media_word(ttos->subtypes[i].desc, val); 52125450Speter if (rval != -1) 52225450Speter return (rval); 52325450Speter } 52425450Speter errx(1, "unknown media subtype: %s", val); 525114164Ssam /*NOTREACHED*/ 52625450Speter} 52725450Speter 52825450Speterstatic int 529114164Ssamget_media_mode(int type, const char *val) 530114164Ssam{ 531114164Ssam struct ifmedia_description *desc; 532114164Ssam struct ifmedia_type_to_subtype *ttos; 533114164Ssam int rval, i; 534114164Ssam 535114164Ssam /* Find the top-level interface type. */ 536114164Ssam for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; 537114164Ssam desc->ifmt_string != NULL; desc++, ttos++) 538114164Ssam if (type == desc->ifmt_word) 539114164Ssam break; 540114164Ssam if (desc->ifmt_string == NULL) 541114164Ssam errx(1, "unknown media mode 0x%x", type); 542114164Ssam 543114164Ssam for (i = 0; ttos->modes[i].desc != NULL; i++) { 544114164Ssam rval = lookup_media_word(ttos->modes[i].desc, val); 545114164Ssam if (rval != -1) 546114164Ssam return (rval); 547114164Ssam } 548114164Ssam return -1; 549114164Ssam} 550114164Ssam 551114164Ssamstatic int 55295005Simpget_media_options(int type, const char *val) 55325450Speter{ 55425450Speter struct ifmedia_description *desc; 55525450Speter struct ifmedia_type_to_subtype *ttos; 55625450Speter char *optlist, *optptr; 55725450Speter int option = 0, i, rval = 0; 55825450Speter 55925450Speter /* We muck with the string, so copy it. */ 56025450Speter optlist = strdup(val); 56125450Speter if (optlist == NULL) 56225450Speter err(1, "strdup"); 56325450Speter 56425450Speter /* Find the top-level interface type. */ 56525450Speter for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; 56625450Speter desc->ifmt_string != NULL; desc++, ttos++) 56725450Speter if (type == desc->ifmt_word) 56825450Speter break; 56925450Speter if (desc->ifmt_string == NULL) 57025450Speter errx(1, "unknown media type 0x%x", type); 57125450Speter 57225450Speter /* 57325450Speter * Look up the options in the user-provided comma-separated 57425450Speter * list. 57525450Speter */ 57625450Speter optptr = optlist; 57725450Speter for (; (optptr = strtok(optptr, ",")) != NULL; optptr = NULL) { 57825450Speter for (i = 0; ttos->options[i].desc != NULL; i++) { 57925450Speter option = lookup_media_word(ttos->options[i].desc, optptr); 58025450Speter if (option != -1) 58125450Speter break; 58225450Speter } 58325450Speter if (option == 0) 58425450Speter errx(1, "unknown option: %s", optptr); 58525450Speter rval |= option; 58625450Speter } 58725450Speter 58825450Speter free(optlist); 58925450Speter return (rval); 59025450Speter} 59125450Speter 59225450Speterstatic int 59395005Simplookup_media_word(struct ifmedia_description *desc, const char *val) 59425450Speter{ 59525450Speter 59625450Speter for (; desc->ifmt_string != NULL; desc++) 59725450Speter if (strcasecmp(desc->ifmt_string, val) == 0) 59825450Speter return (desc->ifmt_word); 59925450Speter 60025450Speter return (-1); 60125450Speter} 60225450Speter 60395005Simpstatic struct ifmedia_description *get_toptype_desc(int ifmw) 60425450Speter{ 60525450Speter struct ifmedia_description *desc; 60677385Sphk 60777385Sphk for (desc = ifm_type_descriptions; desc->ifmt_string != NULL; desc++) 60877385Sphk if (IFM_TYPE(ifmw) == desc->ifmt_word) 60977385Sphk break; 61077385Sphk 61177385Sphk return desc; 61277385Sphk} 61377385Sphk 61495005Simpstatic struct ifmedia_type_to_subtype *get_toptype_ttos(int ifmw) 61577385Sphk{ 61677385Sphk struct ifmedia_description *desc; 61725450Speter struct ifmedia_type_to_subtype *ttos; 61825450Speter 61925450Speter for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; 62025450Speter desc->ifmt_string != NULL; desc++, ttos++) 62125450Speter if (IFM_TYPE(ifmw) == desc->ifmt_word) 62225450Speter break; 62377385Sphk 62477385Sphk return ttos; 62577385Sphk} 62677385Sphk 62795005Simpstatic struct ifmedia_description *get_subtype_desc(int ifmw, 62895005Simp struct ifmedia_type_to_subtype *ttos) 62977385Sphk{ 63077385Sphk int i; 63177385Sphk struct ifmedia_description *desc; 63277385Sphk 63377385Sphk for (i = 0; ttos->subtypes[i].desc != NULL; i++) { 63477385Sphk if (ttos->subtypes[i].alias) 63577385Sphk continue; 63677385Sphk for (desc = ttos->subtypes[i].desc; 63777385Sphk desc->ifmt_string != NULL; desc++) { 63877385Sphk if (IFM_SUBTYPE(ifmw) == desc->ifmt_word) 63977385Sphk return desc; 64077385Sphk } 64177385Sphk } 64277385Sphk 64377385Sphk return NULL; 64477385Sphk} 64577385Sphk 646114164Ssamstatic struct ifmedia_description *get_mode_desc(int ifmw, 647114164Ssam struct ifmedia_type_to_subtype *ttos) 648114164Ssam{ 649114164Ssam int i; 650114164Ssam struct ifmedia_description *desc; 651114164Ssam 652114164Ssam for (i = 0; ttos->modes[i].desc != NULL; i++) { 653114164Ssam if (ttos->modes[i].alias) 654114164Ssam continue; 655114164Ssam for (desc = ttos->modes[i].desc; 656114164Ssam desc->ifmt_string != NULL; desc++) { 657114164Ssam if (IFM_MODE(ifmw) == desc->ifmt_word) 658114164Ssam return desc; 659114164Ssam } 660114164Ssam } 661114164Ssam 662114164Ssam return NULL; 663114164Ssam} 664114164Ssam 66577385Sphkstatic void 66695005Simpprint_media_word(int ifmw, int print_toptype) 66777385Sphk{ 66877385Sphk struct ifmedia_description *desc; 66977385Sphk struct ifmedia_type_to_subtype *ttos; 67077385Sphk int seen_option = 0, i; 67177385Sphk 67277385Sphk /* Find the top-level interface type. */ 67377385Sphk desc = get_toptype_desc(ifmw); 67477385Sphk ttos = get_toptype_ttos(ifmw); 67525450Speter if (desc->ifmt_string == NULL) { 67625450Speter printf("<unknown type>"); 67725450Speter return; 67877385Sphk } else if (print_toptype) { 67977385Sphk printf("%s", desc->ifmt_string); 68025450Speter } 68125450Speter 68225450Speter /* 68325450Speter * Don't print the top-level type; it's not like we can 68425450Speter * change it, or anything. 68525450Speter */ 68625450Speter 68725450Speter /* Find subtype. */ 68877385Sphk desc = get_subtype_desc(ifmw, ttos); 68977385Sphk if (desc != NULL) 69077385Sphk goto got_subtype; 69125450Speter 69225450Speter /* Falling to here means unknown subtype. */ 69325450Speter printf("<unknown subtype>"); 69425450Speter return; 69525450Speter 69625450Speter got_subtype: 69777385Sphk if (print_toptype) 69877385Sphk putchar(' '); 69977385Sphk 70025450Speter printf("%s", desc->ifmt_string); 70125450Speter 702114164Ssam if (print_toptype) { 703114164Ssam desc = get_mode_desc(ifmw, ttos); 704114164Ssam if (desc != NULL) 705114164Ssam printf(" mode %s", desc->ifmt_string); 706114164Ssam } 707114164Ssam 70825450Speter /* Find options. */ 70925450Speter for (i = 0; ttos->options[i].desc != NULL; i++) { 71025450Speter if (ttos->options[i].alias) 71125450Speter continue; 71225450Speter for (desc = ttos->options[i].desc; 71325450Speter desc->ifmt_string != NULL; desc++) { 71425450Speter if (ifmw & desc->ifmt_word) { 71525450Speter if (seen_option == 0) 71625450Speter printf(" <"); 71725450Speter printf("%s%s", seen_option++ ? "," : "", 71825450Speter desc->ifmt_string); 71925450Speter } 72025450Speter } 72125450Speter } 72225450Speter printf("%s", seen_option ? ">" : ""); 72325450Speter} 72425450Speter 72577385Sphkstatic void 72695005Simpprint_media_word_ifconfig(int ifmw) 72777385Sphk{ 72877385Sphk struct ifmedia_description *desc; 72977385Sphk struct ifmedia_type_to_subtype *ttos; 73077385Sphk int i; 73177385Sphk 73277385Sphk /* Find the top-level interface type. */ 73377385Sphk desc = get_toptype_desc(ifmw); 73477385Sphk ttos = get_toptype_ttos(ifmw); 73577385Sphk if (desc->ifmt_string == NULL) { 73677385Sphk printf("<unknown type>"); 73777385Sphk return; 73877385Sphk } 73977385Sphk 74077385Sphk /* 74177385Sphk * Don't print the top-level type; it's not like we can 74277385Sphk * change it, or anything. 74377385Sphk */ 74477385Sphk 74577385Sphk /* Find subtype. */ 74677385Sphk desc = get_subtype_desc(ifmw, ttos); 74777385Sphk if (desc != NULL) 74877385Sphk goto got_subtype; 74977385Sphk 75077385Sphk /* Falling to here means unknown subtype. */ 75177385Sphk printf("<unknown subtype>"); 75277385Sphk return; 75377385Sphk 75477385Sphk got_subtype: 75577385Sphk printf("media %s", desc->ifmt_string); 75677385Sphk 757114164Ssam desc = get_mode_desc(ifmw, ttos); 758114164Ssam if (desc != NULL) 759114164Ssam printf(" mode %s", desc->ifmt_string); 760114164Ssam 76177385Sphk /* Find options. */ 76277385Sphk for (i = 0; ttos->options[i].desc != NULL; i++) { 76377385Sphk if (ttos->options[i].alias) 76477385Sphk continue; 76577385Sphk for (desc = ttos->options[i].desc; 76677385Sphk desc->ifmt_string != NULL; desc++) { 76777385Sphk if (ifmw & desc->ifmt_word) { 76877385Sphk printf(" mediaopt %s", desc->ifmt_string); 76977385Sphk } 77077385Sphk } 77177385Sphk } 77277385Sphk} 77377385Sphk 77425450Speter/********************************************************************** 77525450Speter * ...until here. 77625450Speter **********************************************************************/ 777