ifmedia.c revision 116820
125450Speter/* $NetBSD: ifconfig.c,v 1.34 1997/04/21 01:17:58 lukem Exp $ */ 250476Speter/* $FreeBSD: head/sbin/ifconfig/ifmedia.c 116820 2003-06-25 15:05:17Z sam $ */ 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 & ~IFM_MMASK) | IFM_MAKEMODE(mode); 329114164Ssam 330114164Ssam if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) < 0) 331114164Ssam err(1, "SIOCSIFMEDIA (mode)"); 332114164Ssam} 333114164Ssam 33425450Speter/********************************************************************** 33525450Speter * A good chunk of this is duplicated from sys/net/ifmedia.c 33625450Speter **********************************************************************/ 33725450Speter 33825450Speterstatic struct ifmedia_description ifm_type_descriptions[] = 33925450Speter IFM_TYPE_DESCRIPTIONS; 34025450Speter 34125450Speterstatic struct ifmedia_description ifm_subtype_ethernet_descriptions[] = 34225450Speter IFM_SUBTYPE_ETHERNET_DESCRIPTIONS; 34325450Speter 34425450Speterstatic struct ifmedia_description ifm_subtype_ethernet_aliases[] = 34525450Speter IFM_SUBTYPE_ETHERNET_ALIASES; 34625450Speter 34725450Speterstatic struct ifmedia_description ifm_subtype_ethernet_option_descriptions[] = 34825450Speter IFM_SUBTYPE_ETHERNET_OPTION_DESCRIPTIONS; 34925450Speter 35025450Speterstatic struct ifmedia_description ifm_subtype_tokenring_descriptions[] = 35125450Speter IFM_SUBTYPE_TOKENRING_DESCRIPTIONS; 35225450Speter 35325450Speterstatic struct ifmedia_description ifm_subtype_tokenring_aliases[] = 35425450Speter IFM_SUBTYPE_TOKENRING_ALIASES; 35525450Speter 35625450Speterstatic struct ifmedia_description ifm_subtype_tokenring_option_descriptions[] = 35725450Speter IFM_SUBTYPE_TOKENRING_OPTION_DESCRIPTIONS; 35825450Speter 35925450Speterstatic struct ifmedia_description ifm_subtype_fddi_descriptions[] = 36025450Speter IFM_SUBTYPE_FDDI_DESCRIPTIONS; 36125450Speter 36225450Speterstatic struct ifmedia_description ifm_subtype_fddi_aliases[] = 36325450Speter IFM_SUBTYPE_FDDI_ALIASES; 36425450Speter 36525450Speterstatic struct ifmedia_description ifm_subtype_fddi_option_descriptions[] = 36625450Speter IFM_SUBTYPE_FDDI_OPTION_DESCRIPTIONS; 36725450Speter 36877217Sphkstatic struct ifmedia_description ifm_subtype_ieee80211_descriptions[] = 36977217Sphk IFM_SUBTYPE_IEEE80211_DESCRIPTIONS; 37077217Sphk 37177217Sphkstatic struct ifmedia_description ifm_subtype_ieee80211_aliases[] = 37277217Sphk IFM_SUBTYPE_IEEE80211_ALIASES; 37377217Sphk 37477217Sphkstatic struct ifmedia_description ifm_subtype_ieee80211_option_descriptions[] = 37577217Sphk IFM_SUBTYPE_IEEE80211_OPTION_DESCRIPTIONS; 37677217Sphk 377114164Ssamstruct ifmedia_description ifm_subtype_ieee80211_mode_descriptions[] = 378114164Ssam IFM_SUBTYPE_IEEE80211_MODE_DESCRIPTIONS; 379114164Ssam 380116820Ssamstruct ifmedia_description ifm_subtype_ieee80211_mode_aliases[] = 381116820Ssam IFM_SUBTYPE_IEEE80211_MODE_ALIASES; 382116820Ssam 383114232Shartistatic struct ifmedia_description ifm_subtype_atm_descriptions[] = 384114232Sharti IFM_SUBTYPE_ATM_DESCRIPTIONS; 385114232Sharti 386114232Shartistatic struct ifmedia_description ifm_subtype_atm_aliases[] = 387114232Sharti IFM_SUBTYPE_ATM_ALIASES; 388114232Sharti 389114232Shartistatic struct ifmedia_description ifm_subtype_atm_option_descriptions[] = 390114232Sharti IFM_SUBTYPE_ATM_OPTION_DESCRIPTIONS; 391114232Sharti 39225450Speterstatic struct ifmedia_description ifm_subtype_shared_descriptions[] = 39325450Speter IFM_SUBTYPE_SHARED_DESCRIPTIONS; 39425450Speter 39525450Speterstatic struct ifmedia_description ifm_subtype_shared_aliases[] = 39625450Speter IFM_SUBTYPE_SHARED_ALIASES; 39725450Speter 39825450Speterstatic struct ifmedia_description ifm_shared_option_descriptions[] = 39925450Speter IFM_SHARED_OPTION_DESCRIPTIONS; 40025450Speter 40125450Speterstruct ifmedia_type_to_subtype { 40225450Speter struct { 40325450Speter struct ifmedia_description *desc; 40425450Speter int alias; 40525450Speter } subtypes[5]; 40625450Speter struct { 40725450Speter struct ifmedia_description *desc; 40825450Speter int alias; 40925450Speter } options[3]; 410114164Ssam struct { 411114164Ssam struct ifmedia_description *desc; 412114164Ssam int alias; 413116820Ssam } modes[3]; 41425450Speter}; 41525450Speter 41625450Speter/* must be in the same order as IFM_TYPE_DESCRIPTIONS */ 41725450Speterstatic struct ifmedia_type_to_subtype ifmedia_types_to_subtypes[] = { 41825450Speter { 41925450Speter { 42025450Speter { &ifm_subtype_shared_descriptions[0], 0 }, 42125450Speter { &ifm_subtype_shared_aliases[0], 1 }, 42225450Speter { &ifm_subtype_ethernet_descriptions[0], 0 }, 42325450Speter { &ifm_subtype_ethernet_aliases[0], 1 }, 42425450Speter { NULL, 0 }, 42525450Speter }, 42625450Speter { 42725450Speter { &ifm_shared_option_descriptions[0], 0 }, 42877217Sphk { &ifm_subtype_ethernet_option_descriptions[0], 0 }, 42925450Speter { NULL, 0 }, 43025450Speter }, 431114164Ssam { 432114164Ssam { NULL, 0 }, 433114164Ssam }, 43425450Speter }, 43525450Speter { 43625450Speter { 43725450Speter { &ifm_subtype_shared_descriptions[0], 0 }, 43825450Speter { &ifm_subtype_shared_aliases[0], 1 }, 43925450Speter { &ifm_subtype_tokenring_descriptions[0], 0 }, 44025450Speter { &ifm_subtype_tokenring_aliases[0], 1 }, 44125450Speter { NULL, 0 }, 44225450Speter }, 44325450Speter { 44425450Speter { &ifm_shared_option_descriptions[0], 0 }, 44577217Sphk { &ifm_subtype_tokenring_option_descriptions[0], 0 }, 44625450Speter { NULL, 0 }, 44725450Speter }, 448114164Ssam { 449114164Ssam { NULL, 0 }, 450114164Ssam }, 45125450Speter }, 45225450Speter { 45325450Speter { 45425450Speter { &ifm_subtype_shared_descriptions[0], 0 }, 45525450Speter { &ifm_subtype_shared_aliases[0], 1 }, 45625450Speter { &ifm_subtype_fddi_descriptions[0], 0 }, 45725450Speter { &ifm_subtype_fddi_aliases[0], 1 }, 45825450Speter { NULL, 0 }, 45925450Speter }, 46025450Speter { 46125450Speter { &ifm_shared_option_descriptions[0], 0 }, 46277217Sphk { &ifm_subtype_fddi_option_descriptions[0], 0 }, 46325450Speter { NULL, 0 }, 46425450Speter }, 465114164Ssam { 466114164Ssam { NULL, 0 }, 467114164Ssam }, 46825450Speter }, 46977217Sphk { 47077217Sphk { 47177217Sphk { &ifm_subtype_shared_descriptions[0], 0 }, 47277217Sphk { &ifm_subtype_shared_aliases[0], 1 }, 47377217Sphk { &ifm_subtype_ieee80211_descriptions[0], 0 }, 47477217Sphk { &ifm_subtype_ieee80211_aliases[0], 1 }, 47577217Sphk { NULL, 0 }, 47677217Sphk }, 47777217Sphk { 47877217Sphk { &ifm_shared_option_descriptions[0], 0 }, 47977217Sphk { &ifm_subtype_ieee80211_option_descriptions[0], 0 }, 48077217Sphk { NULL, 0 }, 48177217Sphk }, 482114164Ssam { 483114164Ssam { &ifm_subtype_ieee80211_mode_descriptions[0], 0 }, 484116820Ssam { &ifm_subtype_ieee80211_mode_aliases[0], 0 }, 485114164Ssam { NULL, 0 }, 486114164Ssam }, 48777217Sphk }, 488114232Sharti { 489114232Sharti { 490114232Sharti { &ifm_subtype_shared_descriptions[0], 0 }, 491114232Sharti { &ifm_subtype_shared_aliases[0], 1 }, 492114232Sharti { &ifm_subtype_atm_descriptions[0], 0 }, 493114232Sharti { &ifm_subtype_atm_aliases[0], 1 }, 494114232Sharti { NULL, 0 }, 495114232Sharti }, 496114232Sharti { 497114232Sharti { &ifm_shared_option_descriptions[0], 0 }, 498114232Sharti { &ifm_subtype_atm_option_descriptions[0], 0 }, 499114232Sharti { NULL, 0 }, 500114232Sharti }, 501114232Sharti { 502114232Sharti { NULL, 0 }, 503114232Sharti }, 504114232Sharti }, 50525450Speter}; 50625450Speter 50725450Speterstatic int 50895005Simpget_media_subtype(int type, const char *val) 50925450Speter{ 51025450Speter struct ifmedia_description *desc; 51125450Speter struct ifmedia_type_to_subtype *ttos; 51225450Speter int rval, i; 51325450Speter 51425450Speter /* Find the top-level interface type. */ 51525450Speter for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; 51625450Speter desc->ifmt_string != NULL; desc++, ttos++) 51725450Speter if (type == desc->ifmt_word) 51825450Speter break; 51925450Speter if (desc->ifmt_string == NULL) 52025450Speter errx(1, "unknown media type 0x%x", type); 52125450Speter 52225450Speter for (i = 0; ttos->subtypes[i].desc != NULL; i++) { 52325450Speter rval = lookup_media_word(ttos->subtypes[i].desc, val); 52425450Speter if (rval != -1) 52525450Speter return (rval); 52625450Speter } 52725450Speter errx(1, "unknown media subtype: %s", val); 528114164Ssam /*NOTREACHED*/ 52925450Speter} 53025450Speter 53125450Speterstatic int 532114164Ssamget_media_mode(int type, const char *val) 533114164Ssam{ 534114164Ssam struct ifmedia_description *desc; 535114164Ssam struct ifmedia_type_to_subtype *ttos; 536114164Ssam int rval, i; 537114164Ssam 538114164Ssam /* Find the top-level interface type. */ 539114164Ssam for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; 540114164Ssam desc->ifmt_string != NULL; desc++, ttos++) 541114164Ssam if (type == desc->ifmt_word) 542114164Ssam break; 543114164Ssam if (desc->ifmt_string == NULL) 544114164Ssam errx(1, "unknown media mode 0x%x", type); 545114164Ssam 546114164Ssam for (i = 0; ttos->modes[i].desc != NULL; i++) { 547114164Ssam rval = lookup_media_word(ttos->modes[i].desc, val); 548114164Ssam if (rval != -1) 549114164Ssam return (rval); 550114164Ssam } 551114164Ssam return -1; 552114164Ssam} 553114164Ssam 554114164Ssamstatic int 55595005Simpget_media_options(int type, const char *val) 55625450Speter{ 55725450Speter struct ifmedia_description *desc; 55825450Speter struct ifmedia_type_to_subtype *ttos; 55925450Speter char *optlist, *optptr; 56025450Speter int option = 0, i, rval = 0; 56125450Speter 56225450Speter /* We muck with the string, so copy it. */ 56325450Speter optlist = strdup(val); 56425450Speter if (optlist == NULL) 56525450Speter err(1, "strdup"); 56625450Speter 56725450Speter /* Find the top-level interface type. */ 56825450Speter for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; 56925450Speter desc->ifmt_string != NULL; desc++, ttos++) 57025450Speter if (type == desc->ifmt_word) 57125450Speter break; 57225450Speter if (desc->ifmt_string == NULL) 57325450Speter errx(1, "unknown media type 0x%x", type); 57425450Speter 57525450Speter /* 57625450Speter * Look up the options in the user-provided comma-separated 57725450Speter * list. 57825450Speter */ 57925450Speter optptr = optlist; 58025450Speter for (; (optptr = strtok(optptr, ",")) != NULL; optptr = NULL) { 58125450Speter for (i = 0; ttos->options[i].desc != NULL; i++) { 58225450Speter option = lookup_media_word(ttos->options[i].desc, optptr); 58325450Speter if (option != -1) 58425450Speter break; 58525450Speter } 58625450Speter if (option == 0) 58725450Speter errx(1, "unknown option: %s", optptr); 58825450Speter rval |= option; 58925450Speter } 59025450Speter 59125450Speter free(optlist); 59225450Speter return (rval); 59325450Speter} 59425450Speter 59525450Speterstatic int 59695005Simplookup_media_word(struct ifmedia_description *desc, const char *val) 59725450Speter{ 59825450Speter 59925450Speter for (; desc->ifmt_string != NULL; desc++) 60025450Speter if (strcasecmp(desc->ifmt_string, val) == 0) 60125450Speter return (desc->ifmt_word); 60225450Speter 60325450Speter return (-1); 60425450Speter} 60525450Speter 60695005Simpstatic struct ifmedia_description *get_toptype_desc(int ifmw) 60725450Speter{ 60825450Speter struct ifmedia_description *desc; 60977385Sphk 61077385Sphk for (desc = ifm_type_descriptions; desc->ifmt_string != NULL; desc++) 61177385Sphk if (IFM_TYPE(ifmw) == desc->ifmt_word) 61277385Sphk break; 61377385Sphk 61477385Sphk return desc; 61577385Sphk} 61677385Sphk 61795005Simpstatic struct ifmedia_type_to_subtype *get_toptype_ttos(int ifmw) 61877385Sphk{ 61977385Sphk struct ifmedia_description *desc; 62025450Speter struct ifmedia_type_to_subtype *ttos; 62125450Speter 62225450Speter for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; 62325450Speter desc->ifmt_string != NULL; desc++, ttos++) 62425450Speter if (IFM_TYPE(ifmw) == desc->ifmt_word) 62525450Speter break; 62677385Sphk 62777385Sphk return ttos; 62877385Sphk} 62977385Sphk 63095005Simpstatic struct ifmedia_description *get_subtype_desc(int ifmw, 63195005Simp struct ifmedia_type_to_subtype *ttos) 63277385Sphk{ 63377385Sphk int i; 63477385Sphk struct ifmedia_description *desc; 63577385Sphk 63677385Sphk for (i = 0; ttos->subtypes[i].desc != NULL; i++) { 63777385Sphk if (ttos->subtypes[i].alias) 63877385Sphk continue; 63977385Sphk for (desc = ttos->subtypes[i].desc; 64077385Sphk desc->ifmt_string != NULL; desc++) { 64177385Sphk if (IFM_SUBTYPE(ifmw) == desc->ifmt_word) 64277385Sphk return desc; 64377385Sphk } 64477385Sphk } 64577385Sphk 64677385Sphk return NULL; 64777385Sphk} 64877385Sphk 649114164Ssamstatic struct ifmedia_description *get_mode_desc(int ifmw, 650114164Ssam struct ifmedia_type_to_subtype *ttos) 651114164Ssam{ 652114164Ssam int i; 653114164Ssam struct ifmedia_description *desc; 654114164Ssam 655114164Ssam for (i = 0; ttos->modes[i].desc != NULL; i++) { 656114164Ssam if (ttos->modes[i].alias) 657114164Ssam continue; 658114164Ssam for (desc = ttos->modes[i].desc; 659114164Ssam desc->ifmt_string != NULL; desc++) { 660114164Ssam if (IFM_MODE(ifmw) == desc->ifmt_word) 661114164Ssam return desc; 662114164Ssam } 663114164Ssam } 664114164Ssam 665114164Ssam return NULL; 666114164Ssam} 667114164Ssam 66877385Sphkstatic void 66995005Simpprint_media_word(int ifmw, int print_toptype) 67077385Sphk{ 67177385Sphk struct ifmedia_description *desc; 67277385Sphk struct ifmedia_type_to_subtype *ttos; 67377385Sphk int seen_option = 0, i; 67477385Sphk 67577385Sphk /* Find the top-level interface type. */ 67677385Sphk desc = get_toptype_desc(ifmw); 67777385Sphk ttos = get_toptype_ttos(ifmw); 67825450Speter if (desc->ifmt_string == NULL) { 67925450Speter printf("<unknown type>"); 68025450Speter return; 68177385Sphk } else if (print_toptype) { 68277385Sphk printf("%s", desc->ifmt_string); 68325450Speter } 68425450Speter 68525450Speter /* 68625450Speter * Don't print the top-level type; it's not like we can 68725450Speter * change it, or anything. 68825450Speter */ 68925450Speter 69025450Speter /* Find subtype. */ 69177385Sphk desc = get_subtype_desc(ifmw, ttos); 69277385Sphk if (desc != NULL) 69377385Sphk goto got_subtype; 69425450Speter 69525450Speter /* Falling to here means unknown subtype. */ 69625450Speter printf("<unknown subtype>"); 69725450Speter return; 69825450Speter 69925450Speter got_subtype: 70077385Sphk if (print_toptype) 70177385Sphk putchar(' '); 70277385Sphk 70325450Speter printf("%s", desc->ifmt_string); 70425450Speter 705114164Ssam if (print_toptype) { 706114164Ssam desc = get_mode_desc(ifmw, ttos); 707116820Ssam if (desc != NULL && strcasecmp("autoselect", desc->ifmt_string)) 708114164Ssam printf(" mode %s", desc->ifmt_string); 709114164Ssam } 710114164Ssam 71125450Speter /* Find options. */ 71225450Speter for (i = 0; ttos->options[i].desc != NULL; i++) { 71325450Speter if (ttos->options[i].alias) 71425450Speter continue; 71525450Speter for (desc = ttos->options[i].desc; 71625450Speter desc->ifmt_string != NULL; desc++) { 71725450Speter if (ifmw & desc->ifmt_word) { 71825450Speter if (seen_option == 0) 71925450Speter printf(" <"); 72025450Speter printf("%s%s", seen_option++ ? "," : "", 72125450Speter desc->ifmt_string); 72225450Speter } 72325450Speter } 72425450Speter } 72525450Speter printf("%s", seen_option ? ">" : ""); 72625450Speter} 72725450Speter 72877385Sphkstatic void 72995005Simpprint_media_word_ifconfig(int ifmw) 73077385Sphk{ 73177385Sphk struct ifmedia_description *desc; 73277385Sphk struct ifmedia_type_to_subtype *ttos; 73377385Sphk int i; 73477385Sphk 73577385Sphk /* Find the top-level interface type. */ 73677385Sphk desc = get_toptype_desc(ifmw); 73777385Sphk ttos = get_toptype_ttos(ifmw); 73877385Sphk if (desc->ifmt_string == NULL) { 73977385Sphk printf("<unknown type>"); 74077385Sphk return; 74177385Sphk } 74277385Sphk 74377385Sphk /* 74477385Sphk * Don't print the top-level type; it's not like we can 74577385Sphk * change it, or anything. 74677385Sphk */ 74777385Sphk 74877385Sphk /* Find subtype. */ 74977385Sphk desc = get_subtype_desc(ifmw, ttos); 75077385Sphk if (desc != NULL) 75177385Sphk goto got_subtype; 75277385Sphk 75377385Sphk /* Falling to here means unknown subtype. */ 75477385Sphk printf("<unknown subtype>"); 75577385Sphk return; 75677385Sphk 75777385Sphk got_subtype: 75877385Sphk printf("media %s", desc->ifmt_string); 75977385Sphk 760114164Ssam desc = get_mode_desc(ifmw, ttos); 761114164Ssam if (desc != NULL) 762114164Ssam printf(" mode %s", desc->ifmt_string); 763114164Ssam 76477385Sphk /* Find options. */ 76577385Sphk for (i = 0; ttos->options[i].desc != NULL; i++) { 76677385Sphk if (ttos->options[i].alias) 76777385Sphk continue; 76877385Sphk for (desc = ttos->options[i].desc; 76977385Sphk desc->ifmt_string != NULL; desc++) { 77077385Sphk if (ifmw & desc->ifmt_word) { 77177385Sphk printf(" mediaopt %s", desc->ifmt_string); 77277385Sphk } 77377385Sphk } 77477385Sphk } 77577385Sphk} 77677385Sphk 77725450Speter/********************************************************************** 77825450Speter * ...until here. 77925450Speter **********************************************************************/ 780