net.c revision 5fa46bc91672ef5737aee6f99763161511566c24
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley * Copyright (C) 2004, 2005, 2007, 2008, 2012 Internet Systems Consortium, Inc. ("ISC")
5c144477062a5df657acee41a82051d38537fd38Tinderbox User * Copyright (C) 1999-2003 Internet Software Consortium.
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * Permission to use, copy, modify, and/or distribute this software for any
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * purpose with or without fee is hereby granted, provided that the above
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * copyright notice and this permission notice appear in all copies.
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * PERFORMANCE OF THIS SOFTWARE.
af9dbf1ccdd53933aaae9300d13ce0965d39b067Evan Hunt * Definitions about UDP port range specification. This is a total mess of
af9dbf1ccdd53933aaae9300d13ce0965d39b067Evan Hunt * portability variants: some use sysctl (but the sysctl names vary), some use
af9dbf1ccdd53933aaae9300d13ce0965d39b067Evan Hunt * system-specific interfaces, some have the same interface for IPv4 and IPv6,
af9dbf1ccdd53933aaae9300d13ce0965d39b067Evan Hunt * some separate them, etc...
af9dbf1ccdd53933aaae9300d13ce0965d39b067Evan Hunt * The last resort defaults: use all non well known port space
18483fce5b9d1e02748bdcb916014cedea654f78Mark Andrews#endif /* ISC_NET_PORTRANGELOW */
18483fce5b9d1e02748bdcb916014cedea654f78Mark Andrews#endif /* ISC_NET_PORTRANGEHIGH */
0b72c791466d0807bcf22522b5ddb7da902c2720Bob Halley * sysctl variants
12e63bfe1d111ccb57f482b28d56c785cccc7cf7David Lawrence#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__DragonFly__)
12e63bfe1d111ccb57f482b28d56c785cccc7cf7David Lawrence#define SYSCTL_V4PORTRANGE_LOW "net.inet.ip.portrange.hifirst"
12e63bfe1d111ccb57f482b28d56c785cccc7cf7David Lawrence#define SYSCTL_V4PORTRANGE_HIGH "net.inet.ip.portrange.hilast"
dabea86dac4c01f852b7aea728f73b4f55a89d44Mark Andrews#define SYSCTL_V6PORTRANGE_LOW "net.inet.ip.portrange.hifirst"
dabea86dac4c01f852b7aea728f73b4f55a89d44Mark Andrews#define SYSCTL_V6PORTRANGE_HIGH "net.inet.ip.portrange.hilast"
2d46d268ccff30bb50e661b47c6496d23d9156c7Mark Andrews#define SYSCTL_V4PORTRANGE_LOW "net.inet.ip.anonportmin"
dabea86dac4c01f852b7aea728f73b4f55a89d44Mark Andrews#define SYSCTL_V4PORTRANGE_HIGH "net.inet.ip.anonportmax"
0b72c791466d0807bcf22522b5ddb7da902c2720Bob Halley#define SYSCTL_V6PORTRANGE_LOW "net.inet6.ip6.anonportmin"
18483fce5b9d1e02748bdcb916014cedea654f78Mark Andrews#define SYSCTL_V6PORTRANGE_HIGH "net.inet6.ip6.anonportmax"
460b427411b72da26b1836b9424e2e70d65d9394David Lawrence#else /* !HAVE_SYSCTLBYNAME */
460b427411b72da26b1836b9424e2e70d65d9394David Lawrence#define SYSCTL_V4PORTRANGE_LOW { CTL_NET, PF_INET, IPPROTO_IP, \
8319af16557b81eba3277ee67215285f0823b587Mark Andrews#define SYSCTL_V4PORTRANGE_HIGH { CTL_NET, PF_INET, IPPROTO_IP, \
aee5e9cbacd8f88325840b8a498876f4319b0890Mark Andrews/* Same for IPv6 */
18483fce5b9d1e02748bdcb916014cedea654f78Mark Andrews#define SYSCTL_V6PORTRANGE_LOW SYSCTL_V4PORTRANGE_LOW
9e5854255178c04170bc98839282d4cf3fae7443Mark Andrews#define SYSCTL_V6PORTRANGE_HIGH SYSCTL_V4PORTRANGE_HIGH
18483fce5b9d1e02748bdcb916014cedea654f78Mark Andrews#endif /* HAVE_SYSCTLBYNAME */
12e63bfe1d111ccb57f482b28d56c785cccc7cf7David Lawrenceconst struct in6_addr isc_net_in6addrany = IN6ADDR_ANY_INIT;
460b427411b72da26b1836b9424e2e70d65d9394David Lawrence# if defined(ISC_PLATFORM_NEEDIN6ADDRLOOPBACK)
c3e6fbe4b7471d843d015e3f1737b7edb9d0c547Mark Andrewsconst struct in6_addr isc_net_in6addrloop = IN6ADDR_LOOPBACK_INIT;
12e63bfe1d111ccb57f482b28d56c785cccc7cf7David Lawrencestatic isc_once_t once_ipv6only = ISC_ONCE_INIT;
6376f6189950156cc1488c86f22b19dd4feec11cMark Andrewsstatic isc_once_t once_ipv6pktinfo = ISC_ONCE_INIT;
5e47b4200ed81b8e18e165fe3a626d9992003db4Mark Andrews#endif /* ISC_PLATFORM_HAVEIPV6 */
2320f230995995595438a9d9301d84931fd266ceMark Andrewsstatic isc_result_t ipv4_result = ISC_R_NOTFOUND;
c427260a8678f2e99a2337fb95ec98d9c9ee8c05Mark Andrewsstatic isc_result_t ipv6_result = ISC_R_NOTFOUND;
620a452ebe92fff63e85c5930a6e6dc8d9455918Mark Andrewsstatic isc_result_t unix_result = ISC_R_NOTFOUND;
620a452ebe92fff63e85c5930a6e6dc8d9455918Mark Andrewsstatic isc_result_t ipv6only_result = ISC_R_NOTFOUND;
6dcb47e37f9f0cdb94bdabc3fa157ff07983c590Mark Andrewsstatic isc_result_t ipv6pktinfo_result = ISC_R_NOTFOUND;
693d70f96fc2b3c1830580edcc29146afd6a9f61Mark Andrews if (s == -1) {
18483fce5b9d1e02748bdcb916014cedea654f78Mark Andrews "socket() %s: %s",
0b72c791466d0807bcf22522b5ddb7da902c2720Bob Halley unsigned int len;
0b72c791466d0807bcf22522b5ddb7da902c2720Bob Halley * Check to see if IPv6 is broken, as is common on Linux.
0b72c791466d0807bcf22522b5ddb7da902c2720Bob Halley if (getsockname(s, (struct sockaddr *)&sin6, (void *)&len) < 0)
0b72c791466d0807bcf22522b5ddb7da902c2720Bob Halley "retrieving the address of an IPv6 "
0b72c791466d0807bcf22522b5ddb7da902c2720Bob Halley "socket from the kernel failed.");
af9dbf1ccdd53933aaae9300d13ce0965d39b067Evan Hunt "IPv6 is not supported.");
0b72c791466d0807bcf22522b5ddb7da902c2720Bob Halley "IPv6 structures in kernel and "
af9dbf1ccdd53933aaae9300d13ce0965d39b067Evan Hunt "user space do not match.");
af9dbf1ccdd53933aaae9300d13ce0965d39b067Evan Hunt "IPv6 is not supported.");
(void)close(s);
return (result);
initialize_action(void) {
#ifdef ISC_PLATFORM_HAVEIPV6
#ifdef WANT_IPV6
#ifdef ISC_PLATFORM_HAVEIN6PKTINFO
#ifdef ISC_PLATFORM_HAVESYSUNH
initialize(void) {
isc_net_probeipv4(void) {
initialize();
return (ipv4_result);
isc_net_probeipv6(void) {
initialize();
return (ipv6_result);
isc_net_probeunix(void) {
initialize();
return (unix_result);
#ifdef ISC_PLATFORM_HAVEIPV6
#ifdef WANT_IPV6
try_ipv6only(void) {
#ifdef IPV6_V6ONLY
int s, on;
#ifndef IPV6_V6ONLY
strbuf);
goto close;
close(s);
strbuf);
goto close;
close(s);
close(s);
initialize_ipv6only(void) {
#ifdef ISC_PLATFORM_HAVEIN6PKTINFO
try_ipv6pktinfo(void) {
int s, on;
int optname;
strbuf);
#ifdef IPV6_RECVPKTINFO
goto close;
close(s);
close(s);
initialize_ipv6pktinfo(void) {
isc_net_probe_ipv6only(void) {
#ifdef ISC_PLATFORM_HAVEIPV6
#ifdef WANT_IPV6
return (ipv6only_result);
isc_net_probe_ipv6pktinfo(void) {
#ifdef ISC_PLATFORM_HAVEIPV6
#ifdef ISC_PLATFORM_HAVEIN6PKTINFO
#ifdef WANT_IPV6
return (ipv6pktinfo_result);
#if defined(USE_SYSCTL_PORTRANGE)
#if defined(HAVE_SYSCTLBYNAME)
static isc_result_t
NULL, 0) < 0) {
return (ISC_R_FAILURE);
NULL, 0) < 0) {
return (ISC_R_FAILURE);
return (ISC_R_RANGE);
return (ISC_R_SUCCESS);
static isc_result_t
return (ISC_R_FAILURE);
return (ISC_R_FAILURE);
return (ISC_R_RANGE);
return (ISC_R_SUCCESS);
#if defined(USE_SYSCTL_PORTRANGE)
isc_net_disableipv4(void) {
initialize();
isc_net_disableipv6(void) {
initialize();
isc_net_enableipv4(void) {
initialize();
isc_net_enableipv6(void) {
initialize();