source: rtems-libbsd/freebsd/sbin/ifconfig/ifmedia.c @ 60618d5

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 60618d5 was 60618d5, checked in by Sebastian Huber <sebastian.huber@…>, on 10/18/13 at 14:30:27

IFCONFIG(8): Initialize global variables in ctors

  • Property mode set to 100644
File size: 22.3 KB
Line 
1/*      $NetBSD: ifconfig.c,v 1.34 1997/04/21 01:17:58 lukem Exp $      */
2/* $FreeBSD$ */
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 <rtems/bsd/sys/param.h>
70#include <sys/ioctl.h>
71#include <sys/socket.h>
72#include <sys/sysctl.h>
73#include <rtems/bsd/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#include "ifconfig.h"
91
92static void     domediaopt(const char *, int, int);
93static int      get_media_subtype(int, const char *);
94static int      get_media_mode(int, const char *);
95static int      get_media_options(int, const char *);
96static int      lookup_media_word(const struct ifmedia_description *, const char *);
97static void     print_media_word(int, int);
98static void     print_media_word_ifconfig(int);
99
100static const struct ifmedia_description *get_toptype_desc(int);
101static const struct ifmedia_type_to_subtype *get_toptype_ttos(int);
102static const struct ifmedia_description *get_subtype_desc(int,
103    const struct ifmedia_type_to_subtype *ttos);
104
105#define IFM_OPMODE(x) \
106        ((x) & (IFM_IEEE80211_ADHOC | IFM_IEEE80211_HOSTAP | \
107         IFM_IEEE80211_IBSS | IFM_IEEE80211_WDS | IFM_IEEE80211_MONITOR | \
108         IFM_IEEE80211_MBSS))
109#define IFM_IEEE80211_STA       0
110
111static void
112media_status(int s)
113{
114        struct ifmediareq ifmr;
115        int *media_list, i;
116
117        (void) memset(&ifmr, 0, sizeof(ifmr));
118        (void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name));
119
120        if (ioctl(s, SIOCGIFMEDIA, (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, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0)
138                err(1, "SIOCGIFMEDIA");
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                switch (IFM_TYPE(ifmr.ifm_active)) {
154                case IFM_ETHER:
155                case IFM_ATM:
156                        if (ifmr.ifm_status & IFM_ACTIVE)
157                                printf("active");
158                        else
159                                printf("no carrier");
160                        break;
161
162                case IFM_FDDI:
163                case IFM_TOKEN:
164                        if (ifmr.ifm_status & IFM_ACTIVE)
165                                printf("inserted");
166                        else
167                                printf("no ring");
168                        break;
169
170                case IFM_IEEE80211:
171                        if (ifmr.ifm_status & IFM_ACTIVE) {
172                                /* NB: only sta mode associates */
173                                if (IFM_OPMODE(ifmr.ifm_active) == IFM_IEEE80211_STA)
174                                        printf("associated");
175                                else
176                                        printf("running");
177                        } else
178                                printf("no carrier");
179                        break;
180                }
181                putchar('\n');
182        }
183
184        if (ifmr.ifm_count > 0 && supmedia) {
185                printf("\tsupported media:\n");
186                for (i = 0; i < ifmr.ifm_count; i++) {
187                        printf("\t\t");
188                        print_media_word_ifconfig(media_list[i]);
189                        putchar('\n');
190                }
191        }
192
193        free(media_list);
194}
195
196#ifdef __rtems__
197static struct ifmediareq *ifmr = NULL;
198#endif /* __rtems__ */
199struct ifmediareq *
200ifmedia_getstate(int s)
201{
202#ifndef __rtems__
203        static struct ifmediareq *ifmr = NULL;
204#endif /* __rtems__ */
205        int *mwords;
206
207        if (ifmr == NULL) {
208                ifmr = (struct ifmediareq *)malloc(sizeof(struct ifmediareq));
209                if (ifmr == NULL)
210                        err(1, "malloc");
211
212                (void) memset(ifmr, 0, sizeof(struct ifmediareq));
213                (void) strncpy(ifmr->ifm_name, name,
214                    sizeof(ifmr->ifm_name));
215
216                ifmr->ifm_count = 0;
217                ifmr->ifm_ulist = NULL;
218
219                /*
220                 * We must go through the motions of reading all
221                 * supported media because we need to know both
222                 * the current media type and the top-level type.
223                 */
224
225                if (ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0) {
226                        err(1, "SIOCGIFMEDIA");
227                }
228
229                if (ifmr->ifm_count == 0)
230                        errx(1, "%s: no media types?", name);
231
232                mwords = (int *)malloc(ifmr->ifm_count * sizeof(int));
233                if (mwords == NULL)
234                        err(1, "malloc");
235 
236                ifmr->ifm_ulist = mwords;
237                if (ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0)
238                        err(1, "SIOCGIFMEDIA");
239        }
240
241        return ifmr;
242}
243
244#ifdef __rtems__
245static int did_it = 0;
246#endif /* __rtems__ */
247static void
248setifmediacallback(int s, void *arg)
249{
250        struct ifmediareq *ifmr = (struct ifmediareq *)arg;
251#ifndef __rtems__
252        static int did_it = 0;
253#endif /* __rtems__ */
254
255        if (!did_it) {
256                ifr.ifr_media = ifmr->ifm_current;
257                if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) < 0)
258                        err(1, "SIOCSIFMEDIA (media)");
259                free(ifmr->ifm_ulist);
260                free(ifmr);
261                did_it = 1;
262        }
263}
264
265static void
266setmedia(const char *val, int d, int s, const struct afswtch *afp)
267{
268        struct ifmediareq *ifmr;
269        int subtype;
270
271        ifmr = ifmedia_getstate(s);
272
273        /*
274         * We are primarily concerned with the top-level type.
275         * However, "current" may be only IFM_NONE, so we just look
276         * for the top-level type in the first "supported type"
277         * entry.
278         *
279         * (I'm assuming that all supported media types for a given
280         * interface will be the same top-level type..)
281         */
282        subtype = get_media_subtype(IFM_TYPE(ifmr->ifm_ulist[0]), val);
283
284        strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
285        ifr.ifr_media = (ifmr->ifm_current & ~(IFM_NMASK|IFM_TMASK)) |
286            IFM_TYPE(ifmr->ifm_ulist[0]) | subtype;
287
288        if ((ifr.ifr_media & IFM_TMASK) == 0) {
289                ifr.ifr_media &= ~(IFM_GMASK | IFM_OMASK);
290        }
291
292        ifmr->ifm_current = ifr.ifr_media;
293        callback_register(setifmediacallback, (void *)ifmr);
294}
295
296static void
297setmediaopt(const char *val, int d, int s, const struct afswtch *afp)
298{
299
300        domediaopt(val, 0, s);
301}
302
303static void
304unsetmediaopt(const char *val, int d, int s, const struct afswtch *afp)
305{
306
307        domediaopt(val, 1, s);
308}
309
310static void
311domediaopt(const char *val, int clear, int s)
312{
313        struct ifmediareq *ifmr;
314        int options;
315
316        ifmr = ifmedia_getstate(s);
317
318        options = get_media_options(IFM_TYPE(ifmr->ifm_ulist[0]), val);
319
320        strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
321        ifr.ifr_media = ifmr->ifm_current;
322        if (clear)
323                ifr.ifr_media &= ~options;
324        else {
325                if (options & IFM_HDX) {
326                        ifr.ifr_media &= ~IFM_FDX;
327                        options &= ~IFM_HDX;
328                }
329                ifr.ifr_media |= options;
330        }
331        ifmr->ifm_current = ifr.ifr_media;
332        callback_register(setifmediacallback, (void *)ifmr);
333}
334
335static void
336setmediainst(const char *val, int d, int s, const struct afswtch *afp)
337{
338        struct ifmediareq *ifmr;
339        int inst;
340
341        ifmr = ifmedia_getstate(s);
342
343        inst = atoi(val);
344        if (inst < 0 || inst > (int)IFM_INST_MAX)
345                errx(1, "invalid media instance: %s", val);
346
347        strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
348        ifr.ifr_media = (ifmr->ifm_current & ~IFM_IMASK) | inst << IFM_ISHIFT;
349
350        ifmr->ifm_current = ifr.ifr_media;
351        callback_register(setifmediacallback, (void *)ifmr);
352}
353
354static void
355setmediamode(const char *val, int d, int s, const struct afswtch *afp)
356{
357        struct ifmediareq *ifmr;
358        int mode;
359
360        ifmr = ifmedia_getstate(s);
361
362        mode = get_media_mode(IFM_TYPE(ifmr->ifm_ulist[0]), val);
363
364        strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
365        ifr.ifr_media = (ifmr->ifm_current & ~IFM_MMASK) | mode;
366
367        ifmr->ifm_current = ifr.ifr_media;
368        callback_register(setifmediacallback, (void *)ifmr);
369}
370
371/**********************************************************************
372 * A good chunk of this is duplicated from sys/net/ifmedia.c
373 **********************************************************************/
374
375static const struct ifmedia_description ifm_type_descriptions[] =
376    IFM_TYPE_DESCRIPTIONS;
377
378static const struct ifmedia_description ifm_subtype_ethernet_descriptions[] =
379    IFM_SUBTYPE_ETHERNET_DESCRIPTIONS;
380
381static const struct ifmedia_description ifm_subtype_ethernet_aliases[] =
382    IFM_SUBTYPE_ETHERNET_ALIASES;
383
384static const struct ifmedia_description ifm_subtype_ethernet_option_descriptions[] =
385    IFM_SUBTYPE_ETHERNET_OPTION_DESCRIPTIONS;
386
387static const struct ifmedia_description ifm_subtype_tokenring_descriptions[] =
388    IFM_SUBTYPE_TOKENRING_DESCRIPTIONS;
389
390static const struct ifmedia_description ifm_subtype_tokenring_aliases[] =
391    IFM_SUBTYPE_TOKENRING_ALIASES;
392
393static const struct ifmedia_description ifm_subtype_tokenring_option_descriptions[] =
394    IFM_SUBTYPE_TOKENRING_OPTION_DESCRIPTIONS;
395
396static const struct ifmedia_description ifm_subtype_fddi_descriptions[] =
397    IFM_SUBTYPE_FDDI_DESCRIPTIONS;
398
399static const struct ifmedia_description ifm_subtype_fddi_aliases[] =
400    IFM_SUBTYPE_FDDI_ALIASES;
401
402static const struct ifmedia_description ifm_subtype_fddi_option_descriptions[] =
403    IFM_SUBTYPE_FDDI_OPTION_DESCRIPTIONS;
404
405static const struct ifmedia_description ifm_subtype_ieee80211_descriptions[] =
406    IFM_SUBTYPE_IEEE80211_DESCRIPTIONS;
407
408static const struct ifmedia_description ifm_subtype_ieee80211_aliases[] =
409    IFM_SUBTYPE_IEEE80211_ALIASES;
410
411static const struct ifmedia_description ifm_subtype_ieee80211_option_descriptions[] =
412    IFM_SUBTYPE_IEEE80211_OPTION_DESCRIPTIONS;
413
414static const struct ifmedia_description ifm_subtype_ieee80211_mode_descriptions[] =
415    IFM_SUBTYPE_IEEE80211_MODE_DESCRIPTIONS;
416
417static const struct ifmedia_description ifm_subtype_ieee80211_mode_aliases[] =
418    IFM_SUBTYPE_IEEE80211_MODE_ALIASES;
419
420static const struct ifmedia_description ifm_subtype_atm_descriptions[] =
421    IFM_SUBTYPE_ATM_DESCRIPTIONS;
422
423static const struct ifmedia_description ifm_subtype_atm_aliases[] =
424    IFM_SUBTYPE_ATM_ALIASES;
425
426static const struct ifmedia_description ifm_subtype_atm_option_descriptions[] =
427    IFM_SUBTYPE_ATM_OPTION_DESCRIPTIONS;
428
429static const struct ifmedia_description ifm_subtype_shared_descriptions[] =
430    IFM_SUBTYPE_SHARED_DESCRIPTIONS;
431
432static const struct ifmedia_description ifm_subtype_shared_aliases[] =
433    IFM_SUBTYPE_SHARED_ALIASES;
434
435static const struct ifmedia_description ifm_shared_option_descriptions[] =
436    IFM_SHARED_OPTION_DESCRIPTIONS;
437
438struct ifmedia_type_to_subtype {
439        struct {
440                const struct ifmedia_description *desc;
441                int alias;
442        } subtypes[5];
443        struct {
444                const struct ifmedia_description *desc;
445                int alias;
446        } options[3];
447        struct {
448                const struct ifmedia_description *desc;
449                int alias;
450        } modes[3];
451};
452
453/* must be in the same order as IFM_TYPE_DESCRIPTIONS */
454static const struct ifmedia_type_to_subtype ifmedia_types_to_subtypes[] = {
455        {
456                {
457                        { &ifm_subtype_shared_descriptions[0], 0 },
458                        { &ifm_subtype_shared_aliases[0], 1 },
459                        { &ifm_subtype_ethernet_descriptions[0], 0 },
460                        { &ifm_subtype_ethernet_aliases[0], 1 },
461                        { NULL, 0 },
462                },
463                {
464                        { &ifm_shared_option_descriptions[0], 0 },
465                        { &ifm_subtype_ethernet_option_descriptions[0], 0 },
466                        { NULL, 0 },
467                },
468                {
469                        { NULL, 0 },
470                },
471        },
472        {
473                {
474                        { &ifm_subtype_shared_descriptions[0], 0 },
475                        { &ifm_subtype_shared_aliases[0], 1 },
476                        { &ifm_subtype_tokenring_descriptions[0], 0 },
477                        { &ifm_subtype_tokenring_aliases[0], 1 },
478                        { NULL, 0 },
479                },
480                {
481                        { &ifm_shared_option_descriptions[0], 0 },
482                        { &ifm_subtype_tokenring_option_descriptions[0], 0 },
483                        { NULL, 0 },
484                },
485                {
486                        { NULL, 0 },
487                },
488        },
489        {
490                {
491                        { &ifm_subtype_shared_descriptions[0], 0 },
492                        { &ifm_subtype_shared_aliases[0], 1 },
493                        { &ifm_subtype_fddi_descriptions[0], 0 },
494                        { &ifm_subtype_fddi_aliases[0], 1 },
495                        { NULL, 0 },
496                },
497                {
498                        { &ifm_shared_option_descriptions[0], 0 },
499                        { &ifm_subtype_fddi_option_descriptions[0], 0 },
500                        { NULL, 0 },
501                },
502                {
503                        { NULL, 0 },
504                },
505        },
506        {
507                {
508                        { &ifm_subtype_shared_descriptions[0], 0 },
509                        { &ifm_subtype_shared_aliases[0], 1 },
510                        { &ifm_subtype_ieee80211_descriptions[0], 0 },
511                        { &ifm_subtype_ieee80211_aliases[0], 1 },
512                        { NULL, 0 },
513                },
514                {
515                        { &ifm_shared_option_descriptions[0], 0 },
516                        { &ifm_subtype_ieee80211_option_descriptions[0], 0 },
517                        { NULL, 0 },
518                },
519                {
520                        { &ifm_subtype_ieee80211_mode_descriptions[0], 0 },
521                        { &ifm_subtype_ieee80211_mode_aliases[0], 0 },
522                        { NULL, 0 },
523                },
524        },
525        {
526                {
527                        { &ifm_subtype_shared_descriptions[0], 0 },
528                        { &ifm_subtype_shared_aliases[0], 1 },
529                        { &ifm_subtype_atm_descriptions[0], 0 },
530                        { &ifm_subtype_atm_aliases[0], 1 },
531                        { NULL, 0 },
532                },
533                {
534                        { &ifm_shared_option_descriptions[0], 0 },
535                        { &ifm_subtype_atm_option_descriptions[0], 0 },
536                        { NULL, 0 },
537                },
538                {
539                        { NULL, 0 },
540                },
541        },
542};
543
544static int
545get_media_subtype(int type, const char *val)
546{
547        const struct ifmedia_description *desc;
548        const struct ifmedia_type_to_subtype *ttos;
549        int rval, i;
550
551        /* Find the top-level interface type. */
552        for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes;
553            desc->ifmt_string != NULL; desc++, ttos++)
554                if (type == desc->ifmt_word)
555                        break;
556        if (desc->ifmt_string == NULL)
557                errx(1, "unknown media type 0x%x", type);
558
559        for (i = 0; ttos->subtypes[i].desc != NULL; i++) {
560                rval = lookup_media_word(ttos->subtypes[i].desc, val);
561                if (rval != -1)
562                        return (rval);
563        }
564        errx(1, "unknown media subtype: %s", val);
565        /*NOTREACHED*/
566}
567
568static int
569get_media_mode(int type, const char *val)
570{
571        const struct ifmedia_description *desc;
572        const struct ifmedia_type_to_subtype *ttos;
573        int rval, i;
574
575        /* Find the top-level interface type. */
576        for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes;
577            desc->ifmt_string != NULL; desc++, ttos++)
578                if (type == desc->ifmt_word)
579                        break;
580        if (desc->ifmt_string == NULL)
581                errx(1, "unknown media mode 0x%x", type);
582
583        for (i = 0; ttos->modes[i].desc != NULL; i++) {
584                rval = lookup_media_word(ttos->modes[i].desc, val);
585                if (rval != -1)
586                        return (rval);
587        }
588        return -1;
589}
590
591static int
592get_media_options(int type, const char *val)
593{
594        const struct ifmedia_description *desc;
595        const struct ifmedia_type_to_subtype *ttos;
596        char *optlist, *optptr;
597        int option = 0, i, rval = 0;
598
599        /* We muck with the string, so copy it. */
600        optlist = strdup(val);
601        if (optlist == NULL)
602                err(1, "strdup");
603
604        /* Find the top-level interface type. */
605        for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes;
606            desc->ifmt_string != NULL; desc++, ttos++)
607                if (type == desc->ifmt_word)
608                        break;
609        if (desc->ifmt_string == NULL)
610                errx(1, "unknown media type 0x%x", type);
611
612        /*
613         * Look up the options in the user-provided comma-separated
614         * list.
615         */
616        optptr = optlist;
617        for (; (optptr = strtok(optptr, ",")) != NULL; optptr = NULL) {
618                for (i = 0; ttos->options[i].desc != NULL; i++) {
619                        option = lookup_media_word(ttos->options[i].desc, optptr);
620                        if (option != -1)
621                                break;
622                }
623                if (option == 0)
624                        errx(1, "unknown option: %s", optptr);
625                rval |= option;
626        }
627
628        free(optlist);
629        return (rval);
630}
631
632static int
633lookup_media_word(const struct ifmedia_description *desc, const char *val)
634{
635
636        for (; desc->ifmt_string != NULL; desc++)
637                if (strcasecmp(desc->ifmt_string, val) == 0)
638                        return (desc->ifmt_word);
639
640        return (-1);
641}
642
643static const struct ifmedia_description *get_toptype_desc(int ifmw)
644{
645        const struct ifmedia_description *desc;
646
647        for (desc = ifm_type_descriptions; desc->ifmt_string != NULL; desc++)
648                if (IFM_TYPE(ifmw) == desc->ifmt_word)
649                        break;
650
651        return desc;
652}
653
654static const struct ifmedia_type_to_subtype *get_toptype_ttos(int ifmw)
655{
656        const struct ifmedia_description *desc;
657        const struct ifmedia_type_to_subtype *ttos;
658
659        for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes;
660            desc->ifmt_string != NULL; desc++, ttos++)
661                if (IFM_TYPE(ifmw) == desc->ifmt_word)
662                        break;
663
664        return ttos;
665}
666
667static const struct ifmedia_description *get_subtype_desc(int ifmw,
668    const struct ifmedia_type_to_subtype *ttos)
669{
670        int i;
671        const struct ifmedia_description *desc;
672
673        for (i = 0; ttos->subtypes[i].desc != NULL; i++) {
674                if (ttos->subtypes[i].alias)
675                        continue;
676                for (desc = ttos->subtypes[i].desc;
677                    desc->ifmt_string != NULL; desc++) {
678                        if (IFM_SUBTYPE(ifmw) == desc->ifmt_word)
679                                return desc;
680                }
681        }
682
683        return NULL;
684}
685
686static const struct ifmedia_description *get_mode_desc(int ifmw,
687    const struct ifmedia_type_to_subtype *ttos)
688{
689        int i;
690        const struct ifmedia_description *desc;
691
692        for (i = 0; ttos->modes[i].desc != NULL; i++) {
693                if (ttos->modes[i].alias)
694                        continue;
695                for (desc = ttos->modes[i].desc;
696                    desc->ifmt_string != NULL; desc++) {
697                        if (IFM_MODE(ifmw) == desc->ifmt_word)
698                                return desc;
699                }
700        }
701
702        return NULL;
703}
704
705static void
706print_media_word(int ifmw, int print_toptype)
707{
708        const struct ifmedia_description *desc;
709        const struct ifmedia_type_to_subtype *ttos;
710        int seen_option = 0, i;
711
712        /* Find the top-level interface type. */
713        desc = get_toptype_desc(ifmw);
714        ttos = get_toptype_ttos(ifmw);
715        if (desc->ifmt_string == NULL) {
716                printf("<unknown type>");
717                return;
718        } else if (print_toptype) {
719                printf("%s", desc->ifmt_string);
720        }
721
722        /*
723         * Don't print the top-level type; it's not like we can
724         * change it, or anything.
725         */
726
727        /* Find subtype. */
728        desc = get_subtype_desc(ifmw, ttos);
729        if (desc == NULL) {
730                printf("<unknown subtype>");
731                return;
732        }
733
734        if (print_toptype)
735                putchar(' ');
736
737        printf("%s", desc->ifmt_string);
738
739        if (print_toptype) {
740                desc = get_mode_desc(ifmw, ttos);
741                if (desc != NULL && strcasecmp("autoselect", desc->ifmt_string))
742                        printf(" mode %s", desc->ifmt_string);
743        }
744
745        /* Find options. */
746        for (i = 0; ttos->options[i].desc != NULL; i++) {
747                if (ttos->options[i].alias)
748                        continue;
749                for (desc = ttos->options[i].desc;
750                    desc->ifmt_string != NULL; desc++) {
751                        if (ifmw & desc->ifmt_word) {
752                                if (seen_option == 0)
753                                        printf(" <");
754                                printf("%s%s", seen_option++ ? "," : "",
755                                    desc->ifmt_string);
756                        }
757                }
758        }
759        printf("%s", seen_option ? ">" : "");
760
761        if (print_toptype && IFM_INST(ifmw) != 0)
762                printf(" instance %d", IFM_INST(ifmw));
763}
764
765static void
766print_media_word_ifconfig(int ifmw)
767{
768        const struct ifmedia_description *desc;
769        const struct ifmedia_type_to_subtype *ttos;
770        int seen_option = 0, i;
771
772        /* Find the top-level interface type. */
773        desc = get_toptype_desc(ifmw);
774        ttos = get_toptype_ttos(ifmw);
775        if (desc->ifmt_string == NULL) {
776                printf("<unknown type>");
777                return;
778        }
779
780        /*
781         * Don't print the top-level type; it's not like we can
782         * change it, or anything.
783         */
784
785        /* Find subtype. */
786        desc = get_subtype_desc(ifmw, ttos);
787        if (desc == NULL) {
788                printf("<unknown subtype>");
789                return;
790        }
791
792        printf("media %s", desc->ifmt_string);
793
794        desc = get_mode_desc(ifmw, ttos);
795        if (desc != NULL)
796                printf(" mode %s", desc->ifmt_string);
797
798        /* Find options. */
799        for (i = 0; ttos->options[i].desc != NULL; i++) {
800                if (ttos->options[i].alias)
801                        continue;
802                for (desc = ttos->options[i].desc;
803                    desc->ifmt_string != NULL; desc++) {
804                        if (ifmw & desc->ifmt_word) {
805                                if (seen_option == 0)
806                                        printf(" mediaopt ");
807                                printf("%s%s", seen_option++ ? "," : "",
808                                    desc->ifmt_string);
809                        }
810                }
811        }
812
813        if (IFM_INST(ifmw) != 0)
814                printf(" instance %d", IFM_INST(ifmw));
815}
816
817/**********************************************************************
818 * ...until here.
819 **********************************************************************/
820
821static struct cmd media_cmds[] = {
822        DEF_CMD_ARG("media",    setmedia),
823        DEF_CMD_ARG("mode",     setmediamode),
824        DEF_CMD_ARG("mediaopt", setmediaopt),
825        DEF_CMD_ARG("-mediaopt",unsetmediaopt),
826        DEF_CMD_ARG("inst",     setmediainst),
827        DEF_CMD_ARG("instance", setmediainst),
828};
829static struct afswtch af_media = {
830        .af_name        = "af_media",
831        .af_af          = AF_UNSPEC,
832        .af_other_status = media_status,
833};
834
835#ifndef __rtems__
836static __constructor void
837#else /* __rtems__ */
838void
839#endif /* __rtems__ */
840ifmedia_ctor(void)
841{
842#ifdef __rtems__
843        did_it = 0;
844        ifmr = NULL;
845#endif /* __rtems__ */
846#define N(a)    (sizeof(a) / sizeof(a[0]))
847        size_t i;
848
849        for (i = 0; i < N(media_cmds);  i++)
850                cmd_register(&media_cmds[i]);
851        af_register(&af_media);
852#undef N
853}
Note: See TracBrowser for help on using the repository browser.