*/
#define ALLOW_WILDCARD_PACKETS
+/*
+ * Set up some macros to look for IPv6 and IPv6 multicast
+ */
+
+#if defined(ISC_PLATFORM_HAVEIPV6) && !defined(DISABLE_IPV6)
+
+#define INCLUDE_IPV6_SUPPORT
+
+#if defined(INCLUDE_IPV6_SUPPORT) && defined(IPV6_JOIN_GROUP) && defined(IPV6_LEAVE_GROUP)
+#define INCLUDE_IPV6_MULTICAST_SUPPORT
+
+#endif /* IPV6 Multicast Support */
+#endif /* IPv6 Support */
extern int listen_to_virtual_ips;
extern const char *specific_interface;
static void
print_interface(int ind) {
- printf("interface %d: fd=%d, bfd=%d, name=%.8s, flags=0x%x, scope=%d\n",
+
+ printf("interface %d: fd=%d, bfd=%d, name=%s, flags=0x%x, scope=%d\n",
ind,
inter_list[ind].fd,
inter_list[ind].bfd,
/* Only IPv4 has a network mask */
if(inter_list[ind].family == AF_INET)
printf(", mask=%s", stoa((&inter_list[ind].mask)));
- printf("\n");
+
+ printf(" %s\n", inter_list[ind].ignore_packets == ISC_FALSE ? "Enabled": "Disabled");
if (debug > 4) /* in-depth debugging only */
interface_dump(&inter_list[ind]);
}
idx++;
}
-#ifdef ISC_PLATFORM_HAVEIPV6
+#ifdef INCLUDE_IPV6_SUPPORT
/*
* create pseudo-interface with wildcard IPv6 address
*/
void
convert_isc_if(isc_interface_t *isc_if, struct interface *itf, u_short port) {
+ itf->scopeid = 0;
itf->family = (short) isc_if->af;
if(isc_if->af == AF_INET) {
itf->sin.ss_family = (u_short) isc_if->af;
loopback_interface = itf;
}
}
-#ifdef ISC_PLATFORM_HAVEIPV6
+#ifdef INCLUDE_IPV6_SUPPORT
else if (isc_if->af == AF_INET6) {
itf->sin.ss_family = (u_short) isc_if->af;
strcpy(itf->name, isc_if->name);
/* Copy the scopeid and the interface index */
itf->ifindex = isc_if->ifindex;
}
-#endif /* ISC_PLATFORM_HAVEIPV6 */
+#endif /* INCLUDE_IPV6_SUPPORT */
/* Process the rest of the flags */
printf("create_sockets(%d)\n", ntohs( (u_short) port));
#endif
+#ifdef INCLUDE_IPV6_SUPPORT
if (isc_net_probeipv6() == ISC_R_SUCCESS)
scan_ipv6 = ISC_TRUE;
-#if defined(ISC_PLATFORM_HAVEIPV6) && defined(DEBUG)
+#if defined(DEBUG)
else
if(debug)
netsyslog(LOG_ERR, "no IPv6 interfaces found");
+#endif
#endif
if (isc_net_probeipv4() == ISC_R_SUCCESS)
inter_list[i].fd = open_socket(&inter_list[i].sin,
inter_list[i].flags, 0, &inter_list[i], i);
if (inter_list[i].fd != INVALID_SOCKET)
- msyslog(LOG_INFO, "Listening on interface %s, %s#%d",
+ msyslog(LOG_INFO, "Listening on interface %s, %s#%d %s",
inter_list[i].name,
stoa((&inter_list[i].sin)),
- NTP_PORT);
- if ((inter_list[i].flags & INT_BROADCAST) &&
+ NTP_PORT,
+ (inter_list[i].ignore_packets == ISC_FALSE) ?
+ "Enabled": "Disabled");
+/* if ((inter_list[i].flags & INT_BROADCAST) &&
inter_list[i].bfd != INVALID_SOCKET)
msyslog(LOG_INFO, "Listening on broadcast address %s#%d",
stoa((&inter_list[i].bcast)),
NTP_PORT);
+*/
+ /*
+ * Calculate the address hash for each interface address.
+ */
+ inter_list[i].addr_refid = addr2refid(&inter_list[i].sin);
}
/*
RESM_NTPONLY|RESM_INTERFACE, RES_IGNORE);
}
- /*
- * Calculate the address hash for each interface address.
- */
- for (i = 0; i < ninterfaces; i++) {
- inter_list[i].addr_refid = addr2refid(&inter_list[i].sin);
- }
-
#ifdef DEBUG
if (debug > 1) {
static isc_boolean_t
addr_ismulticast(struct sockaddr_storage *maddr)
{
- u_int32 haddr = ntohl(((struct sockaddr_in*)maddr)->sin_addr.s_addr);
switch (maddr->ss_family)
{
case AF_INET :
- if (!IN_CLASSD(haddr)) {
- netsyslog(LOG_ERR,
- "multicast address %s not class D",
+ if (!IN_CLASSD(ntohl(((struct sockaddr_in*)maddr)->sin_addr.s_addr))) {
+#ifdef DEBUG
+ if (debug > 1)
+ printf("multicast address %s not class D\n",
stoa(maddr));
+#endif
return (ISC_FALSE);
}
else
}
case AF_INET6 :
-#if defined(ISC_PLATFORM_HAVEIPV6) && defined(IPV6_JOIN_GROUP) && defined(IPV6_LEAVE_GROUP)
+#ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
if (!IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)maddr)->sin6_addr)) {
- netsyslog(LOG_ERR,
- "address %s not IPv6 multicast address",
+#ifdef DEBUG
+ if (debug > 1)
+ printf("address %s not IPv6 multicast address\n",
stoa(maddr));
+#endif
return (ISC_FALSE);
}
else
static isc_boolean_t
socket_multicast_enable(struct interface *iface, int ind, int lscope, struct sockaddr_storage *maddr)
{
-#ifdef ISC_PLATFORM_HAVEIPV6
+#ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
struct ipv6_mreq mreq6;
struct in6_addr iaddr6;
-#endif /* ISC_PLATFORM_HAVEIPV6 */
+#endif /* INCLUDE_IPV6_MULTICAST_SUPPORT */
struct ip_mreq mreq;
memset((char *)&mreq, 0, sizeof(mreq));
#endif
break;
case AF_INET6:
-#if defined(ISC_PLATFORM_HAVEIPV6) && defined(IPV6_JOIN_GROUP) && defined(IPV6_LEAVE_GROUP)
+#ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
/*
* Enable reception of multicast packets
*/
iaddr6 = ((struct sockaddr_in6*)maddr)->sin6_addr;
mreq6.ipv6mr_multiaddr = iaddr6;
-#ifdef ISC_PLATFORM_HAVESCOPEID
- if (IN6_IS_ADDR_MC_LINKLOCAL(&iaddr6))
- mreq6.ipv6mr_interface = lscope;
- else
-#endif
- mreq6.ipv6mr_interface = lscope;
+ mreq6.ipv6mr_interface = lscope;
if (setsockopt(iface->fd, IPPROTO_IPV6, IPV6_JOIN_GROUP,
(char *)&mreq6, sizeof(mreq6)) == -1) {
break;
#else
return ISC_FALSE;
-#endif /* ISC_PLATFORM_HAVEIPV6 */
+#endif /* INCLUDE_IPV6_MULTICAST_SUPPORT */
}
iface->flags |= INT_MCASTOPEN;
iface->num_mcast++;
static isc_boolean_t
socket_multicast_disable(struct interface *iface, int ind, struct sockaddr_storage *maddr)
{
-#ifdef ISC_PLATFORM_HAVEIPV6
+#ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
struct ipv6_mreq mreq6;
struct in6_addr iaddr6;
-#endif /* ISC_PLATFORM_HAVEIPV6 */
+#endif /* INCLUDE_IPV6_MULTICAST_SUPPORT */
struct ip_mreq mreq;
memset((char *)&mreq, 0, sizeof(mreq));
}
break;
case AF_INET6:
-#if defined(ISC_PLATFORM_HAVEIPV6) && defined(IPV6_JOIN_GROUP) && defined(IPV6_LEAVE_GROUP)
+#ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
/*
* Disable reception of multicast packets
*/
iaddr6 = ((struct sockaddr_in6*)&maddr)->sin6_addr;
mreq6.ipv6mr_multiaddr = iaddr6;
-#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
- if (IN6_IS_ADDR_MC_LINKLOCAL(&iaddr6))
- mreq6.ipv6mr_interface = iface->scopeid;
- else
-#endif
- mreq6.ipv6mr_interface = 0;
+ mreq6.ipv6mr_interface = iface->scopeid;
if (setsockopt(iface->fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
(char *)&mreq6, sizeof(mreq6)) == -1) {
break;
#else
return ISC_FALSE;
-#endif /* ISC_PLATFORM_HAVEIPV6 */
+#endif /* INCLUDE_IPV6_MULTICAST_SUPPORT */
}
iface->num_mcast--;
if (iface->num_mcast <= 0) {
/* Enable Broadcast on socket */
jstatus = socket_broadcast_enable(&inter_list[i], fd, &inter_list[i].sin);
if (jstatus == ISC_TRUE)
+ {
nif++;
-#ifdef DEBUG
- if (debug) {
- if (jstatus == ISC_TRUE)
- printf("io_setbclient: Opened broadcast client on interface %d, socket: %d\n",
+ netsyslog(LOG_INFO,"io_setbclient: Opened broadcast client on interface %d, socket: %d",
i, fd);
- else
- printf("io_setbclient: Unable to Open broadcast client on interface %d\n",
- i);
}
-#endif
}
set_reuseaddr(0);
#ifdef DEBUG
void
io_unsetbclient(void)
{
+#ifdef OPEN_BCAST_SOCKET
int i;
isc_boolean_t lstatus;
continue;
lstatus = socket_broadcast_disable(&inter_list[i], i, &inter_list[i].sin);
}
+#endif
}
void
return;
/* If we already have it we can just return */
- if (find_flagged_addr_in_list(&addr, INT_MCASTOPEN) >= 0)
+ ind = find_flagged_addr_in_list(&addr, INT_MCASTOPEN);
+ if (ind >= 0)
{
netsyslog(LOG_INFO, "Duplicate request found for multicast address %s",
stoa(&addr));
memset(&((struct sockaddr_in*)&inter_list[ind].mask)->sin_addr.s_addr, 0xff, sizeof(struct in_addr));
break;
case AF_INET6:
-#if defined(ISC_PLATFORM_HAVEIPV6) && defined(IPV6_JOIN_GROUP) && defined(IPV6_LEAVE_GROUP)
+#ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
memcpy(&(((struct sockaddr_in6 *)&inter_list[ind].sin)->sin6_addr),
&((struct sockaddr_in6*)&addr)->sin6_addr,
sizeof(struct in6_addr));
memset(&((struct sockaddr_in6*)&inter_list[ind].mask)->sin6_addr.s6_addr, 0xff, sizeof(struct in6_addr));
#endif
i = findlocalcastinterface(&addr, INT_MULTICAST);
- if (i < 0)
- lscope = 0;
- else
+ if (i >= 0)
lscope = ((struct sockaddr_in6*)&inter_list[i].sin)->sin6_scope_id;
#ifdef DEBUG
if (debug > 1)
}
#else
+ /*
+ * For the case where we can't use a separate socket
+ */
ind = findlocalcastinterface(&addr, INT_MULTICAST);
#endif
/*
jstatus = socket_multicast_enable(&inter_list[ind], ind, lscope, &addr);
-#ifdef DEBUG
- if (debug)
- {
- if (jstatus == ISC_TRUE)
- printf("io_multicast_add: %s on interface %d\n", stoa(&addr), ind);
- else
- printf("io_multicast_add: Failed to add %s on interface %d\n", stoa(&addr), ind);
- }
-#endif
+ if (jstatus == ISC_TRUE)
+ netsyslog(LOG_INFO, "Added Multicast Listener %s on interface %d\n", stoa(&addr), ind);
+ else
+ netsyslog(LOG_ERR, "Failed to add Multicast Listener %s\n", stoa(&addr));
#else /* MCAST */
netsyslog(LOG_ERR,
"Cannot add multicast address %s: no Multicast support",
stoa(&addr));
#endif /* MCAST */
+ return;
}
/*
{
#ifdef MCAST
int i;
- u_int32 haddr;
isc_boolean_t lstatus;
-#ifdef ISC_PLATFORM_HAVEIPV6
- struct in6_addr haddr6;
-#endif /* ISC_PLATFORM_HAVEIPV6 */
+ /*
+ * Check to see if this is a multicast address
+ */
+ if (addr_ismulticast(&addr) == ISC_FALSE)
+ {
+ netsyslog(LOG_ERR,
+ "invalid multicast address %s", stoa(&addr));
+ return;
+ }
switch (addr.ss_family)
{
case AF_INET :
- haddr = ntohl(((struct sockaddr_in*)&addr)->sin_addr.s_addr);
-
- if (!IN_CLASSD(haddr))
- {
- netsyslog(LOG_ERR,
- "invalid multicast address %s", stoa(&addr));
- return;
- }
-
/*
* Disable reception of multicast packets
*/
}
break;
-#if defined(ISC_PLATFORM_HAVEIPV6) && defined(IPV6_JOIN_GROUP) && defined(IPV6_LEAVE_GROUP)
+#ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
case AF_INET6 :
- haddr6 = ((struct sockaddr_in6*)&addr)->sin6_addr;
-
- if (!IN6_IS_ADDR_MULTICAST(&haddr6))
- {
- netsyslog(LOG_ERR,
- "invalid multicast address %s", stoa(&addr));
- return;
- }
/*
* Disable reception of multicast packets
lstatus = socket_multicast_disable(&inter_list[i], i, &addr);
}
break;
-#endif /* ISC_PLATFORM_HAVEIPV6 */
+#endif /* INCLUDE_IPV6_MULTICAST_SUPPORT */
}/* switch */
delete_addr_from_list(&addr);
fd, addr->ss_family, (int)ntohs(((struct sockaddr_in*)addr)->sin_port),
stoa(addr),
IN_CLASSD(ntohl(((struct sockaddr_in*)addr)->sin_addr.s_addr)), flags);
-#ifdef ISC_PLATFORM_HAVEIPV6
+#ifdef INCLUDE_IPV6_SUPPORT
else if(addr->ss_family == AF_INET6)
sprintf(buff,
"bind() fd %d, family %d, port %d, scope %d, addr %s, in6_is_addr_multicast=%d flags=%d fails: %%m",
((struct sockaddr_in6*)addr)->sin6_scope_id, stoa(addr),
IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)addr)->sin6_addr), flags);
#endif
- else return INVALID_SOCKET;
+ else
+ return (INVALID_SOCKET);
/*
* Don't log this under all conditions
closesocket(fd);
- /*
- * soft fail if opening a multicast address
- */
- if(addr->ss_family == AF_INET){
- if(IN_CLASSD(ntohl(((struct sockaddr_in*)addr)->sin_addr.s_addr)))
- return (INVALID_SOCKET);
- }
- else {
- if(IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)addr)->sin6_addr))
- return (INVALID_SOCKET);
- }
-#if 0
- exit(1);
-#else
- return INVALID_SOCKET;
-#endif
+ return (INVALID_SOCKET);
}
#ifdef DEBUG
if (debug)
{
SOCKET i, newmax;
+ if (fd < 0)
+ return;
+
(void) closesocket(fd);
/*
{
int i, newmax;
+ if (fd < 0)
+ return;
+
(void) close(fd);
#ifndef HAVE_IO_COMPLETION_PORT
struct in_addr addr;
};
-#ifdef ISC_PLATFORM_HAVEIPV6
+#ifdef INCLUDE_IPV6_SUPPORT
struct cache6 {
u_short port;
struct in6_addr addr;
};
-#endif /* ISC_PLATFORM_HAVEIPV6 */
+#endif /* INCLUDE_IPV6_SUPPORT */
#ifndef ERRORCACHESIZE
#define ERRORCACHESIZE 8
#endif
#if ERRORCACHESIZE > 0
static struct cache badaddrs[ERRORCACHESIZE];
-#ifdef ISC_PLATFORM_HAVEIPV6
+#ifdef INCLUDE_IPV6_SUPPORT
static struct cache6 badaddrs6[ERRORCACHESIZE];
-#endif /* ISC_PLATFORM_HAVEIPV6 */
+#endif /* INCLUDE_IPV6_SUPPORT */
#else
#define badaddrs ((struct cache *)0) /* Only used in empty loops! */
-#ifdef ISC_PLATFORM_HAVEIPV6
+#ifdef INCLUDE_IPV6_SUPPORT
#define badaddrs6 ((struct cache6 *)0) /* Only used in empty loops! */
-#endif /* ISC_PLATFORM_HAVEIPV6 */
+#endif /* INCLUDE_IPV6_SUPPORT */
#endif
#ifdef DEBUG
if (debug > 1)
}
break;
-#ifdef ISC_PLATFORM_HAVEIPV6
+#ifdef INCLUDE_IPV6_SUPPORT
case AF_INET6 :
/*
inter->last_ttl = ttl;
}
break;
-#endif /* ISC_PLATFORM_HAVEIPV6 */
+#endif /* INCLUDE_IPV6_SUPPORT */
default :
exit(1);
badaddrs[slot].addr.s_addr == ((struct sockaddr_in*)dest)->sin_addr.s_addr)
break;
}
-#ifdef ISC_PLATFORM_HAVEIPV6
+#ifdef INCLUDE_IPV6_SUPPORT
else if (dest->ss_family == AF_INET6) {
if (badaddrs6[slot].port == ((struct sockaddr_in6*)dest)->sin6_port &&
badaddrs6[slot].addr.s6_addr == ((struct sockaddr_in6*)dest)->sin6_addr.s6_addr)
break;
}
-#endif /* ISC_PLATFORM_HAVEIPV6 */
+#endif /* INCLUDE_IPV6_SUPPORT */
else exit(1); /* address family not supported yet */
#if defined(HAVE_IO_COMPLETION_PORT)
}
break;
-#ifdef ISC_PLATFORM_HAVEIPV6
+#ifdef INCLUDE_IPV6_SUPPORT
case AF_INET6 :
for (slot = ERRORCACHESIZE; --slot >= 0; )
break;
}
break;
-#endif /* ISC_PLATFORM_HAVEIPV6 */
+#endif /* INCLUDE_IPV6_SUPPORT */
default :
exit(1);
case AF_INET :
badaddrs[slot].port = 0;
break;
-#ifdef ISC_PLATFORM_HAVEIPV6
+#ifdef INCLUDE_IPV6_SUPPORT
case AF_INET6 :
badaddrs6[slot].port = 0;
break;
-#endif /* ISC_PLATFORM_HAVEIPV6 */
+#endif /* INCLUDE_IPV6_SUPPORT */
}
}
}
{
nonzeroreads = 0;
n = select(maxactivefd+1, &fds, (fd_set *)0, (fd_set *)0, &tvzero);
+
+ /*
+ * If there are no packets waiting just return
+ */
+ if (n <= 0)
+ return;
+
++select_count;
++handler_pkts;
--handler_count;
return;
}
- msyslog(LOG_ERR, "input_handler: fell out of infinite for(;;) loop!");
--handler_count;
return;
}
memcpy(&((struct sockaddr_in*)&saddr)->sin_addr, &((struct sockaddr_in*)addr)->sin_addr, sizeof(struct in_addr));
((struct sockaddr_in*)&saddr)->sin_port = htons(2000);
}
-#ifdef ISC_PLATFORM_HAVEIPV6
+#ifdef INCLUDE_IPV6_SUPPORT
else if(addr->ss_family == AF_INET6) {
memcpy(&((struct sockaddr_in6*)&saddr)->sin6_addr, &((struct sockaddr_in6*)addr)->sin6_addr, sizeof(struct in6_addr));
((struct sockaddr_in6*)&saddr)->sin6_port = htons(2000);
int i;
int nif = -1;
-#if defined(ISC_PLATFORM_HAVEIPV6) && defined(IPV6_JOIN_GROUP) && defined(IPV6_LEAVE_GROUP)
+#ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
isc_boolean_t want_linklocal = ISC_FALSE;
if (addr_ismulticast(addr) && flags == INT_MULTICAST)
{
continue;
/* Skip if different family */
- if(inter_list[i].family != addr->ss_family)
+ if(inter_list[i].sin.ss_family != addr->ss_family)
continue;
/* Is this it one of these based on flags? */
continue;
/* for IPv6 multicast check the address for linklocal */
-#if defined(ISC_PLATFORM_HAVEIPV6) && defined(IPV6_JOIN_GROUP) && defined(IPV6_LEAVE_GROUP)
- if (flags == INT_MULTICAST &&
+#ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
+ if (flags == INT_MULTICAST && inter_list[i].sin.ss_family == AF_INET6 &&
(IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6*)&inter_list[i].sin)->sin6_addr))
&& want_linklocal == ISC_TRUE)
{
)
{
#if !defined(MPE) && (defined(SIOCGIFCONF) || defined(SYS_WINNT))
- int i;
- int flag;
+ int i = -1;
#ifdef DEBUG
if (debug>2)
printf("Finding broadcast interface for addr %s in list of addresses\n",
stoa(addr));
#endif
- if (addr_ismulticast(addr))
- flag = INT_MULTICAST;
- else
- flag = INT_BROADCAST;
- i = findlocalcastinterface(addr, flag);
-
- if (i >= 0) {
-#ifdef DEBUG
- if (debug > 1)
- printf("Found bcastinter index %d\n", i);
-#endif
- return (&inter_list[i]);
- }
- /* Didn't find it, so try something else */
i = find_flagged_addr_in_list(addr, INT_BCASTOPEN|INT_MCASTOPEN);
#ifdef DEBUG
return (&inter_list[i]);
}
*/
-
for (i = nwilds; i < ninterfaces; i++) {
/* Don't both with ignore interfaces */
if (inter_list[i].ignore_packets == ISC_TRUE)
*/
if(inter_list[i].sin.ss_family != addr->ss_family)
continue;
+
+ /* Skip the loopback addresses */
+ if (inter_list[i].flags & INT_LOOPBACK)
+ continue;
+
+ /* for IPv6 multicast check the address for linklocal */
+#ifdef INCLUDE_IPV6_SUPPORT
+ if (inter_list[i].sin.ss_family == AF_INET6 &&
+ (IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6*)&inter_list[i].sin)->sin6_addr)))
+ {
+ continue;
+ }
+#endif
+ /*
+ * If we are looking to match a multicast address grab it.
+ * We must not do this before we have eliminated any linklocal
+ * addresses
+ */
+ if (addr_ismulticast(addr) == ISC_TRUE && inter_list[i].flags & INT_MULTICAST)
+ {
+ return (&inter_list[i]);
+ }
/*
* We match only those interfaces marked as
* broadcastable and either the explicit broadcast
* address or the network portion of the IP address.
* Sloppy.
*/
- if (!(inter_list[i].flags & INT_BCASTOPEN))
- continue;
if(addr->ss_family == AF_INET) {
if (SOCKCMP(&inter_list[i].bcast, addr))
return (&inter_list[i]);
NSRCADR(&inter_list[i].mask)))
return (&inter_list[i]);
}
+#ifdef INCLUDE_IPV6_SUPPORT
else if(addr->ss_family == AF_INET6) {
if (SOCKCMP(&inter_list[i].bcast, addr))
return (&inter_list[i]);
if (SOCKCMP(netof(&inter_list[i].sin), netof(addr)))
return (&inter_list[i]);
- }
+ }
+#endif
}
#endif /* SIOCGIFCONF */
return ANY_INTERFACE_CHOOSE(addr);