]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
Updates to support finding interfaces and address lookups
authorDanny Mayer <mayer@ntp.org>
Mon, 2 Aug 2004 04:35:56 +0000 (00:35 -0400)
committerDanny Mayer <mayer@ntp.org>
Mon, 2 Aug 2004 04:35:56 +0000 (00:35 -0400)
bk: 410dc4ac9Y9DhpYh-yql2faRUtvtkQ

libisc/inet_aton.c [new file with mode: 0644]
libisc/inet_pton.c [new file with mode: 0644]
libntp/ntp_rfc2553.c
ntpd/ntp_control.c
ntpd/ntp_io.c
ports/winnt/include/config.h
ports/winnt/libntp/libntp.dsp

diff --git a/libisc/inet_aton.c b/libisc/inet_aton.c
new file mode 100644 (file)
index 0000000..f7df438
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * Portions Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 1996-2001  Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and 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 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.
+ */
+
+/*
+ * Copyright (c) 1983, 1990, 1993
+ *    The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and 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, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)inet_addr.c        8.1 (Berkeley) 6/17/93";
+static char rcsid[] = "$Id: inet_aton.c,v 1.15.12.3 2004/03/08 09:04:49 marka Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <config.h>
+
+#include <ctype.h>
+#include <stddef.h>            /* Required for NULL. */
+
+#include <isc/types.h>
+#include <isc/net.h>
+
+#ifdef SYS_WINNT
+#define isascii __isascii
+#endif
+/*
+ * Check whether "cp" is a valid ascii representation
+ * of an Internet address and convert to a binary address.
+ * Returns 1 if the address is valid, 0 if not.
+ * This replaces inet_addr, the return value from which
+ * cannot distinguish between failure and a local broadcast address.
+ */
+int
+isc_net_aton(const char *cp, struct in_addr *addr) {
+       unsigned long val;
+       int base, n;
+       unsigned char c;
+       isc_uint8_t parts[4];
+       isc_uint8_t *pp = parts;
+       int digit;
+
+       c = *cp;
+       for (;;) {
+               /*
+                * Collect number up to ``.''.
+                * Values are specified as for C:
+                * 0x=hex, 0=octal, isdigit=decimal.
+                */
+               if (!isdigit(c & 0xff))
+                       return (0);
+               val = 0; base = 10; digit = 0;
+               if (c == '0') {
+                       c = *++cp;
+                       if (c == 'x' || c == 'X')
+                               base = 16, c = *++cp;
+                       else {
+                               base = 8;
+                               digit = 1;
+                       }
+               }
+               for (;;) {
+                       /*
+                        * isascii() is valid for all integer values, and
+                        * when it is true, c is known to be in scope
+                        * for isdigit().  No cast necessary.  Similar
+                        * comment applies for later ctype uses.
+                        */
+                       if (isascii(c) && isdigit(c)) {
+                               if (base == 8 && (c == '8' || c == '9'))
+                                       return (0);
+                               val = (val * base) + (c - '0');
+                               c = *++cp;
+                               digit = 1;
+                       } else if (base == 16 && isascii(c) && isxdigit(c)) {
+                               val = (val << 4) |
+                                       (c + 10 - (islower(c) ? 'a' : 'A'));
+                               c = *++cp;
+                               digit = 1;
+                       } else
+                               break;
+               }
+               if (c == '.') {
+                       /*
+                        * Internet format:
+                        *      a.b.c.d
+                        *      a.b.c   (with c treated as 16 bits)
+                        *      a.b     (with b treated as 24 bits)
+                        */
+                       if (pp >= parts + 3 || val > 0xff)
+                               return (0);
+                       *pp++ = (isc_uint8_t)val;
+                       c = *++cp;
+               } else
+                       break;
+       }
+       /*
+        * Check for trailing characters.
+        */
+       if (c != '\0' && (!isascii(c) || !isspace(c)))
+               return (0);
+       /*
+        * Did we get a valid digit?
+        */
+       if (!digit)
+               return (0);
+       /*
+        * Concoct the address according to
+        * the number of parts specified.
+        */
+       n = pp - parts + 1;
+       switch (n) {
+       case 1:                         /* a -- 32 bits */
+               break;
+
+       case 2:                         /* a.b -- 8.24 bits */
+               if (val > 0xffffff)
+                       return (0);
+               val |= parts[0] << 24;
+               break;
+
+       case 3:                         /* a.b.c -- 8.8.16 bits */
+               if (val > 0xffff)
+                       return (0);
+               val |= (parts[0] << 24) | (parts[1] << 16);
+               break;
+
+       case 4:                         /* a.b.c.d -- 8.8.8.8 bits */
+               if (val > 0xff)
+                       return (0);
+               val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
+               break;
+       }
+       if (addr != NULL)
+               addr->s_addr = htonl(val);
+
+       return (1);
+}
diff --git a/libisc/inet_pton.c b/libisc/inet_pton.c
new file mode 100644 (file)
index 0000000..afda394
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1996-2003  Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and 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 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] =
+       "$Id: inet_pton.c,v 1.10.2.4.2.1 2004/03/06 08:14:31 marka Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <config.h>
+
+#include <errno.h>
+#include <string.h>
+
+#include <isc/net.h>
+
+#define NS_INT16SZ      2
+#define NS_INADDRSZ     4
+#define NS_IN6ADDRSZ   16
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static int inet_pton4(const char *src, unsigned char *dst);
+static int inet_pton6(const char *src, unsigned char *dst);
+
+/* int
+ * isc_net_pton(af, src, dst)
+ *     convert from presentation format (which usually means ASCII printable)
+ *     to network format (which is usually some kind of binary format).
+ * return:
+ *     1 if the address was valid for the specified address family
+ *     0 if the address wasn't valid (`dst' is untouched in this case)
+ *     -1 if some other error occurred (`dst' is untouched in this case, too)
+ * author:
+ *     Paul Vixie, 1996.
+ */
+int
+isc_net_pton(int af, const char *src, void *dst) {
+       switch (af) {
+       case AF_INET:
+               return (inet_pton4(src, dst));
+       case AF_INET6:
+               return (inet_pton6(src, dst));
+       default:
+               errno = EAFNOSUPPORT;
+               return (-1);
+       }
+       /* NOTREACHED */
+}
+
+/* int
+ * inet_pton4(src, dst)
+ *     like inet_aton() but without all the hexadecimal and shorthand.
+ * return:
+ *     1 if `src' is a valid dotted quad, else 0.
+ * notice:
+ *     does not touch `dst' unless it's returning 1.
+ * author:
+ *     Paul Vixie, 1996.
+ */
+static int
+inet_pton4(const char *src, unsigned char *dst) {
+       static const char digits[] = "0123456789";
+       int saw_digit, octets, ch;
+       unsigned char tmp[NS_INADDRSZ], *tp;
+
+       saw_digit = 0;
+       octets = 0;
+       *(tp = tmp) = 0;
+       while ((ch = *src++) != '\0') {
+               const char *pch;
+
+               if ((pch = strchr(digits, ch)) != NULL) {
+                       unsigned int new = *tp * 10 + (pch - digits);
+
+                       if (saw_digit && *tp == 0)
+                               return (0);
+                       if (new > 255)
+                               return (0);
+                       *tp = (unsigned char) new;
+                       if (!saw_digit) {
+                               if (++octets > 4)
+                                       return (0);
+                               saw_digit = 1;
+                       }
+               } else if (ch == '.' && saw_digit) {
+                       if (octets == 4)
+                               return (0);
+                       *++tp = 0;
+                       saw_digit = 0;
+               } else
+                       return (0);
+       }
+       if (octets < 4)
+               return (0);
+       memcpy(dst, tmp, NS_INADDRSZ);
+       return (1);
+}
+
+/* int
+ * inet_pton6(src, dst)
+ *     convert presentation level address to network order binary form.
+ * return:
+ *     1 if `src' is a valid [RFC1884 2.2] address, else 0.
+ * notice:
+ *     (1) does not touch `dst' unless it's returning 1.
+ *     (2) :: in a full address is silently ignored.
+ * credit:
+ *     inspired by Mark Andrews.
+ * author:
+ *     Paul Vixie, 1996.
+ */
+static int
+inet_pton6(const char *src, unsigned char *dst) {
+       static const char xdigits_l[] = "0123456789abcdef",
+                         xdigits_u[] = "0123456789ABCDEF";
+       unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
+       const char *xdigits, *curtok;
+       int ch, saw_xdigit;
+       unsigned int val;
+
+       memset((tp = tmp), '\0', NS_IN6ADDRSZ);
+       endp = tp + NS_IN6ADDRSZ;
+       colonp = NULL;
+       /* Leading :: requires some special handling. */
+       if (*src == ':')
+               if (*++src != ':')
+                       return (0);
+       curtok = src;
+       saw_xdigit = 0;
+       val = 0;
+       while ((ch = *src++) != '\0') {
+               const char *pch;
+
+               if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
+                       pch = strchr((xdigits = xdigits_u), ch);
+               if (pch != NULL) {
+                       val <<= 4;
+                       val |= (pch - xdigits);
+                       if (val > 0xffff)
+                               return (0);
+                       saw_xdigit = 1;
+                       continue;
+               }
+               if (ch == ':') {
+                       curtok = src;
+                       if (!saw_xdigit) {
+                               if (colonp)
+                                       return (0);
+                               colonp = tp;
+                               continue;
+                       }
+                       if (tp + NS_INT16SZ > endp)
+                               return (0);
+                       *tp++ = (unsigned char) ((val >> 8) & 0xff);
+                       *tp++ = (unsigned char) (val & 0xff);
+                       saw_xdigit = 0;
+                       val = 0;
+                       continue;
+               }
+               if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
+                   inet_pton4(curtok, tp) > 0) {
+                       tp += NS_INADDRSZ;
+                       saw_xdigit = 0;
+                       break;  /* '\0' was seen by inet_pton4(). */
+               }
+               return (0);
+       }
+       if (saw_xdigit) {
+               if (tp + NS_INT16SZ > endp)
+                       return (0);
+               *tp++ = (unsigned char) ((val >> 8) & 0xff);
+               *tp++ = (unsigned char) (val & 0xff);
+       }
+       if (colonp != NULL) {
+               /*
+                * Since some memmove()'s erroneously fail to handle
+                * overlapping regions, we'll do the shift by hand.
+                */
+               const int n = tp - colonp;
+               int i;
+
+               if (tp == endp)
+                       return (0);
+               for (i = 1; i <= n; i++) {
+                       endp[- i] = colonp[n - i];
+                       colonp[n - i] = 0;
+               }
+               tp = endp;
+       }
+       if (tp != endp)
+               return (0);
+       memcpy(dst, tmp, NS_IN6ADDRSZ);
+       return (1);
+}
index b8ed214f820ef9bb4bb0a43ba129073fdf547592..129603a76eaea7c7102d6804ba0e5e211b383bbe 100644 (file)
@@ -65,9 +65,7 @@
  * Compatability shims with the rfc2553 API to simplify ntp.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
