ifmedia.c revision 77385
125450Speter/* $NetBSD: ifconfig.c,v 1.34 1997/04/21 01:17:58 lukem Exp $ */ 250476Speter/* $FreeBSD: head/sbin/ifconfig/ifmedia.c 77385 2001-05-29 09:13:44Z phk $ */ 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 9225450Speterstatic void domediaopt __P((const char *, int, int)); 9325450Speterstatic int get_media_subtype __P((int, const char *)); 9425450Speterstatic int get_media_options __P((int, const char *)); 9525450Speterstatic int lookup_media_word __P((struct ifmedia_description *, const char *)); 9677385Sphkstatic void print_media_word __P((int, int)); 9777385Sphkstatic void print_media_word_ifconfig __P((int)); 9825450Speter 9977385Sphkstatic struct ifmedia_description *get_toptype_desc __P((int)); 10077385Sphkstatic struct ifmedia_type_to_subtype *get_toptype_ttos __P((int)); 10177385Sphkstatic struct ifmedia_description *get_subtype_desc __P((int, 10277385Sphk struct ifmedia_type_to_subtype *ttos)); 10377385Sphk 10425450Spetervoid 10525667Spetermedia_status(s, info) 10625450Speter int s; 10725667Speter struct rt_addrinfo *info __unused; 10825450Speter{ 10925450Speter struct ifmediareq ifmr; 11025450Speter int *media_list, i; 11125450Speter 11225450Speter (void) memset(&ifmr, 0, sizeof(ifmr)); 11325450Speter (void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name)); 11425450Speter 11525450Speter if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) { 11625450Speter /* 11725450Speter * Interface doesn't support SIOC{G,S}IFMEDIA. 11825450Speter */ 11925450Speter return; 12025450Speter } 12125450Speter 12225450Speter if (ifmr.ifm_count == 0) { 12325450Speter warnx("%s: no media types?", name); 12425450Speter return; 12525450Speter } 12625450Speter 12725450Speter media_list = (int *)malloc(ifmr.ifm_count * sizeof(int)); 12825450Speter if (media_list == NULL) 12925450Speter err(1, "malloc"); 13025450Speter ifmr.ifm_ulist = media_list; 13125450Speter 13225450Speter if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) 13325450Speter err(1, "SIOCGIFMEDIA"); 13425450Speter 13525450Speter printf("\tmedia: "); 13677385Sphk print_media_word(ifmr.ifm_current, 1); 13725450Speter if (ifmr.ifm_active != ifmr.ifm_current) { 13825450Speter putchar(' '); 13925450Speter putchar('('); 14077385Sphk print_media_word(ifmr.ifm_active, 0); 14125450Speter putchar(')'); 14225450Speter } 14325450Speter 14477385Sphk putchar('\n'); 14577385Sphk 14625450Speter if (ifmr.ifm_status & IFM_AVALID) { 14777385Sphk printf("\tstatus: "); 14825450Speter switch (IFM_TYPE(ifmr.ifm_active)) { 14925450Speter case IFM_ETHER: 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; 16377217Sphk case IFM_IEEE80211: 16477217Sphk /* XXX: Different value for adhoc? */ 16577217Sphk if (ifmr.ifm_status & IFM_ACTIVE) 16677217Sphk printf("associated"); 16777217Sphk else 16877217Sphk printf("no carrier"); 16977217Sphk break; 17025450Speter } 17125450Speter } 17225450Speter 17325450Speter putchar('\n'); 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 18725450Spetervoid 18825660Spetersetmedia(val, d, s, afp) 18925450Speter const char *val; 19025450Speter int d; 19125450Speter int s; 19225660Speter const struct afswtch *afp; 19325450Speter{ 19425450Speter struct ifmediareq ifmr; 19525450Speter int first_type, subtype; 19625450Speter 19725450Speter (void) memset(&ifmr, 0, sizeof(ifmr)); 19825450Speter (void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name)); 19925450Speter 20025450Speter ifmr.ifm_count = 1; 20125450Speter ifmr.ifm_ulist = &first_type; 20225450Speter if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) { 20325450Speter /* 20425450Speter * If we get E2BIG, the kernel is telling us 20525450Speter * that there are more, so we can ignore it. 20625450Speter */ 20725450Speter if (errno != E2BIG) 20825450Speter err(1, "SIOCGIFMEDIA"); 20925450Speter } 21025450Speter 21125450Speter if (ifmr.ifm_count == 0) 21225450Speter errx(1, "%s: no media types?", name); 21325450Speter 21425450Speter /* 21525450Speter * We are primarily concerned with the top-level type. 21625450Speter * However, "current" may be only IFM_NONE, so we just look 21725450Speter * for the top-level type in the first "supported type" 21825450Speter * entry. 21925450Speter * 22025450Speter * (I'm assuming that all supported media types for a given 22125450Speter * interface will be the same top-level type..) 22225450Speter */ 22325450Speter subtype = get_media_subtype(IFM_TYPE(first_type), val); 22425450Speter 22525450Speter strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 22625450Speter ifr.ifr_media = (ifmr.ifm_current & ~(IFM_NMASK|IFM_TMASK)) | 22725450Speter IFM_TYPE(first_type) | subtype; 22825450Speter 22925450Speter if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) < 0) 23025450Speter err(1, "SIOCSIFMEDIA"); 23125450Speter} 23225450Speter 23325450Spetervoid 23425660Spetersetmediaopt(val, d, s, afp) 23525450Speter const char *val; 23625450Speter int d; 23725450Speter int s; 23825660Speter const struct afswtch *afp; 23925450Speter{ 24025450Speter 24125450Speter domediaopt(val, 0, s); 24225450Speter} 24325450Speter 24425450Spetervoid 24525660Speterunsetmediaopt(val, d, s, afp) 24625450Speter const char *val; 24725450Speter int d; 24825450Speter int s; 24925660Speter const struct afswtch *afp; 25025450Speter{ 25125450Speter 25225450Speter domediaopt(val, 1, s); 25325450Speter} 25425450Speter 25525450Speterstatic void 25625450Speterdomediaopt(val, clear, s) 25725450Speter const char *val; 25825450Speter int clear; 25925450Speter int s; 26025450Speter{ 26125450Speter struct ifmediareq ifmr; 26225450Speter int *mwords, options; 26325450Speter 26425450Speter (void) memset(&ifmr, 0, sizeof(ifmr)); 26525450Speter (void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name)); 26625450Speter 26725450Speter /* 26825450Speter * We must go through the motions of reading all 26925450Speter * supported media because we need to know both 27025450Speter * the current media type and the top-level type. 27125450Speter */ 27225450Speter 27325450Speter if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) 27425450Speter err(1, "SIOCGIFMEDIA"); 27525450Speter 27625450Speter if (ifmr.ifm_count == 0) 27725450Speter errx(1, "%s: no media types?", name); 27825450Speter 27925450Speter mwords = (int *)malloc(ifmr.ifm_count * sizeof(int)); 28025450Speter if (mwords == NULL) 28125450Speter err(1, "malloc"); 28225450Speter 28325450Speter ifmr.ifm_ulist = mwords; 28425450Speter if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) 28525450Speter err(1, "SIOCGIFMEDIA"); 28625450Speter 28725450Speter options = get_media_options(IFM_TYPE(mwords[0]), val); 28825450Speter 28925450Speter free(mwords); 29025450Speter 29125450Speter strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 29225450Speter ifr.ifr_media = ifmr.ifm_current; 29325450Speter if (clear) 29425450Speter ifr.ifr_media &= ~options; 29525450Speter else 29625450Speter ifr.ifr_media |= options; 29725450Speter 29825450Speter if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) < 0) 29925450Speter err(1, "SIOCSIFMEDIA"); 30025450Speter} 30125450Speter 30225450Speter/********************************************************************** 30325450Speter * A good chunk of this is duplicated from sys/net/ifmedia.c 30425450Speter **********************************************************************/ 30525450Speter 30625450Speterstatic struct ifmedia_description ifm_type_descriptions[] = 30725450Speter IFM_TYPE_DESCRIPTIONS; 30825450Speter 30925450Speterstatic struct ifmedia_description ifm_subtype_ethernet_descriptions[] = 31025450Speter IFM_SUBTYPE_ETHERNET_DESCRIPTIONS; 31125450Speter 31225450Speterstatic struct ifmedia_description ifm_subtype_ethernet_aliases[] = 31325450Speter IFM_SUBTYPE_ETHERNET_ALIASES; 31425450Speter 31525450Speterstatic struct ifmedia_description ifm_subtype_ethernet_option_descriptions[] = 31625450Speter IFM_SUBTYPE_ETHERNET_OPTION_DESCRIPTIONS; 31725450Speter 31825450Speterstatic struct ifmedia_description ifm_subtype_tokenring_descriptions[] = 31925450Speter IFM_SUBTYPE_TOKENRING_DESCRIPTIONS; 32025450Speter 32125450Speterstatic struct ifmedia_description ifm_subtype_tokenring_aliases[] = 32225450Speter IFM_SUBTYPE_TOKENRING_ALIASES; 32325450Speter 32425450Speterstatic struct ifmedia_description ifm_subtype_tokenring_option_descriptions[] = 32525450Speter IFM_SUBTYPE_TOKENRING_OPTION_DESCRIPTIONS; 32625450Speter 32725450Speterstatic struct ifmedia_description ifm_subtype_fddi_descriptions[] = 32825450Speter IFM_SUBTYPE_FDDI_DESCRIPTIONS; 32925450Speter 33025450Speterstatic struct ifmedia_description ifm_subtype_fddi_aliases[] = 33125450Speter IFM_SUBTYPE_FDDI_ALIASES; 33225450Speter 33325450Speterstatic struct ifmedia_description ifm_subtype_fddi_option_descriptions[] = 33425450Speter IFM_SUBTYPE_FDDI_OPTION_DESCRIPTIONS; 33525450Speter 33677217Sphkstatic struct ifmedia_description ifm_subtype_ieee80211_descriptions[] = 33777217Sphk IFM_SUBTYPE_IEEE80211_DESCRIPTIONS; 33877217Sphk 33977217Sphkstatic struct ifmedia_description ifm_subtype_ieee80211_aliases[] = 34077217Sphk IFM_SUBTYPE_IEEE80211_ALIASES; 34177217Sphk 34277217Sphkstatic struct ifmedia_description ifm_subtype_ieee80211_option_descriptions[] = 34377217Sphk IFM_SUBTYPE_IEEE80211_OPTION_DESCRIPTIONS; 34477217Sphk 34525450Speterstatic struct ifmedia_description ifm_subtype_shared_descriptions[] = 34625450Speter IFM_SUBTYPE_SHARED_DESCRIPTIONS; 34725450Speter 34825450Speterstatic struct ifmedia_description ifm_subtype_shared_aliases[] = 34925450Speter IFM_SUBTYPE_SHARED_ALIASES; 35025450Speter 35125450Speterstatic struct ifmedia_description ifm_shared_option_descriptions[] = 35225450Speter IFM_SHARED_OPTION_DESCRIPTIONS; 35325450Speter 35425450Speterstruct ifmedia_type_to_subtype { 35525450Speter struct { 35625450Speter struct ifmedia_description *desc; 35725450Speter int alias; 35825450Speter } subtypes[5]; 35925450Speter struct { 36025450Speter struct ifmedia_description *desc; 36125450Speter int alias; 36225450Speter } options[3]; 36325450Speter}; 36425450Speter 36525450Speter/* must be in the same order as IFM_TYPE_DESCRIPTIONS */ 36625450Speterstatic struct ifmedia_type_to_subtype ifmedia_types_to_subtypes[] = { 36725450Speter { 36825450Speter { 36925450Speter { &ifm_subtype_shared_descriptions[0], 0 }, 37025450Speter { &ifm_subtype_shared_aliases[0], 1 }, 37125450Speter { &ifm_subtype_ethernet_descriptions[0], 0 }, 37225450Speter { &ifm_subtype_ethernet_aliases[0], 1 }, 37325450Speter { NULL, 0 }, 37425450Speter }, 37525450Speter { 37625450Speter { &ifm_shared_option_descriptions[0], 0 }, 37777217Sphk { &ifm_subtype_ethernet_option_descriptions[0], 0 }, 37825450Speter { NULL, 0 }, 37925450Speter }, 38025450Speter }, 38125450Speter { 38225450Speter { 38325450Speter { &ifm_subtype_shared_descriptions[0], 0 }, 38425450Speter { &ifm_subtype_shared_aliases[0], 1 }, 38525450Speter { &ifm_subtype_tokenring_descriptions[0], 0 }, 38625450Speter { &ifm_subtype_tokenring_aliases[0], 1 }, 38725450Speter { NULL, 0 }, 38825450Speter }, 38925450Speter { 39025450Speter { &ifm_shared_option_descriptions[0], 0 }, 39177217Sphk { &ifm_subtype_tokenring_option_descriptions[0], 0 }, 39225450Speter { NULL, 0 }, 39325450Speter }, 39425450Speter }, 39525450Speter { 39625450Speter { 39725450Speter { &ifm_subtype_shared_descriptions[0], 0 }, 39825450Speter { &ifm_subtype_shared_aliases[0], 1 }, 39925450Speter { &ifm_subtype_fddi_descriptions[0], 0 }, 40025450Speter { &ifm_subtype_fddi_aliases[0], 1 }, 40125450Speter { NULL, 0 }, 40225450Speter }, 40325450Speter { 40425450Speter { &ifm_shared_option_descriptions[0], 0 }, 40577217Sphk { &ifm_subtype_fddi_option_descriptions[0], 0 }, 40625450Speter { NULL, 0 }, 40725450Speter }, 40825450Speter }, 40977217Sphk { 41077217Sphk { 41177217Sphk { &ifm_subtype_shared_descriptions[0], 0 }, 41277217Sphk { &ifm_subtype_shared_aliases[0], 1 }, 41377217Sphk { &ifm_subtype_ieee80211_descriptions[0], 0 }, 41477217Sphk { &ifm_subtype_ieee80211_aliases[0], 1 }, 41577217Sphk { NULL, 0 }, 41677217Sphk }, 41777217Sphk { 41877217Sphk { &ifm_shared_option_descriptions[0], 0 }, 41977217Sphk { &ifm_subtype_ieee80211_option_descriptions[0], 0 }, 42077217Sphk { NULL, 0 }, 42177217Sphk }, 42277217Sphk }, 42325450Speter}; 42425450Speter 42525450Speterstatic int 42625450Speterget_media_subtype(type, val) 42725450Speter int type; 42825450Speter const char *val; 42925450Speter{ 43025450Speter struct ifmedia_description *desc; 43125450Speter struct ifmedia_type_to_subtype *ttos; 43225450Speter int rval, i; 43325450Speter 43425450Speter /* Find the top-level interface type. */ 43525450Speter for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; 43625450Speter desc->ifmt_string != NULL; desc++, ttos++) 43725450Speter if (type == desc->ifmt_word) 43825450Speter break; 43925450Speter if (desc->ifmt_string == NULL) 44025450Speter errx(1, "unknown media type 0x%x", type); 44125450Speter 44225450Speter for (i = 0; ttos->subtypes[i].desc != NULL; i++) { 44325450Speter rval = lookup_media_word(ttos->subtypes[i].desc, val); 44425450Speter if (rval != -1) 44525450Speter return (rval); 44625450Speter } 44725450Speter errx(1, "unknown media subtype: %s", val); 44825450Speter /* NOTREACHED */ 44925450Speter} 45025450Speter 45125450Speterstatic int 45225450Speterget_media_options(type, val) 45325450Speter int type; 45425450Speter const char *val; 45525450Speter{ 45625450Speter struct ifmedia_description *desc; 45725450Speter struct ifmedia_type_to_subtype *ttos; 45825450Speter char *optlist, *optptr; 45925450Speter int option = 0, i, rval = 0; 46025450Speter 46125450Speter /* We muck with the string, so copy it. */ 46225450Speter optlist = strdup(val); 46325450Speter if (optlist == NULL) 46425450Speter err(1, "strdup"); 46525450Speter 46625450Speter /* Find the top-level interface type. */ 46725450Speter for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; 46825450Speter desc->ifmt_string != NULL; desc++, ttos++) 46925450Speter if (type == desc->ifmt_word) 47025450Speter break; 47125450Speter if (desc->ifmt_string == NULL) 47225450Speter errx(1, "unknown media type 0x%x", type); 47325450Speter 47425450Speter /* 47525450Speter * Look up the options in the user-provided comma-separated 47625450Speter * list. 47725450Speter */ 47825450Speter optptr = optlist; 47925450Speter for (; (optptr = strtok(optptr, ",")) != NULL; optptr = NULL) { 48025450Speter for (i = 0; ttos->options[i].desc != NULL; i++) { 48125450Speter option = lookup_media_word(ttos->options[i].desc, optptr); 48225450Speter if (option != -1) 48325450Speter break; 48425450Speter } 48525450Speter if (option == 0) 48625450Speter errx(1, "unknown option: %s", optptr); 48725450Speter rval |= option; 48825450Speter } 48925450Speter 49025450Speter free(optlist); 49125450Speter return (rval); 49225450Speter} 49325450Speter 49425450Speterstatic int 49525450Speterlookup_media_word(desc, val) 49625450Speter struct ifmedia_description *desc; 49725450Speter const char *val; 49825450Speter{ 49925450Speter 50025450Speter for (; desc->ifmt_string != NULL; desc++) 50125450Speter if (strcasecmp(desc->ifmt_string, val) == 0) 50225450Speter return (desc->ifmt_word); 50325450Speter 50425450Speter return (-1); 50525450Speter} 50625450Speter 50777385Sphkstatic struct ifmedia_description *get_toptype_desc(ifmw) 50825450Speter int ifmw; 50925450Speter{ 51025450Speter struct ifmedia_description *desc; 51177385Sphk 51277385Sphk for (desc = ifm_type_descriptions; desc->ifmt_string != NULL; desc++) 51377385Sphk if (IFM_TYPE(ifmw) == desc->ifmt_word) 51477385Sphk break; 51577385Sphk 51677385Sphk return desc; 51777385Sphk} 51877385Sphk 51977385Sphkstatic struct ifmedia_type_to_subtype *get_toptype_ttos(ifmw) 52077385Sphk int ifmw; 52177385Sphk{ 52277385Sphk struct ifmedia_description *desc; 52325450Speter struct ifmedia_type_to_subtype *ttos; 52425450Speter 52525450Speter for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; 52625450Speter desc->ifmt_string != NULL; desc++, ttos++) 52725450Speter if (IFM_TYPE(ifmw) == desc->ifmt_word) 52825450Speter break; 52977385Sphk 53077385Sphk return ttos; 53177385Sphk} 53277385Sphk 53377385Sphkstatic struct ifmedia_description *get_subtype_desc(ifmw, ttos) 53477385Sphk int ifmw; 53577385Sphk struct ifmedia_type_to_subtype *ttos; 53677385Sphk{ 53777385Sphk int i; 53877385Sphk struct ifmedia_description *desc; 53977385Sphk 54077385Sphk for (i = 0; ttos->subtypes[i].desc != NULL; i++) { 54177385Sphk if (ttos->subtypes[i].alias) 54277385Sphk continue; 54377385Sphk for (desc = ttos->subtypes[i].desc; 54477385Sphk desc->ifmt_string != NULL; desc++) { 54577385Sphk if (IFM_SUBTYPE(ifmw) == desc->ifmt_word) 54677385Sphk return desc; 54777385Sphk } 54877385Sphk } 54977385Sphk 55077385Sphk return NULL; 55177385Sphk} 55277385Sphk 55377385Sphkstatic void 55477385Sphkprint_media_word(ifmw, print_toptype) 55577385Sphk int ifmw; 55677385Sphk int print_toptype; 55777385Sphk{ 55877385Sphk struct ifmedia_description *desc; 55977385Sphk struct ifmedia_type_to_subtype *ttos; 56077385Sphk int seen_option = 0, i; 56177385Sphk 56277385Sphk /* Find the top-level interface type. */ 56377385Sphk desc = get_toptype_desc(ifmw); 56477385Sphk ttos = get_toptype_ttos(ifmw); 56525450Speter if (desc->ifmt_string == NULL) { 56625450Speter printf("<unknown type>"); 56725450Speter return; 56877385Sphk } else if (print_toptype) { 56977385Sphk printf("%s", desc->ifmt_string); 57025450Speter } 57125450Speter 57225450Speter /* 57325450Speter * Don't print the top-level type; it's not like we can 57425450Speter * change it, or anything. 57525450Speter */ 57625450Speter 57725450Speter /* Find subtype. */ 57877385Sphk desc = get_subtype_desc(ifmw, ttos); 57977385Sphk if (desc != NULL) 58077385Sphk goto got_subtype; 58125450Speter 58225450Speter /* Falling to here means unknown subtype. */ 58325450Speter printf("<unknown subtype>"); 58425450Speter return; 58525450Speter 58625450Speter got_subtype: 58777385Sphk if (print_toptype) 58877385Sphk putchar(' '); 58977385Sphk 59025450Speter printf("%s", desc->ifmt_string); 59125450Speter 59225450Speter /* Find options. */ 59325450Speter for (i = 0; ttos->options[i].desc != NULL; i++) { 59425450Speter if (ttos->options[i].alias) 59525450Speter continue; 59625450Speter for (desc = ttos->options[i].desc; 59725450Speter desc->ifmt_string != NULL; desc++) { 59825450Speter if (ifmw & desc->ifmt_word) { 59925450Speter if (seen_option == 0) 60025450Speter printf(" <"); 60125450Speter printf("%s%s", seen_option++ ? "," : "", 60225450Speter desc->ifmt_string); 60325450Speter } 60425450Speter } 60525450Speter } 60625450Speter printf("%s", seen_option ? ">" : ""); 60725450Speter} 60825450Speter 60977385Sphkstatic void 61077385Sphkprint_media_word_ifconfig(ifmw) 61177385Sphk int ifmw; 61277385Sphk{ 61377385Sphk struct ifmedia_description *desc; 61477385Sphk struct ifmedia_type_to_subtype *ttos; 61577385Sphk int i; 61677385Sphk 61777385Sphk /* Find the top-level interface type. */ 61877385Sphk desc = get_toptype_desc(ifmw); 61977385Sphk ttos = get_toptype_ttos(ifmw); 62077385Sphk if (desc->ifmt_string == NULL) { 62177385Sphk printf("<unknown type>"); 62277385Sphk return; 62377385Sphk } 62477385Sphk 62577385Sphk /* 62677385Sphk * Don't print the top-level type; it's not like we can 62777385Sphk * change it, or anything. 62877385Sphk */ 62977385Sphk 63077385Sphk /* Find subtype. */ 63177385Sphk desc = get_subtype_desc(ifmw, ttos); 63277385Sphk if (desc != NULL) 63377385Sphk goto got_subtype; 63477385Sphk 63577385Sphk /* Falling to here means unknown subtype. */ 63677385Sphk printf("<unknown subtype>"); 63777385Sphk return; 63877385Sphk 63977385Sphk got_subtype: 64077385Sphk printf("media %s", desc->ifmt_string); 64177385Sphk 64277385Sphk /* Find options. */ 64377385Sphk for (i = 0; ttos->options[i].desc != NULL; i++) { 64477385Sphk if (ttos->options[i].alias) 64577385Sphk continue; 64677385Sphk for (desc = ttos->options[i].desc; 64777385Sphk desc->ifmt_string != NULL; desc++) { 64877385Sphk if (ifmw & desc->ifmt_word) { 64977385Sphk printf(" mediaopt %s", desc->ifmt_string); 65077385Sphk } 65177385Sphk } 65277385Sphk } 65377385Sphk} 65477385Sphk 65525450Speter/********************************************************************** 65625450Speter * ...until here. 65725450Speter **********************************************************************/ 658