1*0c3983b2SBen Gras /* $NetBSD: if_media.c,v 1.2 2008/04/28 20:23:03 martin Exp $ */
2*0c3983b2SBen Gras
3*0c3983b2SBen Gras /*-
4*0c3983b2SBen Gras * Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc.
5*0c3983b2SBen Gras * All rights reserved.
6*0c3983b2SBen Gras *
7*0c3983b2SBen Gras * This code is derived from software contributed to The NetBSD Foundation
8*0c3983b2SBen Gras * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9*0c3983b2SBen Gras * NASA Ames Research Center.
10*0c3983b2SBen Gras *
11*0c3983b2SBen Gras * Redistribution and use in source and binary forms, with or without
12*0c3983b2SBen Gras * modification, are permitted provided that the following conditions
13*0c3983b2SBen Gras * are met:
14*0c3983b2SBen Gras * 1. Redistributions of source code must retain the above copyright
15*0c3983b2SBen Gras * notice, this list of conditions and the following disclaimer.
16*0c3983b2SBen Gras * 2. Redistributions in binary form must reproduce the above copyright
17*0c3983b2SBen Gras * notice, this list of conditions and the following disclaimer in the
18*0c3983b2SBen Gras * documentation and/or other materials provided with the distribution.
19*0c3983b2SBen Gras *
20*0c3983b2SBen Gras * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21*0c3983b2SBen Gras * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22*0c3983b2SBen Gras * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23*0c3983b2SBen Gras * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24*0c3983b2SBen Gras * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25*0c3983b2SBen Gras * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26*0c3983b2SBen Gras * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27*0c3983b2SBen Gras * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28*0c3983b2SBen Gras * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29*0c3983b2SBen Gras * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30*0c3983b2SBen Gras * POSSIBILITY OF SUCH DAMAGE.
31*0c3983b2SBen Gras */
32*0c3983b2SBen Gras
33*0c3983b2SBen Gras #include <sys/cdefs.h>
34*0c3983b2SBen Gras #if defined(LIBC_SCCS) && !defined(lint)
35*0c3983b2SBen Gras __RCSID("$NetBSD: if_media.c,v 1.2 2008/04/28 20:23:03 martin Exp $");
36*0c3983b2SBen Gras #endif
37*0c3983b2SBen Gras
38*0c3983b2SBen Gras #include <stdio.h>
39*0c3983b2SBen Gras #include <string.h>
40*0c3983b2SBen Gras #include <stdlib.h>
41*0c3983b2SBen Gras #include <sys/types.h>
42*0c3983b2SBen Gras #include <net/if_media.h>
43*0c3983b2SBen Gras
44*0c3983b2SBen Gras struct ifmedia_description ifm_mode_descriptions[] =
45*0c3983b2SBen Gras IFM_MODE_DESCRIPTIONS;
46*0c3983b2SBen Gras
47*0c3983b2SBen Gras struct ifmedia_description ifm_type_descriptions[] =
48*0c3983b2SBen Gras IFM_TYPE_DESCRIPTIONS;
49*0c3983b2SBen Gras
50*0c3983b2SBen Gras struct ifmedia_description ifm_subtype_descriptions[] =
51*0c3983b2SBen Gras IFM_SUBTYPE_DESCRIPTIONS;
52*0c3983b2SBen Gras
53*0c3983b2SBen Gras struct ifmedia_description ifm_option_descriptions[] =
54*0c3983b2SBen Gras IFM_OPTION_DESCRIPTIONS;
55*0c3983b2SBen Gras
56*0c3983b2SBen Gras const char *
get_media_type_string(int mword)57*0c3983b2SBen Gras get_media_type_string(int mword)
58*0c3983b2SBen Gras {
59*0c3983b2SBen Gras struct ifmedia_description *desc;
60*0c3983b2SBen Gras
61*0c3983b2SBen Gras for (desc = ifm_type_descriptions; desc->ifmt_string != NULL; desc++) {
62*0c3983b2SBen Gras if (IFM_TYPE(mword) == desc->ifmt_word)
63*0c3983b2SBen Gras return (desc->ifmt_string);
64*0c3983b2SBen Gras }
65*0c3983b2SBen Gras return "<unknown type>";
66*0c3983b2SBen Gras }
67*0c3983b2SBen Gras
68*0c3983b2SBen Gras const char *
get_media_subtype_string(int mword)69*0c3983b2SBen Gras get_media_subtype_string(int mword)
70*0c3983b2SBen Gras {
71*0c3983b2SBen Gras struct ifmedia_description *desc;
72*0c3983b2SBen Gras
73*0c3983b2SBen Gras for (desc = ifm_subtype_descriptions; desc->ifmt_string != NULL;
74*0c3983b2SBen Gras desc++) {
75*0c3983b2SBen Gras if (IFM_TYPE_MATCH(desc->ifmt_word, mword) &&
76*0c3983b2SBen Gras IFM_SUBTYPE(desc->ifmt_word) == IFM_SUBTYPE(mword))
77*0c3983b2SBen Gras return desc->ifmt_string;
78*0c3983b2SBen Gras }
79*0c3983b2SBen Gras return "<unknown subtype>";
80*0c3983b2SBen Gras }
81*0c3983b2SBen Gras
82*0c3983b2SBen Gras const char *
get_media_mode_string(int mword)83*0c3983b2SBen Gras get_media_mode_string(int mword)
84*0c3983b2SBen Gras {
85*0c3983b2SBen Gras struct ifmedia_description *desc;
86*0c3983b2SBen Gras
87*0c3983b2SBen Gras for (desc = ifm_mode_descriptions; desc->ifmt_string != NULL; desc++) {
88*0c3983b2SBen Gras if (IFM_TYPE_MATCH(desc->ifmt_word, mword) &&
89*0c3983b2SBen Gras IFM_MODE(mword) == IFM_MODE(desc->ifmt_word))
90*0c3983b2SBen Gras return desc->ifmt_string;
91*0c3983b2SBen Gras }
92*0c3983b2SBen Gras return NULL;
93*0c3983b2SBen Gras }
94*0c3983b2SBen Gras
95*0c3983b2SBen Gras const char *
get_media_option_string(int * mwordp)96*0c3983b2SBen Gras get_media_option_string(int *mwordp)
97*0c3983b2SBen Gras {
98*0c3983b2SBen Gras struct ifmedia_description *desc;
99*0c3983b2SBen Gras int mword = *mwordp;
100*0c3983b2SBen Gras
101*0c3983b2SBen Gras for (desc = ifm_option_descriptions; desc->ifmt_string != NULL;
102*0c3983b2SBen Gras desc++) {
103*0c3983b2SBen Gras if (!IFM_TYPE_MATCH(desc->ifmt_word, mword))
104*0c3983b2SBen Gras continue;
105*0c3983b2SBen Gras if (mword & IFM_OPTIONS(desc->ifmt_word)) {
106*0c3983b2SBen Gras *mwordp = mword & ~IFM_OPTIONS(desc->ifmt_word);
107*0c3983b2SBen Gras return desc->ifmt_string;
108*0c3983b2SBen Gras }
109*0c3983b2SBen Gras }
110*0c3983b2SBen Gras
111*0c3983b2SBen Gras /* Historical behaviour is to ignore unknown option bits! */
112*0c3983b2SBen Gras *mwordp = mword & ~IFM_OPTIONS(~0);
113*0c3983b2SBen Gras return NULL;
114*0c3983b2SBen Gras }
115*0c3983b2SBen Gras
116*0c3983b2SBen Gras int
lookup_media_word(struct ifmedia_description * desc,int type,const char * val)117*0c3983b2SBen Gras lookup_media_word(struct ifmedia_description *desc, int type, const char *val)
118*0c3983b2SBen Gras {
119*0c3983b2SBen Gras
120*0c3983b2SBen Gras for (; desc->ifmt_string != NULL; desc++) {
121*0c3983b2SBen Gras if (IFM_TYPE_MATCH(desc->ifmt_word, type) &&
122*0c3983b2SBen Gras strcasecmp(desc->ifmt_string, val) == 0)
123*0c3983b2SBen Gras return (desc->ifmt_word);
124*0c3983b2SBen Gras }
125*0c3983b2SBen Gras return -1;
126*0c3983b2SBen Gras }
127*0c3983b2SBen Gras
128*0c3983b2SBen Gras int
get_media_mode(int type,const char * val)129*0c3983b2SBen Gras get_media_mode(int type, const char *val)
130*0c3983b2SBen Gras {
131*0c3983b2SBen Gras
132*0c3983b2SBen Gras return lookup_media_word(ifm_mode_descriptions, type, val);
133*0c3983b2SBen Gras }
134*0c3983b2SBen Gras
135*0c3983b2SBen Gras int
get_media_subtype(int type,const char * val)136*0c3983b2SBen Gras get_media_subtype(int type, const char *val)
137*0c3983b2SBen Gras {
138*0c3983b2SBen Gras
139*0c3983b2SBen Gras return lookup_media_word(ifm_subtype_descriptions, type, val);
140*0c3983b2SBen Gras }
141*0c3983b2SBen Gras
142*0c3983b2SBen Gras int
get_media_options(int type,const char * val,char ** invalid)143*0c3983b2SBen Gras get_media_options(int type, const char *val, char **invalid)
144*0c3983b2SBen Gras {
145*0c3983b2SBen Gras char *optlist, *str;
146*0c3983b2SBen Gras int option, rval = 0;
147*0c3983b2SBen Gras
148*0c3983b2SBen Gras /* We muck with the string, so copy it. */
149*0c3983b2SBen Gras optlist = strdup(val);
150*0c3983b2SBen Gras if (optlist == NULL) {
151*0c3983b2SBen Gras if (invalid != NULL)
152*0c3983b2SBen Gras *invalid = NULL;
153*0c3983b2SBen Gras return -1;
154*0c3983b2SBen Gras }
155*0c3983b2SBen Gras str = optlist;
156*0c3983b2SBen Gras
157*0c3983b2SBen Gras /*
158*0c3983b2SBen Gras * Look up the options in the user-provided comma-separated list.
159*0c3983b2SBen Gras */
160*0c3983b2SBen Gras type = IFM_TYPE(type);
161*0c3983b2SBen Gras for (; (str = strtok(str, ",")) != NULL; str = NULL) {
162*0c3983b2SBen Gras option = lookup_media_word(ifm_option_descriptions, type, str);
163*0c3983b2SBen Gras if (option != -1) {
164*0c3983b2SBen Gras rval |= IFM_OPTIONS(option);
165*0c3983b2SBen Gras continue;
166*0c3983b2SBen Gras }
167*0c3983b2SBen Gras rval = -1;
168*0c3983b2SBen Gras if (invalid == NULL)
169*0c3983b2SBen Gras break;
170*0c3983b2SBen Gras /* Pass invalid option at start of malloced buffer */
171*0c3983b2SBen Gras if (str != optlist)
172*0c3983b2SBen Gras memmove(optlist, str, strlen(str) + 1);
173*0c3983b2SBen Gras /* Caller should free() or exit() */
174*0c3983b2SBen Gras *invalid = optlist;
175*0c3983b2SBen Gras return rval;
176*0c3983b2SBen Gras }
177*0c3983b2SBen Gras
178*0c3983b2SBen Gras free(optlist);
179*0c3983b2SBen Gras return (rval);
180*0c3983b2SBen Gras }
181