+* [Bug 1200] Enable IPv6 in Windows port
(4.2.5p179) 2009/05/23 Released by Harlan Stenn <stenn@ntp.org>
* [Bug 1041] xmt -> aorg timestamp cleanup from Dave Mills,
reported by Dave Hart.
isc_netaddr_t dstaddress; /* Destination address
(point-to-point only). */
isc_uint32_t flags; /* Flags; see below. */
- unsigned int ifindex; /* Interface Index */
- unsigned int scopeid; /* Scope id for Multicasting */
};
/* Interface flags. */
#define INTERFACE_F_UP 0x00000001U /* Interface is up */
-#define INTERFACE_F_POINTTOPOINT 0x00000002U /*this is point-to-point interface*/
+#define INTERFACE_F_POINTTOPOINT 0x00000002U /* this is point-to-point interface*/
#define INTERFACE_F_LOOPBACK 0x00000004U /* this is loopback interface */
#define INTERFACE_F_BROADCAST 0x00000008U /* Broadcast is supported */
#define INTERFACE_F_MULTICAST 0x00000010U /* multicast is supported */
struct sockaddr_storage bcast; /* broadcast address */
struct sockaddr_storage mask; /* interface mask */
char name[32]; /* name of interface */
- short family; /* Address family */
+ u_short family; /* Address family */
+ u_short phase; /* phase in update cycle */
int flags; /* interface flags */
int last_ttl; /* last TTL specified */
u_int32 addr_refid; /* IPv4 addr or IPv6 hash */
int num_mcast; /* No. of IP addresses in multicast socket */
- u_long starttime; /* current_time as of creation of interface structure */
+ u_long starttime; /* current_time as of creation of interface structure */
volatile long received; /* number of incoming packets */
long sent; /* number of outgoing packets */
long notsent; /* number of send failures */
u_int scopeid; /* Scope used for Multicasting */
- u_int ifindex; /* interface index */
- u_int ifnum; /* sequential interface instance count */
- u_char phase; /* phase in update cycle */
+ u_int ifnum; /* sequential interface instance count */
isc_boolean_t ignore_packets; /* Specify whether the packet should be ignored */
- ISC_LIST(struct peer) peers; /* list of peers for the interface */
- u_int peercnt; /* number of peers referencinf this interface - informational only */
- ISC_LINK(struct interface) link; /* interface list */
+ ISC_LIST(struct peer) peers; /* list of peers for the interface */
+ u_int peercnt; /* number of peers referencinf this interface - informational only */
+ ISC_LINK(struct interface) link;/* interface list */
};
/*
#define recv_srcadr X_from_where.X_recv_srcadr
#define recv_srcclock X_from_where.X_recv_srcclock
#define recv_peer X_from_where.X_recv_peer
-#if defined HAVE_IO_COMPLETION_PORT
- WSABUF wsabuff;
-#else
+#ifndef HAVE_IO_COMPLETION_PORT
struct sockaddr_storage srcadr; /* where packet came from */
+#else
+ int recv_srcadr_len; /* filled in on completion */
#endif
- int src_addr_len; /* source address length */
struct interface *dstadr; /* interface datagram arrived thru */
SOCKET fd; /* fd on which it was received */
int msg_flags; /* Flags received about the packet */
struct pkt X_recv_pkt;
u_char X_recv_buffer[RX_BUFF_SIZE];
} recv_space;
- int used;
#define recv_pkt recv_space.X_recv_pkt
#define recv_buffer recv_space.X_recv_buffer
+ int used; /* reference count */
};
extern void init_recvbuff (int);
initialise_buffer(recvbuf_t *buff)
{
memset((char *) buff, 0, sizeof(recvbuf_t));
-
-#if defined SYS_WINNT
- buff->wsabuff.len = RX_BUFF_SIZE;
- buff->wsabuff.buf = (char *) buff->recv_buffer;
-#endif
}
static void
#if defined(SYS_WINNT)
#include <transmitbuff.h>
#include <isc/win32os.h>
-/*
- * Define this macro to control the behavior of connection
- * resets on UDP sockets. See Microsoft KnowledgeBase Article Q263823
- * for details.
- * NOTE: This requires that Windows 2000 systems install Service Pack 2
- * or later.
- */
-#ifndef SIO_UDP_CONNRESET
-#define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
-#endif
-
/*
* Windows C runtime ioctl() can't deal properly with sockets,
* map to ioctlsocket for this source file.
netsyslog(LOG_ERR, "No useable winsock.dll: %m");
exit(1);
}
- init_transmitbuff();
#endif /* SYS_WINNT */
/*
printf("received = %ld\n", itf->received);
printf("sent = %ld\n", itf->sent);
printf("notsent = %ld\n", itf->notsent);
- printf("ifindex = %u\n", itf->ifindex);
printf("scopeid = %u\n", itf->scopeid);
printf("peercnt = %u\n", itf->peercnt);
printf("phase = %u\n", itf->phase);
static void
print_interface(struct interface *iface, char *pfx, char *sfx)
{
- printf("%sinterface #%d: fd=%d, bfd=%d, name=%s, flags=0x%x, scope=%d, ifindex=%d",
+ printf("%sinterface #%d: fd=%d, bfd=%d, name=%s, flags=0x%x, scope=%d",
pfx,
iface->ifnum,
iface->fd,
iface->bfd,
iface->name,
iface->flags,
- iface->scopeid,
- iface->ifindex);
- /* Leave these as three printf calls (stoa() static buffer). */
+ iface->scopeid);
printf(", sin=%s",
stoa((&iface->sin)));
if (iface->flags & INT_BROADCAST)
#endif
if(okipv4 == ISC_TRUE) {
- struct interface *interface = new_interface(NULL);
+ struct interface *interface = new_interface(NULL);
interface->family = AF_INET;
interface->sin.ss_family = AF_INET;
* create pseudo-interface with wildcard IPv6 address
*/
if (isc_net_probeipv6() == ISC_R_SUCCESS) {
- struct interface *interface = new_interface(NULL);
+ struct interface *interface = new_interface(NULL);
interface->family = AF_INET6;
interface->sin.ss_family = AF_INET6;
&(isc_if->netmask.type.in6),
sizeof(struct in6_addr));
((struct sockaddr_in6 *)&itf->mask)->sin6_port = port;
- /* Copy the interface index */
- itf->ifindex = isc_if->ifindex;
}
#endif /* INCLUDE_IPV6_SUPPORT */
ifs->sent = htonl(interface->sent);
ifs->notsent = htonl(interface->notsent);
ifs->scopeid = htonl(interface->scopeid);
- ifs->ifindex = htonl(interface->ifindex);
+ /* ifindex was always zero, now no longer in struct interface */
+ ifs->ifindex = 0;
ifs->ifnum = htonl(interface->ifnum);
ifs->uptime = htonl(current_time - interface->starttime);
ifs->ignore_packets = interface->ignore_packets;
/*
* Default values we use.
*/
+#ifndef SYS_WINNT
+#define DEFHOST "localhost" /* default host name */
+#else
+/* Using "localhost" with AF 0 gives a garbage response,
+ * force the IPv4 localhost numeric address works.
+ * Using 'ntpdc ::' also does not work on Windows yet.
+ */
+#define DEFHOST "127.0.0.1"
+#endif
#define DEFTIMEOUT (5) /* 5 second time out */
#define DEFSTIMEOUT (2) /* 2 second time out after first */
#define DEFDELAY 0x51EB852 /* 20 milliseconds, l_fp fraction */
-#define DEFHOST "localhost" /* default host name */
#define LENHOSTNAME 256 /* host name is 256 characters long */
#define MAXCMDS 100 /* maximum commands on cmd line */
#define MAXHOSTS 200 /* maximum hosts on cmd line */
(u_long)ntohl(ik->errcnt));
}
-#define IF_LIST_FMT "%2d %c %48s %c %c %12.12s %03x %3d %2d %5d %5d %5d %2d %2d %3d %7d\n"
-#define IF_LIST_FMT_STR "%2s %c %48s %c %c %12.12s %3s %3s %2s %5s %5s %5s %2s %2s %3s %7s\n"
+#define IF_LIST_FMT "%2d %c %48s %c %c %12.12s %03x %3d %2d %5d %5d %5d %2d %3d %7d\n"
+#define IF_LIST_FMT_STR "%2s %c %48s %c %c %12.12s %3s %3s %2s %5s %5s %5s %2s %3s %7s\n"
#define IF_LIST_AFMT_STR " %48s %c\n"
-#define IF_LIST_LABELS "#", 'A', "Address/Mask/Broadcast", 'T', 'E', "IF name", "Flg", "TL", "#M", "recv", "sent", "drop", "S", "IX", "PC", "uptime"
-#define IF_LIST_LINE "=====================================================================================================================\n"
+#define IF_LIST_LABELS "#", 'A', "Address/Mask/Broadcast", 'T', 'E', "IF name", "Flg", "TL", "#M", "recv", "sent", "drop", "S", "PC", "uptime"
+#define IF_LIST_LINE "==================================================================================================================\n"
static void
iflist(
ntohl(ifs->sent),
ntohl(ifs->notsent),
ntohl(ifs->scopeid),
- ntohl(ifs->ifindex),
ntohl(ifs->peercnt),
ntohl(ifs->uptime));
/*
* Default values we use.
*/
+#ifndef SYS_WINNT
+#define DEFHOST "localhost" /* default host name */
+#else
+/* Using "localhost" with AF 0 gives a garbage response,
+ * force the IPv4 localhost numeric address works.
+ * Using 'ntpq ::' also does not work on Windows yet.
+ */
+#define DEFHOST "127.0.0.1"
+#endif
#define DEFTIMEOUT (5) /* 5 second time out */
#define DEFSTIMEOUT (2) /* 2 second time out after first */
#define DEFDELAY 0x51EB852 /* 20 milliseconds, l_fp fraction */
-#define DEFHOST "localhost" /* default host name */
#define LENHOSTNAME 256 /* host name is 256 characters long */
#define MAXCMDS 100 /* maximum commands on cmd line */
#define MAXHOSTS 200 /* maximum hosts on cmd line */
}
#endif /* SYS_WINNT */
- /* Check to see if we have IPv6. Otherwise force the -4 flag */
- if (isc_net_probeipv6() != ISC_R_SUCCESS) {
+ /* Check to see if we have IPv6. Otherwise default to IPv4 */
+ if (isc_net_probeipv6() != ISC_R_SUCCESS)
ai_fam_default = AF_INET;
- }
progname = argv[0];
#endif
a_info = getaddrinfo(hname, service, &hints, &ai);
}
+#ifdef AI_ADDRCONFIG
/* Some older implementations don't like AI_ADDRCONFIG. */
if (a_info == EAI_BADFLAGS) {
hints.ai_flags = AI_CANONNAME;
a_info = getaddrinfo(hname, service, &hints, &ai);
}
+#endif
if (a_info != 0) {
(void) fprintf(stderr, "%s\n", gai_strerror(a_info));
return 0;
/* config.h for Windows NT */
-#ifndef __CONFIG_H
-#define __CONFIG_H
+#ifndef CONFIG_H
+#define CONFIG_H
/*
* For newer compilers we may we want newer prototypes from Windows
};
/*
- * IPv6 requirements
+ * ntp_rfc2553.h has cruft under #ifdef SYS_WINNT which is
+ * appropriate for older Microsoft IPv6 definitions, such
+ * as in_addr6 being the struct type. We can differentiate
+ * the RFC2553-compliant newer headers because they have
+ * #define in_addr6 in6_addr
+ * for backward compatibility. With the newer headers,
+ * we define ISC_PLATFORM_HAVEIPV6 and disable the cruft.
*/
-/*
- * For VS.NET most of the IPv6 types and structures are defined.
- * This should depend on the contrents of the available headers,
- * not on the compiler version.
- */
-#if defined _MSC_VER && _MSC_VER > 1200
-#define HAVE_STRUCT_SOCKADDR_STORAGE
+#ifdef in_addr6
+#define WANT_IPV6
#define ISC_PLATFORM_HAVEIPV6
+#define INCLUDE_IPV6_SUPPORT
+#define INCLUDE_IPV6_MULTICAST_SUPPORT
+#define ISC_PLATFORM_HAVESCOPEID
+#define HAVE_STRUCT_SOCKADDR_STORAGE
#define ISC_PLATFORM_HAVEIN6PKTINFO
#define NO_OPTION_NAME_WARNINGS
-#endif
+#endif /* in_addr6 / RFC2553-compliant IPv6 headers */
-#ifndef _W64
+#if !defined( _W64 )
+ /*
+ * if ULONG_PTR needs to be defined then the build environment
+ * is pure 32 bit Windows. Since ULONG_PTR and DWORD have
+ * the same size in 32 bit Windows we can safely define
+ * a replacement.
+ */
+typedef DWORD ULONG_PTR;
/* VC6 doesn't know about socklen_t, except if the SDK is installed */
typedef int socklen_t;
-#endif
+#endif /* _W64 */
#define ISC_PLATFORM_NEEDIN6ADDRANY
#define HAVE_SOCKADDR_IN6
#define SO_EXCLUSIVEADDRUSE ((int)(~SO_REUSEADDR))
#endif
+/*
+ * Define this macro to control the behavior of connection
+ * resets on UDP sockets. See Microsoft KnowledgeBase Article Q263823
+ * for details.
+ * Based on that article, it is surprising that a much newer winsock2.h
+ * does not define SIO_UDP_CONNRESET (the one that comes with VS 2008).
+ * NOTE: This requires that Windows 2000 systems install Service Pack 2
+ * or later.
+ */
+#ifndef SIO_UDP_CONNRESET
+#define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
+#endif
+
#if defined _MSC_VER && _MSC_VER < 1400
/*
* Use 32-bit time definitions for versions prior to VS 2005
*/
#include <isc/stat.h>
-#endif /* __CONFIG_H */
+#endif /* CONFIG_H */
-#if !defined __transmitbuff_h
-#define __transmitbuff_h
+#ifndef TRANSMITBUFF_H
+#define TRANSMITBUFF_H
#include "ntp.h"
-#if defined HAVE_IO_COMPLETION_PORT
-# include "ntp_iocompletionport.h"
-#endif
#include <isc/list.h>
/*
typedef struct transmitbuf {
ISC_LINK(transmitbuf_t) link;
- WSABUF wsabuf;
time_t ts; /* Time stamp for the request */
/*
*/
extern transmitbuf_t *get_free_transmit_buffer (void);
-#endif /* defined __transmitbuff_h */
+#endif /* TRANSMITBUFF_H */
#include <fcntl.h>
-#define NCCS 4
+#define NCCS 18 /* refclock_arc.c uses VTIME (17) */
#define VEOL 3
typedef unsigned char cc_t;
typedef unsigned int speed_t;
#define TCSANOW 0
#define TCSADRAIN 1
#define TCSAFLUSH 2
+#define VMIN 16
+#define VTIME 17
/* modem lines */
#define TIOCM_LE 0x001
/*
+ * Copyright (C) 2004, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
- * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
- * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
- * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: interfaceiter.c,v 1.7 2001/11/27 01:56:21 gson Exp $ */
-
-/*
- * Note that this code will need to be revisited to support IPv6 Interfaces.
- * For now we just iterate through IPv4 interfaces.
- */
+/* $Id: interfaceiter.c,v 1.13.110.2 2009/01/18 23:47:41 tbox Exp $ */
#include <config.h>
#include <winsock2.h>
#include <isc/types.h>
#include <isc/util.h>
+void InitSockets(void);
+
/* Common utility functions */
/*
* Extract the network address part from a "struct sockaddr".
*
- * The address family is given explicity
+ * The address family is given explicitly
* instead of using src->sa_family, because the latter does not work
* for copying a network mask obtained by SIOCGIFNETMASK (it does
* not have a valid address family).
int socket;
INTERFACE_INFO IFData; /* Current Interface Info */
int numIF; /* Current Interface count */
- int totalIF; /* Total Number
- of Interfaces */
- INTERFACE_INFO *buf; /* Buffer for WSAIoctl data. */
- unsigned int bufsize; /* Bytes allocated. */
- INTERFACE_INFO *pos; /* Current offset in IF List */
+ int v4IF; /* Number of IPv4 Interfaces */
+ INTERFACE_INFO *buf4; /* Buffer for WSAIoctl data. */
+ unsigned int buf4size; /* Bytes allocated. */
+ INTERFACE_INFO *pos4; /* Current offset in IF List */
+ SOCKET_ADDRESS_LIST *buf6;
+ unsigned int buf6size; /* Bytes allocated. */
+ unsigned int pos6;
isc_interface_t current; /* Current interface data. */
isc_result_t result; /* Last result code. */
};
memcpy(&dst->type.in6,
&((struct sockaddr_in6 *) src)->sin6_addr,
sizeof(struct in6_addr));
+ dst->zone = ((struct sockaddr_in6 *) src)->sin6_scope_id;
break;
default:
INSIST(0);
isc_result_t
isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) {
- char strbuf[ISC_STRERRORSIZE];
+ char strbuf[ISC_STRERRORSIZE];
isc_interfaceiter_t *iter;
isc_result_t result;
int error;
if (iter == NULL)
return (ISC_R_NOMEMORY);
+ InitSockets();
+
iter->mctx = mctx;
- iter->buf = NULL;
+ iter->buf4 = NULL;
+ iter->buf6 = NULL;
+ iter->pos4 = NULL;
+ iter->pos6 = 0;
+ iter->buf6size = 0;
+ iter->buf4size = 0;
+ iter->result = ISC_R_FAILURE;
+ iter->numIF = 0;
+ iter->v4IF = 0;
/*
* Create an unbound datagram socket to do the
*/
if ((iter->socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
error = WSAGetLastError();
+ if (error == WSAEAFNOSUPPORT)
+ goto inet6_only;
isc__strerror(error, strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__,
"making interface scan socket: %s",
* Get the interface configuration, allocating more memory if
* necessary.
*/
- iter->bufsize = IFCONF_SIZE_INITIAL*sizeof(INTERFACE_INFO);
+ iter->buf4size = IFCONF_SIZE_INITIAL*sizeof(INTERFACE_INFO);
for (;;) {
- iter->buf = isc_mem_get(mctx, iter->bufsize);
- if (iter->buf == NULL) {
+ iter->buf4 = isc_mem_get(mctx, iter->buf4size);
+ if (iter->buf4 == NULL) {
result = ISC_R_NOMEMORY;
goto alloc_failure;
}
if (WSAIoctl(iter->socket, SIO_GET_INTERFACE_LIST,
- 0, 0, iter->buf, iter->bufsize,
+ 0, 0, iter->buf4, iter->buf4size,
&bytesReturned, 0, 0) == SOCKET_ERROR)
{
error = WSAGetLastError();
* case and retry.
*/
if (bytesReturned > 0 &&
- (bytesReturned < iter->bufsize))
+ (bytesReturned < iter->buf4size))
break;
}
- if (iter->bufsize >= IFCONF_SIZE_MAX*sizeof(INTERFACE_INFO)) {
+ if (iter->buf4size >= IFCONF_SIZE_MAX*sizeof(INTERFACE_INFO)) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"get interface configuration: "
"maximum buffer size exceeded");
result = ISC_R_UNEXPECTED;
goto ioctl_failure;
}
- isc_mem_put(mctx, iter->buf, iter->bufsize);
+ isc_mem_put(mctx, iter->buf4, iter->buf4size);
- iter->bufsize += IFCONF_SIZE_INCREMENT *
+ iter->buf4size += IFCONF_SIZE_INCREMENT *
sizeof(INTERFACE_INFO);
}
* A newly created iterator has an undefined position
* until isc_interfaceiter_first() is called.
*/
- iter->pos = NULL;
- iter->result = ISC_R_FAILURE;
- iter->numIF = 0;
- iter->totalIF = bytesReturned/sizeof(INTERFACE_INFO);
+ iter->v4IF = bytesReturned/sizeof(INTERFACE_INFO);
+ /* We don't need the socket any more, so close it */
+ closesocket(iter->socket);
+ inet6_only:
+ /*
+ * Create an unbound datagram socket to do the
+ * SIO_ADDRESS_LIST_QUERY WSAIoctl on.
+ */
+ if ((iter->socket = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
+ error = WSAGetLastError();
+ if (error == WSAEAFNOSUPPORT)
+ goto inet_only;
+ isc__strerror(error, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "making interface scan socket: %s",
+ strbuf);
+ result = ISC_R_UNEXPECTED;
+ goto ioctl_failure;
+ }
+
+ /*
+ * Get the interface configuration, allocating more memory if
+ * necessary.
+ */
+ iter->buf6size = sizeof(SOCKET_ADDRESS_LIST) +
+ IFCONF_SIZE_INITIAL*sizeof(SOCKET_ADDRESS);
+
+ for (;;) {
+ iter->buf6 = isc_mem_get(mctx, iter->buf6size);
+ if (iter->buf6 == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto ioctl_failure;
+ }
+
+ if (WSAIoctl(iter->socket, SIO_ADDRESS_LIST_QUERY,
+ 0, 0, iter->buf6, iter->buf6size,
+ &bytesReturned, 0, 0) == SOCKET_ERROR)
+ {
+ error = WSAGetLastError();
+ if (error != WSAEFAULT && error != WSAENOBUFS) {
+ errno = error;
+ isc__strerror(error, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "sio address list query: %s",
+ strbuf);
+ result = ISC_R_UNEXPECTED;
+ goto ioctl6_failure;
+ }
+ /*
+ * EINVAL. Retry with a bigger buffer.
+ */
+ } else
+ break;
+
+ if (iter->buf6size >= IFCONF_SIZE_MAX*sizeof(SOCKET_ADDRESS)) {
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "get interface configuration: "
+ "maximum buffer size exceeded");
+ result = ISC_R_UNEXPECTED;
+ goto ioctl6_failure;
+ }
+ isc_mem_put(mctx, iter->buf6, iter->buf6size);
+
+ iter->buf6size += IFCONF_SIZE_INCREMENT *
+ sizeof(SOCKET_ADDRESS);
+ }
+
+ closesocket(iter->socket);
+
+ inet_only:
iter->magic = IFITER_MAGIC;
*iterp = iter;
- /* We don't need the socket any more, so close it */
- closesocket(iter->socket);
return (ISC_R_SUCCESS);
+ ioctl6_failure:
+ isc_mem_put(mctx, iter->buf6, iter->buf6size);
+
ioctl_failure:
- isc_mem_put(mctx, iter->buf, iter->bufsize);
+ if (iter->buf4 != NULL)
+ isc_mem_put(mctx, iter->buf4, iter->buf4size);
alloc_failure:
- (void) closesocket(iter->socket);
+ if (iter->socket >= 0)
+ (void) closesocket(iter->socket);
socket_failure:
isc_mem_put(mctx, iter, sizeof(*iter));
*/
static isc_result_t
-internal_current(isc_interfaceiter_t *iter, int family) {
+internal_current(isc_interfaceiter_t *iter) {
BOOL ifNamed = FALSE;
unsigned long flags;
REQUIRE(iter->numIF >= 0);
memset(&iter->current, 0, sizeof(iter->current));
- iter->current.af = family;
+ iter->current.af = AF_INET;
- get_addr(family, &iter->current.address,
+ get_addr(AF_INET, &iter->current.address,
(struct sockaddr *)&(iter->IFData.iiAddress));
- /* XXXPDM This will need to be revisited */
- iter->current.ifindex = 0; /* Set to zero for now */
- iter->current.scopeid = 0; /* Set to zero for now */
-
-
/*
* Get interface flags.
*/
if ((flags & IFF_UP) != 0)
iter->current.flags |= INTERFACE_F_UP;
+ if ((flags & IFF_BROADCAST) != 0) {
+ iter->current.flags |= INTERFACE_F_BROADCAST;
+ }
+
+ if ((flags & IFF_MULTICAST) != 0) {
+ iter->current.flags |= INTERFACE_F_MULTICAST;
+ }
+
if ((flags & IFF_POINTTOPOINT) != 0) {
iter->current.flags |= INTERFACE_F_POINTTOPOINT;
sprintf(iter->current.name, "PPP Interface %d", iter->numIF);
ifNamed = TRUE;
}
- if ((flags & IFF_BROADCAST) != 0) {
- iter->current.flags |= INTERFACE_F_BROADCAST;
- }
-
- if ((flags & IFF_MULTICAST) != 0) {
- iter->current.flags |= INTERFACE_F_MULTICAST;
- }
-
- /*
- * Get the network mask.
- */
- switch (family) {
- case AF_INET:
- get_addr(family, &iter->current.netmask,
- (struct sockaddr *)&(iter->IFData.iiNetmask));
- break;
- case AF_INET6:
- break;
- }
-
/*
* If the interface is point-to-point, get the destination address.
*/
if ((iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0) {
- get_addr(family, &iter->current.dstaddress,
+ get_addr(AF_INET, &iter->current.dstaddress,
(struct sockaddr *)&(iter->IFData.iiBroadcastAddress));
}
+
/*
* If the interface is broadcast, get the broadcast address.
*/
if ((iter->current.flags & INTERFACE_F_BROADCAST) != 0) {
- get_addr(family, &iter->current.broadcast,
+ get_addr(AF_INET, &iter->current.broadcast,
(struct sockaddr *)&(iter->IFData.iiBroadcastAddress));
get_broadcastaddr(&iter->current.broadcast, &iter->current.address,
&iter->current.netmask);
if (ifNamed == FALSE)
sprintf(iter->current.name,
- "IP Interface %d", iter->numIF);
+ "TCP/IP Interface %d", iter->numIF);
+
+ /*
+ * Get the network mask.
+ */
+ get_addr(AF_INET, &iter->current.netmask,
+ (struct sockaddr *)&(iter->IFData.iiNetmask));
return (ISC_R_SUCCESS);
}
+static isc_result_t
+internal_current6(isc_interfaceiter_t *iter) {
+ BOOL ifNamed = FALSE;
+ int i;
+
+ REQUIRE(VALID_IFITER(iter));
+ REQUIRE(iter->pos6 >= 0);
+ REQUIRE(iter->buf6 != 0);
+
+ memset(&iter->current, 0, sizeof(iter->current));
+ iter->current.af = AF_INET6;
+
+ get_addr(AF_INET6, &iter->current.address,
+ iter->buf6->Address[iter->pos6].lpSockaddr);
+
+ /*
+ * Get interface flags.
+ */
+
+ iter->current.flags = INTERFACE_F_UP | INTERFACE_F_MULTICAST;
+
+ if (ifNamed == FALSE)
+ sprintf(iter->current.name,
+ "TCP/IPv6 Interface %d", iter->pos6 + 1);
+
+ for (i = 0; i< 16; i++)
+ iter->current.netmask.type.in6.s6_addr[i] = 0xff;
+ iter->current.netmask.family = AF_INET6;
+ return (ISC_R_SUCCESS);
+}
+
/*
* Step the iterator to the next interface. Unlike
* isc_interfaceiter_next(), this may leave the iterator
*/
static isc_result_t
internal_next(isc_interfaceiter_t *iter) {
- if (iter->numIF >= iter->totalIF)
+ if (iter->numIF >= iter->v4IF)
return (ISC_R_NOMORE);
/*
* Microsoft's implementation is peculiar for returning
* the list in reverse order
*/
-
+
if (iter->numIF == 0)
- iter->pos = (INTERFACE_INFO *)(iter->buf + (iter->totalIF));
+ iter->pos4 = (INTERFACE_INFO *)(iter->buf4 + (iter->v4IF));
- iter->pos--;
- if (&(iter->pos) < &(iter->buf))
+ iter->pos4--;
+ if (&(iter->pos4) < &(iter->buf4))
return (ISC_R_NOMORE);
memset(&(iter->IFData), 0, sizeof(INTERFACE_INFO));
- memcpy(&(iter->IFData), iter->pos, sizeof(INTERFACE_INFO));
+ memcpy(&(iter->IFData), iter->pos4, sizeof(INTERFACE_INFO));
iter->numIF++;
return (ISC_R_SUCCESS);
}
+static isc_result_t
+internal_next6(isc_interfaceiter_t *iter) {
+ if (iter->pos6 == 0)
+ return (ISC_R_NOMORE);
+ iter->pos6--;
+ return (ISC_R_SUCCESS);
+}
+
isc_result_t
isc_interfaceiter_current(isc_interfaceiter_t *iter,
isc_interface_t *ifdata) {
isc_result_t
isc_interfaceiter_first(isc_interfaceiter_t *iter) {
- isc_result_t result;
REQUIRE(VALID_IFITER(iter));
- iter->numIF = 0;
- for (;;) {
- result = internal_next(iter);
- if (result != ISC_R_SUCCESS)
- break;
- result = internal_current(iter, AF_INET);
- if (result != ISC_R_IGNORE)
- break;
- }
- iter->result = result;
- return (result);
+ if (iter->buf6 != NULL)
+ iter->pos6 = iter->buf6->iAddressCount;
+ iter->result = ISC_R_SUCCESS;
+ return (isc_interfaceiter_next(iter));
}
isc_result_t
for (;;) {
result = internal_next(iter);
- if (result != ISC_R_SUCCESS)
+ if (result == ISC_R_NOMORE) {
+ result = internal_next6(iter);
+ if (result != ISC_R_SUCCESS)
+ break;
+ result = internal_current6(iter);
+ if (result != ISC_R_IGNORE)
+ break;
+ } else if (result != ISC_R_SUCCESS)
break;
- result = internal_current(iter,AF_INET);
+ result = internal_current(iter);
if (result != ISC_R_IGNORE)
break;
}
iter = *iterp;
REQUIRE(VALID_IFITER(iter));
- isc_mem_put(iter->mctx, iter->buf, iter->bufsize);
+ if (iter->buf4 != NULL)
+ isc_mem_put(iter->mctx, iter->buf4, iter->buf4size);
+ if (iter->buf6 != NULL)
+ isc_mem_put(iter->mctx, iter->buf6, iter->buf6size);
iter->magic = 0;
isc_mem_put(iter->mctx, iter, sizeof(*iter));
*iterp = NULL;
}
-
#ifdef ISC_PLATFORM_HAVEIPV6
#ifdef WANT_IPV6
#ifdef ISC_PLATFORM_HAVEIN6PKTINFO
+#ifndef SYS_WINNT /* code below fails, needs bind() before getsockname() */
if (domain == PF_INET6) {
struct sockaddr_in6 sin6;
unsigned int len;
}
#endif
#endif
+#endif
#endif
closesocket(s);
if (s == INVALID_SOCKET) {
isc__strerror(errno, strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__,
- "socket() %s: %s",
- isc_msgcat_get(isc_msgcat,
- ISC_MSGSET_GENERAL,
- ISC_MSG_FAILED,
- "failed"),
+ "socket() failed: %s",
strbuf);
ipv6only_result = ISC_R_UNEXPECTED;
return;
}
on = 1;
- if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) {
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&on, sizeof(on)) < 0) {
ipv6only_result = ISC_R_NOTFOUND;
goto close;
}
if (s == INVALID_SOCKET) {
isc__strerror(errno, strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__,
- "socket() %s: %s",
- isc_msgcat_get(isc_msgcat,
- ISC_MSGSET_GENERAL,
- ISC_MSG_FAILED,
- "failed"),
+ "socket() failed: %s",
strbuf);
ipv6only_result = ISC_R_UNEXPECTED;
return;
}
on = 1;
- if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) {
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&on, sizeof(on)) < 0) {
ipv6only_result = ISC_R_NOTFOUND;
goto close;
}
if (s == -1) {
isc__strerror(errno, strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__,
- "socket() %s: %s",
- isc_msgcat_get(isc_msgcat,
- ISC_MSGSET_GENERAL,
- ISC_MSG_FAILED,
- "failed"),
+ "socket() failed: %s",
strbuf);
ipv6pktinfo_result = ISC_R_UNEXPECTED;
return;
optname = IPV6_PKTINFO;
#endif
on = 1;
- if (setsockopt(s, IPPROTO_IPV6, optname, &on, sizeof(on)) < 0) {
+ if (setsockopt(s, IPPROTO_IPV6, optname, (char *)&on, sizeof(on)) < 0) {
ipv6pktinfo_result = ISC_R_NOTFOUND;
goto close;
}
/*
+ * Copyright (C) 2004, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
- * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
- * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
- * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: interfaceiter.c,v 1.7 2001/11/27 01:56:21 gson Exp $ */
+/* $Id: interfaceiter.c,v 1.13.110.2 2009/01/18 23:47:41 tbox Exp $ */
/*
* Note that this code will need to be revisited to support IPv6 Interfaces.
#include <isc/types.h>
#include <isc/util.h>
+void InitSockets(void);
+
/* Common utility functions */
/*
* Extract the network address part from a "struct sockaddr".
*
- * The address family is given explicity
+ * The address family is given explicitly
* instead of using src->sa_family, because the latter does not work
* for copying a network mask obtained by SIOCGIFNETMASK (it does
* not have a valid address family).
int socket;
INTERFACE_INFO IFData; /* Current Interface Info */
int numIF; /* Current Interface count */
- int totalIF; /* Total Number
- of Interfaces */
- INTERFACE_INFO *buf; /* Buffer for WSAIoctl data. */
- unsigned int bufsize; /* Bytes allocated. */
- INTERFACE_INFO *pos; /* Current offset in IF List */
+ int v4IF; /* Number of IPv4 Interfaces */
+ INTERFACE_INFO *buf4; /* Buffer for WSAIoctl data. */
+ unsigned int buf4size; /* Bytes allocated. */
+ INTERFACE_INFO *pos4; /* Current offset in IF List */
+ SOCKET_ADDRESS_LIST *buf6;
+ unsigned int buf6size; /* Bytes allocated. */
+ unsigned int pos6;
isc_interface_t current; /* Current interface data. */
isc_result_t result; /* Last result code. */
};
memcpy(&dst->type.in6,
&((struct sockaddr_in6 *) src)->sin6_addr,
sizeof(struct in6_addr));
+ dst->zone = ((struct sockaddr_in6 *) src)->sin6_scope_id;
break;
default:
INSIST(0);
isc_result_t
isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) {
- char strbuf[ISC_STRERRORSIZE];
+ char strbuf[ISC_STRERRORSIZE];
isc_interfaceiter_t *iter;
isc_result_t result;
int error;
if (iter == NULL)
return (ISC_R_NOMEMORY);
+ InitSockets();
+
iter->mctx = mctx;
- iter->buf = NULL;
+ iter->buf4 = NULL;
+ iter->buf6 = NULL;
+ iter->pos4 = NULL;
+ iter->pos6 = 0;
+ iter->buf6size = 0;
+ iter->buf4size = 0;
+ iter->result = ISC_R_FAILURE;
+ iter->numIF = 0;
+ iter->v4IF = 0;
/*
* Create an unbound datagram socket to do the
*/
if ((iter->socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
error = WSAGetLastError();
+ if (error == WSAEAFNOSUPPORT)
+ goto inet6_only;
isc__strerror(error, strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__,
"making interface scan socket: %s",
* Get the interface configuration, allocating more memory if
* necessary.
*/
- iter->bufsize = IFCONF_SIZE_INITIAL*sizeof(INTERFACE_INFO);
+ iter->buf4size = IFCONF_SIZE_INITIAL*sizeof(INTERFACE_INFO);
for (;;) {
- iter->buf = isc_mem_get(mctx, iter->bufsize);
- if (iter->buf == NULL) {
+ iter->buf4 = isc_mem_get(mctx, iter->buf4size);
+ if (iter->buf4 == NULL) {
result = ISC_R_NOMEMORY;
goto alloc_failure;
}
if (WSAIoctl(iter->socket, SIO_GET_INTERFACE_LIST,
- 0, 0, iter->buf, iter->bufsize,
+ 0, 0, iter->buf4, iter->buf4size,
&bytesReturned, 0, 0) == SOCKET_ERROR)
{
error = WSAGetLastError();
* case and retry.
*/
if (bytesReturned > 0 &&
- (bytesReturned < iter->bufsize))
+ (bytesReturned < iter->buf4size))
break;
}
- if (iter->bufsize >= IFCONF_SIZE_MAX*sizeof(INTERFACE_INFO)) {
+ if (iter->buf4size >= IFCONF_SIZE_MAX*sizeof(INTERFACE_INFO)) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"get interface configuration: "
"maximum buffer size exceeded");
result = ISC_R_UNEXPECTED;
goto ioctl_failure;
}
- isc_mem_put(mctx, iter->buf, iter->bufsize);
+ isc_mem_put(mctx, iter->buf4, iter->buf4size);
- iter->bufsize += IFCONF_SIZE_INCREMENT *
+ iter->buf4size += IFCONF_SIZE_INCREMENT *
sizeof(INTERFACE_INFO);
}
* A newly created iterator has an undefined position
* until isc_interfaceiter_first() is called.
*/
- iter->pos = NULL;
- iter->result = ISC_R_FAILURE;
- iter->numIF = 0;
- iter->totalIF = bytesReturned/sizeof(INTERFACE_INFO);
+ iter->v4IF = bytesReturned/sizeof(INTERFACE_INFO);
+
+ /* We don't need the socket any more, so close it */
+ closesocket(iter->socket);
+
+ inet6_only:
+ /*
+ * Create an unbound datagram socket to do the
+ * SIO_ADDRESS_LIST_QUERY WSAIoctl on.
+ */
+ if ((iter->socket = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
+ error = WSAGetLastError();
+ if (error == WSAEAFNOSUPPORT)
+ goto inet_only;
+ isc__strerror(error, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "making interface scan socket: %s",
+ strbuf);
+ result = ISC_R_UNEXPECTED;
+ goto ioctl_failure;
+ }
+
+ /*
+ * Get the interface configuration, allocating more memory if
+ * necessary.
+ */
+ iter->buf6size = sizeof(SOCKET_ADDRESS_LIST) +
+ IFCONF_SIZE_INITIAL*sizeof(SOCKET_ADDRESS);
+ for (;;) {
+ iter->buf6 = isc_mem_get(mctx, iter->buf6size);
+ if (iter->buf6 == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto ioctl_failure;
+ }
+ if (WSAIoctl(iter->socket, SIO_ADDRESS_LIST_QUERY,
+ 0, 0, iter->buf6, iter->buf6size,
+ &bytesReturned, 0, 0) == SOCKET_ERROR)
+ {
+ error = WSAGetLastError();
+ if (error != WSAEFAULT && error != WSAENOBUFS) {
+ errno = error;
+ isc__strerror(error, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "sio address list query: %s",
+ strbuf);
+ result = ISC_R_UNEXPECTED;
+ goto ioctl6_failure;
+ }
+ /*
+ * EINVAL. Retry with a bigger buffer.
+ */
+ } else
+ break;
+
+ if (iter->buf6size >= IFCONF_SIZE_MAX*sizeof(SOCKET_ADDRESS)) {
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "get interface configuration: "
+ "maximum buffer size exceeded");
+ result = ISC_R_UNEXPECTED;
+ goto ioctl6_failure;
+ }
+ isc_mem_put(mctx, iter->buf6, iter->buf6size);
+
+ iter->buf6size += IFCONF_SIZE_INCREMENT *
+ sizeof(SOCKET_ADDRESS);
+ }
+
+ closesocket(iter->socket);
+
+ inet_only:
iter->magic = IFITER_MAGIC;
*iterp = iter;
- /* We don't need the socket any more, so close it */
- closesocket(iter->socket);
return (ISC_R_SUCCESS);
+ ioctl6_failure:
+ isc_mem_put(mctx, iter->buf6, iter->buf6size);
+
ioctl_failure:
- isc_mem_put(mctx, iter->buf, iter->bufsize);
+ if (iter->buf4 != NULL)
+ isc_mem_put(mctx, iter->buf4, iter->buf4size);
alloc_failure:
- (void) closesocket(iter->socket);
+ if (iter->socket >= 0)
+ (void) closesocket(iter->socket);
socket_failure:
isc_mem_put(mctx, iter, sizeof(*iter));
*/
static isc_result_t
-internal_current(isc_interfaceiter_t *iter, int family) {
+internal_current(isc_interfaceiter_t *iter) {
BOOL ifNamed = FALSE;
unsigned long flags;
REQUIRE(iter->numIF >= 0);
memset(&iter->current, 0, sizeof(iter->current));
- iter->current.af = family;
+ iter->current.af = AF_INET;
- get_addr(family, &iter->current.address,
+ get_addr(AF_INET, &iter->current.address,
(struct sockaddr *)&(iter->IFData.iiAddress));
/*
* If the interface is point-to-point, get the destination address.
*/
if ((iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0) {
- get_addr(family, &iter->current.dstaddress,
+ get_addr(AF_INET, &iter->current.dstaddress,
(struct sockaddr *)&(iter->IFData.iiBroadcastAddress));
}
/*
* Get the network mask.
*/
- switch (family) {
- case AF_INET:
- get_addr(family, &iter->current.netmask,
- (struct sockaddr *)&(iter->IFData.iiNetmask));
- break;
- case AF_INET6:
- break;
- }
+ get_addr(AF_INET, &iter->current.netmask,
+ (struct sockaddr *)&(iter->IFData.iiNetmask));
return (ISC_R_SUCCESS);
}
+static isc_result_t
+internal_current6(isc_interfaceiter_t *iter) {
+ BOOL ifNamed = FALSE;
+ int i;
+
+ REQUIRE(VALID_IFITER(iter));
+ REQUIRE(iter->pos6 >= 0);
+ REQUIRE(iter->buf6 != 0);
+
+ memset(&iter->current, 0, sizeof(iter->current));
+ iter->current.af = AF_INET6;
+
+ get_addr(AF_INET6, &iter->current.address,
+ iter->buf6->Address[iter->pos6].lpSockaddr);
+
+ /*
+ * Get interface flags.
+ */
+
+ iter->current.flags = INTERFACE_F_UP;
+
+ if (ifNamed == FALSE)
+ sprintf(iter->current.name,
+ "TCP/IPv6 Interface %d", iter->pos6 + 1);
+
+ for (i = 0; i< 16; i++)
+ iter->current.netmask.type.in6.s6_addr[i] = 0xff;
+ iter->current.netmask.family = AF_INET6;
+ return (ISC_R_SUCCESS);
+}
+
/*
* Step the iterator to the next interface. Unlike
* isc_interfaceiter_next(), this may leave the iterator
*/
static isc_result_t
internal_next(isc_interfaceiter_t *iter) {
- if (iter->numIF >= iter->totalIF)
+ if (iter->numIF >= iter->v4IF)
return (ISC_R_NOMORE);
/*
* Microsoft's implementation is peculiar for returning
* the list in reverse order
*/
-
+
if (iter->numIF == 0)
- iter->pos = (INTERFACE_INFO *)(iter->buf + (iter->totalIF));
+ iter->pos4 = (INTERFACE_INFO *)(iter->buf4 + (iter->v4IF));
- iter->pos--;
- if (&(iter->pos) < &(iter->buf))
+ iter->pos4--;
+ if (&(iter->pos4) < &(iter->buf4))
return (ISC_R_NOMORE);
memset(&(iter->IFData), 0, sizeof(INTERFACE_INFO));
- memcpy(&(iter->IFData), iter->pos, sizeof(INTERFACE_INFO));
+ memcpy(&(iter->IFData), iter->pos4, sizeof(INTERFACE_INFO));
iter->numIF++;
return (ISC_R_SUCCESS);
}
+static isc_result_t
+internal_next6(isc_interfaceiter_t *iter) {
+ if (iter->pos6 == 0)
+ return (ISC_R_NOMORE);
+ iter->pos6--;
+ return (ISC_R_SUCCESS);
+}
+
isc_result_t
isc_interfaceiter_current(isc_interfaceiter_t *iter,
isc_interface_t *ifdata) {
isc_result_t
isc_interfaceiter_first(isc_interfaceiter_t *iter) {
- isc_result_t result;
REQUIRE(VALID_IFITER(iter));
- iter->numIF = 0;
- for (;;) {
- result = internal_next(iter);
- if (result != ISC_R_SUCCESS)
- break;
- result = internal_current(iter, AF_INET);
- if (result != ISC_R_IGNORE)
- break;
- }
- iter->result = result;
- return (result);
+ if (iter->buf6 != NULL)
+ iter->pos6 = iter->buf6->iAddressCount;
+ iter->result = ISC_R_SUCCESS;
+ return (isc_interfaceiter_next(iter));
}
isc_result_t
for (;;) {
result = internal_next(iter);
- if (result != ISC_R_SUCCESS)
+ if (result == ISC_R_NOMORE) {
+ result = internal_next6(iter);
+ if (result != ISC_R_SUCCESS)
+ break;
+ result = internal_current6(iter);
+ if (result != ISC_R_IGNORE)
+ break;
+ } else if (result != ISC_R_SUCCESS)
break;
- result = internal_current(iter,AF_INET);
+ result = internal_current(iter);
if (result != ISC_R_IGNORE)
break;
}
iter = *iterp;
REQUIRE(VALID_IFITER(iter));
- isc_mem_put(iter->mctx, iter->buf, iter->bufsize);
+ if (iter->buf4 != NULL)
+ isc_mem_put(iter->mctx, iter->buf4, iter->buf4size);
+ if (iter->buf6 != NULL)
+ isc_mem_put(iter->mctx, iter->buf6, iter->buf6size);
iter->magic = 0;
isc_mem_put(iter->mctx, iter, sizeof(*iter));
*iterp = NULL;
}
-
RelativePath="..\..\..\include\ntp_malloc.h"
>
</File>
+ <File
+ RelativePath="..\..\..\include\ntp_net.h"
+ >
+ </File>
<File
RelativePath="..\..\..\include\ntp_proto.h"
>
+/*
+ * DEAD CODE ALERT -- for whatever reason all this wonderful stuff is
+ * unused. The initialization was the only code
+ * exercised as of May 2009 when that was nipped.
+ */
+
+
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
# define LOCK(lock) EnterCriticalSection(lock)
# define UNLOCK(lock) LeaveCriticalSection(lock)
-static void
+static inline void
initialise_buffer(transmitbuf *buff)
{
- memset((char *) buff, 0, sizeof(transmitbuf));
-
- buff->wsabuf.len = 0;
- buff->wsabuf.buf = (char *) &buff->pkt;
+ memset(buff, 0, sizeof(*buff));
}
static void
transmitbuf_t *buf;
int i;
- buf = (transmitbuf_t *) emalloc(nbufs*sizeof(transmitbuf_t));
+ buf = emalloc(nbufs * sizeof(*buf));
for (i = 0; i < nbufs; i++)
{
initialise_buffer(buf);
}
/* Initialize random file before OpenSSL checks */
- if(!init_randfile())
+ if (!init_randfile())
msyslog(LOG_ERR, "Unable to initialize .rnd file\n");
+#pragma warning(push)
+#pragma warning(disable: 4127) /* conditional expression is constant */
+
+#ifdef DEBUG
+ if (SIZEOF_TIME_T != sizeof(time_t)
+ || SIZEOF_INT != sizeof(int)
+ || SIZEOF_SIGNED_CHAR != sizeof(char)) {
+
+ msyslog(LOG_ERR, "config.h SIZEOF_* macros wrong, fatal");
+ exit(1);
+ }
+#endif
+
+#pragma warning(pop)
+
/*
* Get privileges needed for fiddling with the clock
*/
#include <stddef.h>
#include <stdio.h>
#include <process.h>
+#include <syslog.h>
+
#include "ntp_stdlib.h"
-#include "syslog.h"
#include "ntp_machine.h"
#include "ntp_fp.h"
#include "ntp.h"
#include "ntp_iocompletionport.h"
#include "transmitbuff.h"
#include "ntp_request.h"
+#include "ntp_assert.h"
#include "clockstuff.h"
#include "ntp_io.h"
#include "clockstuff.h"
#define trans_buf buff_space.tbuf
-#if !defined( _W64 )
- /*
- * if ULONG_PTR needs to be defined then the build environment
- * is pure 32 bit Windows. Since ULONG_PTR and DWORD have
- * the same size in 32 bit Windows we can safely define
- * a replacement.
- */
- typedef DWORD ULONG_PTR;
-#endif
-
/*
* local function definitions
*/
transmitbuf_t *
get_trans_buf()
{
- transmitbuf_t *tb = (transmitbuf_t *) emalloc(sizeof(transmitbuf_t));
- tb->wsabuf.len = 0;
- tb->wsabuf.buf = (char *) &tb->pkt;
+ transmitbuf_t *tb = emalloc(sizeof(*tb));
return (tb);
}
/* Create/initialise the I/O creation port
*/
-extern void
+void
init_io_completion_port(
void
)
}
#endif
+#if 0 /* transmitbuff.c unused, no need to initialize it */
+ init_transmitbuff();
+#endif
+
/* Create the event used to signal an IO event
*/
WaitableIoEventHandle = CreateEvent(NULL, FALSE, FALSE, WAITABLEIOEVENTHANDLE);
}
-extern void
+void
uninit_io_completion_port(
void
)
}
+/*
+ * libisc/interfaceiter.c calls InitSockets(), to minimize deltas
+ * from the upstream source, we provide a no-op implementation.
+ */
+void
+InitSockets(
+ void
+ )
+{
+}
+
+
static int QueueSerialWait(struct refclockio *rio, recvbuf_t *buff, IoCompletionInfo *lpo, BOOL clear_timestamp)
{
lpo->request_type = SERIAL_WAIT;
rc = ReadFile(
(HANDLE)buff->fd,
- buff->wsabuff.buf,
- buff->wsabuff.len,
- &buff->wsabuff.len,
- (LPOVERLAPPED) lpo);
+ buff->recv_buffer,
+ sizeof(buff->recv_buffer),
+ NULL,
+ (LPOVERLAPPED)lpo);
if (!rc && ERROR_IO_PENDING != GetLastError()) {
msyslog(LOG_ERR, "Can't read from Refclock: %m");
IoCompletionInfo *lpo;
recvbuf_t *buff;
- if (NULL == CreateIoCompletionPort((HANDLE)_get_osfhandle(rio->fd), hIoCompletionPort, (ULONG_PTR) rio, 0)) {
+ if (NULL == CreateIoCompletionPort(
+ (HANDLE)_get_osfhandle(rio->fd),
+ hIoCompletionPort,
+ (ULONG_PTR)rio,
+ 0)) {
msyslog(LOG_ERR, "Can't add COM port to i/o completion port: %m");
return 1;
}
- lpo = (IoCompletionInfo *) GetHeapAlloc("io_completion_port_add_clock_io");
- if (lpo == NULL)
- {
+ lpo = GetHeapAlloc("io_completion_port_add_clock_io");
+ if (NULL == lpo) {
msyslog(LOG_ERR, "Can't allocate heap for completion port: %m");
return 1;
}
* Queue a receiver on a socket. Returns 0 if no buffer can be queued
*
* Note: As per the winsock documentation, we use WSARecvFrom. Using
- * ReadFile() is less efficient.
+ * ReadFile() is less efficient.
*/
-static unsigned long QueueSocketRecv(SOCKET s, recvbuf_t *buff, IoCompletionInfo *lpo) {
-
- int AddrLen;
+static unsigned long
+QueueSocketRecv(
+ SOCKET s,
+ recvbuf_t *buff,
+ IoCompletionInfo *lpo
+ )
+{
+ WSABUF wsabuf;
+ DWORD Flags;
+ DWORD Result;
lpo->request_type = SOCK_RECV;
lpo->recv_buf = buff;
if (buff != NULL) {
- DWORD BytesReceived = 0;
- DWORD Flags = 0;
+ Flags = 0;
buff->fd = s;
- AddrLen = sizeof(struct sockaddr_in);
- buff->src_addr_len = sizeof(struct sockaddr);
-
- if (SOCKET_ERROR == WSARecvFrom(buff->fd, &buff->wsabuff, 1,
- &BytesReceived, &Flags,
- (struct sockaddr *) &buff->recv_srcadr, (LPINT) &buff->src_addr_len,
- (LPOVERLAPPED) lpo, NULL)) {
- DWORD Result = WSAGetLastError();
+ buff->recv_srcadr_len = sizeof(buff->recv_srcadr);
+ wsabuf.buf = (char *)buff->recv_buffer;
+ wsabuf.len = sizeof(buff->recv_buffer);
+
+ if (SOCKET_ERROR == WSARecvFrom(buff->fd, &wsabuf, 1,
+ NULL, &Flags,
+ (struct sockaddr *)&buff->recv_srcadr,
+ &buff->recv_srcadr_len,
+ (LPOVERLAPPED)lpo, NULL)) {
+ Result = GetLastError();
switch (Result) {
case NO_ERROR :
case WSA_IO_PENDING :
break ;
case WSAENOTSOCK :
- netsyslog(LOG_ERR, "Can't read from socket, because it isn't a socket: %m");
+ msyslog(LOG_ERR, "Can't read from non-socket fd %d: %m", (int)buff->fd);
/* return the buffer */
freerecvbuf(buff);
return 0;
break;
case WSAEFAULT :
- netsyslog(LOG_ERR, "The buffers parameter is incorrect: %m");
+ msyslog(LOG_ERR, "The buffers parameter is incorrect: %m");
/* return the buffer */
freerecvbuf(buff);
return 0;
get_systime(&arrival_time);
- /* Convert the overlapped pointer back to a recvbuf pointer.
- */
-
- /*
- * Check returned structures
- */
- if (lpo == NULL)
- return (1); /* Nothing to do */
+ NTP_REQUIRE(NULL != lpo);
+ NTP_REQUIRE(NULL != lpo->recv_buf);
- buff = lpo->recv_buf;
/*
- * Make sure we have a buffer
+ * Convert the overlapped pointer back to a recvbuf pointer.
*/
- if (buff == NULL) {
- return (1);
- }
+ buff = lpo->recv_buf;
/*
* If the socket is closed we get an Operation Aborted error
return (1);
}
-
/*
* Get a new recv buffer for the replacement socket receive
*/
newbuff = get_free_recv_buffer_alloc();
QueueSocketRecv(inter->fd, newbuff, lpo);
-#ifdef DEBUG
- if(debug > 3 && get_packet_mode(buff) == MODE_BROADCAST)
- printf("****Accepting Broadcast packet on fd %d from %s\n", buff->fd, stoa(&buff->recv_srcadr));
-#endif
- ignore_this = inter->ignore_packets;
-#ifdef DEBUG
- if (debug > 3)
- printf(" Packet mode is %d\n", get_packet_mode(buff));
-#endif
+ DPRINTF(4, ("%sfd %d %s recv packet mode is %d\n",
+ (MODE_BROADCAST == get_packet_mode(buff))
+ ? " **** Broadcast "
+ : "",
+ (int)buff->fd, stoa(&buff->recv_srcadr),
+ get_packet_mode(buff)));
+
/*
* If we keep it add some info to the structure
*/
- if (Bytes > 0 && ignore_this == ISC_FALSE) {
+ if (Bytes && !inter->ignore_packets) {
memcpy(&buff->recv_time, &arrival_time, sizeof buff->recv_time);
buff->recv_length = (int) Bytes;
buff->receiver = receive;
buff->dstadr = inter;
-#ifdef DEBUG
- if (debug > 1)
- printf("Received %d bytes of fd %d in buffer %x from %s\n", Bytes, buff->fd, buff, stoa(&buff->recv_srcadr));
-#endif
+
+ DPRINTF(2, ("Received %d bytes fd %d in buffer %p from %s\n",
+ Bytes, (int)buff->fd, buff, stoa(&buff->recv_srcadr)));
+
packets_received++;
inter->received++;
add_full_recv_buffer(buff);
int n;
if (fd != INVALID_SOCKET) {
- if (NULL == CreateIoCompletionPort((HANDLE) fd, hIoCompletionPort,
- (DWORD) inter, 0)) {
+ if (NULL == CreateIoCompletionPort((HANDLE)fd,
+ hIoCompletionPort, (ULONG_PTR)inter, 0)) {
msyslog(LOG_ERR, "Can't add socket to i/o completion port: %m");
return 1;
}
struct interface *inter,
struct pkt *pkt,
int len,
- struct sockaddr_storage* dest)
+ struct sockaddr_storage *dest)
{
- transmitbuf_t *buff = NULL;
+ WSABUF wsabuf;
+ transmitbuf_t *buff;
DWORD Result = ERROR_SUCCESS;
int errval;
int AddrLen;
IoCompletionInfo *lpo;
- DWORD BytesSent = 0;
- DWORD Flags = 0;
+ DWORD Flags;
lpo = (IoCompletionInfo *) GetHeapAlloc("io_completion_port_sendto");
}
-
memcpy(&buff->pkt, pkt, len);
- buff->wsabuf.buf = buff->pkt;
- buff->wsabuf.len = len;
+ wsabuf.buf = buff->pkt;
+ wsabuf.len = len;
- AddrLen = sizeof(struct sockaddr_in);
+ AddrLen = SOCKLEN(dest);
lpo->request_type = SOCK_SEND;
lpo->trans_buf = buff;
+ Flags = 0;
- Result = WSASendTo(inter->fd, &buff->wsabuf, 1, &BytesSent, Flags, (struct sockaddr *) dest, AddrLen, (LPOVERLAPPED) lpo, NULL);
+ Result = WSASendTo(inter->fd, &wsabuf, 1, NULL, Flags,
+ (struct sockaddr *)dest, AddrLen,
+ (LPOVERLAPPED)lpo, NULL);
if(Result == SOCKET_ERROR)
{
RelativePath="..\..\..\ntpd\ntp_scanner.c"
>
</File>
+ <File
+ RelativePath="..\..\..\ntpd\ntp_signd.c"
+ >
+ </File>
<File
RelativePath="..\..\..\ntpd\ntp_timer.c"
>
RelativePath="..\..\..\include\ntp_malloc.h"
>
</File>
+ <File
+ RelativePath="..\..\..\include\ntp_net.h"
+ >
+ </File>
<File
RelativePath="..\..\..\ntpd\ntp_parser.h"
>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
- ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
Name="Header Files"
Filter="h;hpp;hxx;hm;inl"
>
+ <File
+ RelativePath="..\include\config.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\isc\net.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\include\ntp.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\include\ntp_fp.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\include\ntp_io.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\include\ntp_machine.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\include\ntp_net.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\include\ntp_select.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\include\ntp_stdlib.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\include\ntp_string.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\include\ntp_syslog.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\include\ntp_unixtime.h"
+ >
+ </File>
<File
RelativePath="..\..\..\ntpdate\ntpdate.h"
>
</File>
+ <File
+ RelativePath="..\include\syslog.h"
+ >
+ </File>
</Filter>
<Filter
Name="Resource Files"