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