1270069b7SAdrian Chadd /* $NetBSD: ifconfig.c,v 1.34 1997/04/21 01:17:58 lukem Exp $ */ 2270069b7SAdrian Chadd /* $FreeBSD$ */ 3270069b7SAdrian Chadd 4270069b7SAdrian Chadd /* 5270069b7SAdrian Chadd * Copyright (c) 1997 Jason R. Thorpe. 6270069b7SAdrian Chadd * All rights reserved. 7270069b7SAdrian Chadd * 8270069b7SAdrian Chadd * Redistribution and use in source and binary forms, with or without 9270069b7SAdrian Chadd * modification, are permitted provided that the following conditions 10270069b7SAdrian Chadd * are met: 11270069b7SAdrian Chadd * 1. Redistributions of source code must retain the above copyright 12270069b7SAdrian Chadd * notice, this list of conditions and the following disclaimer. 13270069b7SAdrian Chadd * 2. Redistributions in binary form must reproduce the above copyright 14270069b7SAdrian Chadd * notice, this list of conditions and the following disclaimer in the 15270069b7SAdrian Chadd * documentation and/or other materials provided with the distribution. 16270069b7SAdrian Chadd * 3. All advertising materials mentioning features or use of this software 17270069b7SAdrian Chadd * must display the following acknowledgement: 18270069b7SAdrian Chadd * This product includes software developed for the NetBSD Project 19270069b7SAdrian Chadd * by Jason R. Thorpe. 20270069b7SAdrian Chadd * 4. The name of the author may not be used to endorse or promote products 21270069b7SAdrian Chadd * derived from this software without specific prior written permission. 22270069b7SAdrian Chadd * 23270069b7SAdrian Chadd * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24270069b7SAdrian Chadd * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25270069b7SAdrian Chadd * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26270069b7SAdrian Chadd * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27270069b7SAdrian Chadd * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28270069b7SAdrian Chadd * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29270069b7SAdrian Chadd * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 30270069b7SAdrian Chadd * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31270069b7SAdrian Chadd * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32270069b7SAdrian Chadd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33270069b7SAdrian Chadd * SUCH DAMAGE. 34270069b7SAdrian Chadd */ 35270069b7SAdrian Chadd 36270069b7SAdrian Chadd /* 37270069b7SAdrian Chadd * Copyright (c) 1983, 1993 38270069b7SAdrian Chadd * The Regents of the University of California. All rights reserved. 39270069b7SAdrian Chadd * 40270069b7SAdrian Chadd * Redistribution and use in source and binary forms, with or without 41270069b7SAdrian Chadd * modification, are permitted provided that the following conditions 42270069b7SAdrian Chadd * are met: 43270069b7SAdrian Chadd * 1. Redistributions of source code must retain the above copyright 44270069b7SAdrian Chadd * notice, this list of conditions and the following disclaimer. 45270069b7SAdrian Chadd * 2. Redistributions in binary form must reproduce the above copyright 46270069b7SAdrian Chadd * notice, this list of conditions and the following disclaimer in the 47270069b7SAdrian Chadd * documentation and/or other materials provided with the distribution. 48270069b7SAdrian Chadd * 4. Neither the name of the University nor the names of its contributors 49270069b7SAdrian Chadd * may be used to endorse or promote products derived from this software 50270069b7SAdrian Chadd * without specific prior written permission. 51270069b7SAdrian Chadd * 52270069b7SAdrian Chadd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 53270069b7SAdrian Chadd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 54270069b7SAdrian Chadd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 55270069b7SAdrian Chadd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 56270069b7SAdrian Chadd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 57270069b7SAdrian Chadd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 58270069b7SAdrian Chadd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 59270069b7SAdrian Chadd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 60270069b7SAdrian Chadd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 61270069b7SAdrian Chadd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 62270069b7SAdrian Chadd * SUCH DAMAGE. 63270069b7SAdrian Chadd */ 64270069b7SAdrian Chadd /* 65270069b7SAdrian Chadd * based on sbin/ifconfig/ifmedia.c r221954 66270069b7SAdrian Chadd */ 67270069b7SAdrian Chadd 68270069b7SAdrian Chadd #include <sys/param.h> 69270069b7SAdrian Chadd #include <sys/ioctl.h> 70270069b7SAdrian Chadd #include <sys/socket.h> 71270069b7SAdrian Chadd #include <sys/sysctl.h> 72270069b7SAdrian Chadd #include <sys/time.h> 73270069b7SAdrian Chadd 74270069b7SAdrian Chadd #include <net/if.h> 75270069b7SAdrian Chadd #include <net/if_dl.h> 76270069b7SAdrian Chadd #include <net/if_types.h> 77270069b7SAdrian Chadd #include <net/if_media.h> 78270069b7SAdrian Chadd #include <net/route.h> 79270069b7SAdrian Chadd 80270069b7SAdrian Chadd #include <ctype.h> 81270069b7SAdrian Chadd #include <err.h> 82270069b7SAdrian Chadd #include <errno.h> 83270069b7SAdrian Chadd #include <fcntl.h> 84270069b7SAdrian Chadd #include <stdio.h> 85270069b7SAdrian Chadd #include <stdlib.h> 86270069b7SAdrian Chadd #include <string.h> 87270069b7SAdrian Chadd #include <unistd.h> 88270069b7SAdrian Chadd 89270069b7SAdrian Chadd void domediaopt(const char *, int, int); 90270069b7SAdrian Chadd int get_media_subtype(int, const char *); 91270069b7SAdrian Chadd int get_media_mode(int, const char *); 92270069b7SAdrian Chadd int get_media_options(int, const char *); 93270069b7SAdrian Chadd int lookup_media_word(struct ifmedia_description *, const char *); 94270069b7SAdrian Chadd void print_media_word(int, int); 95270069b7SAdrian Chadd void print_media_word_ifconfig(int); 96270069b7SAdrian Chadd 97270069b7SAdrian Chadd #if 0 98270069b7SAdrian Chadd static struct ifmedia_description *get_toptype_desc(int); 99270069b7SAdrian Chadd static struct ifmedia_type_to_subtype *get_toptype_ttos(int); 100270069b7SAdrian Chadd static struct ifmedia_description *get_subtype_desc(int, 101270069b7SAdrian Chadd struct ifmedia_type_to_subtype *ttos); 102270069b7SAdrian Chadd 103270069b7SAdrian Chadd #define IFM_OPMODE(x) \ 104270069b7SAdrian Chadd ((x) & (IFM_IEEE80211_ADHOC | IFM_IEEE80211_HOSTAP | \ 105270069b7SAdrian Chadd IFM_IEEE80211_IBSS | IFM_IEEE80211_WDS | IFM_IEEE80211_MONITOR | \ 106270069b7SAdrian Chadd IFM_IEEE80211_MBSS)) 107270069b7SAdrian Chadd #define IFM_IEEE80211_STA 0 108270069b7SAdrian Chadd 109270069b7SAdrian Chadd static void 110270069b7SAdrian Chadd media_status(int s) 111270069b7SAdrian Chadd { 112270069b7SAdrian Chadd struct ifmediareq ifmr; 113270069b7SAdrian Chadd int *media_list, i; 114270069b7SAdrian Chadd 115270069b7SAdrian Chadd (void) memset(&ifmr, 0, sizeof(ifmr)); 116270069b7SAdrian Chadd (void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name)); 117270069b7SAdrian Chadd 118270069b7SAdrian Chadd if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) { 119270069b7SAdrian Chadd /* 120270069b7SAdrian Chadd * Interface doesn't support SIOC{G,S}IFMEDIA. 121270069b7SAdrian Chadd */ 122270069b7SAdrian Chadd return; 123270069b7SAdrian Chadd } 124270069b7SAdrian Chadd 125270069b7SAdrian Chadd if (ifmr.ifm_count == 0) { 126270069b7SAdrian Chadd warnx("%s: no media types?", name); 127270069b7SAdrian Chadd return; 128270069b7SAdrian Chadd } 129270069b7SAdrian Chadd 130270069b7SAdrian Chadd media_list = (int *)malloc(ifmr.ifm_count * sizeof(int)); 131270069b7SAdrian Chadd if (media_list == NULL) 132270069b7SAdrian Chadd err(1, "malloc"); 133270069b7SAdrian Chadd ifmr.ifm_ulist = media_list; 134270069b7SAdrian Chadd 135270069b7SAdrian Chadd if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) 136270069b7SAdrian Chadd err(1, "SIOCGIFMEDIA"); 137270069b7SAdrian Chadd 138270069b7SAdrian Chadd printf("\tmedia: "); 139270069b7SAdrian Chadd print_media_word(ifmr.ifm_current, 1); 140270069b7SAdrian Chadd if (ifmr.ifm_active != ifmr.ifm_current) { 141270069b7SAdrian Chadd putchar(' '); 142270069b7SAdrian Chadd putchar('('); 143270069b7SAdrian Chadd print_media_word(ifmr.ifm_active, 0); 144270069b7SAdrian Chadd putchar(')'); 145270069b7SAdrian Chadd } 146270069b7SAdrian Chadd 147270069b7SAdrian Chadd putchar('\n'); 148270069b7SAdrian Chadd 149270069b7SAdrian Chadd if (ifmr.ifm_status & IFM_AVALID) { 150270069b7SAdrian Chadd printf("\tstatus: "); 151270069b7SAdrian Chadd switch (IFM_TYPE(ifmr.ifm_active)) { 152270069b7SAdrian Chadd case IFM_ETHER: 153270069b7SAdrian Chadd case IFM_ATM: 154270069b7SAdrian Chadd if (ifmr.ifm_status & IFM_ACTIVE) 155270069b7SAdrian Chadd printf("active"); 156270069b7SAdrian Chadd else 157270069b7SAdrian Chadd printf("no carrier"); 158270069b7SAdrian Chadd break; 159270069b7SAdrian Chadd 160270069b7SAdrian Chadd case IFM_FDDI: 161270069b7SAdrian Chadd case IFM_TOKEN: 162270069b7SAdrian Chadd if (ifmr.ifm_status & IFM_ACTIVE) 163270069b7SAdrian Chadd printf("inserted"); 164270069b7SAdrian Chadd else 165270069b7SAdrian Chadd printf("no ring"); 166270069b7SAdrian Chadd break; 167270069b7SAdrian Chadd 168270069b7SAdrian Chadd case IFM_IEEE80211: 169270069b7SAdrian Chadd if (ifmr.ifm_status & IFM_ACTIVE) { 170270069b7SAdrian Chadd /* NB: only sta mode associates */ 171270069b7SAdrian Chadd if (IFM_OPMODE(ifmr.ifm_active) == IFM_IEEE80211_STA) 172270069b7SAdrian Chadd printf("associated"); 173270069b7SAdrian Chadd else 174270069b7SAdrian Chadd printf("running"); 175270069b7SAdrian Chadd } else 176270069b7SAdrian Chadd printf("no carrier"); 177270069b7SAdrian Chadd break; 178270069b7SAdrian Chadd } 179270069b7SAdrian Chadd putchar('\n'); 180270069b7SAdrian Chadd } 181270069b7SAdrian Chadd 182270069b7SAdrian Chadd if (ifmr.ifm_count > 0 && supmedia) { 183270069b7SAdrian Chadd printf("\tsupported media:\n"); 184270069b7SAdrian Chadd for (i = 0; i < ifmr.ifm_count; i++) { 185270069b7SAdrian Chadd printf("\t\t"); 186270069b7SAdrian Chadd print_media_word_ifconfig(media_list[i]); 187270069b7SAdrian Chadd putchar('\n'); 188270069b7SAdrian Chadd } 189270069b7SAdrian Chadd } 190270069b7SAdrian Chadd 191270069b7SAdrian Chadd free(media_list); 192270069b7SAdrian Chadd } 193270069b7SAdrian Chadd 194270069b7SAdrian Chadd struct ifmediareq * 195270069b7SAdrian Chadd ifmedia_getstate(int s) 196270069b7SAdrian Chadd { 197270069b7SAdrian Chadd static struct ifmediareq *ifmr = NULL; 198270069b7SAdrian Chadd int *mwords; 199270069b7SAdrian Chadd 200270069b7SAdrian Chadd if (ifmr == NULL) { 201270069b7SAdrian Chadd ifmr = (struct ifmediareq *)malloc(sizeof(struct ifmediareq)); 202270069b7SAdrian Chadd if (ifmr == NULL) 203270069b7SAdrian Chadd err(1, "malloc"); 204270069b7SAdrian Chadd 205270069b7SAdrian Chadd (void) memset(ifmr, 0, sizeof(struct ifmediareq)); 206270069b7SAdrian Chadd (void) strncpy(ifmr->ifm_name, name, 207270069b7SAdrian Chadd sizeof(ifmr->ifm_name)); 208270069b7SAdrian Chadd 209270069b7SAdrian Chadd ifmr->ifm_count = 0; 210270069b7SAdrian Chadd ifmr->ifm_ulist = NULL; 211270069b7SAdrian Chadd 212270069b7SAdrian Chadd /* 213270069b7SAdrian Chadd * We must go through the motions of reading all 214270069b7SAdrian Chadd * supported media because we need to know both 215270069b7SAdrian Chadd * the current media type and the top-level type. 216270069b7SAdrian Chadd */ 217270069b7SAdrian Chadd 218270069b7SAdrian Chadd if (ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0) { 219270069b7SAdrian Chadd err(1, "SIOCGIFMEDIA"); 220270069b7SAdrian Chadd } 221270069b7SAdrian Chadd 222270069b7SAdrian Chadd if (ifmr->ifm_count == 0) 223270069b7SAdrian Chadd errx(1, "%s: no media types?", name); 224270069b7SAdrian Chadd 225270069b7SAdrian Chadd mwords = (int *)malloc(ifmr->ifm_count * sizeof(int)); 226270069b7SAdrian Chadd if (mwords == NULL) 227270069b7SAdrian Chadd err(1, "malloc"); 228270069b7SAdrian Chadd 229270069b7SAdrian Chadd ifmr->ifm_ulist = mwords; 230270069b7SAdrian Chadd if (ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0) 231270069b7SAdrian Chadd err(1, "SIOCGIFMEDIA"); 232270069b7SAdrian Chadd } 233270069b7SAdrian Chadd 234270069b7SAdrian Chadd return ifmr; 235270069b7SAdrian Chadd } 236270069b7SAdrian Chadd 237270069b7SAdrian Chadd static void 238270069b7SAdrian Chadd setifmediacallback(int s, void *arg) 239270069b7SAdrian Chadd { 240270069b7SAdrian Chadd struct ifmediareq *ifmr = (struct ifmediareq *)arg; 241270069b7SAdrian Chadd static int did_it = 0; 242270069b7SAdrian Chadd 243270069b7SAdrian Chadd if (!did_it) { 244270069b7SAdrian Chadd ifr.ifr_media = ifmr->ifm_current; 245270069b7SAdrian Chadd if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) < 0) 246270069b7SAdrian Chadd err(1, "SIOCSIFMEDIA (media)"); 247270069b7SAdrian Chadd free(ifmr->ifm_ulist); 248270069b7SAdrian Chadd free(ifmr); 249270069b7SAdrian Chadd did_it = 1; 250270069b7SAdrian Chadd } 251270069b7SAdrian Chadd } 252270069b7SAdrian Chadd 253270069b7SAdrian Chadd static void 254270069b7SAdrian Chadd setmedia(const char *val, int d, int s, const struct afswtch *afp) 255270069b7SAdrian Chadd { 256270069b7SAdrian Chadd struct ifmediareq *ifmr; 257270069b7SAdrian Chadd int subtype; 258270069b7SAdrian Chadd 259270069b7SAdrian Chadd ifmr = ifmedia_getstate(s); 260270069b7SAdrian Chadd 261270069b7SAdrian Chadd /* 262270069b7SAdrian Chadd * We are primarily concerned with the top-level type. 263270069b7SAdrian Chadd * However, "current" may be only IFM_NONE, so we just look 264270069b7SAdrian Chadd * for the top-level type in the first "supported type" 265270069b7SAdrian Chadd * entry. 266270069b7SAdrian Chadd * 267270069b7SAdrian Chadd * (I'm assuming that all supported media types for a given 268270069b7SAdrian Chadd * interface will be the same top-level type..) 269270069b7SAdrian Chadd */ 270270069b7SAdrian Chadd subtype = get_media_subtype(IFM_TYPE(ifmr->ifm_ulist[0]), val); 271270069b7SAdrian Chadd 272270069b7SAdrian Chadd strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 273270069b7SAdrian Chadd ifr.ifr_media = (ifmr->ifm_current & IFM_IMASK) | 274270069b7SAdrian Chadd IFM_TYPE(ifmr->ifm_ulist[0]) | subtype; 275270069b7SAdrian Chadd 276270069b7SAdrian Chadd ifmr->ifm_current = ifr.ifr_media; 277270069b7SAdrian Chadd callback_register(setifmediacallback, (void *)ifmr); 278270069b7SAdrian Chadd } 279270069b7SAdrian Chadd 280270069b7SAdrian Chadd static void 281270069b7SAdrian Chadd setmediaopt(const char *val, int d, int s, const struct afswtch *afp) 282270069b7SAdrian Chadd { 283270069b7SAdrian Chadd 284270069b7SAdrian Chadd domediaopt(val, 0, s); 285270069b7SAdrian Chadd } 286270069b7SAdrian Chadd 287270069b7SAdrian Chadd static void 288270069b7SAdrian Chadd unsetmediaopt(const char *val, int d, int s, const struct afswtch *afp) 289270069b7SAdrian Chadd { 290270069b7SAdrian Chadd 291270069b7SAdrian Chadd domediaopt(val, 1, s); 292270069b7SAdrian Chadd } 293270069b7SAdrian Chadd 294270069b7SAdrian Chadd static void 295270069b7SAdrian Chadd domediaopt(const char *val, int clear, int s) 296270069b7SAdrian Chadd { 297270069b7SAdrian Chadd struct ifmediareq *ifmr; 298270069b7SAdrian Chadd int options; 299270069b7SAdrian Chadd 300270069b7SAdrian Chadd ifmr = ifmedia_getstate(s); 301270069b7SAdrian Chadd 302270069b7SAdrian Chadd options = get_media_options(IFM_TYPE(ifmr->ifm_ulist[0]), val); 303270069b7SAdrian Chadd 304270069b7SAdrian Chadd strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 305270069b7SAdrian Chadd ifr.ifr_media = ifmr->ifm_current; 306270069b7SAdrian Chadd if (clear) 307270069b7SAdrian Chadd ifr.ifr_media &= ~options; 308270069b7SAdrian Chadd else { 309270069b7SAdrian Chadd if (options & IFM_HDX) { 310270069b7SAdrian Chadd ifr.ifr_media &= ~IFM_FDX; 311270069b7SAdrian Chadd options &= ~IFM_HDX; 312270069b7SAdrian Chadd } 313270069b7SAdrian Chadd ifr.ifr_media |= options; 314270069b7SAdrian Chadd } 315270069b7SAdrian Chadd ifmr->ifm_current = ifr.ifr_media; 316270069b7SAdrian Chadd callback_register(setifmediacallback, (void *)ifmr); 317270069b7SAdrian Chadd } 318270069b7SAdrian Chadd 319270069b7SAdrian Chadd static void 320270069b7SAdrian Chadd setmediainst(const char *val, int d, int s, const struct afswtch *afp) 321270069b7SAdrian Chadd { 322270069b7SAdrian Chadd struct ifmediareq *ifmr; 323270069b7SAdrian Chadd int inst; 324270069b7SAdrian Chadd 325270069b7SAdrian Chadd ifmr = ifmedia_getstate(s); 326270069b7SAdrian Chadd 327270069b7SAdrian Chadd inst = atoi(val); 328270069b7SAdrian Chadd if (inst < 0 || inst > (int)IFM_INST_MAX) 329270069b7SAdrian Chadd errx(1, "invalid media instance: %s", val); 330270069b7SAdrian Chadd 331270069b7SAdrian Chadd strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 332270069b7SAdrian Chadd ifr.ifr_media = (ifmr->ifm_current & ~IFM_IMASK) | inst << IFM_ISHIFT; 333270069b7SAdrian Chadd 334270069b7SAdrian Chadd ifmr->ifm_current = ifr.ifr_media; 335270069b7SAdrian Chadd callback_register(setifmediacallback, (void *)ifmr); 336270069b7SAdrian Chadd } 337270069b7SAdrian Chadd 338270069b7SAdrian Chadd static void 339270069b7SAdrian Chadd setmediamode(const char *val, int d, int s, const struct afswtch *afp) 340270069b7SAdrian Chadd { 341270069b7SAdrian Chadd struct ifmediareq *ifmr; 342270069b7SAdrian Chadd int mode; 343270069b7SAdrian Chadd 344270069b7SAdrian Chadd ifmr = ifmedia_getstate(s); 345270069b7SAdrian Chadd 346270069b7SAdrian Chadd mode = get_media_mode(IFM_TYPE(ifmr->ifm_ulist[0]), val); 347270069b7SAdrian Chadd 348270069b7SAdrian Chadd strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 349270069b7SAdrian Chadd ifr.ifr_media = (ifmr->ifm_current & ~IFM_MMASK) | mode; 350270069b7SAdrian Chadd 351270069b7SAdrian Chadd ifmr->ifm_current = ifr.ifr_media; 352270069b7SAdrian Chadd callback_register(setifmediacallback, (void *)ifmr); 353270069b7SAdrian Chadd } 354270069b7SAdrian Chadd #endif 355270069b7SAdrian Chadd 356270069b7SAdrian Chadd /********************************************************************** 357270069b7SAdrian Chadd * A good chunk of this is duplicated from sys/net/ifmedia.c 358270069b7SAdrian Chadd **********************************************************************/ 359270069b7SAdrian Chadd 360270069b7SAdrian Chadd static struct ifmedia_description ifm_type_descriptions[] = 361270069b7SAdrian Chadd IFM_TYPE_DESCRIPTIONS; 362270069b7SAdrian Chadd 363270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_ethernet_descriptions[] = 364270069b7SAdrian Chadd IFM_SUBTYPE_ETHERNET_DESCRIPTIONS; 365270069b7SAdrian Chadd 366270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_ethernet_aliases[] = 367270069b7SAdrian Chadd IFM_SUBTYPE_ETHERNET_ALIASES; 368270069b7SAdrian Chadd 369270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_ethernet_option_descriptions[] = 370270069b7SAdrian Chadd IFM_SUBTYPE_ETHERNET_OPTION_DESCRIPTIONS; 371270069b7SAdrian Chadd 372270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_tokenring_descriptions[] = 373270069b7SAdrian Chadd IFM_SUBTYPE_TOKENRING_DESCRIPTIONS; 374270069b7SAdrian Chadd 375270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_tokenring_aliases[] = 376270069b7SAdrian Chadd IFM_SUBTYPE_TOKENRING_ALIASES; 377270069b7SAdrian Chadd 378270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_tokenring_option_descriptions[] = 379270069b7SAdrian Chadd IFM_SUBTYPE_TOKENRING_OPTION_DESCRIPTIONS; 380270069b7SAdrian Chadd 381270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_fddi_descriptions[] = 382270069b7SAdrian Chadd IFM_SUBTYPE_FDDI_DESCRIPTIONS; 383270069b7SAdrian Chadd 384270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_fddi_aliases[] = 385270069b7SAdrian Chadd IFM_SUBTYPE_FDDI_ALIASES; 386270069b7SAdrian Chadd 387270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_fddi_option_descriptions[] = 388270069b7SAdrian Chadd IFM_SUBTYPE_FDDI_OPTION_DESCRIPTIONS; 389270069b7SAdrian Chadd 390270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_ieee80211_descriptions[] = 391270069b7SAdrian Chadd IFM_SUBTYPE_IEEE80211_DESCRIPTIONS; 392270069b7SAdrian Chadd 393270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_ieee80211_aliases[] = 394270069b7SAdrian Chadd IFM_SUBTYPE_IEEE80211_ALIASES; 395270069b7SAdrian Chadd 396270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_ieee80211_option_descriptions[] = 397270069b7SAdrian Chadd IFM_SUBTYPE_IEEE80211_OPTION_DESCRIPTIONS; 398270069b7SAdrian Chadd 399*ae824d80SEd Schouten static struct ifmedia_description ifm_subtype_ieee80211_mode_descriptions[] = 400270069b7SAdrian Chadd IFM_SUBTYPE_IEEE80211_MODE_DESCRIPTIONS; 401270069b7SAdrian Chadd 402*ae824d80SEd Schouten static struct ifmedia_description ifm_subtype_ieee80211_mode_aliases[] = 403270069b7SAdrian Chadd IFM_SUBTYPE_IEEE80211_MODE_ALIASES; 404270069b7SAdrian Chadd 405270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_atm_descriptions[] = 406270069b7SAdrian Chadd IFM_SUBTYPE_ATM_DESCRIPTIONS; 407270069b7SAdrian Chadd 408270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_atm_aliases[] = 409270069b7SAdrian Chadd IFM_SUBTYPE_ATM_ALIASES; 410270069b7SAdrian Chadd 411270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_atm_option_descriptions[] = 412270069b7SAdrian Chadd IFM_SUBTYPE_ATM_OPTION_DESCRIPTIONS; 413270069b7SAdrian Chadd 414270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_shared_descriptions[] = 415270069b7SAdrian Chadd IFM_SUBTYPE_SHARED_DESCRIPTIONS; 416270069b7SAdrian Chadd 417270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_shared_aliases[] = 418270069b7SAdrian Chadd IFM_SUBTYPE_SHARED_ALIASES; 419270069b7SAdrian Chadd 420270069b7SAdrian Chadd static struct ifmedia_description ifm_shared_option_descriptions[] = 421270069b7SAdrian Chadd IFM_SHARED_OPTION_DESCRIPTIONS; 422270069b7SAdrian Chadd 423270069b7SAdrian Chadd static struct ifmedia_description ifm_shared_option_aliases[] = 424270069b7SAdrian Chadd IFM_SHARED_OPTION_ALIASES; 425270069b7SAdrian Chadd 426270069b7SAdrian Chadd struct ifmedia_type_to_subtype { 427270069b7SAdrian Chadd struct { 428270069b7SAdrian Chadd struct ifmedia_description *desc; 429270069b7SAdrian Chadd int alias; 430270069b7SAdrian Chadd } subtypes[5]; 431270069b7SAdrian Chadd struct { 432270069b7SAdrian Chadd struct ifmedia_description *desc; 433270069b7SAdrian Chadd int alias; 434270069b7SAdrian Chadd } options[4]; 435270069b7SAdrian Chadd struct { 436270069b7SAdrian Chadd struct ifmedia_description *desc; 437270069b7SAdrian Chadd int alias; 438270069b7SAdrian Chadd } modes[3]; 439270069b7SAdrian Chadd }; 440270069b7SAdrian Chadd 441270069b7SAdrian Chadd /* must be in the same order as IFM_TYPE_DESCRIPTIONS */ 442270069b7SAdrian Chadd static struct ifmedia_type_to_subtype ifmedia_types_to_subtypes[] = { 443270069b7SAdrian Chadd { 444270069b7SAdrian Chadd { 445270069b7SAdrian Chadd { &ifm_subtype_shared_descriptions[0], 0 }, 446270069b7SAdrian Chadd { &ifm_subtype_shared_aliases[0], 1 }, 447270069b7SAdrian Chadd { &ifm_subtype_ethernet_descriptions[0], 0 }, 448270069b7SAdrian Chadd { &ifm_subtype_ethernet_aliases[0], 1 }, 449270069b7SAdrian Chadd { NULL, 0 }, 450270069b7SAdrian Chadd }, 451270069b7SAdrian Chadd { 452270069b7SAdrian Chadd { &ifm_shared_option_descriptions[0], 0 }, 453270069b7SAdrian Chadd { &ifm_shared_option_aliases[0], 1 }, 454270069b7SAdrian Chadd { &ifm_subtype_ethernet_option_descriptions[0], 0 }, 455270069b7SAdrian Chadd { NULL, 0 }, 456270069b7SAdrian Chadd }, 457270069b7SAdrian Chadd { 458270069b7SAdrian Chadd { NULL, 0 }, 459270069b7SAdrian Chadd }, 460270069b7SAdrian Chadd }, 461270069b7SAdrian Chadd { 462270069b7SAdrian Chadd { 463270069b7SAdrian Chadd { &ifm_subtype_shared_descriptions[0], 0 }, 464270069b7SAdrian Chadd { &ifm_subtype_shared_aliases[0], 1 }, 465270069b7SAdrian Chadd { &ifm_subtype_tokenring_descriptions[0], 0 }, 466270069b7SAdrian Chadd { &ifm_subtype_tokenring_aliases[0], 1 }, 467270069b7SAdrian Chadd { NULL, 0 }, 468270069b7SAdrian Chadd }, 469270069b7SAdrian Chadd { 470270069b7SAdrian Chadd { &ifm_shared_option_descriptions[0], 0 }, 471270069b7SAdrian Chadd { &ifm_shared_option_aliases[0], 1 }, 472270069b7SAdrian Chadd { &ifm_subtype_tokenring_option_descriptions[0], 0 }, 473270069b7SAdrian Chadd { NULL, 0 }, 474270069b7SAdrian Chadd }, 475270069b7SAdrian Chadd { 476270069b7SAdrian Chadd { NULL, 0 }, 477270069b7SAdrian Chadd }, 478270069b7SAdrian Chadd }, 479270069b7SAdrian Chadd { 480270069b7SAdrian Chadd { 481270069b7SAdrian Chadd { &ifm_subtype_shared_descriptions[0], 0 }, 482270069b7SAdrian Chadd { &ifm_subtype_shared_aliases[0], 1 }, 483270069b7SAdrian Chadd { &ifm_subtype_fddi_descriptions[0], 0 }, 484270069b7SAdrian Chadd { &ifm_subtype_fddi_aliases[0], 1 }, 485270069b7SAdrian Chadd { NULL, 0 }, 486270069b7SAdrian Chadd }, 487270069b7SAdrian Chadd { 488270069b7SAdrian Chadd { &ifm_shared_option_descriptions[0], 0 }, 489270069b7SAdrian Chadd { &ifm_shared_option_aliases[0], 1 }, 490270069b7SAdrian Chadd { &ifm_subtype_fddi_option_descriptions[0], 0 }, 491270069b7SAdrian Chadd { NULL, 0 }, 492270069b7SAdrian Chadd }, 493270069b7SAdrian Chadd { 494270069b7SAdrian Chadd { NULL, 0 }, 495270069b7SAdrian Chadd }, 496270069b7SAdrian Chadd }, 497270069b7SAdrian Chadd { 498270069b7SAdrian Chadd { 499270069b7SAdrian Chadd { &ifm_subtype_shared_descriptions[0], 0 }, 500270069b7SAdrian Chadd { &ifm_subtype_shared_aliases[0], 1 }, 501270069b7SAdrian Chadd { &ifm_subtype_ieee80211_descriptions[0], 0 }, 502270069b7SAdrian Chadd { &ifm_subtype_ieee80211_aliases[0], 1 }, 503270069b7SAdrian Chadd { NULL, 0 }, 504270069b7SAdrian Chadd }, 505270069b7SAdrian Chadd { 506270069b7SAdrian Chadd { &ifm_shared_option_descriptions[0], 0 }, 507270069b7SAdrian Chadd { &ifm_shared_option_aliases[0], 1 }, 508270069b7SAdrian Chadd { &ifm_subtype_ieee80211_option_descriptions[0], 0 }, 509270069b7SAdrian Chadd { NULL, 0 }, 510270069b7SAdrian Chadd }, 511270069b7SAdrian Chadd { 512270069b7SAdrian Chadd { &ifm_subtype_ieee80211_mode_descriptions[0], 0 }, 513270069b7SAdrian Chadd { &ifm_subtype_ieee80211_mode_aliases[0], 0 }, 514270069b7SAdrian Chadd { NULL, 0 }, 515270069b7SAdrian Chadd }, 516270069b7SAdrian Chadd }, 517270069b7SAdrian Chadd { 518270069b7SAdrian Chadd { 519270069b7SAdrian Chadd { &ifm_subtype_shared_descriptions[0], 0 }, 520270069b7SAdrian Chadd { &ifm_subtype_shared_aliases[0], 1 }, 521270069b7SAdrian Chadd { &ifm_subtype_atm_descriptions[0], 0 }, 522270069b7SAdrian Chadd { &ifm_subtype_atm_aliases[0], 1 }, 523270069b7SAdrian Chadd { NULL, 0 }, 524270069b7SAdrian Chadd }, 525270069b7SAdrian Chadd { 526270069b7SAdrian Chadd { &ifm_shared_option_descriptions[0], 0 }, 527270069b7SAdrian Chadd { &ifm_shared_option_aliases[0], 1 }, 528270069b7SAdrian Chadd { &ifm_subtype_atm_option_descriptions[0], 0 }, 529270069b7SAdrian Chadd { NULL, 0 }, 530270069b7SAdrian Chadd }, 531270069b7SAdrian Chadd { 532270069b7SAdrian Chadd { NULL, 0 }, 533270069b7SAdrian Chadd }, 534270069b7SAdrian Chadd }, 535270069b7SAdrian Chadd }; 536270069b7SAdrian Chadd 537270069b7SAdrian Chadd int 538270069b7SAdrian Chadd get_media_subtype(int type, const char *val) 539270069b7SAdrian Chadd { 540270069b7SAdrian Chadd struct ifmedia_description *desc; 541270069b7SAdrian Chadd struct ifmedia_type_to_subtype *ttos; 542270069b7SAdrian Chadd int rval, i; 543270069b7SAdrian Chadd 544270069b7SAdrian Chadd /* Find the top-level interface type. */ 545270069b7SAdrian Chadd for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; 546270069b7SAdrian Chadd desc->ifmt_string != NULL; desc++, ttos++) 547270069b7SAdrian Chadd if (type == desc->ifmt_word) 548270069b7SAdrian Chadd break; 549270069b7SAdrian Chadd if (desc->ifmt_string == NULL) 550270069b7SAdrian Chadd errx(1, "unknown media type 0x%x", type); 551270069b7SAdrian Chadd 552270069b7SAdrian Chadd for (i = 0; ttos->subtypes[i].desc != NULL; i++) { 553270069b7SAdrian Chadd rval = lookup_media_word(ttos->subtypes[i].desc, val); 554270069b7SAdrian Chadd if (rval != -1) 555270069b7SAdrian Chadd return (rval); 556270069b7SAdrian Chadd } 557270069b7SAdrian Chadd errx(1, "unknown media subtype: %s", val); 558270069b7SAdrian Chadd /*NOTREACHED*/ 559270069b7SAdrian Chadd } 560270069b7SAdrian Chadd 561270069b7SAdrian Chadd int 562270069b7SAdrian Chadd get_media_mode(int type, const char *val) 563270069b7SAdrian Chadd { 564270069b7SAdrian Chadd struct ifmedia_description *desc; 565270069b7SAdrian Chadd struct ifmedia_type_to_subtype *ttos; 566270069b7SAdrian Chadd int rval, i; 567270069b7SAdrian Chadd 568270069b7SAdrian Chadd /* Find the top-level interface type. */ 569270069b7SAdrian Chadd for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; 570270069b7SAdrian Chadd desc->ifmt_string != NULL; desc++, ttos++) 571270069b7SAdrian Chadd if (type == desc->ifmt_word) 572270069b7SAdrian Chadd break; 573270069b7SAdrian Chadd if (desc->ifmt_string == NULL) 574270069b7SAdrian Chadd errx(1, "unknown media mode 0x%x", type); 575270069b7SAdrian Chadd 576270069b7SAdrian Chadd for (i = 0; ttos->modes[i].desc != NULL; i++) { 577270069b7SAdrian Chadd rval = lookup_media_word(ttos->modes[i].desc, val); 578270069b7SAdrian Chadd if (rval != -1) 579270069b7SAdrian Chadd return (rval); 580270069b7SAdrian Chadd } 581270069b7SAdrian Chadd return -1; 582270069b7SAdrian Chadd } 583270069b7SAdrian Chadd 584270069b7SAdrian Chadd int 585270069b7SAdrian Chadd get_media_options(int type, const char *val) 586270069b7SAdrian Chadd { 587270069b7SAdrian Chadd struct ifmedia_description *desc; 588270069b7SAdrian Chadd struct ifmedia_type_to_subtype *ttos; 589270069b7SAdrian Chadd char *optlist, *optptr; 590270069b7SAdrian Chadd int option = 0, i, rval = 0; 591270069b7SAdrian Chadd 592270069b7SAdrian Chadd /* We muck with the string, so copy it. */ 593270069b7SAdrian Chadd optlist = strdup(val); 594270069b7SAdrian Chadd if (optlist == NULL) 595270069b7SAdrian Chadd err(1, "strdup"); 596270069b7SAdrian Chadd 597270069b7SAdrian Chadd /* Find the top-level interface type. */ 598270069b7SAdrian Chadd for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; 599270069b7SAdrian Chadd desc->ifmt_string != NULL; desc++, ttos++) 600270069b7SAdrian Chadd if (type == desc->ifmt_word) 601270069b7SAdrian Chadd break; 602270069b7SAdrian Chadd if (desc->ifmt_string == NULL) 603270069b7SAdrian Chadd errx(1, "unknown media type 0x%x", type); 604270069b7SAdrian Chadd 605270069b7SAdrian Chadd /* 606270069b7SAdrian Chadd * Look up the options in the user-provided comma-separated 607270069b7SAdrian Chadd * list. 608270069b7SAdrian Chadd */ 609270069b7SAdrian Chadd optptr = optlist; 610270069b7SAdrian Chadd for (; (optptr = strtok(optptr, ",")) != NULL; optptr = NULL) { 611270069b7SAdrian Chadd for (i = 0; ttos->options[i].desc != NULL; i++) { 612270069b7SAdrian Chadd option = lookup_media_word(ttos->options[i].desc, optptr); 613270069b7SAdrian Chadd if (option != -1) 614270069b7SAdrian Chadd break; 615270069b7SAdrian Chadd } 616270069b7SAdrian Chadd if (option == 0) 617270069b7SAdrian Chadd errx(1, "unknown option: %s", optptr); 618270069b7SAdrian Chadd rval |= option; 619270069b7SAdrian Chadd } 620270069b7SAdrian Chadd 621270069b7SAdrian Chadd free(optlist); 622270069b7SAdrian Chadd return (rval); 623270069b7SAdrian Chadd } 624270069b7SAdrian Chadd 625270069b7SAdrian Chadd int 626270069b7SAdrian Chadd lookup_media_word(struct ifmedia_description *desc, const char *val) 627270069b7SAdrian Chadd { 628270069b7SAdrian Chadd 629270069b7SAdrian Chadd for (; desc->ifmt_string != NULL; desc++) 630270069b7SAdrian Chadd if (strcasecmp(desc->ifmt_string, val) == 0) 631270069b7SAdrian Chadd return (desc->ifmt_word); 632270069b7SAdrian Chadd 633270069b7SAdrian Chadd return (-1); 634270069b7SAdrian Chadd } 635270069b7SAdrian Chadd 636270069b7SAdrian Chadd static struct ifmedia_description *get_toptype_desc(int ifmw) 637270069b7SAdrian Chadd { 638270069b7SAdrian Chadd struct ifmedia_description *desc; 639270069b7SAdrian Chadd 640270069b7SAdrian Chadd for (desc = ifm_type_descriptions; desc->ifmt_string != NULL; desc++) 641270069b7SAdrian Chadd if (IFM_TYPE(ifmw) == desc->ifmt_word) 642270069b7SAdrian Chadd break; 643270069b7SAdrian Chadd 644270069b7SAdrian Chadd return desc; 645270069b7SAdrian Chadd } 646270069b7SAdrian Chadd 647270069b7SAdrian Chadd static struct ifmedia_type_to_subtype *get_toptype_ttos(int ifmw) 648270069b7SAdrian Chadd { 649270069b7SAdrian Chadd struct ifmedia_description *desc; 650270069b7SAdrian Chadd struct ifmedia_type_to_subtype *ttos; 651270069b7SAdrian Chadd 652270069b7SAdrian Chadd for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; 653270069b7SAdrian Chadd desc->ifmt_string != NULL; desc++, ttos++) 654270069b7SAdrian Chadd if (IFM_TYPE(ifmw) == desc->ifmt_word) 655270069b7SAdrian Chadd break; 656270069b7SAdrian Chadd 657270069b7SAdrian Chadd return ttos; 658270069b7SAdrian Chadd } 659270069b7SAdrian Chadd 660270069b7SAdrian Chadd static struct ifmedia_description *get_subtype_desc(int ifmw, 661270069b7SAdrian Chadd struct ifmedia_type_to_subtype *ttos) 662270069b7SAdrian Chadd { 663270069b7SAdrian Chadd int i; 664270069b7SAdrian Chadd struct ifmedia_description *desc; 665270069b7SAdrian Chadd 666270069b7SAdrian Chadd for (i = 0; ttos->subtypes[i].desc != NULL; i++) { 667270069b7SAdrian Chadd if (ttos->subtypes[i].alias) 668270069b7SAdrian Chadd continue; 669270069b7SAdrian Chadd for (desc = ttos->subtypes[i].desc; 670270069b7SAdrian Chadd desc->ifmt_string != NULL; desc++) { 671270069b7SAdrian Chadd if (IFM_SUBTYPE(ifmw) == desc->ifmt_word) 672270069b7SAdrian Chadd return desc; 673270069b7SAdrian Chadd } 674270069b7SAdrian Chadd } 675270069b7SAdrian Chadd 676270069b7SAdrian Chadd return NULL; 677270069b7SAdrian Chadd } 678270069b7SAdrian Chadd 679270069b7SAdrian Chadd static struct ifmedia_description *get_mode_desc(int ifmw, 680270069b7SAdrian Chadd struct ifmedia_type_to_subtype *ttos) 681270069b7SAdrian Chadd { 682270069b7SAdrian Chadd int i; 683270069b7SAdrian Chadd struct ifmedia_description *desc; 684270069b7SAdrian Chadd 685270069b7SAdrian Chadd for (i = 0; ttos->modes[i].desc != NULL; i++) { 686270069b7SAdrian Chadd if (ttos->modes[i].alias) 687270069b7SAdrian Chadd continue; 688270069b7SAdrian Chadd for (desc = ttos->modes[i].desc; 689270069b7SAdrian Chadd desc->ifmt_string != NULL; desc++) { 690270069b7SAdrian Chadd if (IFM_MODE(ifmw) == desc->ifmt_word) 691270069b7SAdrian Chadd return desc; 692270069b7SAdrian Chadd } 693270069b7SAdrian Chadd } 694270069b7SAdrian Chadd 695270069b7SAdrian Chadd return NULL; 696270069b7SAdrian Chadd } 697270069b7SAdrian Chadd 698270069b7SAdrian Chadd void 699270069b7SAdrian Chadd print_media_word(int ifmw, int print_toptype) 700270069b7SAdrian Chadd { 701270069b7SAdrian Chadd struct ifmedia_description *desc; 702270069b7SAdrian Chadd struct ifmedia_type_to_subtype *ttos; 703270069b7SAdrian Chadd int seen_option = 0, i; 704270069b7SAdrian Chadd 705270069b7SAdrian Chadd /* Find the top-level interface type. */ 706270069b7SAdrian Chadd desc = get_toptype_desc(ifmw); 707270069b7SAdrian Chadd ttos = get_toptype_ttos(ifmw); 708270069b7SAdrian Chadd if (desc->ifmt_string == NULL) { 709270069b7SAdrian Chadd printf("<unknown type>"); 710270069b7SAdrian Chadd return; 711270069b7SAdrian Chadd } else if (print_toptype) { 712270069b7SAdrian Chadd printf("%s", desc->ifmt_string); 713270069b7SAdrian Chadd } 714270069b7SAdrian Chadd 715270069b7SAdrian Chadd /* 716270069b7SAdrian Chadd * Don't print the top-level type; it's not like we can 717270069b7SAdrian Chadd * change it, or anything. 718270069b7SAdrian Chadd */ 719270069b7SAdrian Chadd 720270069b7SAdrian Chadd /* Find subtype. */ 721270069b7SAdrian Chadd desc = get_subtype_desc(ifmw, ttos); 722270069b7SAdrian Chadd if (desc == NULL) { 723270069b7SAdrian Chadd printf("<unknown subtype>"); 724270069b7SAdrian Chadd return; 725270069b7SAdrian Chadd } 726270069b7SAdrian Chadd 727270069b7SAdrian Chadd if (print_toptype) 728270069b7SAdrian Chadd putchar(' '); 729270069b7SAdrian Chadd 730270069b7SAdrian Chadd printf("%s", desc->ifmt_string); 731270069b7SAdrian Chadd 732270069b7SAdrian Chadd if (print_toptype) { 733270069b7SAdrian Chadd desc = get_mode_desc(ifmw, ttos); 734270069b7SAdrian Chadd if (desc != NULL && strcasecmp("autoselect", desc->ifmt_string)) 735270069b7SAdrian Chadd printf(" mode %s", desc->ifmt_string); 736270069b7SAdrian Chadd } 737270069b7SAdrian Chadd 738270069b7SAdrian Chadd /* Find options. */ 739270069b7SAdrian Chadd for (i = 0; ttos->options[i].desc != NULL; i++) { 740270069b7SAdrian Chadd if (ttos->options[i].alias) 741270069b7SAdrian Chadd continue; 742270069b7SAdrian Chadd for (desc = ttos->options[i].desc; 743270069b7SAdrian Chadd desc->ifmt_string != NULL; desc++) { 744270069b7SAdrian Chadd if (ifmw & desc->ifmt_word) { 745270069b7SAdrian Chadd if (seen_option == 0) 746270069b7SAdrian Chadd printf(" <"); 747270069b7SAdrian Chadd printf("%s%s", seen_option++ ? "," : "", 748270069b7SAdrian Chadd desc->ifmt_string); 749270069b7SAdrian Chadd } 750270069b7SAdrian Chadd } 751270069b7SAdrian Chadd } 752270069b7SAdrian Chadd printf("%s", seen_option ? ">" : ""); 753270069b7SAdrian Chadd 754270069b7SAdrian Chadd if (print_toptype && IFM_INST(ifmw) != 0) 755270069b7SAdrian Chadd printf(" instance %d", IFM_INST(ifmw)); 756270069b7SAdrian Chadd } 757270069b7SAdrian Chadd 758270069b7SAdrian Chadd void 759270069b7SAdrian Chadd print_media_word_ifconfig(int ifmw) 760270069b7SAdrian Chadd { 761270069b7SAdrian Chadd struct ifmedia_description *desc; 762270069b7SAdrian Chadd struct ifmedia_type_to_subtype *ttos; 763270069b7SAdrian Chadd int seen_option = 0, i; 764270069b7SAdrian Chadd 765270069b7SAdrian Chadd /* Find the top-level interface type. */ 766270069b7SAdrian Chadd desc = get_toptype_desc(ifmw); 767270069b7SAdrian Chadd ttos = get_toptype_ttos(ifmw); 768270069b7SAdrian Chadd if (desc->ifmt_string == NULL) { 769270069b7SAdrian Chadd printf("<unknown type>"); 770270069b7SAdrian Chadd return; 771270069b7SAdrian Chadd } 772270069b7SAdrian Chadd 773270069b7SAdrian Chadd /* 774270069b7SAdrian Chadd * Don't print the top-level type; it's not like we can 775270069b7SAdrian Chadd * change it, or anything. 776270069b7SAdrian Chadd */ 777270069b7SAdrian Chadd 778270069b7SAdrian Chadd /* Find subtype. */ 779270069b7SAdrian Chadd desc = get_subtype_desc(ifmw, ttos); 780270069b7SAdrian Chadd if (desc == NULL) { 781270069b7SAdrian Chadd printf("<unknown subtype>"); 782270069b7SAdrian Chadd return; 783270069b7SAdrian Chadd } 784270069b7SAdrian Chadd 785270069b7SAdrian Chadd printf("media %s", desc->ifmt_string); 786270069b7SAdrian Chadd 787270069b7SAdrian Chadd desc = get_mode_desc(ifmw, ttos); 788270069b7SAdrian Chadd if (desc != NULL) 789270069b7SAdrian Chadd printf(" mode %s", desc->ifmt_string); 790270069b7SAdrian Chadd 791270069b7SAdrian Chadd /* Find options. */ 792270069b7SAdrian Chadd for (i = 0; ttos->options[i].desc != NULL; i++) { 793270069b7SAdrian Chadd if (ttos->options[i].alias) 794270069b7SAdrian Chadd continue; 795270069b7SAdrian Chadd for (desc = ttos->options[i].desc; 796270069b7SAdrian Chadd desc->ifmt_string != NULL; desc++) { 797270069b7SAdrian Chadd if (ifmw & desc->ifmt_word) { 798270069b7SAdrian Chadd if (seen_option == 0) 799270069b7SAdrian Chadd printf(" mediaopt "); 800270069b7SAdrian Chadd printf("%s%s", seen_option++ ? "," : "", 801270069b7SAdrian Chadd desc->ifmt_string); 802270069b7SAdrian Chadd } 803270069b7SAdrian Chadd } 804270069b7SAdrian Chadd } 805270069b7SAdrian Chadd 806270069b7SAdrian Chadd if (IFM_INST(ifmw) != 0) 807270069b7SAdrian Chadd printf(" instance %d", IFM_INST(ifmw)); 808270069b7SAdrian Chadd } 809270069b7SAdrian Chadd 810270069b7SAdrian Chadd /********************************************************************** 811270069b7SAdrian Chadd * ...until here. 812270069b7SAdrian Chadd **********************************************************************/ 813