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