1 1.7 christos /* $NetBSD: netscope.c,v 1.7 2025/01/26 16:25:37 christos Exp $ */ 2 1.1 christos 3 1.1 christos /* 4 1.1 christos * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 1.1 christos * 6 1.6 christos * SPDX-License-Identifier: MPL-2.0 7 1.6 christos * 8 1.1 christos * This Source Code Form is subject to the terms of the Mozilla Public 9 1.1 christos * License, v. 2.0. If a copy of the MPL was not distributed with this 10 1.5 christos * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 1.1 christos * 12 1.1 christos * See the COPYRIGHT file distributed with this work for additional 13 1.1 christos * information regarding copyright ownership. 14 1.1 christos */ 15 1.1 christos 16 1.1 christos /*! \file */ 17 1.1 christos 18 1.3 christos #include <inttypes.h> 19 1.3 christos #include <stdlib.h> 20 1.3 christos 21 1.1 christos #include <isc/net.h> 22 1.1 christos #include <isc/netscope.h> 23 1.1 christos #include <isc/result.h> 24 1.4 christos #include <isc/string.h> 25 1.5 christos #include <isc/util.h> 26 1.1 christos 27 1.1 christos isc_result_t 28 1.3 christos isc_netscope_pton(int af, char *scopename, void *addr, uint32_t *zoneid) { 29 1.1 christos char *ep; 30 1.3 christos #ifdef HAVE_IF_NAMETOINDEX 31 1.1 christos unsigned int ifid; 32 1.1 christos struct in6_addr *in6; 33 1.4 christos #endif /* ifdef HAVE_IF_NAMETOINDEX */ 34 1.5 christos uint32_t zone = 0; 35 1.3 christos uint64_t llz; 36 1.1 christos 37 1.5 christos #ifndef HAVE_IF_NAMETOINDEX 38 1.5 christos UNUSED(addr); 39 1.5 christos #endif 40 1.5 christos 41 1.1 christos /* at this moment, we only support AF_INET6 */ 42 1.4 christos if (af != AF_INET6) { 43 1.7 christos return ISC_R_FAILURE; 44 1.4 christos } 45 1.1 christos 46 1.1 christos /* 47 1.4 christos * Basically, "names" are more stable than numeric IDs in terms 48 1.4 christos * of renumbering, and are more preferred. However, since there 49 1.4 christos * is no standard naming convention and APIs to deal with the 50 1.4 christos * names. Thus, we only handle the case of link-local 51 1.4 christos * addresses, for which we use interface names as link names, 52 1.4 christos * assuming one to one mapping between interfaces and links. 53 1.1 christos */ 54 1.3 christos #ifdef HAVE_IF_NAMETOINDEX 55 1.1 christos in6 = (struct in6_addr *)addr; 56 1.1 christos if (IN6_IS_ADDR_LINKLOCAL(in6) && 57 1.1 christos (ifid = if_nametoindex((const char *)scopename)) != 0) 58 1.4 christos { 59 1.3 christos zone = (uint32_t)ifid; 60 1.4 christos } else { 61 1.4 christos #endif /* ifdef HAVE_IF_NAMETOINDEX */ 62 1.3 christos llz = strtoull(scopename, &ep, 10); 63 1.4 christos if (ep == scopename) { 64 1.7 christos return ISC_R_FAILURE; 65 1.4 christos } 66 1.1 christos 67 1.1 christos /* check overflow */ 68 1.3 christos zone = (uint32_t)(llz & 0xffffffffUL); 69 1.4 christos if (zone != llz) { 70 1.7 christos return ISC_R_FAILURE; 71 1.4 christos } 72 1.3 christos #ifdef HAVE_IF_NAMETOINDEX 73 1.1 christos } 74 1.4 christos #endif /* ifdef HAVE_IF_NAMETOINDEX */ 75 1.1 christos 76 1.1 christos *zoneid = zone; 77 1.7 christos return ISC_R_SUCCESS; 78 1.1 christos } 79