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