net.c revision 285612
1139749Simp/* 219410Sguido * Copyright (C) 2004, 2005, 2007, 2008, 2012 Internet Systems Consortium, Inc. ("ISC") 319410Sguido * Copyright (C) 1999-2003 Internet Software Consortium. 419410Sguido * 519410Sguido * Permission to use, copy, modify, and/or distribute this software for any 619410Sguido * purpose with or without fee is hereby granted, provided that the above 719410Sguido * copyright notice and this permission notice appear in all copies. 819410Sguido * 919410Sguido * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 1019410Sguido * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 1119410Sguido * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 1219410Sguido * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 1319410Sguido * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 1419410Sguido * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 1519410Sguido * PERFORMANCE OF THIS SOFTWARE. 1619410Sguido */ 1719410Sguido 1819410Sguido/* $Id$ */ 1919410Sguido 2019410Sguido#include <config.h> 2119410Sguido 2219410Sguido#include <sys/types.h> 2319410Sguido 2419410Sguido#if defined(HAVE_SYS_SYSCTL_H) 2519410Sguido#if defined(HAVE_SYS_PARAM_H) 2619410Sguido#include <sys/param.h> 2719410Sguido#endif 2819410Sguido#include <sys/sysctl.h> 2919410Sguido#endif 3033707Sgpalmer 3119410Sguido#include <errno.h> 3219410Sguido#include <unistd.h> 33119418Sobrien 34119418Sobrien#include <isc/log.h> 35119418Sobrien#include <isc/msgs.h> 3619410Sguido#include <isc/net.h> 3719410Sguido#include <isc/once.h> 3819410Sguido#include <isc/strerror.h> 3919410Sguido#include <isc/string.h> 4019410Sguido#include <isc/util.h> 4119410Sguido 4219410Sguido/*% 4319410Sguido * Definitions about UDP port range specification. This is a total mess of 4419410Sguido * portability variants: some use sysctl (but the sysctl names vary), some use 4519410Sguido * system-specific interfaces, some have the same interface for IPv4 and IPv6, 4619410Sguido * some separate them, etc... 4719410Sguido */ 4819410Sguido 4919410Sguido/*% 5019410Sguido * The last resort defaults: use all non well known port space 5119410Sguido */ 5219410Sguido#ifndef ISC_NET_PORTRANGELOW 5319410Sguido#define ISC_NET_PORTRANGELOW 1024 5419410Sguido#endif /* ISC_NET_PORTRANGELOW */ 5519410Sguido#ifndef ISC_NET_PORTRANGEHIGH 5619410Sguido#define ISC_NET_PORTRANGEHIGH 65535 5719410Sguido#endif /* ISC_NET_PORTRANGEHIGH */ 5819410Sguido 5919410Sguido#ifdef HAVE_SYSCTLBYNAME 6019410Sguido 6119410Sguido/*% 6224204Sbde * sysctl variants 63151014Sjhb */ 6426640Sbde#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__DragonFly__) 6519410Sguido#define USE_SYSCTL_PORTRANGE 6619410Sguido#define SYSCTL_V4PORTRANGE_LOW "net.inet.ip.portrange.hifirst" 6719410Sguido#define SYSCTL_V4PORTRANGE_HIGH "net.inet.ip.portrange.hilast" 6819410Sguido#define SYSCTL_V6PORTRANGE_LOW "net.inet.ip.portrange.hifirst" 6919410Sguido#define SYSCTL_V6PORTRANGE_HIGH "net.inet.ip.portrange.hilast" 7032350Seivind#endif 71152315Sru 72147256Sbrooks#ifdef __NetBSD__ 7319410Sguido#define USE_SYSCTL_PORTRANGE 7468417Swpaul#define SYSCTL_V4PORTRANGE_LOW "net.inet.ip.anonportmin" 7568417Swpaul#define SYSCTL_V4PORTRANGE_HIGH "net.inet.ip.anonportmax" 76121816Sbrooks#define SYSCTL_V6PORTRANGE_LOW "net.inet6.ip6.anonportmin" 77121816Sbrooks#define SYSCTL_V6PORTRANGE_HIGH "net.inet6.ip6.anonportmax" 7819410Sguido#endif 7919410Sguido 8019410Sguido#else /* !HAVE_SYSCTLBYNAME */ 81121491Simp 8219410Sguido#ifdef __OpenBSD__ 8319410Sguido#define USE_SYSCTL_PORTRANGE 8419410Sguido#define SYSCTL_V4PORTRANGE_LOW { CTL_NET, PF_INET, IPPROTO_IP, \ 8569732Swpaul IPCTL_IPPORT_HIFIRSTAUTO } 8619410Sguido#define SYSCTL_V4PORTRANGE_HIGH { CTL_NET, PF_INET, IPPROTO_IP, \ 8719410Sguido IPCTL_IPPORT_HILASTAUTO } 88133980Sgibbs/* Same for IPv6 */ 89133980Sgibbs#define SYSCTL_V6PORTRANGE_LOW SYSCTL_V4PORTRANGE_LOW 9020096Sguido#define SYSCTL_V6PORTRANGE_HIGH SYSCTL_V4PORTRANGE_HIGH 91133980Sgibbs#endif 9219410Sguido 93133980Sgibbs#endif /* HAVE_SYSCTLBYNAME */ 94133980Sgibbs 95133980Sgibbs#if defined(ISC_PLATFORM_NEEDIN6ADDRANY) 9619410Sguidoconst struct in6_addr isc_net_in6addrany = IN6ADDR_ANY_INIT; 97133980Sgibbs#endif 98133980Sgibbs 99133980Sgibbs#if defined(ISC_PLATFORM_HAVEIPV6) 10019410Sguido 101133980Sgibbs# if defined(ISC_PLATFORM_NEEDIN6ADDRLOOPBACK) 102133980Sgibbsconst struct in6_addr isc_net_in6addrloop = IN6ADDR_LOOPBACK_INIT; 103133980Sgibbs# endif 10419410Sguido 105133980Sgibbs# if defined(WANT_IPV6) 106133980Sgibbsstatic isc_once_t once_ipv6only = ISC_ONCE_INIT; 107133980Sgibbs# endif 10819410Sguido 109133980Sgibbs# if defined(ISC_PLATFORM_HAVEIPV6) && \ 110133980Sgibbs defined(WANT_IPV6) && defined(ISC_PLATFORM_HAVEIN6PKTINFO) 111133980Sgibbsstatic isc_once_t once_ipv6pktinfo = ISC_ONCE_INIT; 11219410Sguido# endif 113133980Sgibbs#endif /* ISC_PLATFORM_HAVEIPV6 */ 114133980Sgibbs 115133980Sgibbsstatic isc_once_t once = ISC_ONCE_INIT; 11619410Sguido 117133980Sgibbsstatic isc_result_t ipv4_result = ISC_R_NOTFOUND; 118133980Sgibbsstatic isc_result_t ipv6_result = ISC_R_NOTFOUND; 119133980Sgibbsstatic isc_result_t unix_result = ISC_R_NOTFOUND; 120133980Sgibbsstatic isc_result_t ipv6only_result = ISC_R_NOTFOUND; 121133980Sgibbsstatic isc_result_t ipv6pktinfo_result = ISC_R_NOTFOUND; 122133980Sgibbs 12319410Sguidostatic isc_result_t 12419410Sguidotry_proto(int domain) { 125151014Sjhb int s; 126151014Sjhb isc_result_t result = ISC_R_SUCCESS; 127151014Sjhb char strbuf[ISC_STRERRORSIZE]; 128151014Sjhb 129151014Sjhb s = socket(domain, SOCK_STREAM, 0); 130151014Sjhb if (s == -1) { 131151014Sjhb switch (errno) { 132199559Sjhb#ifdef EAFNOSUPPORT 133151014Sjhb case EAFNOSUPPORT: 134151014Sjhb#endif 135151014Sjhb#ifdef EPROTONOSUPPORT 136151014Sjhb case EPROTONOSUPPORT: 137151014Sjhb#endif 138151014Sjhb#ifdef EINVAL 139151014Sjhb case EINVAL: 140151014Sjhb#endif 14119410Sguido return (ISC_R_NOTFOUND); 14219410Sguido default: 143151014Sjhb isc__strerror(errno, strbuf, sizeof(strbuf)); 14419410Sguido UNEXPECTED_ERROR(__FILE__, __LINE__, 145133980Sgibbs "socket() %s: %s", 146147256Sbrooks isc_msgcat_get(isc_msgcat, 147133980Sgibbs ISC_MSGSET_GENERAL, 148147256Sbrooks ISC_MSG_FAILED, 14919410Sguido "failed"), 150151014Sjhb strbuf); 151147256Sbrooks return (ISC_R_UNEXPECTED); 152147256Sbrooks } 153147256Sbrooks } 154147256Sbrooks 155151014Sjhb#ifdef ISC_PLATFORM_HAVEIPV6 156147256Sbrooks#ifdef WANT_IPV6 157151014Sjhb#ifdef ISC_PLATFORM_HAVEIN6PKTINFO 158151014Sjhb if (domain == PF_INET6) { 159151014Sjhb struct sockaddr_in6 sin6; 160199559Sjhb GETSOCKNAME_SOCKLEN_TYPE len; /* NTP local change */ 161133980Sgibbs 162133980Sgibbs /* 163133980Sgibbs * Check to see if IPv6 is broken, as is common on Linux. 16419410Sguido */ 165151014Sjhb len = sizeof(sin6); 16619410Sguido if (getsockname(s, (struct sockaddr *)&sin6, &len) < 0) 167133980Sgibbs { 168133980Sgibbs isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, 169133980Sgibbs ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, 170133980Sgibbs "retrieving the address of an IPv6 " 171133980Sgibbs "socket from the kernel failed."); 172133980Sgibbs isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, 17319410Sguido ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, 174151014Sjhb "IPv6 is not supported."); 175151014Sjhb result = ISC_R_NOTFOUND; 176151014Sjhb } else { 177133980Sgibbs if (len == sizeof(struct sockaddr_in6)) 178151014Sjhb result = ISC_R_SUCCESS; 179133980Sgibbs else { 180133980Sgibbs isc_log_write(isc_lctx, 181151014Sjhb ISC_LOGCATEGORY_GENERAL, 182151014Sjhb ISC_LOGMODULE_SOCKET, 183151014Sjhb ISC_LOG_ERROR, 184133980Sgibbs "IPv6 structures in kernel and " 185151014Sjhb "user space do not match."); 186133980Sgibbs isc_log_write(isc_lctx, 187147256Sbrooks ISC_LOGCATEGORY_GENERAL, 188147256Sbrooks ISC_LOGMODULE_SOCKET, 189133980Sgibbs ISC_LOG_ERROR, 19019410Sguido "IPv6 is not supported."); 191207554Ssobomax result = ISC_R_NOTFOUND; 192151014Sjhb } 193151014Sjhb } 194151014Sjhb } 195151014Sjhb#endif 196133980Sgibbs#endif 19719410Sguido#endif 198147256Sbrooks 19919410Sguido (void)close(s); 200151014Sjhb 20119410Sguido return (result); 202178469Smarius} 203151014Sjhb 204178469Smariusstatic void 205133980Sgibbsinitialize_action(void) { 206133980Sgibbs ipv4_result = try_proto(PF_INET); 20719410Sguido#ifdef ISC_PLATFORM_HAVEIPV6 20819410Sguido#ifdef WANT_IPV6 20919410Sguido#ifdef ISC_PLATFORM_HAVEIN6PKTINFO 21019410Sguido ipv6_result = try_proto(PF_INET6); 21119410Sguido#endif 21219410Sguido#endif 21319410Sguido#endif 214151014Sjhb#ifdef ISC_PLATFORM_HAVESYSUNH 21519410Sguido unix_result = try_proto(PF_UNIX); 216133980Sgibbs#endif 217151014Sjhb} 218151014Sjhb 219151014Sjhbstatic void 220151014Sjhbinitialize(void) { 221151014Sjhb RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); 222151014Sjhb} 223151014Sjhb 224151014Sjhbisc_result_t 225151014Sjhbisc_net_probeipv4(void) { 226151014Sjhb initialize(); 227133980Sgibbs return (ipv4_result); 22819410Sguido} 229151014Sjhb 230151014Sjhbisc_result_t 231133980Sgibbsisc_net_probeipv6(void) { 23219410Sguido initialize(); 233133980Sgibbs return (ipv6_result); 23419410Sguido} 235133980Sgibbs 236152315Sruisc_result_t 23719410Sguidoisc_net_probeunix(void) { 238133980Sgibbs initialize(); 239133980Sgibbs return (unix_result); 240133980Sgibbs} 241133980Sgibbs 24219410Sguido#ifdef ISC_PLATFORM_HAVEIPV6 243133980Sgibbs#ifdef WANT_IPV6 244133980Sgibbsstatic void 245133980Sgibbstry_ipv6only(void) { 24619410Sguido#ifdef IPV6_V6ONLY 247133980Sgibbs int s, on; 248133980Sgibbs char strbuf[ISC_STRERRORSIZE]; 249133980Sgibbs#endif 250133980Sgibbs isc_result_t result; 25119410Sguido 252133980Sgibbs result = isc_net_probeipv6(); 253133980Sgibbs if (result != ISC_R_SUCCESS) { 254133980Sgibbs ipv6only_result = result; 255133980Sgibbs return; 256133980Sgibbs } 257133980Sgibbs 258133980Sgibbs#ifndef IPV6_V6ONLY 25919410Sguido ipv6only_result = ISC_R_NOTFOUND; 260151014Sjhb return; 261151014Sjhb#else 26219410Sguido /* check for TCP sockets */ 263133980Sgibbs s = socket(PF_INET6, SOCK_STREAM, 0); 264133980Sgibbs if (s == -1) { 26519410Sguido isc__strerror(errno, strbuf, sizeof(strbuf)); 266151014Sjhb UNEXPECTED_ERROR(__FILE__, __LINE__, 26719410Sguido "socket() %s: %s", 268133980Sgibbs isc_msgcat_get(isc_msgcat, 269148887Srwatson ISC_MSGSET_GENERAL, 270148887Srwatson ISC_MSG_FAILED, 271199559Sjhb "failed"), 27219410Sguido strbuf); 273133980Sgibbs ipv6only_result = ISC_R_UNEXPECTED; 274151014Sjhb return; 27519410Sguido } 27619410Sguido 27719410Sguido on = 1; 278151014Sjhb if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) { 27919410Sguido ipv6only_result = ISC_R_NOTFOUND; 280151014Sjhb goto close; 28119410Sguido } 282151014Sjhb 283133980Sgibbs close(s); 284133980Sgibbs 285133980Sgibbs /* check for UDP sockets */ 286133980Sgibbs s = socket(PF_INET6, SOCK_DGRAM, 0); 287133980Sgibbs if (s == -1) { 288133980Sgibbs isc__strerror(errno, strbuf, sizeof(strbuf)); 289133980Sgibbs UNEXPECTED_ERROR(__FILE__, __LINE__, 290151014Sjhb "socket() %s: %s", 29119410Sguido isc_msgcat_get(isc_msgcat, 292133980Sgibbs ISC_MSGSET_GENERAL, 29319410Sguido ISC_MSG_FAILED, 294133980Sgibbs "failed"), 295133980Sgibbs strbuf); 296133980Sgibbs ipv6only_result = ISC_R_UNEXPECTED; 297133980Sgibbs return; 298133980Sgibbs } 299133980Sgibbs 300133980Sgibbs on = 1; 301133980Sgibbs if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) { 302133980Sgibbs ipv6only_result = ISC_R_NOTFOUND; 30319410Sguido goto close; 304133980Sgibbs } 305178469Smarius 306133980Sgibbs ipv6only_result = ISC_R_SUCCESS; 307133980Sgibbs 308133980Sgibbsclose: 309133980Sgibbs close(s); 310133980Sgibbs return; 311133980Sgibbs#endif /* IPV6_V6ONLY */ 312133980Sgibbs} 313133980Sgibbs 314133980Sgibbsstatic void 315178469Smariusinitialize_ipv6only(void) { 316133980Sgibbs RUNTIME_CHECK(isc_once_do(&once_ipv6only, 317178469Smarius try_ipv6only) == ISC_R_SUCCESS); 318133980Sgibbs} 31919410Sguido 32019410Sguido#ifdef ISC_PLATFORM_HAVEIN6PKTINFO 321133980Sgibbsstatic void 322151014Sjhbtry_ipv6pktinfo(void) { 323133980Sgibbs int s, on; 324151014Sjhb char strbuf[ISC_STRERRORSIZE]; 325133980Sgibbs isc_result_t result; 326133980Sgibbs int optname; 327133980Sgibbs 328141166Sgrehan result = isc_net_probeipv6(); 32919410Sguido if (result != ISC_R_SUCCESS) { 330151014Sjhb ipv6pktinfo_result = result; 331133980Sgibbs return; 332133980Sgibbs } 33320096Sguido 334133980Sgibbs /* we only use this for UDP sockets */ 335133980Sgibbs s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); 336133980Sgibbs if (s == -1) { 337133980Sgibbs isc__strerror(errno, strbuf, sizeof(strbuf)); 338133980Sgibbs UNEXPECTED_ERROR(__FILE__, __LINE__, 339133980Sgibbs "socket() %s: %s", 340133980Sgibbs isc_msgcat_get(isc_msgcat, 341133980Sgibbs ISC_MSGSET_GENERAL, 342133980Sgibbs ISC_MSG_FAILED, 343133980Sgibbs "failed"), 344133980Sgibbs strbuf); 345133980Sgibbs ipv6pktinfo_result = ISC_R_UNEXPECTED; 346133980Sgibbs return; 347133980Sgibbs } 348133980Sgibbs 349133980Sgibbs#ifdef IPV6_RECVPKTINFO 350133980Sgibbs optname = IPV6_RECVPKTINFO; 351133980Sgibbs#else 352133980Sgibbs optname = IPV6_PKTINFO; 35320096Sguido#endif 354133980Sgibbs on = 1; 355133980Sgibbs if (setsockopt(s, IPPROTO_IPV6, optname, &on, sizeof(on)) < 0) { 356133980Sgibbs ipv6pktinfo_result = ISC_R_NOTFOUND; 357133980Sgibbs goto close; 358133980Sgibbs } 359133980Sgibbs 360133980Sgibbs ipv6pktinfo_result = ISC_R_SUCCESS; 361133980Sgibbs 362133980Sgibbsclose: 363133980Sgibbs close(s); 364133980Sgibbs return; 365133980Sgibbs} 366133980Sgibbs 367133980Sgibbsstatic void 368133980Sgibbsinitialize_ipv6pktinfo(void) { 369133980Sgibbs RUNTIME_CHECK(isc_once_do(&once_ipv6pktinfo, 370133980Sgibbs try_ipv6pktinfo) == ISC_R_SUCCESS); 371133980Sgibbs} 372133980Sgibbs#endif /* ISC_PLATFORM_HAVEIN6PKTINFO */ 373133980Sgibbs#endif /* WANT_IPV6 */ 374133980Sgibbs#endif /* ISC_PLATFORM_HAVEIPV6 */ 375133980Sgibbs 376133980Sgibbsisc_result_t 377133980Sgibbsisc_net_probe_ipv6only(void) { 378133980Sgibbs#ifdef ISC_PLATFORM_HAVEIPV6 37920096Sguido#ifdef WANT_IPV6 380133980Sgibbs initialize_ipv6only(); 381133980Sgibbs#else 382133980Sgibbs ipv6only_result = ISC_R_NOTFOUND; 383151014Sjhb#endif 384151014Sjhb#endif 385151014Sjhb return (ipv6only_result); 38620096Sguido} 387133980Sgibbs 388133980Sgibbsisc_result_t 389133980Sgibbsisc_net_probe_ipv6pktinfo(void) { 390133980Sgibbs#ifdef ISC_PLATFORM_HAVEIPV6 39120096Sguido#ifdef ISC_PLATFORM_HAVEIN6PKTINFO 392133980Sgibbs#ifdef WANT_IPV6 393133980Sgibbs initialize_ipv6pktinfo(); 39420096Sguido#else 39520096Sguido ipv6pktinfo_result = ISC_R_NOTFOUND; 396133980Sgibbs#endif 39720096Sguido#endif 398133980Sgibbs#endif 399133980Sgibbs return (ipv6pktinfo_result); 400133980Sgibbs} 401133980Sgibbs 402133980Sgibbs#if defined(USE_SYSCTL_PORTRANGE) 403133980Sgibbs#if defined(HAVE_SYSCTLBYNAME) 404133980Sgibbsstatic isc_result_t 405133980Sgibbsgetudpportrange_sysctl(int af, in_port_t *low, in_port_t *high) { 406133980Sgibbs int port_low, port_high; 407133980Sgibbs size_t portlen; 408133980Sgibbs const char *sysctlname_lowport, *sysctlname_hiport; 409133980Sgibbs 410133980Sgibbs if (af == AF_INET) { 411133980Sgibbs sysctlname_lowport = SYSCTL_V4PORTRANGE_LOW; 412133980Sgibbs sysctlname_hiport = SYSCTL_V4PORTRANGE_HIGH; 413133980Sgibbs } else { 414133980Sgibbs sysctlname_lowport = SYSCTL_V6PORTRANGE_LOW; 415133980Sgibbs sysctlname_hiport = SYSCTL_V6PORTRANGE_HIGH; 416133980Sgibbs } 417133980Sgibbs portlen = sizeof(portlen); 418133980Sgibbs if (sysctlbyname(sysctlname_lowport, &port_low, &portlen, 419133980Sgibbs NULL, 0) < 0) { 42019410Sguido return (ISC_R_FAILURE); 42119410Sguido } 42219410Sguido portlen = sizeof(portlen); 423151014Sjhb if (sysctlbyname(sysctlname_hiport, &port_high, &portlen, 42419410Sguido NULL, 0) < 0) { 425151014Sjhb return (ISC_R_FAILURE); 42619410Sguido } 427151014Sjhb if ((port_low & ~0xffff) != 0 || (port_high & ~0xffff) != 0) 428151014Sjhb return (ISC_R_RANGE); 429151014Sjhb 430151014Sjhb *low = (in_port_t)port_low; 431151014Sjhb *high = (in_port_t)port_high; 432151014Sjhb 433151014Sjhb return (ISC_R_SUCCESS); 434151014Sjhb} 435151014Sjhb#else /* !HAVE_SYSCTLBYNAME */ 436151014Sjhbstatic isc_result_t 437151014Sjhbgetudpportrange_sysctl(int af, in_port_t *low, in_port_t *high) { 438151014Sjhb int mib_lo4[4] = SYSCTL_V4PORTRANGE_LOW; 439151014Sjhb int mib_hi4[4] = SYSCTL_V4PORTRANGE_HIGH; 440151014Sjhb int mib_lo6[4] = SYSCTL_V6PORTRANGE_LOW; 441133980Sgibbs int mib_hi6[4] = SYSCTL_V6PORTRANGE_HIGH; 442151014Sjhb int *mib_lo, *mib_hi, miblen; 443148887Srwatson int port_low, port_high; 444133980Sgibbs size_t portlen; 44519410Sguido 44619410Sguido if (af == AF_INET) { 447133980Sgibbs mib_lo = mib_lo4; 448133980Sgibbs mib_hi = mib_hi4; 449133980Sgibbs miblen = sizeof(mib_lo4) / sizeof(mib_lo4[0]); 450133980Sgibbs } else { 451133980Sgibbs mib_lo = mib_lo6; 452133980Sgibbs mib_hi = mib_hi6; 453133980Sgibbs miblen = sizeof(mib_lo6) / sizeof(mib_lo6[0]); 454133980Sgibbs } 45519410Sguido 456133980Sgibbs portlen = sizeof(portlen); 45719410Sguido if (sysctl(mib_lo, miblen, &port_low, &portlen, NULL, 0) < 0) { 458133980Sgibbs return (ISC_R_FAILURE); 459133980Sgibbs } 460133980Sgibbs 461133980Sgibbs portlen = sizeof(portlen); 462133980Sgibbs if (sysctl(mib_hi, miblen, &port_high, &portlen, NULL, 0) < 0) { 463133980Sgibbs return (ISC_R_FAILURE); 464133980Sgibbs } 465133980Sgibbs 466133980Sgibbs if ((port_low & ~0xffff) != 0 || (port_high & ~0xffff) != 0) 467133980Sgibbs return (ISC_R_RANGE); 468133980Sgibbs 469133980Sgibbs *low = (in_port_t) port_low; 470133980Sgibbs *high = (in_port_t) port_high; 471133980Sgibbs 472133980Sgibbs return (ISC_R_SUCCESS); 473133980Sgibbs} 474133980Sgibbs#endif /* HAVE_SYSCTLBYNAME */ 475133980Sgibbs#endif /* USE_SYSCTL_PORTRANGE */ 476148887Srwatson 477199559Sjhbisc_result_t 478133980Sgibbsisc_net_getudpportrange(int af, in_port_t *low, in_port_t *high) { 479133980Sgibbs int result = ISC_R_FAILURE; 480133980Sgibbs 481133980Sgibbs REQUIRE(low != NULL && high != NULL); 48290227Sdillon 483133980Sgibbs#if defined(USE_SYSCTL_PORTRANGE) 484133980Sgibbs result = getudpportrange_sysctl(af, low, high); 48519410Sguido#else 486133980Sgibbs UNUSED(af); 487133980Sgibbs#endif 488151014Sjhb 48919410Sguido if (result != ISC_R_SUCCESS) { 490151014Sjhb *low = ISC_NET_PORTRANGELOW; 49119410Sguido *high = ISC_NET_PORTRANGEHIGH; 492133980Sgibbs } 493133980Sgibbs 494133980Sgibbs return (ISC_R_SUCCESS); /* we currently never fail in this function */ 495151014Sjhb} 496151014Sjhb 497133980Sgibbsvoid 49819410Sguidoisc_net_disableipv4(void) { 499133980Sgibbs initialize(); 50019410Sguido if (ipv4_result == ISC_R_SUCCESS) 501133980Sgibbs ipv4_result = ISC_R_DISABLED; 502133980Sgibbs} 503151014Sjhb 504133980Sgibbsvoid 505133980Sgibbsisc_net_disableipv6(void) { 506133980Sgibbs initialize(); 507151014Sjhb if (ipv6_result == ISC_R_SUCCESS) 508133980Sgibbs ipv6_result = ISC_R_DISABLED; 509133980Sgibbs} 510133980Sgibbs 511133980Sgibbsvoid 512133980Sgibbsisc_net_enableipv4(void) { 513133980Sgibbs initialize(); 51419410Sguido if (ipv4_result == ISC_R_DISABLED) 515133980Sgibbs ipv4_result = ISC_R_SUCCESS; 516199559Sjhb} 51719410Sguido 51819410Sguidovoid 519133980Sgibbsisc_net_enableipv6(void) { 520133980Sgibbs initialize(); 521133980Sgibbs if (ipv6_result == ISC_R_DISABLED) 522133980Sgibbs ipv6_result = ISC_R_SUCCESS; 523133980Sgibbs} 524133980Sgibbs