netscope.c revision 181834
1/* 2 * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (C) 2002 Internet Software Consortium. 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 * PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18#if defined(LIBC_SCCS) && !defined(lint) 19static char rcsid[] = 20 "$Id: netscope.c,v 1.5.142.7 2004/03/12 10:31:26 marka Exp $"; 21#endif /* LIBC_SCCS and not lint */ 22 23#include <config.h> 24 25#include <isc/string.h> 26#include <isc/net.h> 27#include <isc/netscope.h> 28#include <isc/result.h> 29 30isc_result_t 31isc_netscope_pton(int af, char *scopename, void *addr, isc_uint32_t *zoneid) { 32 char *ep; 33#ifdef ISC_PLATFORM_HAVEIFNAMETOINDEX 34 unsigned int ifid; 35#endif 36 struct in6_addr *in6; 37 isc_uint32_t zone; 38 isc_uint64_t llz; 39 40 /* at this moment, we only support AF_INET6 */ 41 if (af != AF_INET6) 42 return (ISC_R_FAILURE); 43 44 in6 = (struct in6_addr *)addr; 45 46 /* 47 * Basically, "names" are more stable than numeric IDs in terms of 48 * renumbering, and are more preferred. However, since there is no 49 * standard naming convention and APIs to deal with the names. Thus, 50 * we only handle the case of link-local addresses, for which we use 51 * interface names as link names, assuming one to one mapping between 52 * interfaces and links. 53 */ 54#ifdef ISC_PLATFORM_HAVEIFNAMETOINDEX 55 if (IN6_IS_ADDR_LINKLOCAL(in6) && 56 (ifid = if_nametoindex((const char *)scopename)) != 0) 57 zone = (isc_uint32_t)ifid; 58 else { 59#endif 60 llz = isc_string_touint64(scopename, &ep, 10); 61 if (ep == scopename) 62 return (ISC_R_FAILURE); 63 64 /* check overflow */ 65 zone = (isc_uint32_t)(llz & 0xffffffffUL); 66 if (zone != llz) 67 return (ISC_R_FAILURE); 68#ifdef ISC_PLATFORM_HAVEIFNAMETOINDEX 69 } 70#endif 71 72 *zoneid = zone; 73 return (ISC_R_SUCCESS); 74} 75