1290001Sglebius/* 2290001Sglebius * Copyright (C) 2004, 2005, 2007, 2008, 2012 Internet Systems Consortium, Inc. ("ISC") 3290001Sglebius * Copyright (C) 1999-2003 Internet Software Consortium. 4290001Sglebius * 5290001Sglebius * Permission to use, copy, modify, and/or distribute this software for any 6290001Sglebius * purpose with or without fee is hereby granted, provided that the above 7290001Sglebius * copyright notice and this permission notice appear in all copies. 8290001Sglebius * 9290001Sglebius * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10290001Sglebius * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11290001Sglebius * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12290001Sglebius * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13290001Sglebius * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14290001Sglebius * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15290001Sglebius * PERFORMANCE OF THIS SOFTWARE. 16290001Sglebius */ 17290001Sglebius 18290001Sglebius/* $Id$ */ 19290001Sglebius 20290001Sglebius#include <config.h> 21290001Sglebius 22290001Sglebius#include <sys/types.h> 23290001Sglebius 24290001Sglebius#if defined(HAVE_SYS_SYSCTL_H) 25290001Sglebius#if defined(HAVE_SYS_PARAM_H) 26290001Sglebius#include <sys/param.h> 27290001Sglebius#endif 28290001Sglebius#include <sys/sysctl.h> 29290001Sglebius#endif 30290001Sglebius 31290001Sglebius#include <errno.h> 32290001Sglebius#include <unistd.h> 33290001Sglebius 34290001Sglebius#include <isc/log.h> 35290001Sglebius#include <isc/msgs.h> 36290001Sglebius#include <isc/net.h> 37290001Sglebius#include <isc/once.h> 38290001Sglebius#include <isc/strerror.h> 39290001Sglebius#include <isc/string.h> 40290001Sglebius#include <isc/util.h> 41290001Sglebius 42290001Sglebius/*% 43290001Sglebius * Definitions about UDP port range specification. This is a total mess of 44290001Sglebius * portability variants: some use sysctl (but the sysctl names vary), some use 45290001Sglebius * system-specific interfaces, some have the same interface for IPv4 and IPv6, 46290001Sglebius * some separate them, etc... 47290001Sglebius */ 48290001Sglebius 49290001Sglebius/*% 50290001Sglebius * The last resort defaults: use all non well known port space 51290001Sglebius */ 52290001Sglebius#ifndef ISC_NET_PORTRANGELOW 53290001Sglebius#define ISC_NET_PORTRANGELOW 1024 54290001Sglebius#endif /* ISC_NET_PORTRANGELOW */ 55290001Sglebius#ifndef ISC_NET_PORTRANGEHIGH 56290001Sglebius#define ISC_NET_PORTRANGEHIGH 65535 57290001Sglebius#endif /* ISC_NET_PORTRANGEHIGH */ 58290001Sglebius 59290001Sglebius#ifdef HAVE_SYSCTLBYNAME 60290001Sglebius 61290001Sglebius/*% 62290001Sglebius * sysctl variants 63290001Sglebius */ 64290001Sglebius#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__DragonFly__) 65290001Sglebius#define USE_SYSCTL_PORTRANGE 66290001Sglebius#define SYSCTL_V4PORTRANGE_LOW "net.inet.ip.portrange.hifirst" 67290001Sglebius#define SYSCTL_V4PORTRANGE_HIGH "net.inet.ip.portrange.hilast" 68290001Sglebius#define SYSCTL_V6PORTRANGE_LOW "net.inet.ip.portrange.hifirst" 69290001Sglebius#define SYSCTL_V6PORTRANGE_HIGH "net.inet.ip.portrange.hilast" 70290001Sglebius#endif 71290001Sglebius 72290001Sglebius#ifdef __NetBSD__ 73290001Sglebius#define USE_SYSCTL_PORTRANGE 74290001Sglebius#define SYSCTL_V4PORTRANGE_LOW "net.inet.ip.anonportmin" 75290001Sglebius#define SYSCTL_V4PORTRANGE_HIGH "net.inet.ip.anonportmax" 76290001Sglebius#define SYSCTL_V6PORTRANGE_LOW "net.inet6.ip6.anonportmin" 77290001Sglebius#define SYSCTL_V6PORTRANGE_HIGH "net.inet6.ip6.anonportmax" 78290001Sglebius#endif 79290001Sglebius 80290001Sglebius#else /* !HAVE_SYSCTLBYNAME */ 81290001Sglebius 82290001Sglebius#ifdef __OpenBSD__ 83290001Sglebius#define USE_SYSCTL_PORTRANGE 84290001Sglebius#define SYSCTL_V4PORTRANGE_LOW { CTL_NET, PF_INET, IPPROTO_IP, \ 85290001Sglebius IPCTL_IPPORT_HIFIRSTAUTO } 86290001Sglebius#define SYSCTL_V4PORTRANGE_HIGH { CTL_NET, PF_INET, IPPROTO_IP, \ 87290001Sglebius IPCTL_IPPORT_HILASTAUTO } 88290001Sglebius/* Same for IPv6 */ 89290001Sglebius#define SYSCTL_V6PORTRANGE_LOW SYSCTL_V4PORTRANGE_LOW 90290001Sglebius#define SYSCTL_V6PORTRANGE_HIGH SYSCTL_V4PORTRANGE_HIGH 91290001Sglebius#endif 92290001Sglebius 93290001Sglebius#endif /* HAVE_SYSCTLBYNAME */ 94290001Sglebius 95290001Sglebius#if defined(ISC_PLATFORM_NEEDIN6ADDRANY) 96290001Sglebiusconst struct in6_addr isc_net_in6addrany = IN6ADDR_ANY_INIT; 97290001Sglebius#endif 98290001Sglebius 99290001Sglebius#if defined(ISC_PLATFORM_HAVEIPV6) 100290001Sglebius 101290001Sglebius# if defined(ISC_PLATFORM_NEEDIN6ADDRLOOPBACK) 102290001Sglebiusconst struct in6_addr isc_net_in6addrloop = IN6ADDR_LOOPBACK_INIT; 103290001Sglebius# endif 104290001Sglebius 105290001Sglebius# if defined(WANT_IPV6) 106290001Sglebiusstatic isc_once_t once_ipv6only = ISC_ONCE_INIT; 107290001Sglebius# endif 108290001Sglebius 109290001Sglebius# if defined(ISC_PLATFORM_HAVEIPV6) && \ 110290001Sglebius defined(WANT_IPV6) && defined(ISC_PLATFORM_HAVEIN6PKTINFO) 111290001Sglebiusstatic isc_once_t once_ipv6pktinfo = ISC_ONCE_INIT; 112290001Sglebius# endif 113290001Sglebius#endif /* ISC_PLATFORM_HAVEIPV6 */ 114290001Sglebius 115290001Sglebiusstatic isc_once_t once = ISC_ONCE_INIT; 116290001Sglebius 117290001Sglebiusstatic isc_result_t ipv4_result = ISC_R_NOTFOUND; 118290001Sglebiusstatic isc_result_t ipv6_result = ISC_R_NOTFOUND; 119290001Sglebiusstatic isc_result_t unix_result = ISC_R_NOTFOUND; 120290001Sglebiusstatic isc_result_t ipv6only_result = ISC_R_NOTFOUND; 121290001Sglebiusstatic isc_result_t ipv6pktinfo_result = ISC_R_NOTFOUND; 122290001Sglebius 123290001Sglebiusstatic isc_result_t 124290001Sglebiustry_proto(int domain) { 125290001Sglebius int s; 126290001Sglebius isc_result_t result = ISC_R_SUCCESS; 127290001Sglebius char strbuf[ISC_STRERRORSIZE]; 128290001Sglebius 129290001Sglebius s = socket(domain, SOCK_STREAM, 0); 130290001Sglebius if (s == -1) { 131290001Sglebius switch (errno) { 132290001Sglebius#ifdef EAFNOSUPPORT 133290001Sglebius case EAFNOSUPPORT: 134290001Sglebius#endif 135290001Sglebius#ifdef EPROTONOSUPPORT 136290001Sglebius case EPROTONOSUPPORT: 137290001Sglebius#endif 138290001Sglebius#ifdef EINVAL 139290001Sglebius case EINVAL: 140290001Sglebius#endif 141290001Sglebius return (ISC_R_NOTFOUND); 142290001Sglebius default: 143290001Sglebius isc__strerror(errno, strbuf, sizeof(strbuf)); 144290001Sglebius UNEXPECTED_ERROR(__FILE__, __LINE__, 145290001Sglebius "socket() %s: %s", 146290001Sglebius isc_msgcat_get(isc_msgcat, 147290001Sglebius ISC_MSGSET_GENERAL, 148290001Sglebius ISC_MSG_FAILED, 149290001Sglebius "failed"), 150290001Sglebius strbuf); 151290001Sglebius return (ISC_R_UNEXPECTED); 152290001Sglebius } 153290001Sglebius } 154290001Sglebius 155290001Sglebius#ifdef ISC_PLATFORM_HAVEIPV6 156290001Sglebius#ifdef WANT_IPV6 157290001Sglebius#ifdef ISC_PLATFORM_HAVEIN6PKTINFO 158290001Sglebius if (domain == PF_INET6) { 159290001Sglebius struct sockaddr_in6 sin6; 160290001Sglebius GETSOCKNAME_SOCKLEN_TYPE len; /* NTP local change */ 161290001Sglebius 162290001Sglebius /* 163290001Sglebius * Check to see if IPv6 is broken, as is common on Linux. 164290001Sglebius */ 165290001Sglebius len = sizeof(sin6); 166290001Sglebius if (getsockname(s, (struct sockaddr *)&sin6, &len) < 0) 167290001Sglebius { 168290001Sglebius isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, 169290001Sglebius ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, 170290001Sglebius "retrieving the address of an IPv6 " 171290001Sglebius "socket from the kernel failed."); 172290001Sglebius isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, 173290001Sglebius ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, 174290001Sglebius "IPv6 is not supported."); 175290001Sglebius result = ISC_R_NOTFOUND; 176290001Sglebius } else { 177290001Sglebius if (len == sizeof(struct sockaddr_in6)) 178290001Sglebius result = ISC_R_SUCCESS; 179290001Sglebius else { 180290001Sglebius isc_log_write(isc_lctx, 181290001Sglebius ISC_LOGCATEGORY_GENERAL, 182290001Sglebius ISC_LOGMODULE_SOCKET, 183290001Sglebius ISC_LOG_ERROR, 184290001Sglebius "IPv6 structures in kernel and " 185290001Sglebius "user space do not match."); 186290001Sglebius isc_log_write(isc_lctx, 187290001Sglebius ISC_LOGCATEGORY_GENERAL, 188290001Sglebius ISC_LOGMODULE_SOCKET, 189290001Sglebius ISC_LOG_ERROR, 190290001Sglebius "IPv6 is not supported."); 191290001Sglebius result = ISC_R_NOTFOUND; 192290001Sglebius } 193290001Sglebius } 194290001Sglebius } 195290001Sglebius#endif 196290001Sglebius#endif 197290001Sglebius#endif 198290001Sglebius 199290001Sglebius (void)close(s); 200290001Sglebius 201290001Sglebius return (result); 202290001Sglebius} 203290001Sglebius 204290001Sglebiusstatic void 205290001Sglebiusinitialize_action(void) { 206290001Sglebius ipv4_result = try_proto(PF_INET); 207290001Sglebius#ifdef ISC_PLATFORM_HAVEIPV6 208290001Sglebius#ifdef WANT_IPV6 209290001Sglebius#ifdef ISC_PLATFORM_HAVEIN6PKTINFO 210290001Sglebius ipv6_result = try_proto(PF_INET6); 211290001Sglebius#endif 212290001Sglebius#endif 213290001Sglebius#endif 214290001Sglebius#ifdef ISC_PLATFORM_HAVESYSUNH 215290001Sglebius unix_result = try_proto(PF_UNIX); 216290001Sglebius#endif 217290001Sglebius} 218290001Sglebius 219290001Sglebiusstatic void 220290001Sglebiusinitialize(void) { 221290001Sglebius RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); 222290001Sglebius} 223290001Sglebius 224290001Sglebiusisc_result_t 225290001Sglebiusisc_net_probeipv4(void) { 226290001Sglebius initialize(); 227290001Sglebius return (ipv4_result); 228290001Sglebius} 229290001Sglebius 230290001Sglebiusisc_result_t 231290001Sglebiusisc_net_probeipv6(void) { 232290001Sglebius initialize(); 233290001Sglebius return (ipv6_result); 234290001Sglebius} 235290001Sglebius 236290001Sglebiusisc_result_t 237290001Sglebiusisc_net_probeunix(void) { 238290001Sglebius initialize(); 239290001Sglebius return (unix_result); 240290001Sglebius} 241290001Sglebius 242290001Sglebius#ifdef ISC_PLATFORM_HAVEIPV6 243290001Sglebius#ifdef WANT_IPV6 244290001Sglebiusstatic void 245290001Sglebiustry_ipv6only(void) { 246290001Sglebius#ifdef IPV6_V6ONLY 247290001Sglebius int s, on; 248290001Sglebius char strbuf[ISC_STRERRORSIZE]; 249290001Sglebius#endif 250290001Sglebius isc_result_t result; 251290001Sglebius 252290001Sglebius result = isc_net_probeipv6(); 253290001Sglebius if (result != ISC_R_SUCCESS) { 254290001Sglebius ipv6only_result = result; 255290001Sglebius return; 256290001Sglebius } 257290001Sglebius 258290001Sglebius#ifndef IPV6_V6ONLY 259290001Sglebius ipv6only_result = ISC_R_NOTFOUND; 260290001Sglebius return; 261290001Sglebius#else 262290001Sglebius /* check for TCP sockets */ 263290001Sglebius s = socket(PF_INET6, SOCK_STREAM, 0); 264290001Sglebius if (s == -1) { 265290001Sglebius isc__strerror(errno, strbuf, sizeof(strbuf)); 266290001Sglebius UNEXPECTED_ERROR(__FILE__, __LINE__, 267290001Sglebius "socket() %s: %s", 268290001Sglebius isc_msgcat_get(isc_msgcat, 269290001Sglebius ISC_MSGSET_GENERAL, 270290001Sglebius ISC_MSG_FAILED, 271290001Sglebius "failed"), 272290001Sglebius strbuf); 273290001Sglebius ipv6only_result = ISC_R_UNEXPECTED; 274290001Sglebius return; 275290001Sglebius } 276290001Sglebius 277290001Sglebius on = 1; 278290001Sglebius if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) { 279290001Sglebius ipv6only_result = ISC_R_NOTFOUND; 280290001Sglebius goto close; 281290001Sglebius } 282290001Sglebius 283290001Sglebius close(s); 284290001Sglebius 285290001Sglebius /* check for UDP sockets */ 286290001Sglebius s = socket(PF_INET6, SOCK_DGRAM, 0); 287290001Sglebius if (s == -1) { 288290001Sglebius isc__strerror(errno, strbuf, sizeof(strbuf)); 289290001Sglebius UNEXPECTED_ERROR(__FILE__, __LINE__, 290290001Sglebius "socket() %s: %s", 291290001Sglebius isc_msgcat_get(isc_msgcat, 292290001Sglebius ISC_MSGSET_GENERAL, 293290001Sglebius ISC_MSG_FAILED, 294290001Sglebius "failed"), 295290001Sglebius strbuf); 296290001Sglebius ipv6only_result = ISC_R_UNEXPECTED; 297290001Sglebius return; 298290001Sglebius } 299290001Sglebius 300290001Sglebius on = 1; 301290001Sglebius if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) { 302290001Sglebius ipv6only_result = ISC_R_NOTFOUND; 303290001Sglebius goto close; 304290001Sglebius } 305290001Sglebius 306290001Sglebius ipv6only_result = ISC_R_SUCCESS; 307290001Sglebius 308290001Sglebiusclose: 309290001Sglebius close(s); 310290001Sglebius return; 311290001Sglebius#endif /* IPV6_V6ONLY */ 312290001Sglebius} 313290001Sglebius 314290001Sglebiusstatic void 315290001Sglebiusinitialize_ipv6only(void) { 316290001Sglebius RUNTIME_CHECK(isc_once_do(&once_ipv6only, 317290001Sglebius try_ipv6only) == ISC_R_SUCCESS); 318290001Sglebius} 319290001Sglebius 320290001Sglebius#ifdef ISC_PLATFORM_HAVEIN6PKTINFO 321290001Sglebiusstatic void 322290001Sglebiustry_ipv6pktinfo(void) { 323290001Sglebius int s, on; 324290001Sglebius char strbuf[ISC_STRERRORSIZE]; 325290001Sglebius isc_result_t result; 326290001Sglebius int optname; 327290001Sglebius 328290001Sglebius result = isc_net_probeipv6(); 329290001Sglebius if (result != ISC_R_SUCCESS) { 330290001Sglebius ipv6pktinfo_result = result; 331290001Sglebius return; 332290001Sglebius } 333290001Sglebius 334290001Sglebius /* we only use this for UDP sockets */ 335290001Sglebius s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); 336290001Sglebius if (s == -1) { 337290001Sglebius isc__strerror(errno, strbuf, sizeof(strbuf)); 338290001Sglebius UNEXPECTED_ERROR(__FILE__, __LINE__, 339290001Sglebius "socket() %s: %s", 340290001Sglebius isc_msgcat_get(isc_msgcat, 341290001Sglebius ISC_MSGSET_GENERAL, 342290001Sglebius ISC_MSG_FAILED, 343290001Sglebius "failed"), 344290001Sglebius strbuf); 345290001Sglebius ipv6pktinfo_result = ISC_R_UNEXPECTED; 346290001Sglebius return; 347290001Sglebius } 348290001Sglebius 349290001Sglebius#ifdef IPV6_RECVPKTINFO 350290001Sglebius optname = IPV6_RECVPKTINFO; 351290001Sglebius#else 352290001Sglebius optname = IPV6_PKTINFO; 353290001Sglebius#endif 354290001Sglebius on = 1; 355290001Sglebius if (setsockopt(s, IPPROTO_IPV6, optname, &on, sizeof(on)) < 0) { 356290001Sglebius ipv6pktinfo_result = ISC_R_NOTFOUND; 357290001Sglebius goto close; 358290001Sglebius } 359290001Sglebius 360290001Sglebius ipv6pktinfo_result = ISC_R_SUCCESS; 361290001Sglebius 362290001Sglebiusclose: 363290001Sglebius close(s); 364290001Sglebius return; 365290001Sglebius} 366290001Sglebius 367290001Sglebiusstatic void 368290001Sglebiusinitialize_ipv6pktinfo(void) { 369290001Sglebius RUNTIME_CHECK(isc_once_do(&once_ipv6pktinfo, 370290001Sglebius try_ipv6pktinfo) == ISC_R_SUCCESS); 371290001Sglebius} 372290001Sglebius#endif /* ISC_PLATFORM_HAVEIN6PKTINFO */ 373290001Sglebius#endif /* WANT_IPV6 */ 374290001Sglebius#endif /* ISC_PLATFORM_HAVEIPV6 */ 375290001Sglebius 376290001Sglebiusisc_result_t 377290001Sglebiusisc_net_probe_ipv6only(void) { 378290001Sglebius#ifdef ISC_PLATFORM_HAVEIPV6 379290001Sglebius#ifdef WANT_IPV6 380290001Sglebius initialize_ipv6only(); 381290001Sglebius#else 382290001Sglebius ipv6only_result = ISC_R_NOTFOUND; 383290001Sglebius#endif 384290001Sglebius#endif 385290001Sglebius return (ipv6only_result); 386290001Sglebius} 387290001Sglebius 388290001Sglebiusisc_result_t 389290001Sglebiusisc_net_probe_ipv6pktinfo(void) { 390290001Sglebius#ifdef ISC_PLATFORM_HAVEIPV6 391290001Sglebius#ifdef ISC_PLATFORM_HAVEIN6PKTINFO 392290001Sglebius#ifdef WANT_IPV6 393290001Sglebius initialize_ipv6pktinfo(); 394290001Sglebius#else 395290001Sglebius ipv6pktinfo_result = ISC_R_NOTFOUND; 396290001Sglebius#endif 397290001Sglebius#endif 398290001Sglebius#endif 399290001Sglebius return (ipv6pktinfo_result); 400290001Sglebius} 401290001Sglebius 402290001Sglebius#if defined(USE_SYSCTL_PORTRANGE) 403290001Sglebius#if defined(HAVE_SYSCTLBYNAME) 404290001Sglebiusstatic isc_result_t 405290001Sglebiusgetudpportrange_sysctl(int af, in_port_t *low, in_port_t *high) { 406290001Sglebius int port_low, port_high; 407290001Sglebius size_t portlen; 408290001Sglebius const char *sysctlname_lowport, *sysctlname_hiport; 409290001Sglebius 410290001Sglebius if (af == AF_INET) { 411290001Sglebius sysctlname_lowport = SYSCTL_V4PORTRANGE_LOW; 412290001Sglebius sysctlname_hiport = SYSCTL_V4PORTRANGE_HIGH; 413290001Sglebius } else { 414290001Sglebius sysctlname_lowport = SYSCTL_V6PORTRANGE_LOW; 415290001Sglebius sysctlname_hiport = SYSCTL_V6PORTRANGE_HIGH; 416290001Sglebius } 417290001Sglebius portlen = sizeof(portlen); 418290001Sglebius if (sysctlbyname(sysctlname_lowport, &port_low, &portlen, 419290001Sglebius NULL, 0) < 0) { 420290001Sglebius return (ISC_R_FAILURE); 421290001Sglebius } 422290001Sglebius portlen = sizeof(portlen); 423290001Sglebius if (sysctlbyname(sysctlname_hiport, &port_high, &portlen, 424290001Sglebius NULL, 0) < 0) { 425290001Sglebius return (ISC_R_FAILURE); 426290001Sglebius } 427290001Sglebius if ((port_low & ~0xffff) != 0 || (port_high & ~0xffff) != 0) 428290001Sglebius return (ISC_R_RANGE); 429290001Sglebius 430290001Sglebius *low = (in_port_t)port_low; 431290001Sglebius *high = (in_port_t)port_high; 432290001Sglebius 433290001Sglebius return (ISC_R_SUCCESS); 434290001Sglebius} 435290001Sglebius#else /* !HAVE_SYSCTLBYNAME */ 436290001Sglebiusstatic isc_result_t 437290001Sglebiusgetudpportrange_sysctl(int af, in_port_t *low, in_port_t *high) { 438290001Sglebius int mib_lo4[4] = SYSCTL_V4PORTRANGE_LOW; 439290001Sglebius int mib_hi4[4] = SYSCTL_V4PORTRANGE_HIGH; 440290001Sglebius int mib_lo6[4] = SYSCTL_V6PORTRANGE_LOW; 441290001Sglebius int mib_hi6[4] = SYSCTL_V6PORTRANGE_HIGH; 442290001Sglebius int *mib_lo, *mib_hi, miblen; 443290001Sglebius int port_low, port_high; 444290001Sglebius size_t portlen; 445290001Sglebius 446290001Sglebius if (af == AF_INET) { 447290001Sglebius mib_lo = mib_lo4; 448290001Sglebius mib_hi = mib_hi4; 449290001Sglebius miblen = sizeof(mib_lo4) / sizeof(mib_lo4[0]); 450290001Sglebius } else { 451290001Sglebius mib_lo = mib_lo6; 452290001Sglebius mib_hi = mib_hi6; 453290001Sglebius miblen = sizeof(mib_lo6) / sizeof(mib_lo6[0]); 454290001Sglebius } 455290001Sglebius 456290001Sglebius portlen = sizeof(portlen); 457290001Sglebius if (sysctl(mib_lo, miblen, &port_low, &portlen, NULL, 0) < 0) { 458290001Sglebius return (ISC_R_FAILURE); 459290001Sglebius } 460290001Sglebius 461290001Sglebius portlen = sizeof(portlen); 462290001Sglebius if (sysctl(mib_hi, miblen, &port_high, &portlen, NULL, 0) < 0) { 463290001Sglebius return (ISC_R_FAILURE); 464290001Sglebius } 465290001Sglebius 466290001Sglebius if ((port_low & ~0xffff) != 0 || (port_high & ~0xffff) != 0) 467290001Sglebius return (ISC_R_RANGE); 468290001Sglebius 469290001Sglebius *low = (in_port_t) port_low; 470290001Sglebius *high = (in_port_t) port_high; 471290001Sglebius 472290001Sglebius return (ISC_R_SUCCESS); 473290001Sglebius} 474290001Sglebius#endif /* HAVE_SYSCTLBYNAME */ 475290001Sglebius#endif /* USE_SYSCTL_PORTRANGE */ 476290001Sglebius 477290001Sglebiusisc_result_t 478290001Sglebiusisc_net_getudpportrange(int af, in_port_t *low, in_port_t *high) { 479290001Sglebius int result = ISC_R_FAILURE; 480290001Sglebius 481290001Sglebius REQUIRE(low != NULL && high != NULL); 482290001Sglebius 483290001Sglebius#if defined(USE_SYSCTL_PORTRANGE) 484290001Sglebius result = getudpportrange_sysctl(af, low, high); 485290001Sglebius#else 486290001Sglebius UNUSED(af); 487290001Sglebius#endif 488290001Sglebius 489290001Sglebius if (result != ISC_R_SUCCESS) { 490290001Sglebius *low = ISC_NET_PORTRANGELOW; 491290001Sglebius *high = ISC_NET_PORTRANGEHIGH; 492290001Sglebius } 493290001Sglebius 494290001Sglebius return (ISC_R_SUCCESS); /* we currently never fail in this function */ 495290001Sglebius} 496290001Sglebius 497290001Sglebiusvoid 498290001Sglebiusisc_net_disableipv4(void) { 499290001Sglebius initialize(); 500290001Sglebius if (ipv4_result == ISC_R_SUCCESS) 501290001Sglebius ipv4_result = ISC_R_DISABLED; 502290001Sglebius} 503290001Sglebius 504290001Sglebiusvoid 505290001Sglebiusisc_net_disableipv6(void) { 506290001Sglebius initialize(); 507290001Sglebius if (ipv6_result == ISC_R_SUCCESS) 508290001Sglebius ipv6_result = ISC_R_DISABLED; 509290001Sglebius} 510290001Sglebius 511290001Sglebiusvoid 512290001Sglebiusisc_net_enableipv4(void) { 513290001Sglebius initialize(); 514290001Sglebius if (ipv4_result == ISC_R_DISABLED) 515290001Sglebius ipv4_result = ISC_R_SUCCESS; 516290001Sglebius} 517290001Sglebius 518290001Sglebiusvoid 519290001Sglebiusisc_net_enableipv6(void) { 520290001Sglebius initialize(); 521290001Sglebius if (ipv6_result == ISC_R_DISABLED) 522290001Sglebius ipv6_result = ISC_R_SUCCESS; 523290001Sglebius} 524