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 $ */
5 * Copyright (c) 1997 Jason R. Thorpe.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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
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.
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
37 * Copyright (c) 1983, 1993
38 * The Regents of the University of California. All rights reserved.
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
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.
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
69 #include <sys/param.h>
70 #include <sys/ioctl.h>
71 #include <sys/socket.h>
72 #include <sys/sysctl.h>
76 #include <net/if_dl.h>
77 #include <net/if_types.h>
78 #include <net/if_media.h>
79 #include <net/route.h>
91 #define SIOCGIFXMEDIA SIOCGIFMEDIA
96 static void domediaopt(const char *, int, int);
97 static int get_media_subtype(int, const char *);
99 static int get_media_mode(int, const char *);
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);
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
);
114 struct ifmediareq ifmr
;
117 (void) memset(&ifmr
, 0, sizeof(ifmr
));
118 (void) strlcpy(ifmr
.ifm_name
, name
, sizeof(ifmr
.ifm_name
));
120 if (ioctl(s
, SIOCGIFXMEDIA
, (caddr_t
)&ifmr
) < 0) {
122 * Interface doesn't support SIOC{G,S}IFMEDIA.
127 if (ifmr
.ifm_count
== 0) {
128 warnx("%s: no media types?", name
);
132 media_list
= (int *)malloc(ifmr
.ifm_count
* sizeof(int));
133 if (media_list
== NULL
)
135 ifmr
.ifm_ulist
= media_list
;
137 if (ioctl(s
, SIOCGIFXMEDIA
, (caddr_t
)&ifmr
) < 0)
138 err(1, "SIOCGIFXMEDIA");
141 print_media_word(ifmr
.ifm_current
, 1);
142 if (ifmr
.ifm_active
!= ifmr
.ifm_current
) {
145 print_media_word(ifmr
.ifm_active
, 0);
151 if (ifmr
.ifm_status
& IFM_AVALID
) {
152 printf("\tstatus: ");
154 switch (IFM_TYPE(ifmr
.ifm_active
)) {
157 if (ifmr
.ifm_status
& IFM_ACTIVE
)
160 printf("no carrier");
165 if (ifmr
.ifm_status
& IFM_ACTIVE
)
172 /* XXX: Different value for adhoc? */
173 if (ifmr
.ifm_status
& IFM_ACTIVE
)
174 printf("associated");
176 printf("no carrier");
180 if (ifmr
.ifm_status
& IFM_ACTIVE
)
188 if (ifmr
.ifm_count
> 0 && supmedia
) {
189 printf("\tsupported media:\n");
190 for (i
= 0; i
< ifmr
.ifm_count
; i
++) {
192 print_media_word_ifconfig(media_list
[i
]);
201 ifmedia_getstate(int s
)
203 static struct ifmediareq
*ifmr
= NULL
;
207 ifmr
= (struct ifmediareq
*)malloc(sizeof(struct ifmediareq
));
211 (void) memset(ifmr
, 0, sizeof(struct ifmediareq
));
212 (void) strlcpy(ifmr
->ifm_name
, name
,
213 sizeof(ifmr
->ifm_name
));
216 ifmr
->ifm_ulist
= NULL
;
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.
224 if (ioctl(s
, SIOCGIFXMEDIA
, (caddr_t
)ifmr
) < 0) {
225 err(1, "SIOCGIFXMEDIA");
228 if (ifmr
->ifm_count
== 0)
229 errx(1, "%s: no media types?", name
);
231 mwords
= (int *)malloc(ifmr
->ifm_count
* sizeof(int));
235 ifmr
->ifm_ulist
= mwords
;
236 if (ioctl(s
, SIOCGIFXMEDIA
, (caddr_t
)ifmr
) < 0)
237 err(1, "SIOCGIFXMEDIA");
244 setifmediacallback(int s
, void *arg
)
246 struct ifmediareq
*ifmr
= (struct ifmediareq
*)arg
;
247 static int did_it
= 0;
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
);
260 setmedia(const char *val
, int d
, int s
, const struct afswtch
*afp
)
262 struct ifmediareq
*ifmr
;
265 ifmr
= ifmedia_getstate(s
);
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"
273 * (I'm assuming that all supported media types for a given
274 * interface will be the same top-level type..)
276 subtype
= get_media_subtype(IFM_TYPE(ifmr
->ifm_ulist
[0]), val
);
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
;
282 if ((ifr
.ifr_media
& IFM_TMASK
) == 0) {
283 ifr
.ifr_media
&= ~IFM_GMASK
;
286 ifmr
->ifm_current
= ifr
.ifr_media
;
287 callback_register(setifmediacallback
, (void *)ifmr
);
291 setmediaopt(const char *val
, int d
, int s
, const struct afswtch
*afp
)
294 domediaopt(val
, 0, s
);
298 unsetmediaopt(const char *val
, int d
, int s
, const struct afswtch
*afp
)
301 domediaopt(val
, 1, s
);
305 domediaopt(const char *val
, int clear
, int s
)
307 struct ifmediareq
*ifmr
;
310 ifmr
= ifmedia_getstate(s
);
312 options
= get_media_options(IFM_TYPE(ifmr
->ifm_ulist
[0]), val
);
314 strlcpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
315 ifr
.ifr_media
= ifmr
->ifm_current
;
317 ifr
.ifr_media
&= ~options
;
319 if (options
& IFM_HDX
) {
320 ifr
.ifr_media
&= ~IFM_FDX
;
323 ifr
.ifr_media
|= options
;
325 ifmr
->ifm_current
= ifr
.ifr_media
;
326 callback_register(setifmediacallback
, (void *)ifmr
);
330 setmediainst(const char *val
, int d
, int s
, const struct afswtch
*afp
)
332 struct ifmediareq
*ifmr
;
335 ifmr
= ifmedia_getstate(s
);
338 if (inst
< 0 || inst
> IFM_INST_MAX
)
339 errx(1, "invalid media instance: %s", val
);
341 strlcpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
342 ifr
.ifr_media
= (ifmr
->ifm_current
& ~IFM_IMASK
) | inst
<< IFM_ISHIFT
;
344 ifmr
->ifm_current
= ifr
.ifr_media
;
345 callback_register(setifmediacallback
, (void *)ifmr
);
350 setmediamode(const char *val
, int d
, int s
, const struct afswtch
*afp
)
352 struct ifmediareq
*ifmr
;
355 ifmr
= ifmedia_getstate(s
);
357 mode
= get_media_mode(IFM_TYPE(ifmr
->ifm_ulist
[0]), val
);
359 strlcpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
360 ifr
.ifr_media
= (ifmr
->ifm_current
& ~IFM_MMASK
) | mode
;
362 ifmr
->ifm_current
= ifr
.ifr_media
;
363 callback_register(setifmediacallback
, (void *)ifmr
);
367 /**********************************************************************
368 * A good chunk of this is duplicated from sys/net/ifmedia.c
369 **********************************************************************/
371 static struct ifmedia_description ifm_type_descriptions
[] =
372 IFM_TYPE_DESCRIPTIONS
;
374 static struct ifmedia_description ifm_subtype_ethernet_descriptions
[] =
375 IFM_SUBTYPE_ETHERNET_DESCRIPTIONS
;
377 static struct ifmedia_description ifm_subtype_ethernet_aliases
[] =
378 IFM_SUBTYPE_ETHERNET_ALIASES
;
380 static struct ifmedia_description ifm_subtype_ethernet_option_descriptions
[] =
381 IFM_SUBTYPE_ETHERNET_OPTION_DESCRIPTIONS
;
383 static struct ifmedia_description ifm_subtype_tokenring_descriptions
[] =
384 IFM_SUBTYPE_TOKENRING_DESCRIPTIONS
;
386 static struct ifmedia_description ifm_subtype_tokenring_aliases
[] =
387 IFM_SUBTYPE_TOKENRING_ALIASES
;
389 static struct ifmedia_description ifm_subtype_tokenring_option_descriptions
[] =
390 IFM_SUBTYPE_TOKENRING_OPTION_DESCRIPTIONS
;
392 static struct ifmedia_description ifm_subtype_fddi_descriptions
[] =
393 IFM_SUBTYPE_FDDI_DESCRIPTIONS
;
395 static struct ifmedia_description ifm_subtype_fddi_aliases
[] =
396 IFM_SUBTYPE_FDDI_ALIASES
;
398 static struct ifmedia_description ifm_subtype_fddi_option_descriptions
[] =
399 IFM_SUBTYPE_FDDI_OPTION_DESCRIPTIONS
;
401 static struct ifmedia_description ifm_subtype_ieee80211_descriptions
[] =
402 IFM_SUBTYPE_IEEE80211_DESCRIPTIONS
;
404 static struct ifmedia_description ifm_subtype_ieee80211_option_descriptions
[] =
405 IFM_SUBTYPE_IEEE80211_OPTION_DESCRIPTIONS
;
408 static struct ifmedia_description ifm_subtype_ieee80211_aliases
[] =
409 IFM_SUBTYPE_IEEE80211_ALIASES
;
411 struct ifmedia_description ifm_subtype_ieee80211_mode_descriptions
[] =
412 IFM_SUBTYPE_IEEE80211_MODE_DESCRIPTIONS
;
414 struct ifmedia_description ifm_subtype_ieee80211_mode_aliases
[] =
415 IFM_SUBTYPE_IEEE80211_MODE_ALIASES
;
417 static struct ifmedia_description ifm_subtype_atm_descriptions
[] =
418 IFM_SUBTYPE_ATM_DESCRIPTIONS
;
420 static struct ifmedia_description ifm_subtype_atm_aliases
[] =
421 IFM_SUBTYPE_ATM_ALIASES
;
423 static struct ifmedia_description ifm_subtype_atm_option_descriptions
[] =
424 IFM_SUBTYPE_ATM_OPTION_DESCRIPTIONS
;
427 static struct ifmedia_description ifm_subtype_shared_descriptions
[] =
428 IFM_SUBTYPE_SHARED_DESCRIPTIONS
;
430 static struct ifmedia_description ifm_subtype_shared_aliases
[] =
431 IFM_SUBTYPE_SHARED_ALIASES
;
433 static struct ifmedia_description ifm_shared_option_descriptions
[] =
434 IFM_SHARED_OPTION_DESCRIPTIONS
;
436 struct ifmedia_type_to_subtype
{
438 struct ifmedia_description
*desc
;
442 struct ifmedia_description
*desc
;
446 struct ifmedia_description
*desc
;
451 /* must be in the same order as IFM_TYPE_DESCRIPTIONS */
452 static struct ifmedia_type_to_subtype ifmedia_types_to_subtypes
[] = {
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 },
462 { &ifm_shared_option_descriptions
[0], 0 },
463 { &ifm_subtype_ethernet_option_descriptions
[0], 0 },
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 },
479 { &ifm_shared_option_descriptions
[0], 0 },
480 { &ifm_subtype_tokenring_option_descriptions
[0], 0 },
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 },
496 { &ifm_shared_option_descriptions
[0], 0 },
497 { &ifm_subtype_fddi_option_descriptions
[0], 0 },
507 { &ifm_subtype_shared_descriptions
[0], 0 },
508 { &ifm_subtype_shared_aliases
[0], 1 },
509 { &ifm_subtype_ieee80211_descriptions
[0], 0 },
513 { &ifm_shared_option_descriptions
[0], 0 },
514 { &ifm_subtype_ieee80211_option_descriptions
[0], 1 },
521 #else /* __APPLE__ */
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 },
532 { &ifm_shared_option_descriptions
[0], 0 },
533 { &ifm_subtype_ieee80211_option_descriptions
[0], 0 },
537 { &ifm_subtype_ieee80211_mode_descriptions
[0], 0 },
538 { &ifm_subtype_ieee80211_mode_aliases
[0], 0 },
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 },
551 { &ifm_shared_option_descriptions
[0], 0 },
552 { &ifm_subtype_atm_option_descriptions
[0], 0 },
560 #endif /* __APPLE__ */
564 get_media_subtype(int type
, const char *val
)
566 struct ifmedia_description
*desc
;
567 struct ifmedia_type_to_subtype
*ttos
;
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
)
575 if (desc
->ifmt_string
== NULL
)
576 errx(1, "unknown media type 0x%x", type
);
578 for (i
= 0; ttos
->subtypes
[i
].desc
!= NULL
; i
++) {
579 rval
= lookup_media_word(ttos
->subtypes
[i
].desc
, val
);
583 errx(1, "unknown media subtype: %s", val
);
589 get_media_mode(int type
, const char *val
)
591 struct ifmedia_description
*desc
;
592 struct ifmedia_type_to_subtype
*ttos
;
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
)
600 if (desc
->ifmt_string
== NULL
)
601 errx(1, "unknown media mode 0x%x", type
);
603 for (i
= 0; ttos
->modes
[i
].desc
!= NULL
; i
++) {
604 rval
= lookup_media_word(ttos
->modes
[i
].desc
, val
);
613 get_media_options(int type
, const char *val
)
615 struct ifmedia_description
*desc
;
616 struct ifmedia_type_to_subtype
*ttos
;
617 char *optlist
, *optptr
;
618 int option
= 0, i
, rval
= 0;
620 /* We muck with the string, so copy it. */
621 optlist
= strdup(val
);
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
)
630 if (desc
->ifmt_string
== NULL
)
631 errx(1, "unknown media type 0x%x", type
);
634 * Look up the options in the user-provided comma-separated
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
);
645 errx(1, "unknown option: %s", optptr
);
654 lookup_media_word(struct ifmedia_description
*desc
, const char *val
)
657 for (; desc
->ifmt_string
!= NULL
; desc
++)
658 if (strcasecmp(desc
->ifmt_string
, val
) == 0)
659 return (desc
->ifmt_word
);
664 static struct ifmedia_description
*get_toptype_desc(int ifmw
)
666 struct ifmedia_description
*desc
;
668 for (desc
= ifm_type_descriptions
; desc
->ifmt_string
!= NULL
; desc
++)
669 if (IFM_TYPE(ifmw
) == desc
->ifmt_word
)
675 static struct ifmedia_type_to_subtype
*get_toptype_ttos(int ifmw
)
677 struct ifmedia_description
*desc
;
678 struct ifmedia_type_to_subtype
*ttos
;
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
)
688 static struct ifmedia_description
*get_subtype_desc(int ifmw
,
689 struct ifmedia_type_to_subtype
*ttos
)
692 struct ifmedia_description
*desc
;
694 for (i
= 0; ttos
->subtypes
[i
].desc
!= NULL
; i
++) {
695 if (ttos
->subtypes
[i
].alias
)
697 for (desc
= ttos
->subtypes
[i
].desc
;
698 desc
->ifmt_string
!= NULL
; desc
++) {
699 if (IFM_SUBTYPE(ifmw
) == desc
->ifmt_word
)
708 static struct ifmedia_description
*get_mode_desc(int ifmw
,
709 struct ifmedia_type_to_subtype
*ttos
)
712 struct ifmedia_description
*desc
;
714 for (i
= 0; ttos
->modes
[i
].desc
!= NULL
; i
++) {
715 if (ttos
->modes
[i
].alias
)
717 for (desc
= ttos
->modes
[i
].desc
;
718 desc
->ifmt_string
!= NULL
; desc
++) {
719 if (IFM_MODE(ifmw
) == desc
->ifmt_word
)
729 print_media_word(int ifmw
, int print_toptype
)
731 struct ifmedia_description
*desc
;
732 struct ifmedia_type_to_subtype
*ttos
;
733 int seen_option
= 0, i
;
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>");
742 } else if (print_toptype
) {
743 printf("%s", desc
->ifmt_string
);
748 * Don't print the top-level type; it's not like we can
749 * change it, or anything.
753 desc
= get_subtype_desc(ifmw
, ttos
);
755 printf("<unknown subtype>");
764 printf("%s", desc
->ifmt_string
);
768 desc
= get_mode_desc(ifmw
, ttos
);
769 if (desc
!= NULL
&& strcasecmp("autoselect", desc
->ifmt_string
))
770 printf(" mode %s", desc
->ifmt_string
);
774 for (i
= 0; ttos
->options
[i
].desc
!= NULL
; i
++) {
775 if (ttos
->options
[i
].alias
)
777 for (desc
= ttos
->options
[i
].desc
;
778 desc
->ifmt_string
!= NULL
; desc
++) {
779 if (ifmw
& desc
->ifmt_word
) {
780 if (seen_option
== 0)
782 printf("%s%s", seen_option
++ ? "," : "",
787 printf("%s", seen_option
? ">" : "");
790 if (print_toptype
&& IFM_INST(ifmw
) != 0)
791 printf(" instance %d", IFM_INST(ifmw
));
796 print_media_word_ifconfig(int ifmw
)
798 struct ifmedia_description
*desc
;
799 struct ifmedia_type_to_subtype
*ttos
;
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>");
811 * Don't print the top-level type; it's not like we can
812 * change it, or anything.
816 desc
= get_subtype_desc(ifmw
, ttos
);
818 printf("<unknown subtype>");
822 printf("media %s", desc
->ifmt_string
);
825 desc
= get_mode_desc(ifmw
, ttos
);
827 printf(" mode %s", desc
->ifmt_string
);
831 for (i
= 0; ttos
->options
[i
].desc
!= NULL
; i
++) {
832 if (ttos
->options
[i
].alias
)
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
);
842 if (IFM_INST(ifmw
) != 0)
843 printf(" instance %d", IFM_INST(ifmw
));
846 /**********************************************************************
848 **********************************************************************/
850 static struct cmd media_cmds
[] = {
851 DEF_CMD_ARG("media", setmedia
),
853 DEF_CMD_ARG("mode", setmediamode
),
855 DEF_CMD_ARG("mediaopt", setmediaopt
),
856 DEF_CMD_ARG("-mediaopt",unsetmediaopt
),
857 DEF_CMD_ARG("inst", setmediainst
),
858 DEF_CMD_ARG("instance", setmediainst
),
860 static struct afswtch af_media
= {
861 .af_name
= "af_media",
863 .af_other_status
= media_status
,
866 static __constructor
void
869 #define N(a) (sizeof(a) / sizeof(a[0]))
872 for (i
= 0; i
< N(media_cmds
); i
++)
873 cmd_register(&media_cmds
[i
]);
874 af_register(&af_media
);