xref: /minix3/lib/libutil/if_media.c (revision 0c3983b25a88161cf074524e5c94585a2582ae82)
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