1*270069b7SAdrian Chadd /* $NetBSD: ifconfig.c,v 1.34 1997/04/21 01:17:58 lukem Exp $ */ 2*270069b7SAdrian Chadd /* $FreeBSD$ */ 3*270069b7SAdrian Chadd 4*270069b7SAdrian Chadd /* 5*270069b7SAdrian Chadd * Copyright (c) 1997 Jason R. Thorpe. 6*270069b7SAdrian Chadd * All rights reserved. 7*270069b7SAdrian Chadd * 8*270069b7SAdrian Chadd * Redistribution and use in source and binary forms, with or without 9*270069b7SAdrian Chadd * modification, are permitted provided that the following conditions 10*270069b7SAdrian Chadd * are met: 11*270069b7SAdrian Chadd * 1. Redistributions of source code must retain the above copyright 12*270069b7SAdrian Chadd * notice, this list of conditions and the following disclaimer. 13*270069b7SAdrian Chadd * 2. Redistributions in binary form must reproduce the above copyright 14*270069b7SAdrian Chadd * notice, this list of conditions and the following disclaimer in the 15*270069b7SAdrian Chadd * documentation and/or other materials provided with the distribution. 16*270069b7SAdrian Chadd * 3. All advertising materials mentioning features or use of this software 17*270069b7SAdrian Chadd * must display the following acknowledgement: 18*270069b7SAdrian Chadd * This product includes software developed for the NetBSD Project 19*270069b7SAdrian Chadd * by Jason R. Thorpe. 20*270069b7SAdrian Chadd * 4. The name of the author may not be used to endorse or promote products 21*270069b7SAdrian Chadd * derived from this software without specific prior written permission. 22*270069b7SAdrian Chadd * 23*270069b7SAdrian Chadd * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24*270069b7SAdrian Chadd * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25*270069b7SAdrian Chadd * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26*270069b7SAdrian Chadd * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27*270069b7SAdrian Chadd * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28*270069b7SAdrian Chadd * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29*270069b7SAdrian Chadd * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 30*270069b7SAdrian Chadd * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31*270069b7SAdrian Chadd * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32*270069b7SAdrian Chadd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33*270069b7SAdrian Chadd * SUCH DAMAGE. 34*270069b7SAdrian Chadd */ 35*270069b7SAdrian Chadd 36*270069b7SAdrian Chadd /* 37*270069b7SAdrian Chadd * Copyright (c) 1983, 1993 38*270069b7SAdrian Chadd * The Regents of the University of California. All rights reserved. 39*270069b7SAdrian Chadd * 40*270069b7SAdrian Chadd * Redistribution and use in source and binary forms, with or without 41*270069b7SAdrian Chadd * modification, are permitted provided that the following conditions 42*270069b7SAdrian Chadd * are met: 43*270069b7SAdrian Chadd * 1. Redistributions of source code must retain the above copyright 44*270069b7SAdrian Chadd * notice, this list of conditions and the following disclaimer. 45*270069b7SAdrian Chadd * 2. Redistributions in binary form must reproduce the above copyright 46*270069b7SAdrian Chadd * notice, this list of conditions and the following disclaimer in the 47*270069b7SAdrian Chadd * documentation and/or other materials provided with the distribution. 48*270069b7SAdrian Chadd * 4. Neither the name of the University nor the names of its contributors 49*270069b7SAdrian Chadd * may be used to endorse or promote products derived from this software 50*270069b7SAdrian Chadd * without specific prior written permission. 51*270069b7SAdrian Chadd * 52*270069b7SAdrian Chadd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 53*270069b7SAdrian Chadd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 54*270069b7SAdrian Chadd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 55*270069b7SAdrian Chadd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 56*270069b7SAdrian Chadd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 57*270069b7SAdrian Chadd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 58*270069b7SAdrian Chadd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 59*270069b7SAdrian Chadd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 60*270069b7SAdrian Chadd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 61*270069b7SAdrian Chadd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 62*270069b7SAdrian Chadd * SUCH DAMAGE. 63*270069b7SAdrian Chadd */ 64*270069b7SAdrian Chadd /* 65*270069b7SAdrian Chadd * based on sbin/ifconfig/ifmedia.c r221954 66*270069b7SAdrian Chadd */ 67*270069b7SAdrian Chadd 68*270069b7SAdrian Chadd #include <sys/param.h> 69*270069b7SAdrian Chadd #include <sys/ioctl.h> 70*270069b7SAdrian Chadd #include <sys/socket.h> 71*270069b7SAdrian Chadd #include <sys/sysctl.h> 72*270069b7SAdrian Chadd #include <sys/time.h> 73*270069b7SAdrian Chadd 74*270069b7SAdrian Chadd #include <net/if.h> 75*270069b7SAdrian Chadd #include <net/if_dl.h> 76*270069b7SAdrian Chadd #include <net/if_types.h> 77*270069b7SAdrian Chadd #include <net/if_media.h> 78*270069b7SAdrian Chadd #include <net/route.h> 79*270069b7SAdrian Chadd 80*270069b7SAdrian Chadd #include <ctype.h> 81*270069b7SAdrian Chadd #include <err.h> 82*270069b7SAdrian Chadd #include <errno.h> 83*270069b7SAdrian Chadd #include <fcntl.h> 84*270069b7SAdrian Chadd #include <stdio.h> 85*270069b7SAdrian Chadd #include <stdlib.h> 86*270069b7SAdrian Chadd #include <string.h> 87*270069b7SAdrian Chadd #include <unistd.h> 88*270069b7SAdrian Chadd 89*270069b7SAdrian Chadd void domediaopt(const char *, int, int); 90*270069b7SAdrian Chadd int get_media_subtype(int, const char *); 91*270069b7SAdrian Chadd int get_media_mode(int, const char *); 92*270069b7SAdrian Chadd int get_media_options(int, const char *); 93*270069b7SAdrian Chadd int lookup_media_word(struct ifmedia_description *, const char *); 94*270069b7SAdrian Chadd void print_media_word(int, int); 95*270069b7SAdrian Chadd void print_media_word_ifconfig(int); 96*270069b7SAdrian Chadd 97*270069b7SAdrian Chadd #if 0 98*270069b7SAdrian Chadd static struct ifmedia_description *get_toptype_desc(int); 99*270069b7SAdrian Chadd static struct ifmedia_type_to_subtype *get_toptype_ttos(int); 100*270069b7SAdrian Chadd static struct ifmedia_description *get_subtype_desc(int, 101*270069b7SAdrian Chadd struct ifmedia_type_to_subtype *ttos); 102*270069b7SAdrian Chadd 103*270069b7SAdrian Chadd #define IFM_OPMODE(x) \ 104*270069b7SAdrian Chadd ((x) & (IFM_IEEE80211_ADHOC | IFM_IEEE80211_HOSTAP | \ 105*270069b7SAdrian Chadd IFM_IEEE80211_IBSS | IFM_IEEE80211_WDS | IFM_IEEE80211_MONITOR | \ 106*270069b7SAdrian Chadd IFM_IEEE80211_MBSS)) 107*270069b7SAdrian Chadd #define IFM_IEEE80211_STA 0 108*270069b7SAdrian Chadd 109*270069b7SAdrian Chadd static void 110*270069b7SAdrian Chadd media_status(int s) 111*270069b7SAdrian Chadd { 112*270069b7SAdrian Chadd struct ifmediareq ifmr; 113*270069b7SAdrian Chadd int *media_list, i; 114*270069b7SAdrian Chadd 115*270069b7SAdrian Chadd (void) memset(&ifmr, 0, sizeof(ifmr)); 116*270069b7SAdrian Chadd (void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name)); 117*270069b7SAdrian Chadd 118*270069b7SAdrian Chadd if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) { 119*270069b7SAdrian Chadd /* 120*270069b7SAdrian Chadd * Interface doesn't support SIOC{G,S}IFMEDIA. 121*270069b7SAdrian Chadd */ 122*270069b7SAdrian Chadd return; 123*270069b7SAdrian Chadd } 124*270069b7SAdrian Chadd 125*270069b7SAdrian Chadd if (ifmr.ifm_count == 0) { 126*270069b7SAdrian Chadd warnx("%s: no media types?", name); 127*270069b7SAdrian Chadd return; 128*270069b7SAdrian Chadd } 129*270069b7SAdrian Chadd 130*270069b7SAdrian Chadd media_list = (int *)malloc(ifmr.ifm_count * sizeof(int)); 131*270069b7SAdrian Chadd if (media_list == NULL) 132*270069b7SAdrian Chadd err(1, "malloc"); 133*270069b7SAdrian Chadd ifmr.ifm_ulist = media_list; 134*270069b7SAdrian Chadd 135*270069b7SAdrian Chadd if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) 136*270069b7SAdrian Chadd err(1, "SIOCGIFMEDIA"); 137*270069b7SAdrian Chadd 138*270069b7SAdrian Chadd printf("\tmedia: "); 139*270069b7SAdrian Chadd print_media_word(ifmr.ifm_current, 1); 140*270069b7SAdrian Chadd if (ifmr.ifm_active != ifmr.ifm_current) { 141*270069b7SAdrian Chadd putchar(' '); 142*270069b7SAdrian Chadd putchar('('); 143*270069b7SAdrian Chadd print_media_word(ifmr.ifm_active, 0); 144*270069b7SAdrian Chadd putchar(')'); 145*270069b7SAdrian Chadd } 146*270069b7SAdrian Chadd 147*270069b7SAdrian Chadd putchar('\n'); 148*270069b7SAdrian Chadd 149*270069b7SAdrian Chadd if (ifmr.ifm_status & IFM_AVALID) { 150*270069b7SAdrian Chadd printf("\tstatus: "); 151*270069b7SAdrian Chadd switch (IFM_TYPE(ifmr.ifm_active)) { 152*270069b7SAdrian Chadd case IFM_ETHER: 153*270069b7SAdrian Chadd case IFM_ATM: 154*270069b7SAdrian Chadd if (ifmr.ifm_status & IFM_ACTIVE) 155*270069b7SAdrian Chadd printf("active"); 156*270069b7SAdrian Chadd else 157*270069b7SAdrian Chadd printf("no carrier"); 158*270069b7SAdrian Chadd break; 159*270069b7SAdrian Chadd 160*270069b7SAdrian Chadd case IFM_FDDI: 161*270069b7SAdrian Chadd case IFM_TOKEN: 162*270069b7SAdrian Chadd if (ifmr.ifm_status & IFM_ACTIVE) 163*270069b7SAdrian Chadd printf("inserted"); 164*270069b7SAdrian Chadd else 165*270069b7SAdrian Chadd printf("no ring"); 166*270069b7SAdrian Chadd break; 167*270069b7SAdrian Chadd 168*270069b7SAdrian Chadd case IFM_IEEE80211: 169*270069b7SAdrian Chadd if (ifmr.ifm_status & IFM_ACTIVE) { 170*270069b7SAdrian Chadd /* NB: only sta mode associates */ 171*270069b7SAdrian Chadd if (IFM_OPMODE(ifmr.ifm_active) == IFM_IEEE80211_STA) 172*270069b7SAdrian Chadd printf("associated"); 173*270069b7SAdrian Chadd else 174*270069b7SAdrian Chadd printf("running"); 175*270069b7SAdrian Chadd } else 176*270069b7SAdrian Chadd printf("no carrier"); 177*270069b7SAdrian Chadd break; 178*270069b7SAdrian Chadd } 179*270069b7SAdrian Chadd putchar('\n'); 180*270069b7SAdrian Chadd } 181*270069b7SAdrian Chadd 182*270069b7SAdrian Chadd if (ifmr.ifm_count > 0 && supmedia) { 183*270069b7SAdrian Chadd printf("\tsupported media:\n"); 184*270069b7SAdrian Chadd for (i = 0; i < ifmr.ifm_count; i++) { 185*270069b7SAdrian Chadd printf("\t\t"); 186*270069b7SAdrian Chadd print_media_word_ifconfig(media_list[i]); 187*270069b7SAdrian Chadd putchar('\n'); 188*270069b7SAdrian Chadd } 189*270069b7SAdrian Chadd } 190*270069b7SAdrian Chadd 191*270069b7SAdrian Chadd free(media_list); 192*270069b7SAdrian Chadd } 193*270069b7SAdrian Chadd 194*270069b7SAdrian Chadd struct ifmediareq * 195*270069b7SAdrian Chadd ifmedia_getstate(int s) 196*270069b7SAdrian Chadd { 197*270069b7SAdrian Chadd static struct ifmediareq *ifmr = NULL; 198*270069b7SAdrian Chadd int *mwords; 199*270069b7SAdrian Chadd 200*270069b7SAdrian Chadd if (ifmr == NULL) { 201*270069b7SAdrian Chadd ifmr = (struct ifmediareq *)malloc(sizeof(struct ifmediareq)); 202*270069b7SAdrian Chadd if (ifmr == NULL) 203*270069b7SAdrian Chadd err(1, "malloc"); 204*270069b7SAdrian Chadd 205*270069b7SAdrian Chadd (void) memset(ifmr, 0, sizeof(struct ifmediareq)); 206*270069b7SAdrian Chadd (void) strncpy(ifmr->ifm_name, name, 207*270069b7SAdrian Chadd sizeof(ifmr->ifm_name)); 208*270069b7SAdrian Chadd 209*270069b7SAdrian Chadd ifmr->ifm_count = 0; 210*270069b7SAdrian Chadd ifmr->ifm_ulist = NULL; 211*270069b7SAdrian Chadd 212*270069b7SAdrian Chadd /* 213*270069b7SAdrian Chadd * We must go through the motions of reading all 214*270069b7SAdrian Chadd * supported media because we need to know both 215*270069b7SAdrian Chadd * the current media type and the top-level type. 216*270069b7SAdrian Chadd */ 217*270069b7SAdrian Chadd 218*270069b7SAdrian Chadd if (ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0) { 219*270069b7SAdrian Chadd err(1, "SIOCGIFMEDIA"); 220*270069b7SAdrian Chadd } 221*270069b7SAdrian Chadd 222*270069b7SAdrian Chadd if (ifmr->ifm_count == 0) 223*270069b7SAdrian Chadd errx(1, "%s: no media types?", name); 224*270069b7SAdrian Chadd 225*270069b7SAdrian Chadd mwords = (int *)malloc(ifmr->ifm_count * sizeof(int)); 226*270069b7SAdrian Chadd if (mwords == NULL) 227*270069b7SAdrian Chadd err(1, "malloc"); 228*270069b7SAdrian Chadd 229*270069b7SAdrian Chadd ifmr->ifm_ulist = mwords; 230*270069b7SAdrian Chadd if (ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0) 231*270069b7SAdrian Chadd err(1, "SIOCGIFMEDIA"); 232*270069b7SAdrian Chadd } 233*270069b7SAdrian Chadd 234*270069b7SAdrian Chadd return ifmr; 235*270069b7SAdrian Chadd } 236*270069b7SAdrian Chadd 237*270069b7SAdrian Chadd static void 238*270069b7SAdrian Chadd setifmediacallback(int s, void *arg) 239*270069b7SAdrian Chadd { 240*270069b7SAdrian Chadd struct ifmediareq *ifmr = (struct ifmediareq *)arg; 241*270069b7SAdrian Chadd static int did_it = 0; 242*270069b7SAdrian Chadd 243*270069b7SAdrian Chadd if (!did_it) { 244*270069b7SAdrian Chadd ifr.ifr_media = ifmr->ifm_current; 245*270069b7SAdrian Chadd if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) < 0) 246*270069b7SAdrian Chadd err(1, "SIOCSIFMEDIA (media)"); 247*270069b7SAdrian Chadd free(ifmr->ifm_ulist); 248*270069b7SAdrian Chadd free(ifmr); 249*270069b7SAdrian Chadd did_it = 1; 250*270069b7SAdrian Chadd } 251*270069b7SAdrian Chadd } 252*270069b7SAdrian Chadd 253*270069b7SAdrian Chadd static void 254*270069b7SAdrian Chadd setmedia(const char *val, int d, int s, const struct afswtch *afp) 255*270069b7SAdrian Chadd { 256*270069b7SAdrian Chadd struct ifmediareq *ifmr; 257*270069b7SAdrian Chadd int subtype; 258*270069b7SAdrian Chadd 259*270069b7SAdrian Chadd ifmr = ifmedia_getstate(s); 260*270069b7SAdrian Chadd 261*270069b7SAdrian Chadd /* 262*270069b7SAdrian Chadd * We are primarily concerned with the top-level type. 263*270069b7SAdrian Chadd * However, "current" may be only IFM_NONE, so we just look 264*270069b7SAdrian Chadd * for the top-level type in the first "supported type" 265*270069b7SAdrian Chadd * entry. 266*270069b7SAdrian Chadd * 267*270069b7SAdrian Chadd * (I'm assuming that all supported media types for a given 268*270069b7SAdrian Chadd * interface will be the same top-level type..) 269*270069b7SAdrian Chadd */ 270*270069b7SAdrian Chadd subtype = get_media_subtype(IFM_TYPE(ifmr->ifm_ulist[0]), val); 271*270069b7SAdrian Chadd 272*270069b7SAdrian Chadd strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 273*270069b7SAdrian Chadd ifr.ifr_media = (ifmr->ifm_current & IFM_IMASK) | 274*270069b7SAdrian Chadd IFM_TYPE(ifmr->ifm_ulist[0]) | subtype; 275*270069b7SAdrian Chadd 276*270069b7SAdrian Chadd ifmr->ifm_current = ifr.ifr_media; 277*270069b7SAdrian Chadd callback_register(setifmediacallback, (void *)ifmr); 278*270069b7SAdrian Chadd } 279*270069b7SAdrian Chadd 280*270069b7SAdrian Chadd static void 281*270069b7SAdrian Chadd setmediaopt(const char *val, int d, int s, const struct afswtch *afp) 282*270069b7SAdrian Chadd { 283*270069b7SAdrian Chadd 284*270069b7SAdrian Chadd domediaopt(val, 0, s); 285*270069b7SAdrian Chadd } 286*270069b7SAdrian Chadd 287*270069b7SAdrian Chadd static void 288*270069b7SAdrian Chadd unsetmediaopt(const char *val, int d, int s, const struct afswtch *afp) 289*270069b7SAdrian Chadd { 290*270069b7SAdrian Chadd 291*270069b7SAdrian Chadd domediaopt(val, 1, s); 292*270069b7SAdrian Chadd } 293*270069b7SAdrian Chadd 294*270069b7SAdrian Chadd static void 295*270069b7SAdrian Chadd domediaopt(const char *val, int clear, int s) 296*270069b7SAdrian Chadd { 297*270069b7SAdrian Chadd struct ifmediareq *ifmr; 298*270069b7SAdrian Chadd int options; 299*270069b7SAdrian Chadd 300*270069b7SAdrian Chadd ifmr = ifmedia_getstate(s); 301*270069b7SAdrian Chadd 302*270069b7SAdrian Chadd options = get_media_options(IFM_TYPE(ifmr->ifm_ulist[0]), val); 303*270069b7SAdrian Chadd 304*270069b7SAdrian Chadd strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 305*270069b7SAdrian Chadd ifr.ifr_media = ifmr->ifm_current; 306*270069b7SAdrian Chadd if (clear) 307*270069b7SAdrian Chadd ifr.ifr_media &= ~options; 308*270069b7SAdrian Chadd else { 309*270069b7SAdrian Chadd if (options & IFM_HDX) { 310*270069b7SAdrian Chadd ifr.ifr_media &= ~IFM_FDX; 311*270069b7SAdrian Chadd options &= ~IFM_HDX; 312*270069b7SAdrian Chadd } 313*270069b7SAdrian Chadd ifr.ifr_media |= options; 314*270069b7SAdrian Chadd } 315*270069b7SAdrian Chadd ifmr->ifm_current = ifr.ifr_media; 316*270069b7SAdrian Chadd callback_register(setifmediacallback, (void *)ifmr); 317*270069b7SAdrian Chadd } 318*270069b7SAdrian Chadd 319*270069b7SAdrian Chadd static void 320*270069b7SAdrian Chadd setmediainst(const char *val, int d, int s, const struct afswtch *afp) 321*270069b7SAdrian Chadd { 322*270069b7SAdrian Chadd struct ifmediareq *ifmr; 323*270069b7SAdrian Chadd int inst; 324*270069b7SAdrian Chadd 325*270069b7SAdrian Chadd ifmr = ifmedia_getstate(s); 326*270069b7SAdrian Chadd 327*270069b7SAdrian Chadd inst = atoi(val); 328*270069b7SAdrian Chadd if (inst < 0 || inst > (int)IFM_INST_MAX) 329*270069b7SAdrian Chadd errx(1, "invalid media instance: %s", val); 330*270069b7SAdrian Chadd 331*270069b7SAdrian Chadd strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 332*270069b7SAdrian Chadd ifr.ifr_media = (ifmr->ifm_current & ~IFM_IMASK) | inst << IFM_ISHIFT; 333*270069b7SAdrian Chadd 334*270069b7SAdrian Chadd ifmr->ifm_current = ifr.ifr_media; 335*270069b7SAdrian Chadd callback_register(setifmediacallback, (void *)ifmr); 336*270069b7SAdrian Chadd } 337*270069b7SAdrian Chadd 338*270069b7SAdrian Chadd static void 339*270069b7SAdrian Chadd setmediamode(const char *val, int d, int s, const struct afswtch *afp) 340*270069b7SAdrian Chadd { 341*270069b7SAdrian Chadd struct ifmediareq *ifmr; 342*270069b7SAdrian Chadd int mode; 343*270069b7SAdrian Chadd 344*270069b7SAdrian Chadd ifmr = ifmedia_getstate(s); 345*270069b7SAdrian Chadd 346*270069b7SAdrian Chadd mode = get_media_mode(IFM_TYPE(ifmr->ifm_ulist[0]), val); 347*270069b7SAdrian Chadd 348*270069b7SAdrian Chadd strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 349*270069b7SAdrian Chadd ifr.ifr_media = (ifmr->ifm_current & ~IFM_MMASK) | mode; 350*270069b7SAdrian Chadd 351*270069b7SAdrian Chadd ifmr->ifm_current = ifr.ifr_media; 352*270069b7SAdrian Chadd callback_register(setifmediacallback, (void *)ifmr); 353*270069b7SAdrian Chadd } 354*270069b7SAdrian Chadd #endif 355*270069b7SAdrian Chadd 356*270069b7SAdrian Chadd /********************************************************************** 357*270069b7SAdrian Chadd * A good chunk of this is duplicated from sys/net/ifmedia.c 358*270069b7SAdrian Chadd **********************************************************************/ 359*270069b7SAdrian Chadd 360*270069b7SAdrian Chadd static struct ifmedia_description ifm_type_descriptions[] = 361*270069b7SAdrian Chadd IFM_TYPE_DESCRIPTIONS; 362*270069b7SAdrian Chadd 363*270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_ethernet_descriptions[] = 364*270069b7SAdrian Chadd IFM_SUBTYPE_ETHERNET_DESCRIPTIONS; 365*270069b7SAdrian Chadd 366*270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_ethernet_aliases[] = 367*270069b7SAdrian Chadd IFM_SUBTYPE_ETHERNET_ALIASES; 368*270069b7SAdrian Chadd 369*270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_ethernet_option_descriptions[] = 370*270069b7SAdrian Chadd IFM_SUBTYPE_ETHERNET_OPTION_DESCRIPTIONS; 371*270069b7SAdrian Chadd 372*270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_tokenring_descriptions[] = 373*270069b7SAdrian Chadd IFM_SUBTYPE_TOKENRING_DESCRIPTIONS; 374*270069b7SAdrian Chadd 375*270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_tokenring_aliases[] = 376*270069b7SAdrian Chadd IFM_SUBTYPE_TOKENRING_ALIASES; 377*270069b7SAdrian Chadd 378*270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_tokenring_option_descriptions[] = 379*270069b7SAdrian Chadd IFM_SUBTYPE_TOKENRING_OPTION_DESCRIPTIONS; 380*270069b7SAdrian Chadd 381*270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_fddi_descriptions[] = 382*270069b7SAdrian Chadd IFM_SUBTYPE_FDDI_DESCRIPTIONS; 383*270069b7SAdrian Chadd 384*270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_fddi_aliases[] = 385*270069b7SAdrian Chadd IFM_SUBTYPE_FDDI_ALIASES; 386*270069b7SAdrian Chadd 387*270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_fddi_option_descriptions[] = 388*270069b7SAdrian Chadd IFM_SUBTYPE_FDDI_OPTION_DESCRIPTIONS; 389*270069b7SAdrian Chadd 390*270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_ieee80211_descriptions[] = 391*270069b7SAdrian Chadd IFM_SUBTYPE_IEEE80211_DESCRIPTIONS; 392*270069b7SAdrian Chadd 393*270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_ieee80211_aliases[] = 394*270069b7SAdrian Chadd IFM_SUBTYPE_IEEE80211_ALIASES; 395*270069b7SAdrian Chadd 396*270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_ieee80211_option_descriptions[] = 397*270069b7SAdrian Chadd IFM_SUBTYPE_IEEE80211_OPTION_DESCRIPTIONS; 398*270069b7SAdrian Chadd 399*270069b7SAdrian Chadd struct ifmedia_description ifm_subtype_ieee80211_mode_descriptions[] = 400*270069b7SAdrian Chadd IFM_SUBTYPE_IEEE80211_MODE_DESCRIPTIONS; 401*270069b7SAdrian Chadd 402*270069b7SAdrian Chadd struct ifmedia_description ifm_subtype_ieee80211_mode_aliases[] = 403*270069b7SAdrian Chadd IFM_SUBTYPE_IEEE80211_MODE_ALIASES; 404*270069b7SAdrian Chadd 405*270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_atm_descriptions[] = 406*270069b7SAdrian Chadd IFM_SUBTYPE_ATM_DESCRIPTIONS; 407*270069b7SAdrian Chadd 408*270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_atm_aliases[] = 409*270069b7SAdrian Chadd IFM_SUBTYPE_ATM_ALIASES; 410*270069b7SAdrian Chadd 411*270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_atm_option_descriptions[] = 412*270069b7SAdrian Chadd IFM_SUBTYPE_ATM_OPTION_DESCRIPTIONS; 413*270069b7SAdrian Chadd 414*270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_shared_descriptions[] = 415*270069b7SAdrian Chadd IFM_SUBTYPE_SHARED_DESCRIPTIONS; 416*270069b7SAdrian Chadd 417*270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_shared_aliases[] = 418*270069b7SAdrian Chadd IFM_SUBTYPE_SHARED_ALIASES; 419*270069b7SAdrian Chadd 420*270069b7SAdrian Chadd static struct ifmedia_description ifm_shared_option_descriptions[] = 421*270069b7SAdrian Chadd IFM_SHARED_OPTION_DESCRIPTIONS; 422*270069b7SAdrian Chadd 423*270069b7SAdrian Chadd static struct ifmedia_description ifm_shared_option_aliases[] = 424*270069b7SAdrian Chadd IFM_SHARED_OPTION_ALIASES; 425*270069b7SAdrian Chadd 426*270069b7SAdrian Chadd struct ifmedia_type_to_subtype { 427*270069b7SAdrian Chadd struct { 428*270069b7SAdrian Chadd struct ifmedia_description *desc; 429*270069b7SAdrian Chadd int alias; 430*270069b7SAdrian Chadd } subtypes[5]; 431*270069b7SAdrian Chadd struct { 432*270069b7SAdrian Chadd struct ifmedia_description *desc; 433*270069b7SAdrian Chadd int alias; 434*270069b7SAdrian Chadd } options[4]; 435*270069b7SAdrian Chadd struct { 436*270069b7SAdrian Chadd struct ifmedia_description *desc; 437*270069b7SAdrian Chadd int alias; 438*270069b7SAdrian Chadd } modes[3]; 439*270069b7SAdrian Chadd }; 440*270069b7SAdrian Chadd 441*270069b7SAdrian Chadd /* must be in the same order as IFM_TYPE_DESCRIPTIONS */ 442*270069b7SAdrian Chadd static struct ifmedia_type_to_subtype ifmedia_types_to_subtypes[] = { 443*270069b7SAdrian Chadd { 444*270069b7SAdrian Chadd { 445*270069b7SAdrian Chadd { &ifm_subtype_shared_descriptions[0], 0 }, 446*270069b7SAdrian Chadd { &ifm_subtype_shared_aliases[0], 1 }, 447*270069b7SAdrian Chadd { &ifm_subtype_ethernet_descriptions[0], 0 }, 448*270069b7SAdrian Chadd { &ifm_subtype_ethernet_aliases[0], 1 }, 449*270069b7SAdrian Chadd { NULL, 0 }, 450*270069b7SAdrian Chadd }, 451*270069b7SAdrian Chadd { 452*270069b7SAdrian Chadd { &ifm_shared_option_descriptions[0], 0 }, 453*270069b7SAdrian Chadd { &ifm_shared_option_aliases[0], 1 }, 454*270069b7SAdrian Chadd { &ifm_subtype_ethernet_option_descriptions[0], 0 }, 455*270069b7SAdrian Chadd { NULL, 0 }, 456*270069b7SAdrian Chadd }, 457*270069b7SAdrian Chadd { 458*270069b7SAdrian Chadd { NULL, 0 }, 459*270069b7SAdrian Chadd }, 460*270069b7SAdrian Chadd }, 461*270069b7SAdrian Chadd { 462*270069b7SAdrian Chadd { 463*270069b7SAdrian Chadd { &ifm_subtype_shared_descriptions[0], 0 }, 464*270069b7SAdrian Chadd { &ifm_subtype_shared_aliases[0], 1 }, 465*270069b7SAdrian Chadd { &ifm_subtype_tokenring_descriptions[0], 0 }, 466*270069b7SAdrian Chadd { &ifm_subtype_tokenring_aliases[0], 1 }, 467*270069b7SAdrian Chadd { NULL, 0 }, 468*270069b7SAdrian Chadd }, 469*270069b7SAdrian Chadd { 470*270069b7SAdrian Chadd { &ifm_shared_option_descriptions[0], 0 }, 471*270069b7SAdrian Chadd { &ifm_shared_option_aliases[0], 1 }, 472*270069b7SAdrian Chadd { &ifm_subtype_tokenring_option_descriptions[0], 0 }, 473*270069b7SAdrian Chadd { NULL, 0 }, 474*270069b7SAdrian Chadd }, 475*270069b7SAdrian Chadd { 476*270069b7SAdrian Chadd { NULL, 0 }, 477*270069b7SAdrian Chadd }, 478*270069b7SAdrian Chadd }, 479*270069b7SAdrian Chadd { 480*270069b7SAdrian Chadd { 481*270069b7SAdrian Chadd { &ifm_subtype_shared_descriptions[0], 0 }, 482*270069b7SAdrian Chadd { &ifm_subtype_shared_aliases[0], 1 }, 483*270069b7SAdrian Chadd { &ifm_subtype_fddi_descriptions[0], 0 }, 484*270069b7SAdrian Chadd { &ifm_subtype_fddi_aliases[0], 1 }, 485*270069b7SAdrian Chadd { NULL, 0 }, 486*270069b7SAdrian Chadd }, 487*270069b7SAdrian Chadd { 488*270069b7SAdrian Chadd { &ifm_shared_option_descriptions[0], 0 }, 489*270069b7SAdrian Chadd { &ifm_shared_option_aliases[0], 1 }, 490*270069b7SAdrian Chadd { &ifm_subtype_fddi_option_descriptions[0], 0 }, 491*270069b7SAdrian Chadd { NULL, 0 }, 492*270069b7SAdrian Chadd }, 493*270069b7SAdrian Chadd { 494*270069b7SAdrian Chadd { NULL, 0 }, 495*270069b7SAdrian Chadd }, 496*270069b7SAdrian Chadd }, 497*270069b7SAdrian Chadd { 498*270069b7SAdrian Chadd { 499*270069b7SAdrian Chadd { &ifm_subtype_shared_descriptions[0], 0 }, 500*270069b7SAdrian Chadd { &ifm_subtype_shared_aliases[0], 1 }, 501*270069b7SAdrian Chadd { &ifm_subtype_ieee80211_descriptions[0], 0 }, 502*270069b7SAdrian Chadd { &ifm_subtype_ieee80211_aliases[0], 1 }, 503*270069b7SAdrian Chadd { NULL, 0 }, 504*270069b7SAdrian Chadd }, 505*270069b7SAdrian Chadd { 506*270069b7SAdrian Chadd { &ifm_shared_option_descriptions[0], 0 }, 507*270069b7SAdrian Chadd { &ifm_shared_option_aliases[0], 1 }, 508*270069b7SAdrian Chadd { &ifm_subtype_ieee80211_option_descriptions[0], 0 }, 509*270069b7SAdrian Chadd { NULL, 0 }, 510*270069b7SAdrian Chadd }, 511*270069b7SAdrian Chadd { 512*270069b7SAdrian Chadd { &ifm_subtype_ieee80211_mode_descriptions[0], 0 }, 513*270069b7SAdrian Chadd { &ifm_subtype_ieee80211_mode_aliases[0], 0 }, 514*270069b7SAdrian Chadd { NULL, 0 }, 515*270069b7SAdrian Chadd }, 516*270069b7SAdrian Chadd }, 517*270069b7SAdrian Chadd { 518*270069b7SAdrian Chadd { 519*270069b7SAdrian Chadd { &ifm_subtype_shared_descriptions[0], 0 }, 520*270069b7SAdrian Chadd { &ifm_subtype_shared_aliases[0], 1 }, 521*270069b7SAdrian Chadd { &ifm_subtype_atm_descriptions[0], 0 }, 522*270069b7SAdrian Chadd { &ifm_subtype_atm_aliases[0], 1 }, 523*270069b7SAdrian Chadd { NULL, 0 }, 524*270069b7SAdrian Chadd }, 525*270069b7SAdrian Chadd { 526*270069b7SAdrian Chadd { &ifm_shared_option_descriptions[0], 0 }, 527*270069b7SAdrian Chadd { &ifm_shared_option_aliases[0], 1 }, 528*270069b7SAdrian Chadd { &ifm_subtype_atm_option_descriptions[0], 0 }, 529*270069b7SAdrian Chadd { NULL, 0 }, 530*270069b7SAdrian Chadd }, 531*270069b7SAdrian Chadd { 532*270069b7SAdrian Chadd { NULL, 0 }, 533*270069b7SAdrian Chadd }, 534*270069b7SAdrian Chadd }, 535*270069b7SAdrian Chadd }; 536*270069b7SAdrian Chadd 537*270069b7SAdrian Chadd int 538*270069b7SAdrian Chadd get_media_subtype(int type, const char *val) 539*270069b7SAdrian Chadd { 540*270069b7SAdrian Chadd struct ifmedia_description *desc; 541*270069b7SAdrian Chadd struct ifmedia_type_to_subtype *ttos; 542*270069b7SAdrian Chadd int rval, i; 543*270069b7SAdrian Chadd 544*270069b7SAdrian Chadd /* Find the top-level interface type. */ 545*270069b7SAdrian Chadd for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; 546*270069b7SAdrian Chadd desc->ifmt_string != NULL; desc++, ttos++) 547*270069b7SAdrian Chadd if (type == desc->ifmt_word) 548*270069b7SAdrian Chadd break; 549*270069b7SAdrian Chadd if (desc->ifmt_string == NULL) 550*270069b7SAdrian Chadd errx(1, "unknown media type 0x%x", type); 551*270069b7SAdrian Chadd 552*270069b7SAdrian Chadd for (i = 0; ttos->subtypes[i].desc != NULL; i++) { 553*270069b7SAdrian Chadd rval = lookup_media_word(ttos->subtypes[i].desc, val); 554*270069b7SAdrian Chadd if (rval != -1) 555*270069b7SAdrian Chadd return (rval); 556*270069b7SAdrian Chadd } 557*270069b7SAdrian Chadd errx(1, "unknown media subtype: %s", val); 558*270069b7SAdrian Chadd /*NOTREACHED*/ 559*270069b7SAdrian Chadd } 560*270069b7SAdrian Chadd 561*270069b7SAdrian Chadd int 562*270069b7SAdrian Chadd get_media_mode(int type, const char *val) 563*270069b7SAdrian Chadd { 564*270069b7SAdrian Chadd struct ifmedia_description *desc; 565*270069b7SAdrian Chadd struct ifmedia_type_to_subtype *ttos; 566*270069b7SAdrian Chadd int rval, i; 567*270069b7SAdrian Chadd 568*270069b7SAdrian Chadd /* Find the top-level interface type. */ 569*270069b7SAdrian Chadd for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; 570*270069b7SAdrian Chadd desc->ifmt_string != NULL; desc++, ttos++) 571*270069b7SAdrian Chadd if (type == desc->ifmt_word) 572*270069b7SAdrian Chadd break; 573*270069b7SAdrian Chadd if (desc->ifmt_string == NULL) 574*270069b7SAdrian Chadd errx(1, "unknown media mode 0x%x", type); 575*270069b7SAdrian Chadd 576*270069b7SAdrian Chadd for (i = 0; ttos->modes[i].desc != NULL; i++) { 577*270069b7SAdrian Chadd rval = lookup_media_word(ttos->modes[i].desc, val); 578*270069b7SAdrian Chadd if (rval != -1) 579*270069b7SAdrian Chadd return (rval); 580*270069b7SAdrian Chadd } 581*270069b7SAdrian Chadd return -1; 582*270069b7SAdrian Chadd } 583*270069b7SAdrian Chadd 584*270069b7SAdrian Chadd int 585*270069b7SAdrian Chadd get_media_options(int type, const char *val) 586*270069b7SAdrian Chadd { 587*270069b7SAdrian Chadd struct ifmedia_description *desc; 588*270069b7SAdrian Chadd struct ifmedia_type_to_subtype *ttos; 589*270069b7SAdrian Chadd char *optlist, *optptr; 590*270069b7SAdrian Chadd int option = 0, i, rval = 0; 591*270069b7SAdrian Chadd 592*270069b7SAdrian Chadd /* We muck with the string, so copy it. */ 593*270069b7SAdrian Chadd optlist = strdup(val); 594*270069b7SAdrian Chadd if (optlist == NULL) 595*270069b7SAdrian Chadd err(1, "strdup"); 596*270069b7SAdrian Chadd 597*270069b7SAdrian Chadd /* Find the top-level interface type. */ 598*270069b7SAdrian Chadd for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; 599*270069b7SAdrian Chadd desc->ifmt_string != NULL; desc++, ttos++) 600*270069b7SAdrian Chadd if (type == desc->ifmt_word) 601*270069b7SAdrian Chadd break; 602*270069b7SAdrian Chadd if (desc->ifmt_string == NULL) 603*270069b7SAdrian Chadd errx(1, "unknown media type 0x%x", type); 604*270069b7SAdrian Chadd 605*270069b7SAdrian Chadd /* 606*270069b7SAdrian Chadd * Look up the options in the user-provided comma-separated 607*270069b7SAdrian Chadd * list. 608*270069b7SAdrian Chadd */ 609*270069b7SAdrian Chadd optptr = optlist; 610*270069b7SAdrian Chadd for (; (optptr = strtok(optptr, ",")) != NULL; optptr = NULL) { 611*270069b7SAdrian Chadd for (i = 0; ttos->options[i].desc != NULL; i++) { 612*270069b7SAdrian Chadd option = lookup_media_word(ttos->options[i].desc, optptr); 613*270069b7SAdrian Chadd if (option != -1) 614*270069b7SAdrian Chadd break; 615*270069b7SAdrian Chadd } 616*270069b7SAdrian Chadd if (option == 0) 617*270069b7SAdrian Chadd errx(1, "unknown option: %s", optptr); 618*270069b7SAdrian Chadd rval |= option; 619*270069b7SAdrian Chadd } 620*270069b7SAdrian Chadd 621*270069b7SAdrian Chadd free(optlist); 622*270069b7SAdrian Chadd return (rval); 623*270069b7SAdrian Chadd } 624*270069b7SAdrian Chadd 625*270069b7SAdrian Chadd int 626*270069b7SAdrian Chadd lookup_media_word(struct ifmedia_description *desc, const char *val) 627*270069b7SAdrian Chadd { 628*270069b7SAdrian Chadd 629*270069b7SAdrian Chadd for (; desc->ifmt_string != NULL; desc++) 630*270069b7SAdrian Chadd if (strcasecmp(desc->ifmt_string, val) == 0) 631*270069b7SAdrian Chadd return (desc->ifmt_word); 632*270069b7SAdrian Chadd 633*270069b7SAdrian Chadd return (-1); 634*270069b7SAdrian Chadd } 635*270069b7SAdrian Chadd 636*270069b7SAdrian Chadd static struct ifmedia_description *get_toptype_desc(int ifmw) 637*270069b7SAdrian Chadd { 638*270069b7SAdrian Chadd struct ifmedia_description *desc; 639*270069b7SAdrian Chadd 640*270069b7SAdrian Chadd for (desc = ifm_type_descriptions; desc->ifmt_string != NULL; desc++) 641*270069b7SAdrian Chadd if (IFM_TYPE(ifmw) == desc->ifmt_word) 642*270069b7SAdrian Chadd break; 643*270069b7SAdrian Chadd 644*270069b7SAdrian Chadd return desc; 645*270069b7SAdrian Chadd } 646*270069b7SAdrian Chadd 647*270069b7SAdrian Chadd static struct ifmedia_type_to_subtype *get_toptype_ttos(int ifmw) 648*270069b7SAdrian Chadd { 649*270069b7SAdrian Chadd struct ifmedia_description *desc; 650*270069b7SAdrian Chadd struct ifmedia_type_to_subtype *ttos; 651*270069b7SAdrian Chadd 652*270069b7SAdrian Chadd for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; 653*270069b7SAdrian Chadd desc->ifmt_string != NULL; desc++, ttos++) 654*270069b7SAdrian Chadd if (IFM_TYPE(ifmw) == desc->ifmt_word) 655*270069b7SAdrian Chadd break; 656*270069b7SAdrian Chadd 657*270069b7SAdrian Chadd return ttos; 658*270069b7SAdrian Chadd } 659*270069b7SAdrian Chadd 660*270069b7SAdrian Chadd static struct ifmedia_description *get_subtype_desc(int ifmw, 661*270069b7SAdrian Chadd struct ifmedia_type_to_subtype *ttos) 662*270069b7SAdrian Chadd { 663*270069b7SAdrian Chadd int i; 664*270069b7SAdrian Chadd struct ifmedia_description *desc; 665*270069b7SAdrian Chadd 666*270069b7SAdrian Chadd for (i = 0; ttos->subtypes[i].desc != NULL; i++) { 667*270069b7SAdrian Chadd if (ttos->subtypes[i].alias) 668*270069b7SAdrian Chadd continue; 669*270069b7SAdrian Chadd for (desc = ttos->subtypes[i].desc; 670*270069b7SAdrian Chadd desc->ifmt_string != NULL; desc++) { 671*270069b7SAdrian Chadd if (IFM_SUBTYPE(ifmw) == desc->ifmt_word) 672*270069b7SAdrian Chadd return desc; 673*270069b7SAdrian Chadd } 674*270069b7SAdrian Chadd } 675*270069b7SAdrian Chadd 676*270069b7SAdrian Chadd return NULL; 677*270069b7SAdrian Chadd } 678*270069b7SAdrian Chadd 679*270069b7SAdrian Chadd static struct ifmedia_description *get_mode_desc(int ifmw, 680*270069b7SAdrian Chadd struct ifmedia_type_to_subtype *ttos) 681*270069b7SAdrian Chadd { 682*270069b7SAdrian Chadd int i; 683*270069b7SAdrian Chadd struct ifmedia_description *desc; 684*270069b7SAdrian Chadd 685*270069b7SAdrian Chadd for (i = 0; ttos->modes[i].desc != NULL; i++) { 686*270069b7SAdrian Chadd if (ttos->modes[i].alias) 687*270069b7SAdrian Chadd continue; 688*270069b7SAdrian Chadd for (desc = ttos->modes[i].desc; 689*270069b7SAdrian Chadd desc->ifmt_string != NULL; desc++) { 690*270069b7SAdrian Chadd if (IFM_MODE(ifmw) == desc->ifmt_word) 691*270069b7SAdrian Chadd return desc; 692*270069b7SAdrian Chadd } 693*270069b7SAdrian Chadd } 694*270069b7SAdrian Chadd 695*270069b7SAdrian Chadd return NULL; 696*270069b7SAdrian Chadd } 697*270069b7SAdrian Chadd 698*270069b7SAdrian Chadd void 699*270069b7SAdrian Chadd print_media_word(int ifmw, int print_toptype) 700*270069b7SAdrian Chadd { 701*270069b7SAdrian Chadd struct ifmedia_description *desc; 702*270069b7SAdrian Chadd struct ifmedia_type_to_subtype *ttos; 703*270069b7SAdrian Chadd int seen_option = 0, i; 704*270069b7SAdrian Chadd 705*270069b7SAdrian Chadd /* Find the top-level interface type. */ 706*270069b7SAdrian Chadd desc = get_toptype_desc(ifmw); 707*270069b7SAdrian Chadd ttos = get_toptype_ttos(ifmw); 708*270069b7SAdrian Chadd if (desc->ifmt_string == NULL) { 709*270069b7SAdrian Chadd printf("<unknown type>"); 710*270069b7SAdrian Chadd return; 711*270069b7SAdrian Chadd } else if (print_toptype) { 712*270069b7SAdrian Chadd printf("%s", desc->ifmt_string); 713*270069b7SAdrian Chadd } 714*270069b7SAdrian Chadd 715*270069b7SAdrian Chadd /* 716*270069b7SAdrian Chadd * Don't print the top-level type; it's not like we can 717*270069b7SAdrian Chadd * change it, or anything. 718*270069b7SAdrian Chadd */ 719*270069b7SAdrian Chadd 720*270069b7SAdrian Chadd /* Find subtype. */ 721*270069b7SAdrian Chadd desc = get_subtype_desc(ifmw, ttos); 722*270069b7SAdrian Chadd if (desc == NULL) { 723*270069b7SAdrian Chadd printf("<unknown subtype>"); 724*270069b7SAdrian Chadd return; 725*270069b7SAdrian Chadd } 726*270069b7SAdrian Chadd 727*270069b7SAdrian Chadd if (print_toptype) 728*270069b7SAdrian Chadd putchar(' '); 729*270069b7SAdrian Chadd 730*270069b7SAdrian Chadd printf("%s", desc->ifmt_string); 731*270069b7SAdrian Chadd 732*270069b7SAdrian Chadd if (print_toptype) { 733*270069b7SAdrian Chadd desc = get_mode_desc(ifmw, ttos); 734*270069b7SAdrian Chadd if (desc != NULL && strcasecmp("autoselect", desc->ifmt_string)) 735*270069b7SAdrian Chadd printf(" mode %s", desc->ifmt_string); 736*270069b7SAdrian Chadd } 737*270069b7SAdrian Chadd 738*270069b7SAdrian Chadd /* Find options. */ 739*270069b7SAdrian Chadd for (i = 0; ttos->options[i].desc != NULL; i++) { 740*270069b7SAdrian Chadd if (ttos->options[i].alias) 741*270069b7SAdrian Chadd continue; 742*270069b7SAdrian Chadd for (desc = ttos->options[i].desc; 743*270069b7SAdrian Chadd desc->ifmt_string != NULL; desc++) { 744*270069b7SAdrian Chadd if (ifmw & desc->ifmt_word) { 745*270069b7SAdrian Chadd if (seen_option == 0) 746*270069b7SAdrian Chadd printf(" <"); 747*270069b7SAdrian Chadd printf("%s%s", seen_option++ ? "," : "", 748*270069b7SAdrian Chadd desc->ifmt_string); 749*270069b7SAdrian Chadd } 750*270069b7SAdrian Chadd } 751*270069b7SAdrian Chadd } 752*270069b7SAdrian Chadd printf("%s", seen_option ? ">" : ""); 753*270069b7SAdrian Chadd 754*270069b7SAdrian Chadd if (print_toptype && IFM_INST(ifmw) != 0) 755*270069b7SAdrian Chadd printf(" instance %d", IFM_INST(ifmw)); 756*270069b7SAdrian Chadd } 757*270069b7SAdrian Chadd 758*270069b7SAdrian Chadd void 759*270069b7SAdrian Chadd print_media_word_ifconfig(int ifmw) 760*270069b7SAdrian Chadd { 761*270069b7SAdrian Chadd struct ifmedia_description *desc; 762*270069b7SAdrian Chadd struct ifmedia_type_to_subtype *ttos; 763*270069b7SAdrian Chadd int seen_option = 0, i; 764*270069b7SAdrian Chadd 765*270069b7SAdrian Chadd /* Find the top-level interface type. */ 766*270069b7SAdrian Chadd desc = get_toptype_desc(ifmw); 767*270069b7SAdrian Chadd ttos = get_toptype_ttos(ifmw); 768*270069b7SAdrian Chadd if (desc->ifmt_string == NULL) { 769*270069b7SAdrian Chadd printf("<unknown type>"); 770*270069b7SAdrian Chadd return; 771*270069b7SAdrian Chadd } 772*270069b7SAdrian Chadd 773*270069b7SAdrian Chadd /* 774*270069b7SAdrian Chadd * Don't print the top-level type; it's not like we can 775*270069b7SAdrian Chadd * change it, or anything. 776*270069b7SAdrian Chadd */ 777*270069b7SAdrian Chadd 778*270069b7SAdrian Chadd /* Find subtype. */ 779*270069b7SAdrian Chadd desc = get_subtype_desc(ifmw, ttos); 780*270069b7SAdrian Chadd if (desc == NULL) { 781*270069b7SAdrian Chadd printf("<unknown subtype>"); 782*270069b7SAdrian Chadd return; 783*270069b7SAdrian Chadd } 784*270069b7SAdrian Chadd 785*270069b7SAdrian Chadd printf("media %s", desc->ifmt_string); 786*270069b7SAdrian Chadd 787*270069b7SAdrian Chadd desc = get_mode_desc(ifmw, ttos); 788*270069b7SAdrian Chadd if (desc != NULL) 789*270069b7SAdrian Chadd printf(" mode %s", desc->ifmt_string); 790*270069b7SAdrian Chadd 791*270069b7SAdrian Chadd /* Find options. */ 792*270069b7SAdrian Chadd for (i = 0; ttos->options[i].desc != NULL; i++) { 793*270069b7SAdrian Chadd if (ttos->options[i].alias) 794*270069b7SAdrian Chadd continue; 795*270069b7SAdrian Chadd for (desc = ttos->options[i].desc; 796*270069b7SAdrian Chadd desc->ifmt_string != NULL; desc++) { 797*270069b7SAdrian Chadd if (ifmw & desc->ifmt_word) { 798*270069b7SAdrian Chadd if (seen_option == 0) 799*270069b7SAdrian Chadd printf(" mediaopt "); 800*270069b7SAdrian Chadd printf("%s%s", seen_option++ ? "," : "", 801*270069b7SAdrian Chadd desc->ifmt_string); 802*270069b7SAdrian Chadd } 803*270069b7SAdrian Chadd } 804*270069b7SAdrian Chadd } 805*270069b7SAdrian Chadd 806*270069b7SAdrian Chadd if (IFM_INST(ifmw) != 0) 807*270069b7SAdrian Chadd printf(" instance %d", IFM_INST(ifmw)); 808*270069b7SAdrian Chadd } 809*270069b7SAdrian Chadd 810*270069b7SAdrian Chadd /********************************************************************** 811*270069b7SAdrian Chadd * ...until here. 812*270069b7SAdrian Chadd **********************************************************************/ 813