ifmedia.c revision 166169
125450Speter/* $NetBSD: ifconfig.c,v 1.34 1997/04/21 01:17:58 lukem Exp $ */ 250476Speter/* $FreeBSD: head/sbin/ifconfig/ifmedia.c 166169 2007-01-22 13:42:07Z marius $ */ 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 105138593Ssamstatic void 106139494Ssammedia_status(int s) 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: 149161536Sthomas case IFM_ATM: 15025450Speter if (ifmr.ifm_status & IFM_ACTIVE) 15125450Speter printf("active"); 15225450Speter else 15325450Speter printf("no carrier"); 15425450Speter break; 15525450Speter 15625450Speter case IFM_FDDI: 15725450Speter case IFM_TOKEN: 15825450Speter if (ifmr.ifm_status & IFM_ACTIVE) 15925450Speter printf("inserted"); 16025450Speter else 16125450Speter printf("no ring"); 16225450Speter break; 163114232Sharti 16477217Sphk case IFM_IEEE80211: 16577217Sphk /* XXX: Different value for adhoc? */ 16677217Sphk if (ifmr.ifm_status & IFM_ACTIVE) 16777217Sphk printf("associated"); 16877217Sphk else 16977217Sphk printf("no carrier"); 17077217Sphk break; 17125450Speter } 17285853Syar putchar('\n'); 17325450Speter } 17425450Speter 17577385Sphk if (ifmr.ifm_count > 0 && supmedia) { 17677385Sphk printf("\tsupported media:\n"); 17725450Speter for (i = 0; i < ifmr.ifm_count; i++) { 17877385Sphk printf("\t\t"); 17977385Sphk print_media_word_ifconfig(media_list[i]); 18077385Sphk putchar('\n'); 18125450Speter } 18225450Speter } 18325450Speter 18425450Speter free(media_list); 18525450Speter} 18625450Speter 187140913Sambriskostatic struct ifmediareq * 188140913Sambriskogetifmediastate(int s) 18925450Speter{ 190140913Sambrisko static struct ifmediareq *ifmr = NULL; 191140913Sambrisko int *mwords; 19225450Speter 193140913Sambrisko if (ifmr == NULL) { 194140913Sambrisko ifmr = (struct ifmediareq *)malloc(sizeof(struct ifmediareq)); 195140913Sambrisko if (ifmr == NULL) 196140913Sambrisko err(1, "malloc"); 19725450Speter 198140913Sambrisko (void) memset(ifmr, 0, sizeof(struct ifmediareq)); 199140913Sambrisko (void) strncpy(ifmr->ifm_name, name, 200140913Sambrisko sizeof(ifmr->ifm_name)); 201140913Sambrisko 202140913Sambrisko ifmr->ifm_count = 0; 203140913Sambrisko ifmr->ifm_ulist = NULL; 204140913Sambrisko 20525450Speter /* 206140913Sambrisko * We must go through the motions of reading all 207140913Sambrisko * supported media because we need to know both 208140913Sambrisko * the current media type and the top-level type. 20925450Speter */ 210140913Sambrisko 211140913Sambrisko if (ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0) { 21225450Speter err(1, "SIOCGIFMEDIA"); 213140913Sambrisko } 214140913Sambrisko 215140913Sambrisko if (ifmr->ifm_count == 0) 216140913Sambrisko errx(1, "%s: no media types?", name); 217140913Sambrisko 218140913Sambrisko mwords = (int *)malloc(ifmr->ifm_count * sizeof(int)); 219140913Sambrisko if (mwords == NULL) 220140913Sambrisko err(1, "malloc"); 221140913Sambrisko 222140913Sambrisko ifmr->ifm_ulist = mwords; 223140913Sambrisko if (ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0) 224140913Sambrisko err(1, "SIOCGIFMEDIA"); 22525450Speter } 22625450Speter 227140913Sambrisko return ifmr; 228140913Sambrisko} 22925450Speter 230140913Sambriskostatic void 231140913Sambriskosetifmediacallback(int s, void *arg) 232140913Sambrisko{ 233140913Sambrisko struct ifmediareq *ifmr = (struct ifmediareq *)arg; 234140913Sambrisko static int did_it = 0; 235140913Sambrisko 236140913Sambrisko if (!did_it) { 237154240Sambrisko ifr.ifr_media = ifmr->ifm_current; 238140913Sambrisko if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) < 0) 239140913Sambrisko err(1, "SIOCSIFMEDIA (media)"); 240140913Sambrisko free(ifmr->ifm_ulist); 241140913Sambrisko free(ifmr); 242140913Sambrisko did_it = 1; 243140913Sambrisko } 244140913Sambrisko} 245140913Sambrisko 246140913Sambriskostatic void 247140913Sambriskosetmedia(const char *val, int d, int s, const struct afswtch *afp) 248140913Sambrisko{ 249140913Sambrisko struct ifmediareq *ifmr; 250140913Sambrisko int subtype; 251140913Sambrisko 252140913Sambrisko ifmr = getifmediastate(s); 253140913Sambrisko 25425450Speter /* 25525450Speter * We are primarily concerned with the top-level type. 25625450Speter * However, "current" may be only IFM_NONE, so we just look 25725450Speter * for the top-level type in the first "supported type" 25825450Speter * entry. 25925450Speter * 26025450Speter * (I'm assuming that all supported media types for a given 26125450Speter * interface will be the same top-level type..) 26225450Speter */ 263140913Sambrisko subtype = get_media_subtype(IFM_TYPE(ifmr->ifm_ulist[0]), val); 26425450Speter 26525450Speter strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 266140913Sambrisko ifr.ifr_media = (ifmr->ifm_current & ~(IFM_NMASK|IFM_TMASK)) | 267140913Sambrisko IFM_TYPE(ifmr->ifm_ulist[0]) | subtype; 26825450Speter 269140913Sambrisko if ((ifr.ifr_media & IFM_TMASK) == 0) { 270140913Sambrisko ifr.ifr_media &= ~IFM_GMASK; 271140913Sambrisko } 272140913Sambrisko 273140913Sambrisko ifmr->ifm_current = ifr.ifr_media; 274140913Sambrisko callback_register(setifmediacallback, (void *)ifmr); 27525450Speter} 27625450Speter 277138593Ssamstatic void 27895005Simpsetmediaopt(const char *val, int d, int s, const struct afswtch *afp) 27925450Speter{ 28025450Speter 28125450Speter domediaopt(val, 0, s); 28225450Speter} 28325450Speter 284138593Ssamstatic void 28595005Simpunsetmediaopt(const char *val, int d, int s, const struct afswtch *afp) 28625450Speter{ 28725450Speter 28825450Speter domediaopt(val, 1, s); 28925450Speter} 29025450Speter 29125450Speterstatic void 29295005Simpdomediaopt(const char *val, int clear, int s) 29325450Speter{ 294140913Sambrisko struct ifmediareq *ifmr; 295140913Sambrisko int options; 29625450Speter 297140913Sambrisko ifmr = getifmediastate(s); 29825450Speter 299140913Sambrisko options = get_media_options(IFM_TYPE(ifmr->ifm_ulist[0]), val); 30025450Speter 30125450Speter strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 302140913Sambrisko ifr.ifr_media = ifmr->ifm_current; 30325450Speter if (clear) 30425450Speter ifr.ifr_media &= ~options; 305165359Sjkim else { 306165359Sjkim if (options & IFM_HDX) { 307165359Sjkim ifr.ifr_media &= ~IFM_FDX; 308165359Sjkim options &= ~IFM_HDX; 309165359Sjkim } 31025450Speter ifr.ifr_media |= options; 311165359Sjkim } 312140913Sambrisko ifmr->ifm_current = ifr.ifr_media; 313140913Sambrisko callback_register(setifmediacallback, (void *)ifmr); 31425450Speter} 31525450Speter 316166113Smariusstatic void 317166113Smariussetmediainst(const char *val, int d, int s, const struct afswtch *afp) 318166113Smarius{ 319166113Smarius struct ifmediareq *ifmr; 320166113Smarius int inst; 321114164Ssam 322166113Smarius ifmr = getifmediastate(s); 323166113Smarius 324166113Smarius inst = atoi(val); 325166113Smarius if (inst < 0 || inst > IFM_INST_MAX) 326166113Smarius errx(1, "invalid media instance: %s", val); 327166113Smarius 328166113Smarius strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 329166113Smarius ifr.ifr_media = (ifmr->ifm_current & ~IFM_IMASK) | inst << IFM_ISHIFT; 330166113Smarius 331166113Smarius ifmr->ifm_current = ifr.ifr_media; 332166113Smarius callback_register(setifmediacallback, (void *)ifmr); 333166113Smarius} 334166113Smarius 335138593Ssamstatic void 336114164Ssamsetmediamode(const char *val, int d, int s, const struct afswtch *afp) 337114164Ssam{ 338140913Sambrisko struct ifmediareq *ifmr; 339140913Sambrisko int mode; 340114164Ssam 341140913Sambrisko ifmr = getifmediastate(s); 342114164Ssam 343140913Sambrisko mode = get_media_mode(IFM_TYPE(ifmr->ifm_ulist[0]), val); 344114164Ssam 345114164Ssam strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 346140913Sambrisko ifr.ifr_media = (ifmr->ifm_current & ~IFM_MMASK) | mode; 347114164Ssam 348140913Sambrisko ifmr->ifm_current = ifr.ifr_media; 349140913Sambrisko callback_register(setifmediacallback, (void *)ifmr); 350114164Ssam} 351114164Ssam 35225450Speter/********************************************************************** 35325450Speter * A good chunk of this is duplicated from sys/net/ifmedia.c 35425450Speter **********************************************************************/ 35525450Speter 35625450Speterstatic struct ifmedia_description ifm_type_descriptions[] = 35725450Speter IFM_TYPE_DESCRIPTIONS; 35825450Speter 35925450Speterstatic struct ifmedia_description ifm_subtype_ethernet_descriptions[] = 36025450Speter IFM_SUBTYPE_ETHERNET_DESCRIPTIONS; 36125450Speter 36225450Speterstatic struct ifmedia_description ifm_subtype_ethernet_aliases[] = 36325450Speter IFM_SUBTYPE_ETHERNET_ALIASES; 36425450Speter 36525450Speterstatic struct ifmedia_description ifm_subtype_ethernet_option_descriptions[] = 36625450Speter IFM_SUBTYPE_ETHERNET_OPTION_DESCRIPTIONS; 36725450Speter 36825450Speterstatic struct ifmedia_description ifm_subtype_tokenring_descriptions[] = 36925450Speter IFM_SUBTYPE_TOKENRING_DESCRIPTIONS; 37025450Speter 37125450Speterstatic struct ifmedia_description ifm_subtype_tokenring_aliases[] = 37225450Speter IFM_SUBTYPE_TOKENRING_ALIASES; 37325450Speter 37425450Speterstatic struct ifmedia_description ifm_subtype_tokenring_option_descriptions[] = 37525450Speter IFM_SUBTYPE_TOKENRING_OPTION_DESCRIPTIONS; 37625450Speter 37725450Speterstatic struct ifmedia_description ifm_subtype_fddi_descriptions[] = 37825450Speter IFM_SUBTYPE_FDDI_DESCRIPTIONS; 37925450Speter 38025450Speterstatic struct ifmedia_description ifm_subtype_fddi_aliases[] = 38125450Speter IFM_SUBTYPE_FDDI_ALIASES; 38225450Speter 38325450Speterstatic struct ifmedia_description ifm_subtype_fddi_option_descriptions[] = 38425450Speter IFM_SUBTYPE_FDDI_OPTION_DESCRIPTIONS; 38525450Speter 38677217Sphkstatic struct ifmedia_description ifm_subtype_ieee80211_descriptions[] = 38777217Sphk IFM_SUBTYPE_IEEE80211_DESCRIPTIONS; 38877217Sphk 38977217Sphkstatic struct ifmedia_description ifm_subtype_ieee80211_aliases[] = 39077217Sphk IFM_SUBTYPE_IEEE80211_ALIASES; 39177217Sphk 39277217Sphkstatic struct ifmedia_description ifm_subtype_ieee80211_option_descriptions[] = 39377217Sphk IFM_SUBTYPE_IEEE80211_OPTION_DESCRIPTIONS; 39477217Sphk 395114164Ssamstruct ifmedia_description ifm_subtype_ieee80211_mode_descriptions[] = 396114164Ssam IFM_SUBTYPE_IEEE80211_MODE_DESCRIPTIONS; 397114164Ssam 398116820Ssamstruct ifmedia_description ifm_subtype_ieee80211_mode_aliases[] = 399116820Ssam IFM_SUBTYPE_IEEE80211_MODE_ALIASES; 400116820Ssam 401114232Shartistatic struct ifmedia_description ifm_subtype_atm_descriptions[] = 402114232Sharti IFM_SUBTYPE_ATM_DESCRIPTIONS; 403114232Sharti 404114232Shartistatic struct ifmedia_description ifm_subtype_atm_aliases[] = 405114232Sharti IFM_SUBTYPE_ATM_ALIASES; 406114232Sharti 407114232Shartistatic struct ifmedia_description ifm_subtype_atm_option_descriptions[] = 408114232Sharti IFM_SUBTYPE_ATM_OPTION_DESCRIPTIONS; 409114232Sharti 41025450Speterstatic struct ifmedia_description ifm_subtype_shared_descriptions[] = 41125450Speter IFM_SUBTYPE_SHARED_DESCRIPTIONS; 41225450Speter 41325450Speterstatic struct ifmedia_description ifm_subtype_shared_aliases[] = 41425450Speter IFM_SUBTYPE_SHARED_ALIASES; 41525450Speter 41625450Speterstatic struct ifmedia_description ifm_shared_option_descriptions[] = 41725450Speter IFM_SHARED_OPTION_DESCRIPTIONS; 41825450Speter 41925450Speterstruct ifmedia_type_to_subtype { 42025450Speter struct { 42125450Speter struct ifmedia_description *desc; 42225450Speter int alias; 42325450Speter } subtypes[5]; 42425450Speter struct { 42525450Speter struct ifmedia_description *desc; 42625450Speter int alias; 42725450Speter } options[3]; 428114164Ssam struct { 429114164Ssam struct ifmedia_description *desc; 430114164Ssam int alias; 431116820Ssam } modes[3]; 43225450Speter}; 43325450Speter 43425450Speter/* must be in the same order as IFM_TYPE_DESCRIPTIONS */ 43525450Speterstatic struct ifmedia_type_to_subtype ifmedia_types_to_subtypes[] = { 43625450Speter { 43725450Speter { 43825450Speter { &ifm_subtype_shared_descriptions[0], 0 }, 43925450Speter { &ifm_subtype_shared_aliases[0], 1 }, 44025450Speter { &ifm_subtype_ethernet_descriptions[0], 0 }, 44125450Speter { &ifm_subtype_ethernet_aliases[0], 1 }, 44225450Speter { NULL, 0 }, 44325450Speter }, 44425450Speter { 44525450Speter { &ifm_shared_option_descriptions[0], 0 }, 44677217Sphk { &ifm_subtype_ethernet_option_descriptions[0], 0 }, 44725450Speter { NULL, 0 }, 44825450Speter }, 449114164Ssam { 450114164Ssam { NULL, 0 }, 451114164Ssam }, 45225450Speter }, 45325450Speter { 45425450Speter { 45525450Speter { &ifm_subtype_shared_descriptions[0], 0 }, 45625450Speter { &ifm_subtype_shared_aliases[0], 1 }, 45725450Speter { &ifm_subtype_tokenring_descriptions[0], 0 }, 45825450Speter { &ifm_subtype_tokenring_aliases[0], 1 }, 45925450Speter { NULL, 0 }, 46025450Speter }, 46125450Speter { 46225450Speter { &ifm_shared_option_descriptions[0], 0 }, 46377217Sphk { &ifm_subtype_tokenring_option_descriptions[0], 0 }, 46425450Speter { NULL, 0 }, 46525450Speter }, 466114164Ssam { 467114164Ssam { NULL, 0 }, 468114164Ssam }, 46925450Speter }, 47025450Speter { 47125450Speter { 47225450Speter { &ifm_subtype_shared_descriptions[0], 0 }, 47325450Speter { &ifm_subtype_shared_aliases[0], 1 }, 47425450Speter { &ifm_subtype_fddi_descriptions[0], 0 }, 47525450Speter { &ifm_subtype_fddi_aliases[0], 1 }, 47625450Speter { NULL, 0 }, 47725450Speter }, 47825450Speter { 47925450Speter { &ifm_shared_option_descriptions[0], 0 }, 48077217Sphk { &ifm_subtype_fddi_option_descriptions[0], 0 }, 48125450Speter { NULL, 0 }, 48225450Speter }, 483114164Ssam { 484114164Ssam { NULL, 0 }, 485114164Ssam }, 48625450Speter }, 48777217Sphk { 48877217Sphk { 48977217Sphk { &ifm_subtype_shared_descriptions[0], 0 }, 49077217Sphk { &ifm_subtype_shared_aliases[0], 1 }, 49177217Sphk { &ifm_subtype_ieee80211_descriptions[0], 0 }, 49277217Sphk { &ifm_subtype_ieee80211_aliases[0], 1 }, 49377217Sphk { NULL, 0 }, 49477217Sphk }, 49577217Sphk { 49677217Sphk { &ifm_shared_option_descriptions[0], 0 }, 49777217Sphk { &ifm_subtype_ieee80211_option_descriptions[0], 0 }, 49877217Sphk { NULL, 0 }, 49977217Sphk }, 500114164Ssam { 501114164Ssam { &ifm_subtype_ieee80211_mode_descriptions[0], 0 }, 502116820Ssam { &ifm_subtype_ieee80211_mode_aliases[0], 0 }, 503114164Ssam { NULL, 0 }, 504114164Ssam }, 50577217Sphk }, 506114232Sharti { 507114232Sharti { 508114232Sharti { &ifm_subtype_shared_descriptions[0], 0 }, 509114232Sharti { &ifm_subtype_shared_aliases[0], 1 }, 510114232Sharti { &ifm_subtype_atm_descriptions[0], 0 }, 511114232Sharti { &ifm_subtype_atm_aliases[0], 1 }, 512114232Sharti { NULL, 0 }, 513114232Sharti }, 514114232Sharti { 515114232Sharti { &ifm_shared_option_descriptions[0], 0 }, 516114232Sharti { &ifm_subtype_atm_option_descriptions[0], 0 }, 517114232Sharti { NULL, 0 }, 518114232Sharti }, 519114232Sharti { 520114232Sharti { NULL, 0 }, 521114232Sharti }, 522114232Sharti }, 52325450Speter}; 52425450Speter 52525450Speterstatic int 52695005Simpget_media_subtype(int type, const char *val) 52725450Speter{ 52825450Speter struct ifmedia_description *desc; 52925450Speter struct ifmedia_type_to_subtype *ttos; 53025450Speter int rval, i; 53125450Speter 53225450Speter /* Find the top-level interface type. */ 53325450Speter for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; 53425450Speter desc->ifmt_string != NULL; desc++, ttos++) 53525450Speter if (type == desc->ifmt_word) 53625450Speter break; 53725450Speter if (desc->ifmt_string == NULL) 53825450Speter errx(1, "unknown media type 0x%x", type); 53925450Speter 54025450Speter for (i = 0; ttos->subtypes[i].desc != NULL; i++) { 54125450Speter rval = lookup_media_word(ttos->subtypes[i].desc, val); 54225450Speter if (rval != -1) 54325450Speter return (rval); 54425450Speter } 54525450Speter errx(1, "unknown media subtype: %s", val); 546114164Ssam /*NOTREACHED*/ 54725450Speter} 54825450Speter 54925450Speterstatic int 550114164Ssamget_media_mode(int type, const char *val) 551114164Ssam{ 552114164Ssam struct ifmedia_description *desc; 553114164Ssam struct ifmedia_type_to_subtype *ttos; 554114164Ssam int rval, i; 555114164Ssam 556114164Ssam /* Find the top-level interface type. */ 557114164Ssam for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; 558114164Ssam desc->ifmt_string != NULL; desc++, ttos++) 559114164Ssam if (type == desc->ifmt_word) 560114164Ssam break; 561114164Ssam if (desc->ifmt_string == NULL) 562114164Ssam errx(1, "unknown media mode 0x%x", type); 563114164Ssam 564114164Ssam for (i = 0; ttos->modes[i].desc != NULL; i++) { 565114164Ssam rval = lookup_media_word(ttos->modes[i].desc, val); 566114164Ssam if (rval != -1) 567114164Ssam return (rval); 568114164Ssam } 569114164Ssam return -1; 570114164Ssam} 571114164Ssam 572114164Ssamstatic int 57395005Simpget_media_options(int type, const char *val) 57425450Speter{ 57525450Speter struct ifmedia_description *desc; 57625450Speter struct ifmedia_type_to_subtype *ttos; 57725450Speter char *optlist, *optptr; 57825450Speter int option = 0, i, rval = 0; 57925450Speter 58025450Speter /* We muck with the string, so copy it. */ 58125450Speter optlist = strdup(val); 58225450Speter if (optlist == NULL) 58325450Speter err(1, "strdup"); 58425450Speter 58525450Speter /* Find the top-level interface type. */ 58625450Speter for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; 58725450Speter desc->ifmt_string != NULL; desc++, ttos++) 58825450Speter if (type == desc->ifmt_word) 58925450Speter break; 59025450Speter if (desc->ifmt_string == NULL) 59125450Speter errx(1, "unknown media type 0x%x", type); 59225450Speter 59325450Speter /* 59425450Speter * Look up the options in the user-provided comma-separated 59525450Speter * list. 59625450Speter */ 59725450Speter optptr = optlist; 59825450Speter for (; (optptr = strtok(optptr, ",")) != NULL; optptr = NULL) { 59925450Speter for (i = 0; ttos->options[i].desc != NULL; i++) { 60025450Speter option = lookup_media_word(ttos->options[i].desc, optptr); 60125450Speter if (option != -1) 60225450Speter break; 60325450Speter } 60425450Speter if (option == 0) 60525450Speter errx(1, "unknown option: %s", optptr); 60625450Speter rval |= option; 60725450Speter } 60825450Speter 60925450Speter free(optlist); 61025450Speter return (rval); 61125450Speter} 61225450Speter 61325450Speterstatic int 61495005Simplookup_media_word(struct ifmedia_description *desc, const char *val) 61525450Speter{ 61625450Speter 61725450Speter for (; desc->ifmt_string != NULL; desc++) 61825450Speter if (strcasecmp(desc->ifmt_string, val) == 0) 61925450Speter return (desc->ifmt_word); 62025450Speter 62125450Speter return (-1); 62225450Speter} 62325450Speter 62495005Simpstatic struct ifmedia_description *get_toptype_desc(int ifmw) 62525450Speter{ 62625450Speter struct ifmedia_description *desc; 62777385Sphk 62877385Sphk for (desc = ifm_type_descriptions; desc->ifmt_string != NULL; desc++) 62977385Sphk if (IFM_TYPE(ifmw) == desc->ifmt_word) 63077385Sphk break; 63177385Sphk 63277385Sphk return desc; 63377385Sphk} 63477385Sphk 63595005Simpstatic struct ifmedia_type_to_subtype *get_toptype_ttos(int ifmw) 63677385Sphk{ 63777385Sphk struct ifmedia_description *desc; 63825450Speter struct ifmedia_type_to_subtype *ttos; 63925450Speter 64025450Speter for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; 64125450Speter desc->ifmt_string != NULL; desc++, ttos++) 64225450Speter if (IFM_TYPE(ifmw) == desc->ifmt_word) 64325450Speter break; 64477385Sphk 64577385Sphk return ttos; 64677385Sphk} 64777385Sphk 64895005Simpstatic struct ifmedia_description *get_subtype_desc(int ifmw, 64995005Simp struct ifmedia_type_to_subtype *ttos) 65077385Sphk{ 65177385Sphk int i; 65277385Sphk struct ifmedia_description *desc; 65377385Sphk 65477385Sphk for (i = 0; ttos->subtypes[i].desc != NULL; i++) { 65577385Sphk if (ttos->subtypes[i].alias) 65677385Sphk continue; 65777385Sphk for (desc = ttos->subtypes[i].desc; 65877385Sphk desc->ifmt_string != NULL; desc++) { 65977385Sphk if (IFM_SUBTYPE(ifmw) == desc->ifmt_word) 66077385Sphk return desc; 66177385Sphk } 66277385Sphk } 66377385Sphk 66477385Sphk return NULL; 66577385Sphk} 66677385Sphk 667114164Ssamstatic struct ifmedia_description *get_mode_desc(int ifmw, 668114164Ssam struct ifmedia_type_to_subtype *ttos) 669114164Ssam{ 670114164Ssam int i; 671114164Ssam struct ifmedia_description *desc; 672114164Ssam 673114164Ssam for (i = 0; ttos->modes[i].desc != NULL; i++) { 674114164Ssam if (ttos->modes[i].alias) 675114164Ssam continue; 676114164Ssam for (desc = ttos->modes[i].desc; 677114164Ssam desc->ifmt_string != NULL; desc++) { 678114164Ssam if (IFM_MODE(ifmw) == desc->ifmt_word) 679114164Ssam return desc; 680114164Ssam } 681114164Ssam } 682114164Ssam 683114164Ssam return NULL; 684114164Ssam} 685114164Ssam 68677385Sphkstatic void 68795005Simpprint_media_word(int ifmw, int print_toptype) 68877385Sphk{ 68977385Sphk struct ifmedia_description *desc; 69077385Sphk struct ifmedia_type_to_subtype *ttos; 69177385Sphk int seen_option = 0, i; 69277385Sphk 69377385Sphk /* Find the top-level interface type. */ 69477385Sphk desc = get_toptype_desc(ifmw); 69577385Sphk ttos = get_toptype_ttos(ifmw); 69625450Speter if (desc->ifmt_string == NULL) { 69725450Speter printf("<unknown type>"); 69825450Speter return; 69977385Sphk } else if (print_toptype) { 70077385Sphk printf("%s", desc->ifmt_string); 70125450Speter } 70225450Speter 70325450Speter /* 70425450Speter * Don't print the top-level type; it's not like we can 70525450Speter * change it, or anything. 70625450Speter */ 70725450Speter 70825450Speter /* Find subtype. */ 70977385Sphk desc = get_subtype_desc(ifmw, ttos); 710161536Sthomas if (desc == NULL) { 711161536Sthomas printf("<unknown subtype>"); 712161536Sthomas return; 713161536Sthomas } 71425450Speter 71577385Sphk if (print_toptype) 71677385Sphk putchar(' '); 71777385Sphk 71825450Speter printf("%s", desc->ifmt_string); 71925450Speter 720114164Ssam if (print_toptype) { 721114164Ssam desc = get_mode_desc(ifmw, ttos); 722116820Ssam if (desc != NULL && strcasecmp("autoselect", desc->ifmt_string)) 723114164Ssam printf(" mode %s", desc->ifmt_string); 724114164Ssam } 725114164Ssam 72625450Speter /* Find options. */ 72725450Speter for (i = 0; ttos->options[i].desc != NULL; i++) { 72825450Speter if (ttos->options[i].alias) 72925450Speter continue; 73025450Speter for (desc = ttos->options[i].desc; 73125450Speter desc->ifmt_string != NULL; desc++) { 73225450Speter if (ifmw & desc->ifmt_word) { 73325450Speter if (seen_option == 0) 73425450Speter printf(" <"); 73525450Speter printf("%s%s", seen_option++ ? "," : "", 73625450Speter desc->ifmt_string); 73725450Speter } 73825450Speter } 73925450Speter } 74025450Speter printf("%s", seen_option ? ">" : ""); 741166113Smarius 742166169Smarius if (print_toptype && IFM_INST(ifmw) != 0) 743166113Smarius printf(" instance %d", IFM_INST(ifmw)); 74425450Speter} 74525450Speter 74677385Sphkstatic void 74795005Simpprint_media_word_ifconfig(int ifmw) 74877385Sphk{ 74977385Sphk struct ifmedia_description *desc; 75077385Sphk struct ifmedia_type_to_subtype *ttos; 75177385Sphk int i; 75277385Sphk 75377385Sphk /* Find the top-level interface type. */ 75477385Sphk desc = get_toptype_desc(ifmw); 75577385Sphk ttos = get_toptype_ttos(ifmw); 75677385Sphk if (desc->ifmt_string == NULL) { 75777385Sphk printf("<unknown type>"); 75877385Sphk return; 75977385Sphk } 76077385Sphk 76177385Sphk /* 76277385Sphk * Don't print the top-level type; it's not like we can 76377385Sphk * change it, or anything. 76477385Sphk */ 76577385Sphk 76677385Sphk /* Find subtype. */ 76777385Sphk desc = get_subtype_desc(ifmw, ttos); 768161536Sthomas if (desc == NULL) { 769161536Sthomas printf("<unknown subtype>"); 770161536Sthomas return; 771161536Sthomas } 77277385Sphk 77377385Sphk printf("media %s", desc->ifmt_string); 77477385Sphk 775114164Ssam desc = get_mode_desc(ifmw, ttos); 776114164Ssam if (desc != NULL) 777114164Ssam printf(" mode %s", desc->ifmt_string); 778114164Ssam 77977385Sphk /* Find options. */ 78077385Sphk for (i = 0; ttos->options[i].desc != NULL; i++) { 78177385Sphk if (ttos->options[i].alias) 78277385Sphk continue; 78377385Sphk for (desc = ttos->options[i].desc; 78477385Sphk desc->ifmt_string != NULL; desc++) { 78577385Sphk if (ifmw & desc->ifmt_word) { 78677385Sphk printf(" mediaopt %s", desc->ifmt_string); 78777385Sphk } 78877385Sphk } 78977385Sphk } 790166113Smarius 791166169Smarius if (IFM_INST(ifmw) != 0) 792166169Smarius printf(" instance %d", IFM_INST(ifmw)); 79377385Sphk} 79477385Sphk 79525450Speter/********************************************************************** 79625450Speter * ...until here. 79725450Speter **********************************************************************/ 798138593Ssam 799138593Ssamstatic struct cmd media_cmds[] = { 800138593Ssam DEF_CMD_ARG("media", setmedia), 801138593Ssam DEF_CMD_ARG("mode", setmediamode), 802138593Ssam DEF_CMD_ARG("mediaopt", setmediaopt), 803138593Ssam DEF_CMD_ARG("-mediaopt",unsetmediaopt), 804166113Smarius DEF_CMD_ARG("inst", setmediainst), 805166113Smarius DEF_CMD_ARG("instance", setmediainst), 806138593Ssam}; 807138593Ssamstatic struct afswtch af_media = { 808138593Ssam .af_name = "af_media", 809138593Ssam .af_af = AF_UNSPEC, 810139494Ssam .af_other_status = media_status, 811138593Ssam}; 812138593Ssam 813138593Ssamstatic __constructor void 814138593Ssamifmedia_ctor(void) 815138593Ssam{ 816138593Ssam#define N(a) (sizeof(a) / sizeof(a[0])) 817138593Ssam int i; 818138593Ssam 819138593Ssam for (i = 0; i < N(media_cmds); i++) 820138593Ssam cmd_register(&media_cmds[i]); 821138593Ssam af_register(&af_media); 822138593Ssam#undef N 823138593Ssam} 824