summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Routhier <sar@isc.org>2011-06-27 16:00:32 +0000
committerShawn Routhier <sar@isc.org>2011-06-27 16:00:32 +0000
commit7cfeb9160de5c62e091429395c76ec7e28ac2f72 (patch)
tree5fec6f2bda301e11aad4f40306e2b2bcce86ded3
parentade10315e1b6cd8795da0e53e03d58ce41b91dfa (diff)
downloadisc-dhcp-7cfeb9160de5c62e091429395c76ec7e28ac2f72.tar.gz
In Solaris 11 switch to using sockets instead of DLPI, thanks
to a patch form Oracle. [ISC-Bugs #24634].
-rw-r--r--README21
-rw-r--r--RELNOTES3
-rw-r--r--common/discover.c41
-rw-r--r--common/socket.c291
-rw-r--r--configure.ac18
-rw-r--r--includes/config.h.in45
6 files changed, 375 insertions, 44 deletions
diff --git a/README b/README
index 2b131f01..e026956e 100644
--- a/README
+++ b/README
@@ -33,6 +33,8 @@ the ISC DHCP Distribution.
5.6 FreeBSD
5.7 NeXTSTEP
5.8 SOLARIS
+ 5.8.1 Solaris 11
+ 5.8.2 Other Solaris Items
5.9 AIX
5.10 MacOS X
6 SUPPORT
@@ -416,8 +418,8 @@ The first is that older Sun compilers generate an error on some of
our uses of the flexible array option. Newer versions only generate
a warning, which can be safely ignored. If you run into this error
("type of struct member "buf" can not be derived from structure with
-flexible array member"), upgrade your tools to Sun Studio 12 or
-something newer.
+flexible array member"), upgrade your tools to Oracle Solaris Studio
+(previously Sun Studio) 12 or something newer.
The second is the interaction between the configure script and the
makefiles for the Bind libraries. Currently we don't pass all
@@ -435,6 +437,21 @@ following commands:
CC=/opt/SUNWspro/bin/cc ./configure
CC=/opt/SUNWspro/bin/cc make
+ Solaris 11
+
+We have integrated a patch from Oracle to use sockets instead of
+DLPI on Solaris 11. This functionality was written for use with
+Solaris Studio 12.2 and requires the system/header package.
+
+By default this code is disabled in order to minimize disruptions
+for current users. In order to enable this code you will need to
+enable both USE_SOCKETS and USE_V4_PKTINFO as part of the
+configuration step. The command line would be something like:
+
+ ./configure --enable-use-sockets --enable-ipv4-pktinfo
+
+ Other Solaris Items
+
One problem which has been observed and is not fixed in this
patchlevel has to do with using DLPI on Solaris machines. The symptom
of this problem is that the DHCP server never receives any requests.
diff --git a/RELNOTES b/RELNOTES
index efda1dc9..92d4da8b 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -171,6 +171,9 @@ work on other platforms. Please report any problems and suggested fixes to
print routines to allow for greater than 60 characters or, when
printing as hex strings, 20 characters. [ISC-Bugs #22743]
+- In Solaris 11 switch to using sockets instead of DLPI, thanks
+ to a patch form Oracle. [ISC-Bugs #24634].
+
Changes since 4.2.0
- Documentation cleanup covering multiple tickets
diff --git a/common/discover.c b/common/discover.c
index 3cb8ec9e..07129e5d 100644
--- a/common/discover.c
+++ b/common/discover.c
@@ -309,12 +309,15 @@ int
next_iface(struct iface_info *info, int *err, struct iface_conf_list *ifaces) {
struct LIFREQ *p;
struct LIFREQ tmp;
+ isc_boolean_t foundif;
#if defined(sun) || defined(__linux)
/* Pointer used to remove interface aliases. */
char *s;
#endif
do {
+ foundif = ISC_FALSE;
+
if (ifaces->next >= ifaces->num) {
*err = 0;
return 0;
@@ -328,6 +331,13 @@ next_iface(struct iface_info *info, int *err, struct iface_conf_list *ifaces) {
log_error("Interface name '%s' too long", p->lifr_name);
return 0;
}
+
+ /* Reject if interface address family does not match */
+ if (p->lifr_addr.ss_family != local_family) {
+ ifaces->next++;
+ continue;
+ }
+
strcpy(info->name, p->lifr_name);
memset(&info->addr, 0, sizeof(info->addr));
memcpy(&info->addr, &p->lifr_addr, sizeof(p->lifr_addr));
@@ -340,7 +350,9 @@ next_iface(struct iface_info *info, int *err, struct iface_conf_list *ifaces) {
}
#endif /* defined(sun) || defined(__linux) */
- } while (strncmp(info->name, "dummy", 5) == 0);
+ foundif = ISC_TRUE;
+ } while ((foundif == ISC_FALSE) ||
+ (strncmp(info->name, "dummy", 5) == 0));
memset(&tmp, 0, sizeof(tmp));
strcpy(tmp.lifr_name, info->name);
@@ -958,7 +970,12 @@ discover_interfaces(int state) {
point-to-point in case an OS incorrectly marks them
as broadcast). Also skip down interfaces unless we're
trying to get a list of configurable interfaces. */
- if (((!(info.flags & IFF_BROADCAST) ||
+ if ((((local_family == AF_INET &&
+ !(info.flags & IFF_BROADCAST)) ||
+#ifdef DHCPv6
+ (local_family == AF_INET6 &&
+ !(info.flags & IFF_MULTICAST)) ||
+#endif
info.flags & IFF_LOOPBACK ||
info.flags & IFF_POINTOPOINT) && !tmp) ||
(!(info.flags & IFF_UP) &&
@@ -1394,6 +1411,25 @@ isc_result_t got_one (h)
if (result < DHCP_FIXED_NON_UDP - DHCP_SNAME_LEN - DHCP_FILE_LEN)
return ISC_R_UNEXPECTED;
+#if defined(IP_PKTINFO) && defined(IP_RECVPKTINFO) && defined(USE_V4_PKTINFO)
+ {
+ /* We retrieve the ifindex from the unused hfrom variable */
+ unsigned int ifindex;
+
+ memcpy(&ifindex, hfrom.hbuf, sizeof (ifindex));
+
+ /*
+ * Seek forward from the first interface to find the matching
+ * source interface by interface index.
+ */
+ ip = interfaces;
+ while ((ip != NULL) && (if_nametoindex(ip->name) != ifindex))
+ ip = ip->next;
+ if (ip == NULL)
+ return ISC_R_NOTFOUND;
+ }
+#endif
+
if (bootp_packet_handler) {
ifrom.len = 4;
memcpy (ifrom.iabuf, &from.sin_addr, ifrom.len);
@@ -1451,6 +1487,7 @@ got_one_v6(omapi_object_t *h) {
memcpy(ifrom.iabuf, &from.sin6_addr, ifrom.len);
/* Seek forward to find the matching source interface. */
+ ip = interfaces;
while ((ip != NULL) && (if_nametoindex(ip->name) != if_idx))
ip = ip->next;
diff --git a/common/socket.c b/common/socket.c
index 50ca746b..a48404b0 100644
--- a/common/socket.c
+++ b/common/socket.c
@@ -3,7 +3,7 @@
BSD socket interface code... */
/*
- * Copyright (c) 2004-2010 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2011 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1995-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -46,6 +46,13 @@
#include <sys/uio.h>
#include <sys/uio.h>
+#if defined(sun) && defined(USE_V4_PKTINFO)
+#include <sys/sysmacros.h>
+#include <net/if.h>
+#include <sys/sockio.h>
+#include <net/if_dl.h>
+#endif
+
#ifdef USE_SOCKET_FALLBACK
# if !defined (USE_SOCKET_SEND)
# define if_register_send if_register_fallback
@@ -66,6 +73,16 @@ static void if_register_multicast(struct interface_info *info);
#endif
/*
+ * We can use a single socket for AF_INET (similar to AF_INET6) on all
+ * interfaces configured for DHCP if the system has support for IP_PKTINFO
+ * and IP_RECVPKTINFO (for example Solaris 11).
+ */
+#if defined(IP_PKTINFO) && defined(IP_RECVPKTINFO) && defined(USE_V4_PKTINFO)
+static unsigned int global_v4_socket_references = 0;
+static int global_v4_socket = -1;
+#endif
+
+/*
* If we can't bind() to a specific interface, then we can only have
* a single socket. This variable insures that we don't try to listen
* on two sockets.
@@ -248,6 +265,20 @@ if_register_socket(struct interface_info *info, int family,
log_fatal("Can't set IP_BROADCAST_IF on dhcp socket: %m");
#endif
+#if defined(IP_PKTINFO) && defined(IP_RECVPKTINFO) && defined(USE_V4_PKTINFO)
+ /*
+ * If we turn on IP_RECVPKTINFO we will be able to receive
+ * the interface index information of the received packet.
+ */
+ if (family == AF_INET) {
+ int on = 1;
+ if (setsockopt(sock, IPPROTO_IP, IP_RECVPKTINFO,
+ &on, sizeof(on)) != 0) {
+ log_fatal("setsockopt: IPV_RECVPKTINFO: %m");
+ }
+ }
+#endif
+
#ifdef DHCPv6
/*
* If we turn on IPV6_PKTINFO, we will be able to receive
@@ -281,10 +312,6 @@ if_register_socket(struct interface_info *info, int family,
}
#endif /* DHCPv6 */
- /* If this is a normal IPv4 address, get the hardware address. */
- if ((local_family == AF_INET) && (strcmp(info->name, "fallback") != 0))
- get_hw_addr(info->name, &info->hw_address);
-
return sock;
}
#endif /* USE_SOCKET_SEND || USE_SOCKET_RECEIVE || USE_SOCKET_FALLBACK */
@@ -294,21 +321,24 @@ void if_register_send (info)
struct interface_info *info;
{
#ifndef USE_SOCKET_RECEIVE
- info -> wfdesc = if_register_socket (info, AF_INET, 0);
+ info->wfdesc = if_register_socket(info, AF_INET, 0);
+ /* If this is a normal IPv4 address, get the hardware address. */
+ if (strcmp(info->name, "fallback") != 0)
+ get_hw_addr(info->name, &info->hw_address);
#if defined (USE_SOCKET_FALLBACK)
/* Fallback only registers for send, but may need to receive as
well. */
- info -> rfdesc = info -> wfdesc;
+ info->rfdesc = info->wfdesc;
#endif
#else
- info -> wfdesc = info -> rfdesc;
+ info->wfdesc = info->rfdesc;
#endif
if (!quiet_interface_discovery)
log_info ("Sending on Socket/%s%s%s",
- info -> name,
- (info -> shared_network ? "/" : ""),
- (info -> shared_network ?
- info -> shared_network -> name : ""));
+ info->name,
+ (info->shared_network ? "/" : ""),
+ (info->shared_network ?
+ info->shared_network->name : ""));
}
#if defined (USE_SOCKET_SEND)
@@ -334,23 +364,61 @@ void if_deregister_send (info)
void if_register_receive (info)
struct interface_info *info;
{
+
+#if defined(IP_PKTINFO) && defined(IP_RECVPKTINFO) && defined(USE_V4_PKTINFO)
+ if (global_v4_socket_references == 0) {
+ global_v4_socket = if_register_socket(info, AF_INET, 0);
+ if (global_v4_socket < 0) {
+ /*
+ * if_register_socket() fatally logs if it fails to
+ * create a socket, this is just a sanity check.
+ */
+ log_fatal("Failed to create AF_INET socket %s:%d",
+ MDL);
+ }
+ }
+
+ info->rfdesc = global_v4_socket;
+ global_v4_socket_references++;
+#else
/* If we're using the socket API for sending and receiving,
we don't need to register this interface twice. */
- info -> rfdesc = if_register_socket (info, AF_INET, 0);
+ info->rfdesc = if_register_socket(info, AF_INET, 0);
+#endif /* IP_PKTINFO... */
+ /* If this is a normal IPv4 address, get the hardware address. */
+ if (strcmp(info->name, "fallback") != 0)
+ get_hw_addr(info->name, &info->hw_address);
+
if (!quiet_interface_discovery)
log_info ("Listening on Socket/%s%s%s",
- info -> name,
- (info -> shared_network ? "/" : ""),
- (info -> shared_network ?
- info -> shared_network -> name : ""));
+ info->name,
+ (info->shared_network ? "/" : ""),
+ (info->shared_network ?
+ info->shared_network->name : ""));
}
void if_deregister_receive (info)
struct interface_info *info;
{
- close (info -> rfdesc);
- info -> rfdesc = -1;
+#if defined(IP_PKTINFO) && defined(IP_RECVPKTINFO) && defined(USE_V4_PKTINFO)
+ /* Dereference the global v4 socket. */
+ if ((info->rfdesc == global_v4_socket) &&
+ (info->wfdesc == global_v4_socket) &&
+ (global_v4_socket_references > 0)) {
+ global_v4_socket_references--;
+ info->rfdesc = -1;
+ } else {
+ log_fatal("Impossible condition at %s:%d", MDL);
+ }
+ if (global_v4_socket_references == 0) {
+ close(global_v4_socket);
+ global_v4_socket = -1;
+ }
+#else
+ close(info->rfdesc);
+ info->rfdesc = -1;
+#endif /* IP_PKTINFO... */
if (!quiet_interface_discovery)
log_info ("Disabling input on Socket/%s%s%s",
info -> name,
@@ -495,6 +563,18 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
int retry = 0;
do {
#endif
+#if defined(IP_PKTINFO) && defined(IP_RECVPKTINFO) && defined(USE_V4_PKTINFO)
+ struct in_pktinfo pktinfo;
+
+ if (interface->ifp != NULL) {
+ memset(&pktinfo, 0, sizeof (pktinfo));
+ pktinfo.ipi_ifindex = interface->ifp->ifr_index;
+ if (setsockopt(interface->wfdesc, IPPROTO_IP,
+ IP_PKTINFO, (char *)&pktinfo,
+ sizeof(pktinfo)) < 0)
+ log_fatal("setsockopt: IP_PKTINFO: %m");
+ }
+#endif
result = sendto (interface -> wfdesc, (char *)raw, len, 0,
(struct sockaddr *)to, sizeof *to);
#ifdef IGNORE_HOSTUNREACH
@@ -565,11 +645,15 @@ static size_t CMSG_SPACE(size_t len) {
#endif /* DHCPv6 */
-#ifdef DHCPv6
+#if defined(DHCPv6) || \
+ (defined(IP_PKTINFO) && defined(IP_RECVPKTINFO) && \
+ defined(USE_V4_PKTINFO))
/*
* For both send_packet6() and receive_packet6() we need to allocate
* space for the cmsg header information. We do this once and reuse
- * the buffer.
+ * the buffer. We also need the control buf for send_packet() and
+ * receive_packet() when we use a single socket and IP_PKTINFO to
+ * send the packet out the correct interface.
*/
static void *control_buf = NULL;
static size_t control_buf_len = 0;
@@ -580,7 +664,9 @@ allocate_cmsg_cbuf(void) {
control_buf = dmalloc(control_buf_len, MDL);
return;
}
+#endif /* DHCPv6, IP_PKTINFO ... */
+#ifdef DHCPv6
/*
* For both send_packet6() and receive_packet6() we need to use the
* sendmsg()/recvmsg() functions rather than the simpler send()/recv()
@@ -679,7 +765,9 @@ ssize_t receive_packet (interface, buf, len, from, hfrom)
struct sockaddr_in *from;
struct hardware *hfrom;
{
+#if !defined(USE_V4_PKTINFO)
SOCKLEN_T flen = sizeof *from;
+#endif
int result;
/*
@@ -693,8 +781,99 @@ ssize_t receive_packet (interface, buf, len, from, hfrom)
int retry = 0;
do {
#endif
+
+#if defined(IP_PKTINFO) && defined(IP_RECVPKTINFO) && defined(USE_V4_PKTINFO)
+ struct msghdr m;
+ struct iovec v;
+ struct cmsghdr *cmsg;
+ struct in_pktinfo *pktinfo;
+ unsigned int ifindex;
+ int found_pktinfo;
+
+ /*
+ * If necessary allocate space for the control message header.
+ * The space is common between send and receive.
+ */
+ if (control_buf == NULL) {
+ allocate_cmsg_cbuf();
+ if (control_buf == NULL) {
+ log_error("receive_packet: unable to allocate cmsg "
+ "header");
+ return(ENOMEM);
+ }
+ }
+ memset(control_buf, 0, control_buf_len);
+
+ /*
+ * Initialize our message header structure.
+ */
+ memset(&m, 0, sizeof(m));
+
+ /*
+ * Point so we can get the from address.
+ */
+ m.msg_name = from;
+ m.msg_namelen = sizeof(*from);
+
+ /*
+ * Set the data buffer we're receiving. (Using this wacky
+ * "scatter-gather" stuff... but we that doesn't really make
+ * sense for us, so we use a single vector entry.)
+ */
+ v.iov_base = buf;
+ v.iov_len = len;
+ m.msg_iov = &v;
+ m.msg_iovlen = 1;
+
+ /*
+ * Getting the interface is a bit more involved.
+ *
+ * We set up some space for a "control message". We have
+ * previously asked the kernel to give us packet
+ * information (when we initialized the interface), so we
+ * should get the destination address from that.
+ */
+ m.msg_control = control_buf;
+ m.msg_controllen = control_buf_len;
+
+ result = recvmsg(interface->rfdesc, &m, 0);
+
+ if (result >= 0) {
+ /*
+ * If we did read successfully, then we need to loop
+ * through the control messages we received and
+ * find the one with our destination address.
+ *
+ * We also keep a flag to see if we found it. If we
+ * didn't, then we consider this to be an error.
+ */
+ found_pktinfo = 0;
+ cmsg = CMSG_FIRSTHDR(&m);
+ while (cmsg != NULL) {
+ if ((cmsg->cmsg_level == IPPROTO_IP) &&
+ (cmsg->cmsg_type == IP_PKTINFO)) {
+ pktinfo = (struct in_pktinfo *)CMSG_DATA(cmsg);
+ ifindex = pktinfo->ipi_ifindex;
+ /*
+ * We pass the ifindex back to the caller
+ * using the unused hfrom parameter avoiding
+ * interface changes between sockets and
+ * the discover code.
+ */
+ memcpy(hfrom->hbuf, &ifindex, sizeof(ifindex));
+ found_pktinfo = 1;
+ }
+ cmsg = CMSG_NXTHDR(&m, cmsg);
+ }
+ if (!found_pktinfo) {
+ result = -1;
+ errno = EIO;
+ }
+ }
+#else
result = recvfrom (interface -> rfdesc, (char *)buf, len, 0,
(struct sockaddr *)from, &flen);
+#endif /* IP_PKTINFO ... */
#ifdef IGNORE_HOSTUNREACH
} while (result < 0 &&
(errno == EHOSTUNREACH ||
@@ -848,10 +1027,12 @@ int can_receive_unicast_unconfigured (ip)
int supports_multiple_interfaces (ip)
struct interface_info *ip;
{
-#if defined (SO_BINDTODEVICE)
- return 1;
+#if defined(SO_BINDTODEVICE) || \
+ (defined(IP_PKTINFO) && defined(IP_RECVPKTINFO) && \
+ defined(USE_V4_PKTINFO))
+ return(1);
#else
- return 0;
+ return(0);
#endif
}
@@ -882,4 +1063,66 @@ void maybe_setup_fallback ()
}
#endif
}
+
+
+#if defined(sun) && defined(USE_V4_PKTINFO)
+/* This code assumes the existence of SIOCGLIFHWADDR */
+void
+get_hw_addr(const char *name, struct hardware *hw) {
+ struct sockaddr_dl *dladdrp;
+ int rv, sock, i;
+ struct lifreq lifr;
+
+ memset(&lifr, 0, sizeof (lifr));
+ (void) strlcpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
+ /*
+ * Check if the interface is a virtual or IPMP interface - in those
+ * cases it has no hw address, so generate a random one.
+ */
+ if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ||
+ ioctl(sock, SIOCGLIFFLAGS, &lifr) < 0) {
+ if (sock != -1)
+ (void) close(sock);
+
+#ifdef DHCPv6
+ /*
+ * If approrpriate try this with an IPv6 socket
+ */
+ if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) >= 0 &&
+ ioctl(sock, SIOCGLIFFLAGS, &lifr) >= 0) {
+ goto flag_check;
+ }
+ if (sock != -1)
+ (void) close(sock);
+#endif
+ log_fatal("Couldn't get interface flags for %s: %m", name);
+
+ }
+
+ flag_check:
+ if (lifr.lifr_flags & (IFF_VIRTUAL|IFF_IPMP)) {
+ hw->hlen = sizeof (hw->hbuf);
+ srandom((long)gethrtime());
+
+ for (i = 0; i < hw->hlen; ++i) {
+ hw->hbuf[i] = random() % 256;
+ }
+
+ if (sock != -1)
+ (void) close(sock);
+ return;
+ }
+
+ if (ioctl(sock, SIOCGLIFHWADDR, &lifr) < 0)
+ log_fatal("Couldn't get interface hardware address for %s: %m",
+ name);
+ dladdrp = (struct sockaddr_dl *)&lifr.lifr_addr;
+ hw->hlen = dladdrp->sdl_alen;
+ memcpy(hw->hbuf, LLADDR(dladdrp), hw->hlen);
+
+ if (sock != -1)
+ (void) close(sock);
+}
+#endif /* defined(sun) */
+
#endif /* USE_SOCKET_SEND */
diff --git a/configure.ac b/configure.ac
index 7b228834..823c3cf1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -143,6 +143,24 @@ if test "$enable_early_chroot" = "yes" ; then
[Define to any value to chroot() prior to loading config.])
fi
+AC_ARG_ENABLE(IPv4_PKTINFO,
+ AC_HELP_STRING([--enable-ipv4-pktinfo],
+ [enable use of pktinfo on IPv4 sockets (default is no)]))
+
+if test "$enable_ipv4_pktinfo" = "yes"; then
+ AC_DEFINE([USE_V4_PKTINFO], [1],
+ [Define to 1 to enable IPv4 packet info support.])
+fi
+
+AC_ARG_ENABLE(USE_SOCKETS,
+ AC_HELP_STRING([--enable-use-sockets],
+ [use the standard BSD socket API (default is no)]))
+
+if test "$enable_use_sockets" = "yes"; then
+ AC_DEFINE([USE_SOCKETS], [1],
+ [Define to 1 to use the standard BSD socket API.])
+fi
+
###
### Path fun. Older versions of DHCP were installed in /usr/sbin, so we
### need to look there and potentially overwrite by default (but not if
diff --git a/includes/config.h.in b/includes/config.h.in
index 0b00ea4c..b162ee85 100644
--- a/includes/config.h.in
+++ b/includes/config.h.in
@@ -133,19 +133,21 @@
/* Define to include server activity tracing support. */
#undef TRACING
+/* Define to 1 to use the standard BSD socket API. */
+#undef USE_SOCKETS
+
+/* Define to 1 to enable IPv4 packet info support. */
+#undef USE_V4_PKTINFO
+
/* Version number of package */
#undef VERSION
-/* Define to 1 if on AIX 3.
- System headers sometimes define this.
- We just want to avoid a redefinition error message. */
-#ifndef _ALL_SOURCE
-# undef _ALL_SOURCE
-#endif
-
-/* Enable GNU extensions on systems that have them. */
-#ifndef _GNU_SOURCE
-# undef _GNU_SOURCE
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel and VAX). */
+#if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+#elif ! defined __LITTLE_ENDIAN__
+# undef WORDS_BIGENDIAN
#endif
/* Define to 1 if on MINIX. */
@@ -189,30 +191,41 @@
#undef _POSIX_SOURCE
/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
- <pthread.h>, or <semaphore.h> is not used. If the typedef was allowed, the
+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
#undef _UINT32_T
/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
- <pthread.h>, or <semaphore.h> is not used. If the typedef was allowed, the
+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
#undef _UINT64_T
/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
- <pthread.h>, or <semaphore.h> is not used. If the typedef was allowed, the
+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
#undef _UINT8_T
-/* Enable extensions on Solaris. */
-#ifndef __EXTENSIONS__
-# undef __EXTENSIONS__
+/* Enable extensions on AIX 3, Interix. */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
#endif
+/* Enable threading extensions on Solaris. */
#ifndef _POSIX_PTHREAD_SEMANTICS
# undef _POSIX_PTHREAD_SEMANTICS
#endif
+/* Enable extensions on HP NonStop. */
#ifndef _TANDEM_SOURCE
# undef _TANDEM_SOURCE
#endif
+/* Enable general extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+
/* Define to the type of a signed integer type of width exactly 16 bits if
such a type exists and the standard includes do not define it. */