-#endif
 
 #include <sys/types.h>
 #include <ctype.h>
@@ -82,6 +80,7 @@
 #include "ntp_malloc.h"
 #include "ntp_stdlib.h"
 #include "ntp_string.h"
+#include <isc/net.h>
 
 #ifdef ISC_PLATFORM_NEEDIN6ADDRANY
 
@@ -115,7 +114,6 @@ static char *ai_errlist[] = {
        "Unknown error",                                /* EAI_MAX        */
 };
 
-static int ipv4_aton P((const char *, struct sockaddr_storage *));
 static int do_nodename P((const char *nodename, struct addrinfo *ai,
     const struct addrinfo *hints));
 
@@ -222,8 +220,20 @@ do_nodename(
        if (ai->ai_addr == NULL)
                return (EAI_MEMORY);
 
+       /*
+        * See if we have an IPv6 address
+        */
+       if(strchr(nodename, ':') != NULL) {
+               if (inet_pton(AF_INET6, nodename,
+                   (struct sockaddr_storage *)ai->ai_addr) == 1) {
+                       ai->ai_family = AF_INET6;
+                       ai->ai_addrlen = sizeof(struct sockaddr_in6);
+                       return (0);
+               }
+       }
+
        if (hints != NULL && hints->ai_flags & AI_NUMERICHOST) {
-               if (ipv4_aton(nodename,
+               if (inet_pton(AF_INET, nodename,
                    (struct sockaddr_storage *)ai->ai_addr) == 1) {
                        ai->ai_family = AF_INET;
                        ai->ai_addrlen = sizeof(struct sockaddr_in);
@@ -236,7 +246,7 @@ do_nodename(
                if (h_errno == TRY_AGAIN)
                        return (EAI_AGAIN);
                else {
-                       if (ipv4_aton(nodename,
+                       if (inet_pton(AF_INET, nodename,
                            (struct sockaddr_storage *)ai->ai_addr) == 1) {
                                ai->ai_family = AF_INET;
                                ai->ai_addrlen = sizeof(struct sockaddr_in);
@@ -262,73 +272,4 @@ do_nodename(
        return (0);
 }
 
-/*
- * ipv4_aton - return a net number (this is crude, but careful)
- */
-static int
-ipv4_aton(
-       const char *num,
-       struct sockaddr_storage *saddr
-       )
-{
-       const char *cp;
-       char *bp;
-       int i;
-       int temp;
-       char buf[80];           /* will core dump on really stupid stuff */
-       u_int32 netnum;
-       struct sockaddr_in *addr;
-
-       cp = num;
-       netnum = 0;
-       for (i = 0; i < 4; i++) {
-               bp = buf;
-               while (isdigit((int)*cp))
-                       *bp++ = *cp++;
-               if (bp == buf)
-                       break;
-
-               if (i < 3) {
-                       if (*cp++ != '.')
-                               break;
-               } else if (*cp != '\0')
-                       break;
-
-               *bp = '\0';
-               temp = atoi(buf);
-               if (temp > 255)
-                       break;
-               netnum <<= 8;
-               netnum += temp;
-#ifdef DEBUG
-               if (debug > 3)
-                       printf("ipv4_aton %s step %d buf %s temp %d netnum %lu\n",
-                          num, i, buf, temp, (u_long)netnum);
-#endif
-       }
-
-       if (i < 4) {
-#ifdef DEBUG
-               if (debug > 3)
-                       printf(
-                               "ipv4_aton: \"%s\" invalid host number, line ignored\n",
-                               num);
-#endif
-               return (0);
-       }
-
-       /*
-        * make up socket address.      Clear it out for neatness.
-        */
-       memset((void *)saddr, 0, sizeof(struct sockaddr_storage));
-       addr = (struct sockaddr_in *)saddr;
-       addr->sin_family = AF_INET;
-       addr->sin_port = htons(NTP_PORT);
-       addr->sin_addr.s_addr = htonl(netnum);
-#ifdef DEBUG
-       if (debug > 1)
-               printf("ipv4_aton given %s, got %s.\n", num, ntoa(saddr));
-#endif
-       return (1);
-}
 #endif /* !ISC_PLATFORM_HAVEIPV6 */
index 87667114f56be1249dde405224e93d33374ede6d..fc82317fddbd1ec444b2c3724f5b132908ad007a 100644 (file)
@@ -1106,7 +1106,6 @@ ctl_putadr(
        ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
 }
 
-
 /*
  * ctl_putid - write a tagged clock ID into the response
  */
index 0ab9245b9469e235bd9a314d4efaef33b58b235b..deb1e1919cb0179db75796e7d599ad629093e2d1 100644 (file)
@@ -121,6 +121,11 @@ int nwilds;                                /* Total number of wildcard intefaces */
 int wildipv4 = -1;                     /* Index into inter_list for IPv4 wildcard */
 int wildipv6 = -1;                     /* Index into inter_list for IPv6 wildcard */
 
+/*
+ * These should be set if there is only one */
+int outifaceipv4 = -1;         /* The only IPv4 outgoing interface */
+int outifaceipv6 = -1;         /* The only IPv6 outgoing interface */
+
 #ifdef REFCLOCK
 /*
  * Refclock stuff.     We keep a chain of structures with data concerning
@@ -431,6 +436,8 @@ create_sockets(
 {
        struct sockaddr_storage resmask;
        int i;
+       isc_boolean_t ofacesetipv4;
+       isc_boolean_t ofacesetipv6;
        isc_mem_t *mctx = NULL;
        isc_interfaceiter_t *iter = NULL;
        isc_boolean_t scan_ipv4 = ISC_FALSE;
@@ -539,10 +546,34 @@ create_sockets(
         * Wildcard interfaces, if any, are ignored.
         */
 
+       ofacesetipv4 = ISC_FALSE;
+       ofacesetipv6 = ISC_FALSE;
        for (i = nwilds; i < ninterfaces; i++) {
                SET_HOSTMASK(&resmask, inter_list[i].sin.ss_family);
                hack_restrict(RESTRICT_FLAGS, &inter_list[i].sin, &resmask,
                    RESM_NTPONLY|RESM_INTERFACE, RES_IGNORE);
+
+               /*
+                * We set the outgoing interface number ONLY if there is just one
+                */
+               if (inter_list[i].sin.ss_family == AF_INET) {
+                       if((outifaceipv4 == -1) && !(inter_list[i].flags & INT_LOOPBACK) && 
+                               ofacesetipv4 == ISC_FALSE) {
+                               outifaceipv4 = i;
+                               ofacesetipv4 = ISC_TRUE;
+                       }
+                       else if ((outifaceipv4 == -1) && !(inter_list[i].flags & INT_LOOPBACK))
+                               outifaceipv4 = -1;
+               }
+               if (inter_list[i].sin.ss_family == AF_INET6) {
+                       if((outifaceipv6 == -1) && !(inter_list[i].flags & INT_LOOPBACK) && 
+                               ofacesetipv6 == ISC_FALSE) {
+                               outifaceipv6 = i;
+                               ofacesetipv6 = ISC_TRUE;
+                       }
+                       else if ((outifaceipv6 == -1) && !(inter_list[i].flags & INT_LOOPBACK))
+                               outifaceipv6 = -1;
+               }
        }
 
        /*
@@ -1964,11 +1995,59 @@ findinterface(
        )
 {
        int ind;
-
+       int i;
        SOCKET s;
-       int rtn, i;
+       int rtn;
        struct sockaddr_storage saddr;
-       int saddrlen = SOCKLEN(addr);
+       int saddrlen;
+       u_int32 amask, imask;
+       u_int32 laddr, iaddr, maddr;
+
+       /*
+        * If there is only one outgoing interface we already know the interface
+        *
+       if (addr->ss_family == AF_INET && outifaceipv4 != -1) {
+               return (&inter_list[outifaceipv4]);
+       }
+       if (addr->ss_family == AF_INET6 && outifaceipv6 != -1) {
+               return (&inter_list[outifaceipv6]);
+       }
+
+       /*
+        * If we got this far we need to try and match the
+        * network part of the address
+        */
+       for (i= nwilds; i < ninterfaces; i++)
+       {
+               /*
+                * For IPv4 we can check the network mask to see if
+                * we have a match on the outgoing interface
+                */
+               if (addr->ss_family == AF_INET) {
+                       laddr = htonl(((struct sockaddr_in*)addr)->sin_addr.s_addr);
+                       maddr = ((struct sockaddr_in*)&inter_list[i].mask)->sin_addr.s_addr;
+                       iaddr = ((struct sockaddr_in*)&inter_list[i])->sin_addr.s_addr;
+
+                       amask = (((struct sockaddr_in*)addr)->sin_addr.s_addr &
+                           ((struct sockaddr_in*)&inter_list[i].mask)->sin_addr.s_addr);
+                       amask = (((struct sockaddr_in*)addr)->sin_addr.s_addr &
+                           ((struct sockaddr_in*)&inter_list[i].mask)->sin_addr.s_addr);
+                       imask = (((struct sockaddr_in*)&inter_list[i])->sin_addr.s_addr &
+                           ((struct sockaddr_in*)&inter_list[i].mask)->sin_addr.s_addr);
+/*
+                       if ((((struct sockaddr_in*)&addr)->sin_addr.s_addr &
+                           ((struct sockaddr_in*)&inter_list[i].mask)->sin_addr.s_addr) ==
+                            (((struct sockaddr_in*)&inter_list[i])->sin_addr.s_addr &
+                           ((struct sockaddr_in*)&inter_list[i].mask)->sin_addr.s_addr))
+*/
+                       if (amask == imask)
+                            return (&inter_list[i]);
+               }
+       }
+
+
+
+       saddrlen = SOCKLEN(addr);
        ind = find_addr_in_list(addr);
        if (ind >= 0)
                return (&inter_list[ind]);
index dd98c3df7b16986b28a7f8af93919b418edcb725..fbb4444436b194398a8fe29521860a82d9bfa6a3 100644 (file)
@@ -95,6 +95,7 @@ int NT_set_process_priority(void);    /* Define this function */
 # define HAVE_IO_COMPLETION_PORT
 # define HAVE_SOCKADDR_IN6
 # define ISC_PLATFORM_NEEDNTOP
+# define ISC_PLATFORM_NEEDPTON
 
 #define ISC_PLATFORM_NEEDIN6ADDRANY
 
index 39b0e29ea927fd9e347c605a01366696bd96782c..091ee01f2fd91a0f24aa8ac12d644f9ab98d2ecd 100644 (file)
@@ -209,10 +209,18 @@ SOURCE=..\..\..\libntp\ieee754io.c
 # End Source File
 # Begin Source File
 
+SOURCE=..\..\..\libisc\inet_aton.c
+# End Source File
+# Begin Source File
+
 SOURCE=..\..\..\libisc\inet_ntop.c
 # End Source File
 # Begin Source File
 
+SOURCE=..\..\..\libisc\inet_pton.c
+# End Source File
+# Begin Source File
+
 SOURCE=..\libisc\interfaceiter.c
 # End Source File
 # Begin Source File