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