1235289Sadrian/* $NetBSD: ifconfig.c,v 1.34 1997/04/21 01:17:58 lukem Exp $ */ 2235289Sadrian/* $FreeBSD$ */ 3235289Sadrian 4331722Seadler/* 5235289Sadrian * Copyright (c) 1997 Jason R. Thorpe. 6235289Sadrian * All rights reserved. 7235289Sadrian * 8235289Sadrian * Redistribution and use in source and binary forms, with or without 9235289Sadrian * modification, are permitted provided that the following conditions 10235289Sadrian * are met: 11235289Sadrian * 1. Redistributions of source code must retain the above copyright 12235289Sadrian * notice, this list of conditions and the following disclaimer. 13235289Sadrian * 2. Redistributions in binary form must reproduce the above copyright 14235289Sadrian * notice, this list of conditions and the following disclaimer in the 15235289Sadrian * documentation and/or other materials provided with the distribution. 16235289Sadrian * 3. All advertising materials mentioning features or use of this software 17235289Sadrian * must display the following acknowledgement: 18235289Sadrian * This product includes software developed for the NetBSD Project 19235289Sadrian * by Jason R. Thorpe. 20235289Sadrian * 4. The name of the author may not be used to endorse or promote products 21235289Sadrian * derived from this software without specific prior written permission. 22235289Sadrian * 23235289Sadrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24235289Sadrian * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25235289Sadrian * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26235289Sadrian * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27235289Sadrian * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28235289Sadrian * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29235289Sadrian * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 30235289Sadrian * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31235289Sadrian * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32235289Sadrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33235289Sadrian * SUCH DAMAGE. 34235289Sadrian */ 35235289Sadrian 36235289Sadrian/* 37235289Sadrian * Copyright (c) 1983, 1993 38235289Sadrian * The Regents of the University of California. All rights reserved. 39235289Sadrian * 40235289Sadrian * Redistribution and use in source and binary forms, with or without 41235289Sadrian * modification, are permitted provided that the following conditions 42235289Sadrian * are met: 43235289Sadrian * 1. Redistributions of source code must retain the above copyright 44235289Sadrian * notice, this list of conditions and the following disclaimer. 45235289Sadrian * 2. Redistributions in binary form must reproduce the above copyright 46235289Sadrian * notice, this list of conditions and the following disclaimer in the 47235289Sadrian * documentation and/or other materials provided with the distribution. 48235289Sadrian * 4. Neither the name of the University nor the names of its contributors 49235289Sadrian * may be used to endorse or promote products derived from this software 50235289Sadrian * without specific prior written permission. 51235289Sadrian * 52235289Sadrian * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 53235289Sadrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 54235289Sadrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 55235289Sadrian * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 56235289Sadrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 57235289Sadrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 58235289Sadrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 59235289Sadrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 60235289Sadrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 61235289Sadrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 62235289Sadrian * SUCH DAMAGE. 63235289Sadrian */ 64235289Sadrian/* 65235289Sadrian * based on sbin/ifconfig/ifmedia.c r221954 66235289Sadrian */ 67235289Sadrian 68235289Sadrian#include <sys/param.h> 69235289Sadrian#include <sys/ioctl.h> 70235289Sadrian#include <sys/socket.h> 71235289Sadrian#include <sys/sysctl.h> 72235289Sadrian#include <sys/time.h> 73235289Sadrian 74235289Sadrian#include <net/if.h> 75235289Sadrian#include <net/if_dl.h> 76235289Sadrian#include <net/if_types.h> 77235289Sadrian#include <net/if_media.h> 78235289Sadrian#include <net/route.h> 79235289Sadrian 80235289Sadrian#include <ctype.h> 81235289Sadrian#include <err.h> 82235289Sadrian#include <errno.h> 83235289Sadrian#include <fcntl.h> 84235289Sadrian#include <stdio.h> 85235289Sadrian#include <stdlib.h> 86235289Sadrian#include <string.h> 87235289Sadrian#include <unistd.h> 88235289Sadrian 89235289Sadrianvoid domediaopt(const char *, int, int); 90235289Sadrianint get_media_subtype(int, const char *); 91235289Sadrianint get_media_mode(int, const char *); 92235289Sadrianint get_media_options(int, const char *); 93235289Sadrianint lookup_media_word(struct ifmedia_description *, const char *); 94235289Sadrianvoid print_media_word(int, int); 95235289Sadrianvoid print_media_word_ifconfig(int); 96235289Sadrian 97235289Sadrian#if 0 98235289Sadrianstatic struct ifmedia_description *get_toptype_desc(int); 99235289Sadrianstatic struct ifmedia_type_to_subtype *get_toptype_ttos(int); 100235289Sadrianstatic struct ifmedia_description *get_subtype_desc(int, 101235289Sadrian struct ifmedia_type_to_subtype *ttos); 102235289Sadrian 103235289Sadrian#define IFM_OPMODE(x) \ 104235289Sadrian ((x) & (IFM_IEEE80211_ADHOC | IFM_IEEE80211_HOSTAP | \ 105235289Sadrian IFM_IEEE80211_IBSS | IFM_IEEE80211_WDS | IFM_IEEE80211_MONITOR | \ 106235289Sadrian IFM_IEEE80211_MBSS)) 107235289Sadrian#define IFM_IEEE80211_STA 0 108235289Sadrian 109235289Sadrianstatic void 110235289Sadrianmedia_status(int s) 111235289Sadrian{ 112235289Sadrian struct ifmediareq ifmr; 113235289Sadrian int *media_list, i; 114235289Sadrian 115235289Sadrian (void) memset(&ifmr, 0, sizeof(ifmr)); 116235289Sadrian (void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name)); 117235289Sadrian 118235289Sadrian if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) { 119235289Sadrian /* 120235289Sadrian * Interface doesn't support SIOC{G,S}IFMEDIA. 121235289Sadrian */ 122235289Sadrian return; 123235289Sadrian } 124235289Sadrian 125235289Sadrian if (ifmr.ifm_count == 0) { 126235289Sadrian warnx("%s: no media types?", name); 127235289Sadrian return; 128235289Sadrian } 129235289Sadrian 130235289Sadrian media_list = (int *)malloc(ifmr.ifm_count * sizeof(int)); 131235289Sadrian if (media_list == NULL) 132235289Sadrian err(1, "malloc"); 133235289Sadrian ifmr.ifm_ulist = media_list; 134235289Sadrian 135235289Sadrian if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) 136235289Sadrian err(1, "SIOCGIFMEDIA"); 137235289Sadrian 138235289Sadrian printf("\tmedia: "); 139235289Sadrian print_media_word(ifmr.ifm_current, 1); 140235289Sadrian if (ifmr.ifm_active != ifmr.ifm_current) { 141235289Sadrian putchar(' '); 142235289Sadrian putchar('('); 143235289Sadrian print_media_word(ifmr.ifm_active, 0); 144235289Sadrian putchar(')'); 145235289Sadrian } 146235289Sadrian 147235289Sadrian putchar('\n'); 148235289Sadrian 149235289Sadrian if (ifmr.ifm_status & IFM_AVALID) { 150235289Sadrian printf("\tstatus: "); 151235289Sadrian switch (IFM_TYPE(ifmr.ifm_active)) { 152235289Sadrian case IFM_ETHER: 153235289Sadrian case IFM_ATM: 154235289Sadrian if (ifmr.ifm_status & IFM_ACTIVE) 155235289Sadrian printf("active"); 156235289Sadrian else 157235289Sadrian printf("no carrier"); 158235289Sadrian break; 159235289Sadrian 160235289Sadrian case IFM_FDDI: 161235289Sadrian case IFM_TOKEN: 162235289Sadrian if (ifmr.ifm_status & IFM_ACTIVE) 163235289Sadrian printf("inserted"); 164235289Sadrian else 165235289Sadrian printf("no ring"); 166235289Sadrian break; 167235289Sadrian 168235289Sadrian case IFM_IEEE80211: 169235289Sadrian if (ifmr.ifm_status & IFM_ACTIVE) { 170235289Sadrian /* NB: only sta mode associates */ 171235289Sadrian if (IFM_OPMODE(ifmr.ifm_active) == IFM_IEEE80211_STA) 172235289Sadrian printf("associated"); 173235289Sadrian else 174235289Sadrian printf("running"); 175235289Sadrian } else 176235289Sadrian printf("no carrier"); 177235289Sadrian break; 178235289Sadrian } 179235289Sadrian putchar('\n'); 180235289Sadrian } 181235289Sadrian 182235289Sadrian if (ifmr.ifm_count > 0 && supmedia) { 183235289Sadrian printf("\tsupported media:\n"); 184235289Sadrian for (i = 0; i < ifmr.ifm_count; i++) { 185235289Sadrian printf("\t\t"); 186235289Sadrian print_media_word_ifconfig(media_list[i]); 187235289Sadrian putchar('\n'); 188235289Sadrian } 189235289Sadrian } 190235289Sadrian 191235289Sadrian free(media_list); 192235289Sadrian} 193235289Sadrian 194235289Sadrianstruct ifmediareq * 195235289Sadrianifmedia_getstate(int s) 196235289Sadrian{ 197235289Sadrian static struct ifmediareq *ifmr = NULL; 198235289Sadrian int *mwords; 199235289Sadrian 200235289Sadrian if (ifmr == NULL) { 201235289Sadrian ifmr = (struct ifmediareq *)malloc(sizeof(struct ifmediareq)); 202235289Sadrian if (ifmr == NULL) 203235289Sadrian err(1, "malloc"); 204235289Sadrian 205235289Sadrian (void) memset(ifmr, 0, sizeof(struct ifmediareq)); 206235289Sadrian (void) strncpy(ifmr->ifm_name, name, 207235289Sadrian sizeof(ifmr->ifm_name)); 208235289Sadrian 209235289Sadrian ifmr->ifm_count = 0; 210235289Sadrian ifmr->ifm_ulist = NULL; 211235289Sadrian 212235289Sadrian /* 213235289Sadrian * We must go through the motions of reading all 214235289Sadrian * supported media because we need to know both 215235289Sadrian * the current media type and the top-level type. 216235289Sadrian */ 217235289Sadrian 218235289Sadrian if (ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0) { 219235289Sadrian err(1, "SIOCGIFMEDIA"); 220235289Sadrian } 221235289Sadrian 222235289Sadrian if (ifmr->ifm_count == 0) 223235289Sadrian errx(1, "%s: no media types?", name); 224235289Sadrian 225235289Sadrian mwords = (int *)malloc(ifmr->ifm_count * sizeof(int)); 226235289Sadrian if (mwords == NULL) 227235289Sadrian err(1, "malloc"); 228235289Sadrian 229235289Sadrian ifmr->ifm_ulist = mwords; 230235289Sadrian if (ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0) 231235289Sadrian err(1, "SIOCGIFMEDIA"); 232235289Sadrian } 233235289Sadrian 234235289Sadrian return ifmr; 235235289Sadrian} 236235289Sadrian 237235289Sadrianstatic void 238235289Sadriansetifmediacallback(int s, void *arg) 239235289Sadrian{ 240235289Sadrian struct ifmediareq *ifmr = (struct ifmediareq *)arg; 241235289Sadrian static int did_it = 0; 242235289Sadrian 243235289Sadrian if (!did_it) { 244235289Sadrian ifr.ifr_media = ifmr->ifm_current; 245235289Sadrian if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) < 0) 246235289Sadrian err(1, "SIOCSIFMEDIA (media)"); 247235289Sadrian free(ifmr->ifm_ulist); 248235289Sadrian free(ifmr); 249235289Sadrian did_it = 1; 250235289Sadrian } 251235289Sadrian} 252235289Sadrian 253235289Sadrianstatic void 254235289Sadriansetmedia(const char *val, int d, int s, const struct afswtch *afp) 255235289Sadrian{ 256235289Sadrian struct ifmediareq *ifmr; 257235289Sadrian int subtype; 258235289Sadrian 259235289Sadrian ifmr = ifmedia_getstate(s); 260235289Sadrian 261235289Sadrian /* 262235289Sadrian * We are primarily concerned with the top-level type. 263235289Sadrian * However, "current" may be only IFM_NONE, so we just look 264235289Sadrian * for the top-level type in the first "supported type" 265235289Sadrian * entry. 266235289Sadrian * 267235289Sadrian * (I'm assuming that all supported media types for a given 268235289Sadrian * interface will be the same top-level type..) 269235289Sadrian */ 270235289Sadrian subtype = get_media_subtype(IFM_TYPE(ifmr->ifm_ulist[0]), val); 271235289Sadrian 272235289Sadrian strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 273235289Sadrian ifr.ifr_media = (ifmr->ifm_current & IFM_IMASK) | 274235289Sadrian IFM_TYPE(ifmr->ifm_ulist[0]) | subtype; 275235289Sadrian 276235289Sadrian ifmr->ifm_current = ifr.ifr_media; 277235289Sadrian callback_register(setifmediacallback, (void *)ifmr); 278235289Sadrian} 279235289Sadrian 280235289Sadrianstatic void 281235289Sadriansetmediaopt(const char *val, int d, int s, const struct afswtch *afp) 282235289Sadrian{ 283235289Sadrian 284235289Sadrian domediaopt(val, 0, s); 285235289Sadrian} 286235289Sadrian 287235289Sadrianstatic void 288235289Sadrianunsetmediaopt(const char *val, int d, int s, const struct afswtch *afp) 289235289Sadrian{ 290235289Sadrian 291235289Sadrian domediaopt(val, 1, s); 292235289Sadrian} 293235289Sadrian 294235289Sadrianstatic void 295235289Sadriandomediaopt(const char *val, int clear, int s) 296235289Sadrian{ 297235289Sadrian struct ifmediareq *ifmr; 298235289Sadrian int options; 299235289Sadrian 300235289Sadrian ifmr = ifmedia_getstate(s); 301235289Sadrian 302235289Sadrian options = get_media_options(IFM_TYPE(ifmr->ifm_ulist[0]), val); 303235289Sadrian 304235289Sadrian strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 305235289Sadrian ifr.ifr_media = ifmr->ifm_current; 306235289Sadrian if (clear) 307235289Sadrian ifr.ifr_media &= ~options; 308235289Sadrian else { 309235289Sadrian if (options & IFM_HDX) { 310235289Sadrian ifr.ifr_media &= ~IFM_FDX; 311235289Sadrian options &= ~IFM_HDX; 312235289Sadrian } 313235289Sadrian ifr.ifr_media |= options; 314235289Sadrian } 315235289Sadrian ifmr->ifm_current = ifr.ifr_media; 316235289Sadrian callback_register(setifmediacallback, (void *)ifmr); 317235289Sadrian} 318235289Sadrian 319235289Sadrianstatic void 320235289Sadriansetmediainst(const char *val, int d, int s, const struct afswtch *afp) 321235289Sadrian{ 322235289Sadrian struct ifmediareq *ifmr; 323235289Sadrian int inst; 324235289Sadrian 325235289Sadrian ifmr = ifmedia_getstate(s); 326235289Sadrian 327235289Sadrian inst = atoi(val); 328235289Sadrian if (inst < 0 || inst > (int)IFM_INST_MAX) 329235289Sadrian errx(1, "invalid media instance: %s", val); 330235289Sadrian 331235289Sadrian strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 332235289Sadrian ifr.ifr_media = (ifmr->ifm_current & ~IFM_IMASK) | inst << IFM_ISHIFT; 333235289Sadrian 334235289Sadrian ifmr->ifm_current = ifr.ifr_media; 335235289Sadrian callback_register(setifmediacallback, (void *)ifmr); 336235289Sadrian} 337235289Sadrian 338235289Sadrianstatic void 339235289Sadriansetmediamode(const char *val, int d, int s, const struct afswtch *afp) 340235289Sadrian{ 341235289Sadrian struct ifmediareq *ifmr; 342235289Sadrian int mode; 343235289Sadrian 344235289Sadrian ifmr = ifmedia_getstate(s); 345235289Sadrian 346235289Sadrian mode = get_media_mode(IFM_TYPE(ifmr->ifm_ulist[0]), val); 347235289Sadrian 348235289Sadrian strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 349235289Sadrian ifr.ifr_media = (ifmr->ifm_current & ~IFM_MMASK) | mode; 350235289Sadrian 351235289Sadrian ifmr->ifm_current = ifr.ifr_media; 352235289Sadrian callback_register(setifmediacallback, (void *)ifmr); 353235289Sadrian} 354235289Sadrian#endif 355235289Sadrian 356235289Sadrian/********************************************************************** 357235289Sadrian * A good chunk of this is duplicated from sys/net/ifmedia.c 358235289Sadrian **********************************************************************/ 359235289Sadrian 360235289Sadrianstatic struct ifmedia_description ifm_type_descriptions[] = 361235289Sadrian IFM_TYPE_DESCRIPTIONS; 362235289Sadrian 363235289Sadrianstatic struct ifmedia_description ifm_subtype_ethernet_descriptions[] = 364235289Sadrian IFM_SUBTYPE_ETHERNET_DESCRIPTIONS; 365235289Sadrian 366235289Sadrianstatic struct ifmedia_description ifm_subtype_ethernet_aliases[] = 367235289Sadrian IFM_SUBTYPE_ETHERNET_ALIASES; 368235289Sadrian 369235289Sadrianstatic struct ifmedia_description ifm_subtype_ethernet_option_descriptions[] = 370235289Sadrian IFM_SUBTYPE_ETHERNET_OPTION_DESCRIPTIONS; 371235289Sadrian 372235289Sadrianstatic struct ifmedia_description ifm_subtype_tokenring_descriptions[] = 373235289Sadrian IFM_SUBTYPE_TOKENRING_DESCRIPTIONS; 374235289Sadrian 375235289Sadrianstatic struct ifmedia_description ifm_subtype_tokenring_aliases[] = 376235289Sadrian IFM_SUBTYPE_TOKENRING_ALIASES; 377235289Sadrian 378235289Sadrianstatic struct ifmedia_description ifm_subtype_tokenring_option_descriptions[] = 379235289Sadrian IFM_SUBTYPE_TOKENRING_OPTION_DESCRIPTIONS; 380235289Sadrian 381235289Sadrianstatic struct ifmedia_description ifm_subtype_fddi_descriptions[] = 382235289Sadrian IFM_SUBTYPE_FDDI_DESCRIPTIONS; 383235289Sadrian 384235289Sadrianstatic struct ifmedia_description ifm_subtype_fddi_aliases[] = 385235289Sadrian IFM_SUBTYPE_FDDI_ALIASES; 386235289Sadrian 387235289Sadrianstatic struct ifmedia_description ifm_subtype_fddi_option_descriptions[] = 388235289Sadrian IFM_SUBTYPE_FDDI_OPTION_DESCRIPTIONS; 389235289Sadrian 390235289Sadrianstatic struct ifmedia_description ifm_subtype_ieee80211_descriptions[] = 391235289Sadrian IFM_SUBTYPE_IEEE80211_DESCRIPTIONS; 392235289Sadrian 393235289Sadrianstatic struct ifmedia_description ifm_subtype_ieee80211_aliases[] = 394235289Sadrian IFM_SUBTYPE_IEEE80211_ALIASES; 395235289Sadrian 396235289Sadrianstatic struct ifmedia_description ifm_subtype_ieee80211_option_descriptions[] = 397235289Sadrian IFM_SUBTYPE_IEEE80211_OPTION_DESCRIPTIONS; 398235289Sadrian 399241720Sedstatic struct ifmedia_description ifm_subtype_ieee80211_mode_descriptions[] = 400235289Sadrian IFM_SUBTYPE_IEEE80211_MODE_DESCRIPTIONS; 401235289Sadrian 402241720Sedstatic struct ifmedia_description ifm_subtype_ieee80211_mode_aliases[] = 403235289Sadrian IFM_SUBTYPE_IEEE80211_MODE_ALIASES; 404235289Sadrian 405235289Sadrianstatic struct ifmedia_description ifm_subtype_atm_descriptions[] = 406235289Sadrian IFM_SUBTYPE_ATM_DESCRIPTIONS; 407235289Sadrian 408235289Sadrianstatic struct ifmedia_description ifm_subtype_atm_aliases[] = 409235289Sadrian IFM_SUBTYPE_ATM_ALIASES; 410235289Sadrian 411235289Sadrianstatic struct ifmedia_description ifm_subtype_atm_option_descriptions[] = 412235289Sadrian IFM_SUBTYPE_ATM_OPTION_DESCRIPTIONS; 413235289Sadrian 414235289Sadrianstatic struct ifmedia_description ifm_subtype_shared_descriptions[] = 415235289Sadrian IFM_SUBTYPE_SHARED_DESCRIPTIONS; 416235289Sadrian 417235289Sadrianstatic struct ifmedia_description ifm_subtype_shared_aliases[] = 418235289Sadrian IFM_SUBTYPE_SHARED_ALIASES; 419235289Sadrian 420235289Sadrianstatic struct ifmedia_description ifm_shared_option_descriptions[] = 421235289Sadrian IFM_SHARED_OPTION_DESCRIPTIONS; 422235289Sadrian 423235289Sadrianstatic struct ifmedia_description ifm_shared_option_aliases[] = 424235289Sadrian IFM_SHARED_OPTION_ALIASES; 425235289Sadrian 426235289Sadrianstruct ifmedia_type_to_subtype { 427235289Sadrian struct { 428235289Sadrian struct ifmedia_description *desc; 429235289Sadrian int alias; 430235289Sadrian } subtypes[5]; 431235289Sadrian struct { 432235289Sadrian struct ifmedia_description *desc; 433235289Sadrian int alias; 434235289Sadrian } options[4]; 435235289Sadrian struct { 436235289Sadrian struct ifmedia_description *desc; 437235289Sadrian int alias; 438235289Sadrian } modes[3]; 439235289Sadrian}; 440235289Sadrian 441235289Sadrian/* must be in the same order as IFM_TYPE_DESCRIPTIONS */ 442235289Sadrianstatic struct ifmedia_type_to_subtype ifmedia_types_to_subtypes[] = { 443235289Sadrian { 444235289Sadrian { 445235289Sadrian { &ifm_subtype_shared_descriptions[0], 0 }, 446235289Sadrian { &ifm_subtype_shared_aliases[0], 1 }, 447235289Sadrian { &ifm_subtype_ethernet_descriptions[0], 0 }, 448235289Sadrian { &ifm_subtype_ethernet_aliases[0], 1 }, 449235289Sadrian { NULL, 0 }, 450235289Sadrian }, 451235289Sadrian { 452235289Sadrian { &ifm_shared_option_descriptions[0], 0 }, 453235289Sadrian { &ifm_shared_option_aliases[0], 1 }, 454235289Sadrian { &ifm_subtype_ethernet_option_descriptions[0], 0 }, 455235289Sadrian { NULL, 0 }, 456235289Sadrian }, 457235289Sadrian { 458235289Sadrian { NULL, 0 }, 459235289Sadrian }, 460235289Sadrian }, 461235289Sadrian { 462235289Sadrian { 463235289Sadrian { &ifm_subtype_shared_descriptions[0], 0 }, 464235289Sadrian { &ifm_subtype_shared_aliases[0], 1 }, 465235289Sadrian { &ifm_subtype_tokenring_descriptions[0], 0 }, 466235289Sadrian { &ifm_subtype_tokenring_aliases[0], 1 }, 467235289Sadrian { NULL, 0 }, 468235289Sadrian }, 469235289Sadrian { 470235289Sadrian { &ifm_shared_option_descriptions[0], 0 }, 471235289Sadrian { &ifm_shared_option_aliases[0], 1 }, 472235289Sadrian { &ifm_subtype_tokenring_option_descriptions[0], 0 }, 473235289Sadrian { NULL, 0 }, 474235289Sadrian }, 475235289Sadrian { 476235289Sadrian { NULL, 0 }, 477235289Sadrian }, 478235289Sadrian }, 479235289Sadrian { 480235289Sadrian { 481235289Sadrian { &ifm_subtype_shared_descriptions[0], 0 }, 482235289Sadrian { &ifm_subtype_shared_aliases[0], 1 }, 483235289Sadrian { &ifm_subtype_fddi_descriptions[0], 0 }, 484235289Sadrian { &ifm_subtype_fddi_aliases[0], 1 }, 485235289Sadrian { NULL, 0 }, 486235289Sadrian }, 487235289Sadrian { 488235289Sadrian { &ifm_shared_option_descriptions[0], 0 }, 489235289Sadrian { &ifm_shared_option_aliases[0], 1 }, 490235289Sadrian { &ifm_subtype_fddi_option_descriptions[0], 0 }, 491235289Sadrian { NULL, 0 }, 492235289Sadrian }, 493235289Sadrian { 494235289Sadrian { NULL, 0 }, 495235289Sadrian }, 496235289Sadrian }, 497235289Sadrian { 498235289Sadrian { 499235289Sadrian { &ifm_subtype_shared_descriptions[0], 0 }, 500235289Sadrian { &ifm_subtype_shared_aliases[0], 1 }, 501235289Sadrian { &ifm_subtype_ieee80211_descriptions[0], 0 }, 502235289Sadrian { &ifm_subtype_ieee80211_aliases[0], 1 }, 503235289Sadrian { NULL, 0 }, 504235289Sadrian }, 505235289Sadrian { 506235289Sadrian { &ifm_shared_option_descriptions[0], 0 }, 507235289Sadrian { &ifm_shared_option_aliases[0], 1 }, 508235289Sadrian { &ifm_subtype_ieee80211_option_descriptions[0], 0 }, 509235289Sadrian { NULL, 0 }, 510235289Sadrian }, 511235289Sadrian { 512235289Sadrian { &ifm_subtype_ieee80211_mode_descriptions[0], 0 }, 513235289Sadrian { &ifm_subtype_ieee80211_mode_aliases[0], 0 }, 514235289Sadrian { NULL, 0 }, 515235289Sadrian }, 516235289Sadrian }, 517235289Sadrian { 518235289Sadrian { 519235289Sadrian { &ifm_subtype_shared_descriptions[0], 0 }, 520235289Sadrian { &ifm_subtype_shared_aliases[0], 1 }, 521235289Sadrian { &ifm_subtype_atm_descriptions[0], 0 }, 522235289Sadrian { &ifm_subtype_atm_aliases[0], 1 }, 523235289Sadrian { NULL, 0 }, 524235289Sadrian }, 525235289Sadrian { 526235289Sadrian { &ifm_shared_option_descriptions[0], 0 }, 527235289Sadrian { &ifm_shared_option_aliases[0], 1 }, 528235289Sadrian { &ifm_subtype_atm_option_descriptions[0], 0 }, 529235289Sadrian { NULL, 0 }, 530235289Sadrian }, 531235289Sadrian { 532235289Sadrian { NULL, 0 }, 533235289Sadrian }, 534235289Sadrian }, 535235289Sadrian}; 536235289Sadrian 537235289Sadrianint 538235289Sadrianget_media_subtype(int type, const char *val) 539235289Sadrian{ 540235289Sadrian struct ifmedia_description *desc; 541235289Sadrian struct ifmedia_type_to_subtype *ttos; 542235289Sadrian int rval, i; 543235289Sadrian 544235289Sadrian /* Find the top-level interface type. */ 545235289Sadrian for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; 546235289Sadrian desc->ifmt_string != NULL; desc++, ttos++) 547235289Sadrian if (type == desc->ifmt_word) 548235289Sadrian break; 549235289Sadrian if (desc->ifmt_string == NULL) 550235289Sadrian errx(1, "unknown media type 0x%x", type); 551235289Sadrian 552235289Sadrian for (i = 0; ttos->subtypes[i].desc != NULL; i++) { 553235289Sadrian rval = lookup_media_word(ttos->subtypes[i].desc, val); 554235289Sadrian if (rval != -1) 555235289Sadrian return (rval); 556235289Sadrian } 557235289Sadrian errx(1, "unknown media subtype: %s", val); 558235289Sadrian /*NOTREACHED*/ 559235289Sadrian} 560235289Sadrian 561235289Sadrianint 562235289Sadrianget_media_mode(int type, const char *val) 563235289Sadrian{ 564235289Sadrian struct ifmedia_description *desc; 565235289Sadrian struct ifmedia_type_to_subtype *ttos; 566235289Sadrian int rval, i; 567235289Sadrian 568235289Sadrian /* Find the top-level interface type. */ 569235289Sadrian for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; 570235289Sadrian desc->ifmt_string != NULL; desc++, ttos++) 571235289Sadrian if (type == desc->ifmt_word) 572235289Sadrian break; 573235289Sadrian if (desc->ifmt_string == NULL) 574235289Sadrian errx(1, "unknown media mode 0x%x", type); 575235289Sadrian 576235289Sadrian for (i = 0; ttos->modes[i].desc != NULL; i++) { 577235289Sadrian rval = lookup_media_word(ttos->modes[i].desc, val); 578235289Sadrian if (rval != -1) 579235289Sadrian return (rval); 580235289Sadrian } 581235289Sadrian return -1; 582235289Sadrian} 583235289Sadrian 584235289Sadrianint 585235289Sadrianget_media_options(int type, const char *val) 586235289Sadrian{ 587235289Sadrian struct ifmedia_description *desc; 588235289Sadrian struct ifmedia_type_to_subtype *ttos; 589235289Sadrian char *optlist, *optptr; 590235289Sadrian int option = 0, i, rval = 0; 591235289Sadrian 592235289Sadrian /* We muck with the string, so copy it. */ 593235289Sadrian optlist = strdup(val); 594235289Sadrian if (optlist == NULL) 595235289Sadrian err(1, "strdup"); 596235289Sadrian 597235289Sadrian /* Find the top-level interface type. */ 598235289Sadrian for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; 599235289Sadrian desc->ifmt_string != NULL; desc++, ttos++) 600235289Sadrian if (type == desc->ifmt_word) 601235289Sadrian break; 602235289Sadrian if (desc->ifmt_string == NULL) 603235289Sadrian errx(1, "unknown media type 0x%x", type); 604235289Sadrian 605235289Sadrian /* 606235289Sadrian * Look up the options in the user-provided comma-separated 607235289Sadrian * list. 608235289Sadrian */ 609235289Sadrian optptr = optlist; 610235289Sadrian for (; (optptr = strtok(optptr, ",")) != NULL; optptr = NULL) { 611235289Sadrian for (i = 0; ttos->options[i].desc != NULL; i++) { 612235289Sadrian option = lookup_media_word(ttos->options[i].desc, optptr); 613235289Sadrian if (option != -1) 614235289Sadrian break; 615235289Sadrian } 616235289Sadrian if (option == 0) 617235289Sadrian errx(1, "unknown option: %s", optptr); 618235289Sadrian rval |= option; 619235289Sadrian } 620235289Sadrian 621235289Sadrian free(optlist); 622235289Sadrian return (rval); 623235289Sadrian} 624235289Sadrian 625235289Sadrianint 626235289Sadrianlookup_media_word(struct ifmedia_description *desc, const char *val) 627235289Sadrian{ 628235289Sadrian 629235289Sadrian for (; desc->ifmt_string != NULL; desc++) 630235289Sadrian if (strcasecmp(desc->ifmt_string, val) == 0) 631235289Sadrian return (desc->ifmt_word); 632235289Sadrian 633235289Sadrian return (-1); 634235289Sadrian} 635235289Sadrian 636235289Sadrianstatic struct ifmedia_description *get_toptype_desc(int ifmw) 637235289Sadrian{ 638235289Sadrian struct ifmedia_description *desc; 639235289Sadrian 640235289Sadrian for (desc = ifm_type_descriptions; desc->ifmt_string != NULL; desc++) 641235289Sadrian if (IFM_TYPE(ifmw) == desc->ifmt_word) 642235289Sadrian break; 643235289Sadrian 644235289Sadrian return desc; 645235289Sadrian} 646235289Sadrian 647235289Sadrianstatic struct ifmedia_type_to_subtype *get_toptype_ttos(int ifmw) 648235289Sadrian{ 649235289Sadrian struct ifmedia_description *desc; 650235289Sadrian struct ifmedia_type_to_subtype *ttos; 651235289Sadrian 652235289Sadrian for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; 653235289Sadrian desc->ifmt_string != NULL; desc++, ttos++) 654235289Sadrian if (IFM_TYPE(ifmw) == desc->ifmt_word) 655235289Sadrian break; 656235289Sadrian 657235289Sadrian return ttos; 658235289Sadrian} 659235289Sadrian 660235289Sadrianstatic struct ifmedia_description *get_subtype_desc(int ifmw, 661235289Sadrian struct ifmedia_type_to_subtype *ttos) 662235289Sadrian{ 663235289Sadrian int i; 664235289Sadrian struct ifmedia_description *desc; 665235289Sadrian 666235289Sadrian for (i = 0; ttos->subtypes[i].desc != NULL; i++) { 667235289Sadrian if (ttos->subtypes[i].alias) 668235289Sadrian continue; 669235289Sadrian for (desc = ttos->subtypes[i].desc; 670235289Sadrian desc->ifmt_string != NULL; desc++) { 671235289Sadrian if (IFM_SUBTYPE(ifmw) == desc->ifmt_word) 672235289Sadrian return desc; 673235289Sadrian } 674235289Sadrian } 675235289Sadrian 676235289Sadrian return NULL; 677235289Sadrian} 678235289Sadrian 679235289Sadrianstatic struct ifmedia_description *get_mode_desc(int ifmw, 680235289Sadrian struct ifmedia_type_to_subtype *ttos) 681235289Sadrian{ 682235289Sadrian int i; 683235289Sadrian struct ifmedia_description *desc; 684235289Sadrian 685235289Sadrian for (i = 0; ttos->modes[i].desc != NULL; i++) { 686235289Sadrian if (ttos->modes[i].alias) 687235289Sadrian continue; 688235289Sadrian for (desc = ttos->modes[i].desc; 689235289Sadrian desc->ifmt_string != NULL; desc++) { 690235289Sadrian if (IFM_MODE(ifmw) == desc->ifmt_word) 691235289Sadrian return desc; 692235289Sadrian } 693235289Sadrian } 694235289Sadrian 695235289Sadrian return NULL; 696235289Sadrian} 697235289Sadrian 698235289Sadrianvoid 699235289Sadrianprint_media_word(int ifmw, int print_toptype) 700235289Sadrian{ 701235289Sadrian struct ifmedia_description *desc; 702235289Sadrian struct ifmedia_type_to_subtype *ttos; 703235289Sadrian int seen_option = 0, i; 704235289Sadrian 705235289Sadrian /* Find the top-level interface type. */ 706235289Sadrian desc = get_toptype_desc(ifmw); 707235289Sadrian ttos = get_toptype_ttos(ifmw); 708235289Sadrian if (desc->ifmt_string == NULL) { 709235289Sadrian printf("<unknown type>"); 710235289Sadrian return; 711235289Sadrian } else if (print_toptype) { 712235289Sadrian printf("%s", desc->ifmt_string); 713235289Sadrian } 714235289Sadrian 715235289Sadrian /* 716235289Sadrian * Don't print the top-level type; it's not like we can 717235289Sadrian * change it, or anything. 718235289Sadrian */ 719235289Sadrian 720235289Sadrian /* Find subtype. */ 721235289Sadrian desc = get_subtype_desc(ifmw, ttos); 722235289Sadrian if (desc == NULL) { 723235289Sadrian printf("<unknown subtype>"); 724235289Sadrian return; 725235289Sadrian } 726235289Sadrian 727235289Sadrian if (print_toptype) 728235289Sadrian putchar(' '); 729235289Sadrian 730235289Sadrian printf("%s", desc->ifmt_string); 731235289Sadrian 732235289Sadrian if (print_toptype) { 733235289Sadrian desc = get_mode_desc(ifmw, ttos); 734235289Sadrian if (desc != NULL && strcasecmp("autoselect", desc->ifmt_string)) 735235289Sadrian printf(" mode %s", desc->ifmt_string); 736235289Sadrian } 737235289Sadrian 738235289Sadrian /* Find options. */ 739235289Sadrian for (i = 0; ttos->options[i].desc != NULL; i++) { 740235289Sadrian if (ttos->options[i].alias) 741235289Sadrian continue; 742235289Sadrian for (desc = ttos->options[i].desc; 743235289Sadrian desc->ifmt_string != NULL; desc++) { 744235289Sadrian if (ifmw & desc->ifmt_word) { 745235289Sadrian if (seen_option == 0) 746235289Sadrian printf(" <"); 747235289Sadrian printf("%s%s", seen_option++ ? "," : "", 748235289Sadrian desc->ifmt_string); 749235289Sadrian } 750235289Sadrian } 751235289Sadrian } 752235289Sadrian printf("%s", seen_option ? ">" : ""); 753235289Sadrian 754235289Sadrian if (print_toptype && IFM_INST(ifmw) != 0) 755235289Sadrian printf(" instance %d", IFM_INST(ifmw)); 756235289Sadrian} 757235289Sadrian 758235289Sadrianvoid 759235289Sadrianprint_media_word_ifconfig(int ifmw) 760235289Sadrian{ 761235289Sadrian struct ifmedia_description *desc; 762235289Sadrian struct ifmedia_type_to_subtype *ttos; 763235289Sadrian int seen_option = 0, i; 764235289Sadrian 765235289Sadrian /* Find the top-level interface type. */ 766235289Sadrian desc = get_toptype_desc(ifmw); 767235289Sadrian ttos = get_toptype_ttos(ifmw); 768235289Sadrian if (desc->ifmt_string == NULL) { 769235289Sadrian printf("<unknown type>"); 770235289Sadrian return; 771235289Sadrian } 772235289Sadrian 773235289Sadrian /* 774235289Sadrian * Don't print the top-level type; it's not like we can 775235289Sadrian * change it, or anything. 776235289Sadrian */ 777235289Sadrian 778235289Sadrian /* Find subtype. */ 779235289Sadrian desc = get_subtype_desc(ifmw, ttos); 780235289Sadrian if (desc == NULL) { 781235289Sadrian printf("<unknown subtype>"); 782235289Sadrian return; 783235289Sadrian } 784235289Sadrian 785235289Sadrian printf("media %s", desc->ifmt_string); 786235289Sadrian 787235289Sadrian desc = get_mode_desc(ifmw, ttos); 788235289Sadrian if (desc != NULL) 789235289Sadrian printf(" mode %s", desc->ifmt_string); 790235289Sadrian 791235289Sadrian /* Find options. */ 792235289Sadrian for (i = 0; ttos->options[i].desc != NULL; i++) { 793235289Sadrian if (ttos->options[i].alias) 794235289Sadrian continue; 795235289Sadrian for (desc = ttos->options[i].desc; 796235289Sadrian desc->ifmt_string != NULL; desc++) { 797235289Sadrian if (ifmw & desc->ifmt_word) { 798235289Sadrian if (seen_option == 0) 799235289Sadrian printf(" mediaopt "); 800235289Sadrian printf("%s%s", seen_option++ ? "," : "", 801235289Sadrian desc->ifmt_string); 802235289Sadrian } 803235289Sadrian } 804235289Sadrian } 805235289Sadrian 806235289Sadrian if (IFM_INST(ifmw) != 0) 807235289Sadrian printf(" instance %d", IFM_INST(ifmw)); 808235289Sadrian} 809235289Sadrian 810235289Sadrian/********************************************************************** 811235289Sadrian * ...until here. 812235289Sadrian **********************************************************************/ 813