Add start of IPv6 implementation. Currently most of this is avoiding
authorJeremy Allison <jra@samba.org>
Thu, 11 Oct 2007 01:25:16 +0000 (18:25 -0700)
committerJeremy Allison <jra@samba.org>
Thu, 11 Oct 2007 01:25:16 +0000 (18:25 -0700)
IPv6 in winbindd, but moves most of the socket functions that were
wrongly in lib/util.c into lib/util_sock.c and provides generic
IPv4/6 independent versions of most things. Still lots of work
to do, but now I can see how I'll fix the access check code.
Nasty part that remains is the name resolution code which is
used to returning arrays of in_addr structs.
Jeremy.
(This used to be commit 3f6bd0e1ec5cc6670f3d08f76fc2cd94c9cd1a08)

46 files changed:
source3/auth/auth_server.c
source3/client/client.c
source3/include/interfaces.h
source3/include/smb.h
source3/lib/access.c
source3/lib/interface.c
source3/lib/interfaces.c
source3/lib/util.c
source3/lib/util_sock.c
source3/lib/wins_srv.c
source3/librpc/ndr/ndr_basic.c
source3/libsmb/cliconnect.c
source3/libsmb/clidfs.c
source3/libsmb/dsgetdcname.c
source3/libsmb/libsmbclient.c
source3/libsmb/namequery.c
source3/libsmb/namequery_dc.c
source3/nmbd/nmbd.c
source3/nmbd/nmbd_become_dmb.c
source3/nmbd/nmbd_browsesync.c
source3/nmbd/nmbd_incomingrequests.c
source3/nmbd/nmbd_lmhosts.c
source3/nmbd/nmbd_logonnames.c
source3/nmbd/nmbd_namequery.c
source3/nmbd/nmbd_packets.c
source3/nmbd/nmbd_processlogon.c
source3/nmbd/nmbd_subnetdb.c
source3/nmbd/nmbd_synclists.c
source3/nmbd/nmbd_winsproxy.c
source3/nmbd/nmbd_winsserver.c
source3/nmbd/nmbd_workgroupdb.c
source3/nsswitch/wins.c
source3/rpc_server/srv_spoolss_nt.c
source3/smbd/server.c
source3/torture/locktest.c
source3/torture/masktest.c
source3/torture/torture.c
source3/utils/net.c
source3/utils/net_dns.c
source3/utils/netlookup.c
source3/utils/nmblookup.c
source3/utils/smbcacls.c
source3/utils/smbcquotas.c
source3/web/diagnose.c
source3/winbindd/winbindd_cm.c
source3/winbindd/winbindd_wins.c

index b7669e945cfb1f5f6ae6133b3144042ae6e5a8eb..44f36dc4cff413e87ecd362f66eda88a8cb7b018 100644 (file)
@@ -59,7 +59,7 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx)
                        continue;
                }
 
-               if (ismyip(dest_ip)) {
+               if (ismyip_v4(dest_ip)) {
                        DEBUG(1,("Password server loop - disabling password server %s\n",desthost));
                        continue;
                }
index 171d413b0ae546031058dc6485ff9fecf7126df6..4e916f6372ee5b1ba9f909d569ad304b66de029c 100644 (file)
@@ -3853,7 +3853,7 @@ static int do_message_op(void)
        snprintf(name_type_hex, sizeof(name_type_hex), "#%X", name_type);
        fstrcat(server_name, name_type_hex);
 
-        zero_ip(&ip);
+        zero_ip_v4(&ip);
        if (have_ip) 
                ip = dest_ip;
 
@@ -3994,7 +3994,7 @@ static int do_message_op(void)
                case 'I':
                        {
                                dest_ip = *interpret_addr2(poptGetOptArg(pc));
-                               if (is_zero_ip(dest_ip))
+                               if (is_zero_ip_v4(dest_ip))
                                        exit(1);
                                have_ip = True;
 
index 371f64292f61fe8845d6b5fd8784497bb18e7e4a..66ea151f02e89dc47fb344a6a1bb888bdeb93576 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
    This structure is used by lib/interfaces.c to return the list of network
    interfaces on the machine
 */
@@ -7,17 +7,8 @@
 
 struct iface_struct {
        char name[16];
-       sa_family_t sa_family;
-       union {
-               struct in_addr ip;
-#ifdef AF_INET6
-               struct in6_addr ip6;
-#endif
-       } iface_addr;
-       union {
-               struct in_addr netmask;
-#ifdef AF_INET6
-               struct in6_addr netmask6;
-#endif
-       } iface_netmask;
+       int flags;
+       struct sockaddr_storage ip;
+       struct sockaddr_storage netmask;
+       struct sockaddr_storage bcast;
 };
index 75ec4363d0cbf6813aec4e48ca4a637110518526..7386613029521eb2b4613399e9b577668a19238e 100644 (file)
@@ -726,9 +726,11 @@ struct server_info_struct {
 /* used for network interfaces */
 struct interface {
        struct interface *next, *prev;
-       struct in_addr ip;
-       struct in_addr bcast;
-       struct in_addr nmask;
+       char *name;
+       int flags;
+       struct sockaddr_storage ip;
+       struct sockaddr_storage netmask;
+       struct sockaddr_storage bcast;
 };
 
 /* Internal message queue for deferred opens. */
index 303e3ed4c491adb18a39e0a4aea775ea3183b5af..17f4c367ebf749f953cd8cd2322c4a290481a1bf 100644 (file)
@@ -279,7 +279,7 @@ static BOOL only_ipaddrs_in_list(const char** list)
                        continue;
                }
                
-               if (!is_ipaddress(*list)) {
+               if (!is_ipaddress_v4(*list)) {
                        /* 
                         * if we failed, make sure that it was not because the token
                         * was a network/netmask pair.  Only network/netmask pairs
index 5982d82e4722d9583e83d41641c9ea9f3ed06a49..1471a06f46cf0c5db3f01ee2163dfa34f7223fcc 100644 (file)
@@ -2,6 +2,7 @@
    Unix SMB/CIFS implementation.
    multiple interface handling
    Copyright (C) Andrew Tridgell 1992-1998
+   Copyright (C) Jeremy Allison 2007
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 static struct iface_struct *probed_ifaces;
 static int total_probed;
 
-struct in_addr allones_ip;
-struct in_addr loopback_ip;
-
 static struct interface *local_interfaces;
 
-#define ALLONES  ((uint32)0xFFFFFFFF)
-#define MKBCADDR(_IP, _NM) ((_IP & _NM) | (_NM ^ ALLONES))
-#define MKNETADDR(_IP, _NM) (_IP & _NM)
+/****************************************************************************
+ Check if an IP is one of mine.
+**************************************************************************/
+
+bool ismyaddr(const struct sockaddr_storage *ip)
+{
+       struct interface *i;
+       for (i=local_interfaces;i;i=i->next) {
+               if (addr_equal(&i->ip,ip)) {
+                       return true;
+               }
+       }
+       return false;
+}
+
+bool ismyip_v4(struct in_addr ip)
+{
+       struct sockaddr_storage ss;
+       in_addr_to_sockaddr_storage(&ss, ip);
+       return ismyaddr(&ss);
+}
 
 /****************************************************************************
  Try and find an interface that matches an ip. If we cannot, return NULL.
 **************************************************************************/
 
-static struct interface *iface_find(struct in_addr ip, BOOL CheckMask)
+static struct interface *iface_find(const struct sockaddr_storage *ip,
+                               bool check_mask)
 {
        struct interface *i;
-       if (is_zero_ip(ip)) return local_interfaces;
 
-       for (i=local_interfaces;i;i=i->next)
-               if (CheckMask) {
-                       if (same_net(i->ip,ip,i->nmask)) return i;
-               } else if ((i->ip).s_addr == ip.s_addr) return i;
+       if (is_address_any(ip)) {
+               return local_interfaces;
+       }
+
+       for (i=local_interfaces;i;i=i->next) {
+               if (check_mask) {
+                       if (same_net(ip, &i->ip, &i->netmask)) {
+                               return i;
+                       }
+               } else if (addr_equal(&i->ip, ip)) {
+                       return i;
+               }
+       }
 
        return NULL;
 }
 
+/****************************************************************************
+ Check if a packet is from a local (known) net.
+**************************************************************************/
+
+bool is_local_net(const struct sockaddr_storage *from)
+{
+       struct interface *i;
+       for (i=local_interfaces;i;i=i->next) {
+               if (same_net(from, &i->ip, &i->netmask)) {
+                       return true;
+               }
+       }
+       return false;
+}
+
+/****************************************************************************
+ Check if a packet is from a local (known) net.
+**************************************************************************/
+
+bool is_local_net_v4(struct in_addr from)
+{
+       struct sockaddr_storage ss;
+
+       in_addr_to_sockaddr_storage(&ss, from);
+       return is_local_net(&ss);
+}
+
+/****************************************************************************
+ How many interfaces do we have ?
+**************************************************************************/
+
+int iface_count(void)
+{
+       int ret = 0;
+       struct interface *i;
+
+       for (i=local_interfaces;i;i=i->next) {
+               ret++;
+       }
+       return ret;
+}
+
+/****************************************************************************
+ How many interfaces do we have (v4 only) ?
+**************************************************************************/
+
+int iface_count_v4(void)
+{
+       int ret = 0;
+       struct interface *i;
+
+       for (i=local_interfaces;i;i=i->next) {
+               if (i->ip.ss_family == AF_INET) {
+                       ret++;
+               }
+       }
+       return ret;
+}
+
+/****************************************************************************
+ Return a pointer to the in_addr of the first IPv4 interface.
+**************************************************************************/
+
+const struct in_addr *first_ipv4_iface(void)
+{
+       struct interface *i;
+
+       for (i=local_interfaces;i ;i=i->next) {
+               if (i->ip.ss_family == AF_INET) {
+                       break;
+               }
+       }
+
+       if (!i) {
+               return NULL;
+       }
+       return &((const struct sockaddr_in *)&i->ip)->sin_addr;
+}
+
+/****************************************************************************
+ Return the Nth interface.
+**************************************************************************/
+
+struct interface *get_interface(int n)
+{
+       struct interface *i;
+
+       for (i=local_interfaces;i && n;i=i->next) {
+               n--;
+       }
+
+       if (i) {
+               return i;
+       }
+       return NULL;
+}
+
+/****************************************************************************
+ Return IP sockaddr_storage of the Nth interface.
+**************************************************************************/
+
+const struct sockaddr_storage *iface_n_sockaddr_storage(int n)
+{
+       struct interface *i;
+
+       for (i=local_interfaces;i && n;i=i->next) {
+               n--;
+       }
+
+       if (i) {
+               return &i->ip;
+       }
+       return NULL;
+}
+
+/****************************************************************************
+ Return IPv4 of the Nth interface (if a v4 address). NULL otherwise.
+**************************************************************************/
+
+const struct in_addr *iface_n_ip_v4(int n)
+{
+       struct interface *i;
+
+       for (i=local_interfaces;i && n;i=i->next) {
+               n--;
+       }
+
+       if (i && i->ip.ss_family == AF_INET) {
+               return &((const struct sockaddr_in *)&i->ip)->sin_addr;
+       }
+       return NULL;
+}
+
+/****************************************************************************
+ Return IPv4 bcast of the Nth interface (if a v4 address). NULL otherwise.
+**************************************************************************/
+
+const struct in_addr *iface_n_bcast_v4(int n)
+{
+       struct interface *i;
+
+       for (i=local_interfaces;i && n;i=i->next) {
+               n--;
+       }
+
+       if (i && i->ip.ss_family == AF_INET) {
+               return &((const struct sockaddr_in *)&i->bcast)->sin_addr;
+       }
+       return NULL;
+}
+
+/****************************************************************************
+ Return bcast of the Nth interface.
+**************************************************************************/
+
+const struct sockaddr_storage *iface_n_bcast(int n)
+{
+       struct interface *i;
+
+       for (i=local_interfaces;i && n;i=i->next) {
+               n--;
+       }
+
+       if (i) {
+               return &i->bcast;
+       }
+       return NULL;
+}
+
+/* these 3 functions return the ip/bcast/nmask for the interface
+   most appropriate for the given ip address. If they can't find
+   an appropriate interface they return the requested field of the
+   first known interface. */
+
+const struct sockaddr_storage *iface_ip(const struct sockaddr_storage *ip)
+{
+       struct interface *i = iface_find(ip, true);
+       if (i) {
+               return &i->ip;
+       }
+
+       /* Search for the first interface with
+        * matching address family. */
+
+       for (i=local_interfaces;i;i=i->next) {
+               if (i->ip.ss_family == ip->ss_family) {
+                       return &i->ip;
+               }
+       }
+       return NULL;
+}
+
+/*
+  return True if a IP is directly reachable on one of our interfaces
+*/
+
+bool iface_local(struct sockaddr_storage *ip)
+{
+       return iface_find(ip, True) ? true : false;
+}
+
 /****************************************************************************
  Add an interface to the linked list of interfaces.
 ****************************************************************************/
 
-static void add_interface(struct in_addr ip, struct in_addr nmask)
+static void add_interface(const struct iface_struct *ifs)
 {
+       char addr[INET6_ADDRSTRLEN];
        struct interface *iface;
-       if (iface_find(ip, False)) {
-               DEBUG(3,("not adding duplicate interface %s\n",inet_ntoa(ip)));
+
+       if (iface_find(&ifs->ip, False)) {
+               DEBUG(3,("add_interface: not adding duplicate interface %s\n",
+                       print_sockaddr(addr, sizeof(addr),
+                               &ifs->ip, sizeof(struct sockaddr_storage)) ));
                return;
        }
 
-#if !defined(__s390__)
-       if (ip_equal(nmask, allones_ip)) {
+       if (!(ifs->flags & IFF_BROADCAST)) {
                DEBUG(3,("not adding non-broadcast interface %s\n",
-                                       inet_ntoa(ip)));
+                                       ifs->name ));
                return;
        }
-#endif
 
        iface = SMB_MALLOC_P(struct interface);
-       if (!iface) return;
+       if (!iface) {
+               return;
+       }
 
        ZERO_STRUCTPN(iface);
 
-       iface->ip = ip;
-       iface->nmask = nmask;
-       iface->bcast.s_addr = MKBCADDR(iface->ip.s_addr, iface->nmask.s_addr);
+       iface->name = SMB_STRDUP(ifs->name);
+       if (!iface->name) {
+               SAFE_FREE(iface);
+               return;
+       }
+       iface->flags = ifs->flags;
+       iface->ip = ifs->ip;
+       iface->netmask = ifs->netmask;
+       iface->bcast = ifs->bcast;
 
        DLIST_ADD(local_interfaces, iface);
 
-       DEBUG(2,("added interface ip=%s ",inet_ntoa(iface->ip)));
-       DEBUG(2,("bcast=%s ",inet_ntoa(iface->bcast)));
-       DEBUG(2,("nmask=%s\n",inet_ntoa(iface->nmask)));
+       DEBUG(2,("added interface %s ip=%s ",
+               iface->name,
+               print_sockaddr(addr, sizeof(addr),
+                       &iface->ip, sizeof(struct sockaddr_storage)) ));
+       DEBUG(2,("bcast=%s ",
+               print_sockaddr(addr, sizeof(addr),
+                       &iface->bcast,
+                       sizeof(struct sockaddr_storage)) ));
+       DEBUG(2,("netmask=%s\n",
+               print_sockaddr(addr, sizeof(addr),
+                       &iface->netmask,
+                       sizeof(struct sockaddr_storage)) ));
+}
+
+/****************************************************************************
+ Create a struct sockaddr_storage with the netmask bits set to 1.
+****************************************************************************/
+
+static bool make_netmask(struct sockaddr_storage *pss_out,
+                       const struct sockaddr_storage *pss_in,
+                       unsigned long masklen)
+{
+       *pss_out = *pss_in;
+       /* Now apply masklen bits of mask. */
+#if defined(AF_INET6)
+       if (pss_in->ss_family == AF_INET6) {
+               char *p = (char *)&((struct sockaddr_in6 *)pss_out)->sin6_addr;
+               unsigned int i;
+
+               if (masklen > 128) {
+                       return false;
+               }
+               for (i = 0; masklen >= 8; masklen -= 8, i++) {
+                       *p++ = 0xff;
+               }
+               /* Deal with the partial byte. */
+               *p++ &= (0xff & ~(0xff>>masklen));
+               i++;
+               for (;i < sizeof(struct in6_addr); i++) {
+                       *p++ = '\0';
+               }
+               return true;
+       }
+#endif
+       if (pss_in->ss_family == AF_INET) {
+               if (masklen > 32) {
+                       return false;
+               }
+               ((struct sockaddr_in *)pss_out)->sin_addr.s_addr =
+                       htonl(((0xFFFFFFFFL >> masklen) ^ 0xFFFFFFFFL));
+               return true;
+       }
+       return false;
+}
+
+/****************************************************************************
+ Create a struct sockaddr_storage set to the broadcast or network adress from
+ an incoming sockaddr_storage.
+****************************************************************************/
+
+static void make_bcast_or_net(struct sockaddr_storage *pss_out,
+                       const struct sockaddr_storage *pss_in,
+                       const struct sockaddr_storage *nmask,
+                       bool make_bcast)
+{
+       unsigned int i = 0, len = 0;
+       char *pmask = NULL;
+       char *p = NULL;
+       *pss_out = *pss_in;
+
+       /* Set all zero netmask bits to 1. */
+#if defined(AF_INET6)
+       if (pss_in->ss_family == AF_INET6) {
+               p = (char *)&((struct sockaddr_in6 *)pss_out)->sin6_addr;
+               pmask = (char *)&((struct sockaddr_in6 *)nmask)->sin6_addr;
+               len = 16;
+       }
+#endif
+       if (pss_in->ss_family == AF_INET) {
+               p = (char *)&((struct sockaddr_in *)pss_out)->sin_addr;
+               pmask = (char *)&((struct sockaddr_in *)nmask)->sin_addr;
+               len = 4;
+       }
+
+       for (i = 0; i < len; i++, p++, pmask++) {
+               if (make_bcast) {
+                       *p = (*p & *pmask) | (*pmask ^ 0xff);
+               } else {
+                       /* make_net */
+                       *p = (*p & *pmask);
+               }
+       }
+}
+
+static void make_bcast(struct sockaddr_storage *pss_out,
+                       const struct sockaddr_storage *pss_in,
+                       const struct sockaddr_storage *nmask)
+{
+       make_bcast_or_net(pss_out, pss_in, nmask, true);
+}
+
+static void make_net(struct sockaddr_storage *pss_out,
+                       const struct sockaddr_storage *pss_in,
+                       const struct sockaddr_storage *nmask)
+{
+       make_bcast_or_net(pss_out, pss_in, nmask, false);
 }
 
 /****************************************************************************
@@ -98,68 +437,121 @@ static void add_interface(struct in_addr ip, struct in_addr nmask)
 
 static void interpret_interface(char *token)
 {
-       struct in_addr ip, nmask;
+       struct sockaddr_storage ss;
+       struct sockaddr_storage ss_mask;
+       struct sockaddr_storage ss_net;
+       struct sockaddr_storage ss_bcast;
+       struct iface_struct ifs;
        char *p;
-       int i, added=0;
-
-        zero_ip(&ip);
-        zero_ip(&nmask);
+       int i;
+       bool added=false;
+       bool goodaddr = false;
 
        /* first check if it is an interface name */
        for (i=0;i<total_probed;i++) {
                if (gen_fnmatch(token, probed_ifaces[i].name) == 0) {
-                       add_interface(probed_ifaces[i].iface_addr.ip,
-                                     probed_ifaces[i].iface_netmask.netmask);
-                       added = 1;
+                       add_interface(&probed_ifaces[i]);
+                       added = true;
                }
        }
-       if (added) return;
+       if (added) {
+               return;
+       }
 
        /* maybe it is a DNS name */
        p = strchr_m(token,'/');
-       if (!p) {
-               ip = *interpret_addr2(token);
+       if (!p && interpret_string_addr(&ss, token)) {
                for (i=0;i<total_probed;i++) {
-                       if (ip.s_addr == probed_ifaces[i].iface_addr.ip.s_addr
-                                       && !ip_equal(allones_ip,
-                                   probed_ifaces[i].iface_netmask.netmask)) {
-                               add_interface(probed_ifaces[i].iface_addr.ip,
-                                     probed_ifaces[i].iface_netmask.netmask);
+                       if (addr_equal(&ss, &probed_ifaces[i].ip)) {
+                               add_interface(&probed_ifaces[i]);
                                return;
                        }
                }
-               DEBUG(2,("can't determine netmask for %s\n", token));
+               DEBUG(2,("interpret_interface: "
+                       "can't determine interface for %s\n",
+                       token));
                return;
        }
 
        /* parse it into an IP address/netmasklength pair */
        *p = 0;
-       ip = *interpret_addr2(token);
+       goodaddr = interpret_string_addr(&ss, token);
        *p++ = '/';
 
+       if (!goodaddr) {
+               DEBUG(2,("interpret_interface: "
+                       "can't determine interface for %s\n",
+                       token));
+               return;
+       }
+
        if (strlen(p) > 2) {
-               nmask = *interpret_addr2(p);
+               goodaddr = interpret_string_addr(&ss_mask, p);
+               if (!goodaddr) {
+                       DEBUG(2,("interpret_interface: "
+                               "can't determine netmask from %s\n",
+                               p));
+                       return;
+               }
        } else {
-               nmask.s_addr = htonl(((ALLONES >> atoi(p)) ^ ALLONES));
+               char *endp = NULL;
+               unsigned long val = strtoul(p, &endp, 0);
+               if (p == endp || (endp && *endp != '\0')) {
+                       DEBUG(2,("interpret_interface: "
+                               "can't determine netmask value from %s\n",
+                               p));
+                       return;
+               }
+               if (!make_netmask(&ss_mask, &ss, val)) {
+                       DEBUG(2,("interpret_interface: "
+                               "can't apply netmask value %lu from %s\n",
+                               val,
+                               p));
+                       return;
+               }
        }
 
-       /* maybe the first component was a broadcast address */
-       if (ip.s_addr == MKBCADDR(ip.s_addr, nmask.s_addr) ||
-           ip.s_addr == MKNETADDR(ip.s_addr, nmask.s_addr)) {
+       make_bcast(&ss_bcast, &ss, &ss_mask);
+       make_net(&ss_net, &ss, &ss_mask);
+
+       /* Maybe the first component was a broadcast address. */
+       if (addr_equal(&ss_bcast, &ss) || addr_equal(&ss_net, &ss)) {
                for (i=0;i<total_probed;i++) {
-                       if (same_net(ip, probed_ifaces[i].iface_addr.ip,
-                                               nmask)) {
-                               add_interface(probed_ifaces[i].iface_addr.ip,
-                                               nmask);
+                       if (same_net(&ss, &probed_ifaces[i].ip, &ss_mask)) {
+                               /* Temporarily replace netmask on
+                                * the detected interface - user knows
+                                * best.... */
+                               struct sockaddr_storage saved_mask =
+                                       probed_ifaces[i].netmask;
+                               probed_ifaces[i].netmask = ss_mask;
+                               DEBUG(2,("interpret_interface: "
+                                       "using netmask value %s from "
+                                       "config file on interface %s\n",
+                                       p,
+                                       probed_ifaces[i].name));
+                               add_interface(&probed_ifaces[i]);
+                               probed_ifaces[i].netmask = saved_mask;
                                return;
                        }
                }
-               DEBUG(2,("Can't determine ip for broadcast address %s\n",
-                                       token));
+               DEBUG(2,("interpret_interface: Can't determine ip for "
+                       "broadcast address %s\n",
+                       token));
                return;
        }
 
-       add_interface(ip, nmask);
+       /* Just fake up the interface definition. User knows best. */
+
+       DEBUG(2,("interpret_interface: Adding interface %s\n",
+               token));
+
+       ZERO_STRUCT(ifs);
+       safe_strcpy(ifs.name, token, sizeof(ifs.name)-1);
+       ifs.flags = IFF_BROADCAST;
+       ifs.ip = ss;
+       ifs.netmask = ss_mask;
+       ifs.bcast = ss_bcast;
+       add_interface(&ifs);
 }
 
 /****************************************************************************
@@ -168,14 +560,9 @@ static void interpret_interface(char *token)
 
 void load_interfaces(void)
 {
-       const char **ptr;
-       int i;
        struct iface_struct ifaces[MAX_INTERFACES];
-
-       ptr = lp_interfaces();
-
-       allones_ip = *interpret_addr2("255.255.255.255");
-       loopback_ip = *interpret_addr2("127.0.0.1");
+       const char **ptr = lp_interfaces();
+       int i;
 
        SAFE_FREE(probed_ifaces);
 
@@ -183,11 +570,11 @@ void load_interfaces(void)
        while (local_interfaces) {
                struct interface *iface = local_interfaces;
                DLIST_REMOVE(local_interfaces, local_interfaces);
-               ZERO_STRUCTPN(iface);
+               SAFE_FREE(iface->name);
                SAFE_FREE(iface);
        }
 
-       /* probe the kernel for interfaces */
+       /* Probe the kernel for interfaces */
        total_probed = get_interfaces(ifaces, MAX_INTERFACES);
 
        if (total_probed > 0) {
@@ -208,15 +595,8 @@ void load_interfaces(void)
                        exit(1);
                }
                for (i=0;i<total_probed;i++) {
-                       if (
-#if !defined(__s390__)
-                           probed_ifaces[i].iface_netmask.netmask.s_addr !=
-                                allones_ip.s_addr &&
-#endif
-                           probed_ifaces[i].iface_addr.ip.s_addr !=
-                                loopback_ip.s_addr) {
-                               add_interface(probed_ifaces[i].iface_addr.ip,
-                                       probed_ifaces[i].iface_netmask.netmask);
+                       if (probed_ifaces[i].flags & IFF_BROADCAST) {
+                               add_interface(&probed_ifaces[i]);
                        }
                }
                return;
@@ -244,7 +624,7 @@ void gfree_interfaces(void)
        while (local_interfaces) {
                struct interface *iface = local_interfaces;
                DLIST_REMOVE(local_interfaces, local_interfaces);
-               ZERO_STRUCTPN(iface);
+               SAFE_FREE(iface->name);
                SAFE_FREE(iface);
        }
 
@@ -255,7 +635,7 @@ void gfree_interfaces(void)
  Return True if the list of probed interfaces has changed.
 ****************************************************************************/
 
-BOOL interfaces_changed(void)
+bool interfaces_changed(void)
 {
        int n;
        struct iface_struct ifaces[MAX_INTERFACES];
@@ -263,115 +643,9 @@ BOOL interfaces_changed(void)
        n = get_interfaces(ifaces, MAX_INTERFACES);
 
        if ((n > 0 )&& (n != total_probed ||
-           memcmp(ifaces, probed_ifaces, sizeof(ifaces[0])*n))) {
-               return True;
-       }
-
-       return False;
-}
-
-/****************************************************************************
- Check if an IP is one of mine.
-**************************************************************************/
-
-BOOL ismyip(struct in_addr ip)
-{
-       struct interface *i;
-       for (i=local_interfaces;i;i=i->next)
-               if (ip_equal(i->ip,ip)) return True;
-       return False;
-}
-
-/****************************************************************************
- Check if a packet is from a local (known) net.
-**************************************************************************/
-
-BOOL is_local_net(struct in_addr from)
-{
-       struct interface *i;
-       for (i=local_interfaces;i;i=i->next) {
-               if((from.s_addr & i->nmask.s_addr) ==
-                  (i->ip.s_addr & i->nmask.s_addr))
-                       return True;
+                       memcmp(ifaces, probed_ifaces, sizeof(ifaces[0])*n))) {
+               return true;
        }
-       return False;
-}
-
-/****************************************************************************
- How many interfaces do we have
-**************************************************************************/
-
-int iface_count(void)
-{
-       int ret = 0;
-       struct interface *i;
-
-       for (i=local_interfaces;i;i=i->next)
-               ret++;
-       return ret;
-}
-
-/****************************************************************************
- Return the Nth interface.
-**************************************************************************/
-
-struct interface *get_interface(int n)
-{
-       struct interface *i;
-
-       for (i=local_interfaces;i && n;i=i->next)
-               n--;
-
-       if (i) return i;
-       return NULL;
-}
-
-/****************************************************************************
- Return IP of the Nth interface.
-**************************************************************************/
-
-struct in_addr *iface_n_ip(int n)
-{
-       struct interface *i;
-
-       for (i=local_interfaces;i && n;i=i->next)
-               n--;
-
-       if (i) return &i->ip;
-       return NULL;
-}
-
-/****************************************************************************
- Return bcast of the Nth interface.
-**************************************************************************/
-
-struct in_addr *iface_n_bcast(int n)
-{
-       struct interface *i;
-
-       for (i=local_interfaces;i && n;i=i->next)
-               n--;
-
-       if (i) return &i->bcast;
-       return NULL;
-}
 
-/* these 3 functions return the ip/bcast/nmask for the interface
-   most appropriate for the given ip address. If they can't find
-   an appropriate interface they return the requested field of the
-   first known interface. */
-
-struct in_addr *iface_ip(struct in_addr ip)
-{
-       struct interface *i = iface_find(ip, True);
-       return(i ? &i->ip : &local_interfaces->ip);
-}
-
-/*
-  return True if a IP is directly reachable on one of our interfaces
-*/
-
-BOOL iface_local(struct in_addr ip)
-{
-       return iface_find(ip, True) ? True : False;
+       return false;
 }
index 632b38f2b63541bb24e404b7ec207e5e2d123ba4..c56155c64e75fefdecfd42ae3f3042e5ead0f42d 100644 (file)
@@ -101,6 +101,7 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces)
        struct ifaddrs *iflist = NULL;
        struct ifaddrs *ifptr = NULL;
        int total = 0;
+       size_t copy_size;
 
        if (getifaddrs(&iflist) < 0) {
                return -1;
@@ -111,25 +112,40 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces)
                        ifptr != NULL && total < max_interfaces;
                        ifptr = ifptr->ifa_next) {
 
+               memset(&ifaces[total], '\0', sizeof(ifaces[total]));
+
+               copy_size = sizeof(struct sockaddr_in);
+
                if (!ifptr->ifa_addr || !ifptr->ifa_netmask) {
                        continue;
                }
 
-               /* Skip ipv6 for now. */
-               if (ifptr->ifa_addr->sa_family != AF_INET) {
-                       continue;
-               }
-               if (!(ifptr->ifa_flags & IFF_UP)) {
+               ifaces[total].flags = ifptr->ifa_flags;
+
+               /* Check the interface is up. */
+               if (!(ifaces[total].flags & IFF_UP)) {
                        continue;
                }
 
-               ifaces[total].sa_family = ifptr->ifa_addr->sa_family;
-
-               ifaces[total].iface_addr.ip =
-                       ((struct sockaddr_in *)ifptr->ifa_addr)->sin_addr;
+#ifdef AF_INET6
+               if (ifptr->ifa_addr->sa_family == AF_INET6) {
+                       copy_size = sizeof(struct sockaddr_in6);
+               }
+#endif
 
-               ifaces[total].iface_netmask.netmask =
-                       ((struct sockaddr_in *)ifptr->ifa_netmask)->sin_addr;
+               memcpy(&ifaces[total].ip, ifptr->ifa_addr, copy_size);
+               memcpy(&ifaces[total].netmask, ifptr->ifa_netmask, copy_size);
+               if (ifaces[total].flags & IFF_BROADCAST) {
+                       memcpy(&ifaces[total].bcast,
+                               ifptr->ifa_broadaddr,
+                               copy_size);
+               } else if (ifaces[total].flags & IFF_POINTOPOINT) {
+                       memcpy(&ifaces[total].bcast,
+                               ifptr->ifa_dstaddr,
+                               copy_size);
+               } else {
+                       continue;
+               }
 
                strncpy(ifaces[total].name, ifptr->ifa_name,
                                sizeof(ifaces[total].name)-1);
@@ -162,9 +178,6 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces)
        int fd, i, n;
        struct ifreq *ifr=NULL;
        int total = 0;
-       struct in_addr ipaddr;
-       struct in_addr nmask;
-       char *iname;
 
        if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
                return -1;
@@ -184,32 +197,54 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces)
 
        /* Loop through interfaces, looking for given IP address */
        for (i=n-1;i>=0 && total < max_interfaces;i--) {
-               if (ioctl(fd, SIOCGIFADDR, &ifr[i]) != 0) {
+
+               memset(&ifaces[total], '\0', sizeof(ifaces[total]));
+
+               /* Check the interface is up. */
+               if (ioctl(fd, SIOCGIFFLAGS, &ifr[i]) != 0) {
                        continue;
                }
 
-               iname = ifr[i].ifr_name;
-               ipaddr = (*(struct sockaddr_in *)&ifr[i].ifr_addr).sin_addr;
+               ifaces[total].flags = ifr[i].ifr_flags;
 
-               if (ioctl(fd, SIOCGIFFLAGS, &ifr[i]) != 0) {
+               if (!(flags & IFF_UP)) {
                        continue;
                }
 
-               if (!(ifr[i].ifr_flags & IFF_UP)) {
+               if (ioctl(fd, SIOCGIFADDR, &ifr[i]) != 0) {
                        continue;
                }
 
+               strncpy(ifaces[total].name, ifr[i].ifr_name,
+                               sizeof(ifaces[total].name)-1);
+               ifaces[total].name[sizeof(ifaces[total].name)-1] = 0;
+
+               memcpy(&ifaces[total].ip, &ifr[i].ifr_addr,
+                               sizeof(struct sockaddr_in));
+
                if (ioctl(fd, SIOCGIFNETMASK, &ifr[i]) != 0) {
                        continue;
                }
 
-               nmask = ((struct sockaddr_in *)&ifr[i].ifr_addr)->sin_addr;
+               memcpy(&ifaces[total].netmask, &ifr[i].ifr_netmask,
+                               sizeof(struct sockaddr_in));
+
+               if (ifaces[total].flags & IFF_BROADCAST) {
+                       if (ioctl(fd, SIOCGIFBRDADDR, &ifr[i]) != 0) {
+                               continue;
+                       }
+                       memcpy(&ifaces[total].bcast, &ifr[i].ifr_broadaddr,
+                               sizeof(struct sockaddr_in));
+               } else if (ifaces[total].flags & IFF_POINTOPOINT) {
+                       if (ioctl(fd, SIOCGIFDSTADDR, &ifr[i]) != 0) {
+                               continue;
+                       }
+                       memcpy(&ifaces[total].bcast, &ifr[i].ifr_dstaddr,
+                               sizeof(struct sockaddr_in));
+               } else {
+                       continue;
+               }
 
-               strncpy(ifaces[total].name, iname, sizeof(ifaces[total].name)-1);
-               ifaces[total].name[sizeof(ifaces[total].name)-1] = 0;
-               ifaces[total].sa_family = AF_INET;
-               ifaces[total].iface_addr.ip = ipaddr;
-               ifaces[total].iface_netmask.netmask = nmask;
                total++;
        }
 
@@ -239,9 +274,6 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces)
        int fd, i, n;
        struct ifreq *ifr=NULL;
        int total = 0;
-       struct in_addr ipaddr;
-       struct in_addr nmask;
-       char *iname;
 
        if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
                return -1;
@@ -271,6 +303,9 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces)
        /* Loop through interfaces */
 
        for (i = 0; i<n && total < max_interfaces; i++) {
+
+               memset(&ifaces[total], '\0', sizeof(ifaces[total]));
+
                ifreq = ifr[i];
 
                strioctl.ic_cmd = SIOCGIFFLAGS;
@@ -280,7 +315,9 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces)
                        continue;
                }
 
-               if (!(ifreq.ifr_flags & IFF_UP)) {
+               ifaces[total].flags = ifreq.ifr_flags;
+
+               if (!(ifaces[total].flags & IFF_UP)) {
                        continue;
                }
 
@@ -291,8 +328,12 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces)
                        continue;
                }
 
-               ipaddr = (*(struct sockaddr_in *) &ifreq.ifr_addr).sin_addr;
-               iname = ifreq.ifr_name;
+               strncpy(ifaces[total].name, iname,
+                               sizeof(ifaces[total].name)-1);
+               ifaces[total].name[sizeof(ifaces[total].name)-1] = 0;
+
+               memcpy(&ifaces[total].ip, &ifreq.ifr_addr,
+                               sizeof(struct sockaddr_in));
 
                strioctl.ic_cmd = SIOCGIFNETMASK;
                strioctl.ic_dp  = (char *)&ifreq;
@@ -301,13 +342,30 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces)
                        continue;
                }
 
-               nmask = ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr;
+               memcpy(&ifaces[total].netmask, &ifreq.ifr_addr,
+                               sizeof(struct sockaddr_in));
 
-               strncpy(ifaces[total].name, iname, sizeof(ifaces[total].name)-1);
-               ifaces[total].name[sizeof(ifaces[total].name)-1] = 0;
-               ifaces[total].sa_family = AF_INET;
-               ifaces[total].iface_addr.ip = ipaddr;
-               ifaces[total].iface_netmask.netmask = nmask;
+               if (ifaces[total].flags & IFF_BROADCAST) {
+                       strioctl.ic_cmd = SIOCGIFBRDADDR;
+                       strioctl.ic_dp  = (char *)&ifreq;
+                       strioctl.ic_len = sizeof(struct ifreq);
+                       if (ioctl(fd, I_STR, &strioctl) != 0) {
+                               continue;
+                       }
+                       memcpy(&ifaces[total].bcast, &ifreq.ifr_broadaddr,
+                               sizeof(struct sockaddr_in));
+               } else if (ifaces[total].flags & IFF_POINTOPOINT) {
+                       strioctl.ic_cmd = SIOCGIFDSTADDR;
+                       strioctl.ic_dp  = (char *)&ifreq;
+                       strioctl.ic_len = sizeof(struct ifreq);
+                       if (ioctl(fd, I_STR, &strioctl) != 0) {
+                               continue;
+                       }
+                       memcpy(&ifaces[total].bcast, &ifreq.ifr_dstaddr,
+                               sizeof(struct sockaddr_in));
+               } else {
+                       continue;
+               }
 
                total++;
        }
@@ -331,9 +389,6 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces)
        int fd, i;
        struct ifconf ifc;
        struct ifreq *ifr=NULL;
-       struct in_addr ipaddr;
-       struct in_addr nmask;
-       char *iname;
        int total = 0;
 
        if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
@@ -357,34 +412,54 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces)
        while (i > 0 && total < max_interfaces) {
                uint_t inc;
 
+               memset(&ifaces[total], '\0', sizeof(ifaces[total]));
+
                inc = ifr->ifr_addr.sa_len;
 
-               if (ioctl(fd, SIOCGIFADDR, ifr) != 0) {
+               if (ioctl(fd, SIOCGIFFLAGS, ifr) != 0) {
                        goto next;
                }
 
-               ipaddr = (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr;
-               iname = ifr->ifr_name;
+               ifaces[total].flags = ifr->ifr_flags;
 
-               if (ioctl(fd, SIOCGIFFLAGS, ifr) != 0) {
+               if (!(ifaces[total].flags & IFF_UP)) {
                        goto next;
                }
 
-               if (!(ifr->ifr_flags & IFF_UP)) {
+               if (ioctl(fd, SIOCGIFADDR, ifr) != 0) {
                        goto next;
                }
 
+               memcpy(&ifaces[total].ip, &ifr->ifr_addr,
+                               sizeof(struct sockaddr_in));
+
+               strncpy(ifaces[total].name, ifr->ifr_name,
+                               sizeof(ifaces[total].name)-1);
+               ifaces[total].name[sizeof(ifaces[total].name)-1] = 0;
+
                if (ioctl(fd, SIOCGIFNETMASK, ifr) != 0) {
                        goto next;
                }
 
-               nmask = ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr;
+               memcpy(&ifaces[total].netmask, &ifr->ifr_addr,
+                               sizeof(struct sockaddr_in));
+
+               if (ifaces[total].flags & IFF_BROADCAST) {
+                       if (ioctl(fd, SIOCGIFBRDADDR, &ifr[i]) != 0) {
+                               continue;
+                       }
+                       memcpy(&ifaces[total].bcast, &ifr[i].ifr_broadaddr,
+                               sizeof(struct sockaddr_in));
+               } else if (ifaces[total].flags & IFF_POINTOPOINT) {
+                       if (ioctl(fd, SIOCGIFDSTADDR, &ifr[i]) != 0) {
+                               continue;
+                       }
+                       memcpy(&ifaces[total].bcast, &ifr[i].ifr_dstaddr,
+                               sizeof(struct sockaddr_in));
+               } else {
+                       continue;
+               }
 
-               strncpy(ifaces[total].name, iname, sizeof(ifaces[total].name)-1);
-               ifaces[total].name[sizeof(ifaces[total].name)-1] = 0;
-               ifaces[total].sa_family = AF_INET;
-               ifaces[total].iface_addr.ip = ipaddr;
-               ifaces[total].iface_netmask.netmask = nmask;
 
                total++;
 
@@ -421,25 +496,36 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces)
 static int iface_comp(struct iface_struct *i1, struct iface_struct *i2)
 {
        int r;
-       r = strcmp(i1->name, i2->name);
-       if (r) {
-               return r;
-       }
-       r = i1->sa_family - i2->sa_family;
-       if (r) {
-               return r;
-       }
 
 #ifdef AF_INET6
-       if (i1->sa_family == AF_INET6) {
-               r = memcmp(&i1->iface_addr.ip6,
-                               &i2->iface_addr.ip6,
+       /*
+        * If we have IPv6 - sort these interfaces lower
+        * than any IPv4 ones.
+        */
+       if (i1->ip.ss_family == AF_INET6 &&
+                       i2->ip.ss_family == AF_INET) {
+               return -1;
+       } else if (i1->ip.ss_family == AF_INET &&
+                       i2->ip.ss_family == AF_INET6) {
+               return 1;
+       }
+
+       if (i1->ip.ss_family == AF_INET6) {
+               struct sockaddr_in6 *s1 = (struct sockaddr_in6 *)&i1->ip;
+               struct sockaddr_in6 *s2 = (struct sockaddr_in6 *)&i2->ip;
+
+               r = memcmp(&s1->sin6_addr,
+                               &s2->sin6_addr,
                                sizeof(struct in6_addr));
                if (r) {
                        return r;
                }
-               r = memcmp(&i1->iface_netmask.netmask6,
-                               &i1->iface_netmask.netmask6,
+
+               s1 = (struct sockaddr_in6 *)&i1->netmask;
+               s2 = (struct sockaddr_in6 *)&i2->netmask;
+
+               r = memcmp(&s1->sin6_addr,
+                               &s2->sin6_addr,
                                sizeof(struct in6_addr));
                if (r) {
                        return r;
@@ -447,14 +533,21 @@ static int iface_comp(struct iface_struct *i1, struct iface_struct *i2)
        }
 #endif
 
-       if (i1->sa_family == AF_INET) {
-               r = ntohl(i1->iface_addr.ip.s_addr) -
-                       ntohl(i2->iface_addr.ip.s_addr);
+       if (i1->ip.ss_family == AF_INET) {
+               struct sockaddr_in *s1 = (struct sockaddr_in *)&i1->ip;
+               struct sockaddr_in *s2 = (struct sockaddr_in *)&i2->ip;
+
+               r = ntohl(s1->sin_addr.s_addr) -
+                       ntohl(s2->sin_addr.s_addr);
                if (r) {
                        return r;
                }
-               r = ntohl(i1->iface_netmask.netmask.s_addr) -
-                       ntohl(i2->iface_netmask.netmask.s_addr);
+
+               s1 = (struct sockaddr_in *)&i1->netmask;
+               s2 = (struct sockaddr_in *)&i2->netmask;
+
+               r = ntohl(s1->sin_addr.s_addr) -
+                       ntohl(s2->sin_addr.s_addr);
        }
        return r;
 }
@@ -503,15 +596,26 @@ int get_interfaces(struct iface_struct *ifaces, int max_interfaces)
 
        for (i=0;i<total;i++) {
                char addr[INET6_ADDRSTRLEN];
+               int ret;
                printf("%-10s ", ifaces[i].name);
-               printf("IP=%s ", inet_ntop(ifaces[i].sa_family,
-                                       (const void *)&ifaces[i].iface_addr.ip,
-                                       addr,
-                                       sizeof(addr)));
-               printf("NETMASK=%s\n", inet_ntop(ifaces[i].sa_family,
-                               (const void *)&ifaces[i].iface_netmask.netmask,
-                               addr,
-                               sizeof(addr)));
+               addr[0] = '\0';
+               ret = getnameinfo((struct sockaddr *)&ifaces[i].ip,
+                               sizeof(ifaces[i].ip),
+                               addr, sizeof(addr),
+                               NULL, 0, NI_NUMERICHOST);
+               printf("IP=%s ", addr);
+               addr[0] = '\0';
+               ret = getnameinfo((struct sockaddr *)&ifaces[i].netmask,
+                               sizeof(ifaces[i].netmask),
+                               addr, sizeof(addr),
+                               NULL, 0, NI_NUMERICHOST);
+               printf("NETMASK=%s ", addr);
+               addr[0] = '\0';
+               ret = getnameinfo((struct sockaddr *)&ifaces[i].bcast,
+                               sizeof(ifaces[i].bcast),
+                               addr, sizeof(addr),
+                               NULL, 0, NI_NUMERICHOST);
+               printf("BCAST=%s\n", addr);
        }
        return 0;
 }
index adbebb04d458544fd19ea489d705ebfdf03e1217..f457e53c47f4aa160342815a6dc6a45f788582b9 100644 (file)
@@ -1286,102 +1286,6 @@ int interpret_protocol(const char *str,int def)
        return(def);
 }
 
-/****************************************************************************
- Return true if a string could be a pure IP address.
-****************************************************************************/
-
-BOOL is_ipaddress(const char *str)
-{
-       BOOL pure_address = True;
-       int i;
-  
-       for (i=0; pure_address && str[i]; i++)
-               if (!(isdigit((int)str[i]) || str[i] == '.'))
-                       pure_address = False;
-
-       /* Check that a pure number is not misinterpreted as an IP */
-       pure_address = pure_address && (strchr_m(str, '.') != NULL);
-
-       return pure_address;
-}
-
-/****************************************************************************
- Interpret an internet address or name into an IP address in 4 byte form.
-****************************************************************************/
-
-uint32 interpret_addr(const char *str)
-{
-       struct hostent *hp;
-       uint32 res;
-
-       if (strcmp(str,"0.0.0.0") == 0)
-               return(0);
-       if (strcmp(str,"255.255.255.255") == 0)
-               return(0xFFFFFFFF);
-
-  /* if it's in the form of an IP address then get the lib to interpret it */
-       if (is_ipaddress(str)) {
-               res = inet_addr(str);
-       } else {
-               /* otherwise assume it's a network name of some sort and use 
-                       sys_gethostbyname */
-               if ((hp = sys_gethostbyname(str)) == 0) {
-                       DEBUG(3,("sys_gethostbyname: Unknown host. %s\n",str));
-                       return 0;
-               }
-
-               if(hp->h_addr == NULL) {
-                       DEBUG(3,("sys_gethostbyname: host address is invalid for host %s\n",str));
-                       return 0;
-               }
-               putip((char *)&res,(char *)hp->h_addr);
-       }
-
-       if (res == (uint32)-1)
-               return(0);
-
-       return(res);
-}
-
-/*******************************************************************
- A convenient addition to interpret_addr().
-******************************************************************/
-
-struct in_addr *interpret_addr2(const char *str)
-{
-       static struct in_addr ret;
-       uint32 a = interpret_addr(str);
-       ret.s_addr = a;
-       return(&ret);
-}
-
-/*******************************************************************
- Check if an IP is the 0.0.0.0.
-******************************************************************/
-
-BOOL is_zero_ip(struct in_addr ip)
-{
-       uint32 a;
-       putip((char *)&a,(char *)&ip);
-       return(a == 0);
-}
-
-/*******************************************************************
- Set an IP to 0.0.0.0.
-******************************************************************/
-
-void zero_ip(struct in_addr *ip)
-{
-        static BOOL init;
-        static struct in_addr ipzero;
-
-        if (!init) {
-                ipzero = *interpret_addr2("0.0.0.0");
-                init = True;
-        }
-
-        *ip = ipzero;
-}
 
 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
 /******************************************************************
@@ -1506,22 +1410,6 @@ char *automount_lookup(const char *user_name)
 #endif /* WITH_NISPLUS_HOME */
 #endif
 
-/*******************************************************************
- Are two IPs on the same subnet?
-********************************************************************/
-
-BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
-{
-       uint32 net1,net2,nmask;
-
-       nmask = ntohl(mask.s_addr);
-       net1  = ntohl(ip1.s_addr);
-       net2  = ntohl(ip2.s_addr);
-            
-       return((net1 & nmask) == (net2 & nmask));
-}
-
-
 /****************************************************************************
  Check if a process exists. Does this work on all unixes?
 ****************************************************************************/
@@ -2097,83 +1985,6 @@ BOOL is_myname(const char *s)
        return(ret);
 }
 
-BOOL is_myname_or_ipaddr(const char *s)
-{
-       fstring name, dnsname;
-       char *servername;
-
-       if ( !s )
-               return False;
-
-       /* santize the string from '\\name' */
-
-       fstrcpy( name, s );
-
-       servername = strrchr_m( name, '\\' );
-       if ( !servername )
-               servername = name;
-       else
-               servername++;
-
-       /* optimize for the common case */
-
-       if (strequal(servername, global_myname()))
-               return True;
-
-       /* check for an alias */
-
-       if (is_myname(servername))
-               return True;
-
-       /* check for loopback */
-
-       if (strequal(servername, "127.0.0.1"))
-               return True;
-
-       if (strequal(servername, "localhost"))
-               return True;
-
-       /* maybe it's my dns name */
-
-       if ( get_mydnsfullname( dnsname ) )
-               if ( strequal( servername, dnsname ) )
-                       return True;
-
-       /* handle possible CNAME records */
-
-       if ( !is_ipaddress( servername ) ) {
-               /* use DNS to resolve the name, but only the first address */
-               struct hostent *hp;
-
-               if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
-                       struct in_addr return_ip;
-                       putip( (char*)&return_ip, (char*)hp->h_addr );
-                       fstrcpy( name, inet_ntoa( return_ip ) );
-                       servername = name;
-               }
-       }
-
-       /* maybe its an IP address? */
-       if (is_ipaddress(servername)) {
-               struct iface_struct nics[MAX_INTERFACES];
-               int i, n;
-               uint32 ip;
-
-               ip = interpret_addr(servername);
-               if ((ip==0) || (ip==0xffffffff))
-                       return False;
-
-               n = get_interfaces(nics, MAX_INTERFACES);
-               for (i=0; i<n; i++) {
-                       if (ip == nics[i].iface_addr.ip.s_addr)
-                               return True;
-               }
-       }
-
-       /* no match */
-       return False;
-}
-
 /*******************************************************************
  Is the name specified our workgroup/domain.
  Returns true if it is equal, false otherwise.
index 1508ddfce34ec0a733ec06a105e928f1afbd6408..7a1a05ec294c64f0d9e223196d82af6836093955 100644 (file)
@@ -29,33 +29,353 @@ static int client_fd = -1;
 static char client_ip_string[INET6_ADDRSTRLEN];
 
 /****************************************************************************
Pritn out an IPv4 or IPv6 address from a struct sockaddr_storage.
Return true if a string could be a pure IPv4 address.
 ****************************************************************************/
 
-char *print_sockaddr(char *dest,
-                       size_t destlen,
-                       struct sockaddr_storage *psa)
+bool is_ipaddress_v4(const char *str)
 {
-       if (destlen > 0) {
-               dest[0] = '\0';
+       bool pure_address = true;
+       int i;
+
+       for (i=0; pure_address && str[i]; i++) {
+               if (!(isdigit((int)str[i]) || str[i] == '.')) {
+                       pure_address = false;
+               }
+       }
+
+       /* Check that a pure number is not misinterpreted as an IP */
+       pure_address = pure_address && (strchr_m(str, '.') != NULL);
+       return pure_address;
+}
+
+/****************************************************************************
+ Interpret an internet address or name into an IP address in 4 byte form.
+****************************************************************************/
+
+uint32 interpret_addr(const char *str)
+{
+       struct hostent *hp;
+       uint32 res;
+
+       if (strcmp(str,"0.0.0.0") == 0)
+               return(0);
+       if (strcmp(str,"255.255.255.255") == 0)
+               return(0xFFFFFFFF);
+
+       /* if it's in the form of an IP address then
+        * get the lib to interpret it */
+       if (is_ipaddress_v4(str)) {
+               res = inet_addr(str);
+       } else {
+               /* otherwise assume it's a network name of some sort and use
+                       sys_gethostbyname */
+               if ((hp = sys_gethostbyname(str)) == 0) {
+                       DEBUG(3,("sys_gethostbyname: Unknown host. %s\n",str));
+                       return 0;
+               }
+
+               if(hp->h_addr == NULL) {
+                       DEBUG(3,("sys_gethostbyname: host address is "
+                               "invalid for host %s\n",str));
+                       return 0;
+               }
+               putip((char *)&res,(char *)hp->h_addr);
+       }
+
+       if (res == (uint32)-1)
+               return(0);
+
+       return(res);
+}
+
+/*******************************************************************
+ A convenient addition to interpret_addr().
+******************************************************************/
+
+struct in_addr *interpret_addr2(const char *str)
+{
+       static struct in_addr ret;
+       uint32 a = interpret_addr(str);
+       ret.s_addr = a;
+       return(&ret);
+}
+
+/*******************************************************************
+ Map a text hostname or IP address (IPv4 or IPv6) into a
+ struct sockaddr_storage.
+******************************************************************/
+
+bool interpret_string_addr(struct sockaddr_storage *pss, const char *str)
+{
+       int ret;
+       struct addrinfo *res = NULL;
+       struct addrinfo hints;
+
+       memset(pss,'\0', sizeof(*pss));
+
+       memset(&hints, '\0', sizeof(hints));
+       /* By default make sure it supports TCP. */
+       hints.ai_socktype = SOCK_STREAM;
+       hints.ai_flags = AI_ADDRCONFIG;
+
+       ret = getaddrinfo(str, NULL,
+                       &hints,
+                       &res);
+
+       if (ret) {
+               DEBUG(3,("interpret_string_addr: getaddrinfo failed for "
+                       "name %s [%s]\n",
+                       str,
+                       gai_strerror(ret) ));
+               return false;
+       }
+
+       /* Copy the first sockaddr. */
+       memcpy(pss, res->ai_addr, res->ai_addrlen);
+       freeaddrinfo(res);
+       return true;
+}
+
+/*******************************************************************
+ Check if an IPv7 is 127.0.0.1
+******************************************************************/
+
+bool is_loopback_ip_v4(struct in_addr ip)
+{
+       struct in_addr a;
+       a.s_addr = htonl(INADDR_LOOPBACK);
+       return(ip.s_addr == a.s_addr);
+}
+
+/*******************************************************************
+ Check if a struct sockaddr_storage is the loopback address.
+******************************************************************/
+
+bool is_loopback_addr(const struct sockaddr_storage *pss)
+{
+#if defined(AF_INET6)
+       if (pss->ss_family == AF_INET) {
+               struct in6_addr *pin6 = &((struct sockaddr_in6 *)pss)->sin6_addr;
+               return IN6_IS_ADDR_LOOPBACK(pin6);
+       }
+#endif
+       if (pss->ss_family == AF_INET) {
+               struct in_addr *pin = &((struct sockaddr_in *)pss)->sin_addr;
+               return is_loopback_ip_v4(*pin);
+       }
+       return false;
+}
+
+/*******************************************************************
+ Check if an IPv4 is 0.0.0.0.
+******************************************************************/
+
+bool is_zero_ip_v4(struct in_addr ip)
+{
+       uint32 a;
+       putip((char *)&a,(char *)&ip);
+       return(a == 0);
+}
+
+/*******************************************************************
+ Check if a struct sockaddr_storage has an unspecified address.
+******************************************************************/
+
+bool is_zero_addr(const struct sockaddr_storage *pss)
+{
+#if defined(AF_INET6)
+       if (pss->ss_family == AF_INET) {
+               struct in6_addr *pin6 = &((struct sockaddr_in6 *)pss)->sin6_addr;
+               return IN6_IS_ADDR_UNSPECIFIED(pin6);
+       }
+#endif
+       if (pss->ss_family == AF_INET) {
+               struct in_addr *pin = &((struct sockaddr_in *)pss)->sin_addr;
+               return is_zero_ip_v4(*pin);
        }
+       return false;
+}
+
+/*******************************************************************
+ Set an IP to 0.0.0.0.
+******************************************************************/
+
+void zero_ip_v4(struct in_addr *ip)
+{
+        static bool init;
+        static struct in_addr ipzero;
+
+        if (!init) {
+                ipzero = *interpret_addr2("0.0.0.0");
+                init = true;
+        }
+
+        *ip = ipzero;
+}
+
+/*******************************************************************
+ Are two IPs on the same subnet - IPv4 version ?
+********************************************************************/
+
+bool same_net_v4(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
+{
+       uint32 net1,net2,nmask;
+
+       nmask = ntohl(mask.s_addr);
+       net1  = ntohl(ip1.s_addr);
+       net2  = ntohl(ip2.s_addr);
+
+       return((net1 & nmask) == (net2 & nmask));
+}
+
+/*******************************************************************
+ Convert an IPv4 struct in_addr to a struct sockaddr_storage.
+********************************************************************/
+
+void in_addr_to_sockaddr_storage(struct sockaddr_storage *ss,
+               struct in_addr ip)
+{
+       struct sockaddr_in *sa = (struct sockaddr_in *)ss;
+       memset(ss, '\0', sizeof(*ss));
+       ss->ss_family = AF_INET;
+       sa->sin_addr = ip;
+}
+
+#ifdef AF_INET6
+/*******************************************************************
+ Convert an IPv6 struct in_addr to a struct sockaddr_storage.
+********************************************************************/
+
+void in6_addr_to_sockaddr_storage(struct sockaddr_storage *ss,
+               struct in6_addr ip)
+{
+       struct sockaddr_in6 *sa = (struct sockaddr_in6 *)ss;
+       memset(ss, '\0', sizeof(*ss));
+       ss->ss_family = AF_INET6;
+       sa->sin6_addr = ip;
+}
+#endif
+
+/*******************************************************************
+ Are two IPs on the same subnet?
+********************************************************************/
+
+bool same_net(const struct sockaddr_storage *ip1,
+               const struct sockaddr_storage *ip2,
+               const struct sockaddr_storage *mask)
+{
+       if (ip1->ss_family != ip2->ss_family) {
+               /* Never on the same net. */
+               return false;
+       }
+
+#ifdef AF_INET6
+       if (ip1->ss_family == AF_INET6) {
+               struct sockaddr_in6 ip1_6 = *(struct sockaddr_in6 *)ip1;
+               struct sockaddr_in6 ip2_6 = *(struct sockaddr_in6 *)ip2;
+               struct sockaddr_in6 mask_6 = *(struct sockaddr_in6 *)mask;
+               char *p1 = (char *)&ip1_6.sin6_addr;
+               char *p2 = (char *)&ip2_6.sin6_addr;
+               char *m = (char *)&mask_6.sin6_addr;
+               int i;
+
+               for (i = 0; i < sizeof(struct in6_addr); i++) {
+                       *p1++ &= *m;
+                       *p2++ &= *m;
+                       m++;
+               }
+               return (memcmp(&ip1_6.sin6_addr,
+                               &ip2_6.sin6_addr,
+                               sizeof(struct in6_addr)) == 0);
+       }
+#endif
+       if (ip1->ss_family == AF_INET) {
+               return same_net_v4(((const struct sockaddr_in *)ip1)->sin_addr,
+                               ((const struct sockaddr_in *)ip2)->sin_addr,
+                               ((const struct sockaddr_in *)mask)->sin_addr);
+       }
+       return false;
+}
+
+/*******************************************************************
+ Are two sockaddr_storage's the same family and address ? Ignore port etc.
+********************************************************************/
+
+bool addr_equal(const struct sockaddr_storage *ip1,
+               const struct sockaddr_storage *ip2)
+{
+       if (ip1->ss_family != ip2->ss_family) {
+               /* Never the same. */
+               return false;
+       }
+
+#ifdef AF_INET6
+       if (ip1->ss_family == AF_INET6) {
+               return (memcmp(&((const struct sockaddr_in6 *)ip1)->sin6_addr,
+                               &((const struct sockaddr_in6 *)ip2)->sin6_addr,
+                               sizeof(struct in6_addr)) == 0);
+       }
+#endif
+       if (ip1->ss_family == AF_INET) {
+               return (memcmp(&((const struct sockaddr_in *)ip1)->sin_addr,
+                               &((const struct sockaddr_in *)ip2)->sin_addr,
+                               sizeof(struct in_addr)) == 0);
+       }
+       return false;
+}
+
+
+/****************************************************************************
+ Is an IP address the INADDR_ANY or in6addr_any value ?
+****************************************************************************/
+
+bool is_address_any(const struct sockaddr_storage *psa)
+{
 #ifdef AF_INET6
        if (psa->ss_family == AF_INET6) {
-               inet_ntop(AF_INET6,
-                       &((struct sockaddr_in6 *)psa)->sin6_addr,
-                       dest,
-                       destlen);
+               struct sockaddr_in6 *si6 = (struct sockaddr_in6 *)psa;
+               if (memcmp(&in6addr_any,
+                               &si6->sin6_addr,
+                               sizeof(in6addr_any)) == 0) {
+                       return true;
+               }
+               return false;
        }
 #endif
        if (psa->ss_family == AF_INET) {
-               inet_ntop(AF_INET,
-                       &((struct sockaddr_in *)psa)->sin_addr,
-                       dest,
-                       destlen);
+               struct sockaddr_in *si = (struct sockaddr_in *)psa;
+               if (si->sin_addr.s_addr == INADDR_ANY) {
+                       return true;
+               }
+               return false;
        }
+       return false;
+}
+
+/****************************************************************************
+ Print out an IPv4 or IPv6 address from a struct sockaddr_storage.
+****************************************************************************/
+
+char *print_sockaddr(char *dest,
+                       size_t destlen,
+                       const struct sockaddr_storage *psa,
+                       socklen_t psalen)
+{
+       if (destlen > 0) {
+               dest[0] = '\0';
+       }
+       (void)getnameinfo((const struct sockaddr *)psa,
+                       psalen,
+                       dest, destlen,
+                       NULL, 0,
+                       NI_NUMERICHOST);
        return dest;
 }
 
+/****************************************************************************
+ Set the global client_fd variable.
+****************************************************************************/
+
 void client_setfd(int fd)
 {
        client_fd = fd;
@@ -64,6 +384,10 @@ void client_setfd(int fd)
                        sizeof(client_ip_string)-1);
 }
 
+/****************************************************************************
+ Return a static string of an IP address (IPv4 or IPv6).
+****************************************************************************/
+
 static char *get_socket_addr(int fd)
 {
        struct sockaddr_storage sa;
@@ -87,9 +411,13 @@ static char *get_socket_addr(int fd)
                return addr_buf;
        }
 
-       return print_sockaddr(addr_buf, sizeof(addr_buf), &sa);
+       return print_sockaddr(addr_buf, sizeof(addr_buf), &sa, length);
 }
 
+/****************************************************************************
+ Return the port number we've bound to on a socket.
+****************************************************************************/
+
 static int get_socket_port(int fd)
 {
        struct sockaddr_storage sa;
@@ -118,7 +446,7 @@ static int get_socket_port(int fd)
 
 char *client_name(void)
 {
-       return get_peer_name(client_fd,False);
+       return get_peer_name(client_fd,false);
 }
 
 char *client_addr(void)
@@ -142,7 +470,7 @@ int smb_read_error = 0;
  Determine if a file descriptor is in fact a socket.
 ****************************************************************************/
 
-BOOL is_a_socket(int fd)
+bool is_a_socket(int fd)
 {
        int v;
        socklen_t l;
@@ -247,12 +575,12 @@ void set_socket_options(int fd, const char *options)
                int ret=0,i;
                int value = 1;
                char *p;
-               BOOL got_value = False;
+               bool got_value = false;
 
                if ((p = strchr_m(tok,'='))) {
                        *p = 0;
                        value = atoi(p+1);
-                       got_value = True;
+                       got_value = true;
                }
 
                for (i=0;socket_options[i].name;i++)
@@ -559,7 +887,7 @@ ssize_t write_data(int fd, const char *buffer, size_t N)
  Send a keepalive packet (rfc1002).
 ****************************************************************************/
 
-BOOL send_keepalive(int client)
+bool send_keepalive(int client)
 {
        unsigned char buf[4];
 
@@ -583,7 +911,7 @@ static ssize_t read_smb_length_return_keepalive(int fd,
 {
        ssize_t len=0;
        int msg_type;
-       BOOL ok = False;
+       bool ok = false;
 
        while (!ok) {
                if (timeout > 0) {
@@ -809,23 +1137,23 @@ static ssize_t receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
  Checks the MAC on signed packets.
 ****************************************************************************/
 
-BOOL receive_smb(int fd, char *buffer, unsigned int timeout)
+bool receive_smb(int fd, char *buffer, unsigned int timeout)
 {
        if (receive_smb_raw(fd, buffer, timeout, 0) < 0) {
-               return False;
+               return false;
        }
 
        /* Check the incoming SMB signature. */
-       if (!srv_check_sign_mac(buffer, True)) {
+       if (!srv_check_sign_mac(buffer, true)) {
                DEBUG(0, ("receive_smb: SMB Signature verification "
                        "failed on incoming packet!\n"));
                if (smb_read_error == 0) {
                        smb_read_error = READ_BAD_SIG;
                }
-               return False;
+               return false;
        }
 
-       return True;
+       return true;
 }
 
 ssize_t receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd, char **buffer,
@@ -840,7 +1168,7 @@ ssize_t receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd, char **buffer,
        }
 
        /* Check the incoming SMB signature. */
-       if (!srv_check_sign_mac(*buffer, True)) {
+       if (!srv_check_sign_mac(*buffer, true)) {
                DEBUG(0, ("receive_smb: SMB Signature verification failed on "
                          "incoming packet!\n"));
                if (smb_read_error == 0) {
@@ -856,7 +1184,7 @@ ssize_t receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd, char **buffer,
  Send an smb to a fd.
 ****************************************************************************/
 
-BOOL send_smb(int fd, char *buffer)
+bool send_smb(int fd, char *buffer)
 {
        size_t len;
        size_t nwritten=0;
@@ -872,12 +1200,12 @@ BOOL send_smb(int fd, char *buffer)
                if (ret <= 0) {
                        DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n",
                                (int)len,(int)ret, strerror(errno) ));
-                       return False;
+                       return false;
                }
                nwritten += ret;
        }
 
-       return True;
+       return true;
 }
 
 /****************************************************************************
@@ -888,7 +1216,7 @@ int open_socket_in(int type,
                int port,
                int dlevel,
                uint32 socket_addr,
-               BOOL rebind )
+               bool rebind )
 {
        struct sockaddr_in sock;
        int res;
@@ -919,7 +1247,7 @@ int open_socket_in(int type,
                        if( DEBUGLVL( dlevel ) ) {
                                dbgtext( "open_socket_in(): setsockopt: " );
                                dbgtext( "SO_REUSEADDR = %s ",
-                                               val?"True":"False" );
+                                               val?"true":"false" );
                                dbgtext( "on port %d failed ", port );
                                dbgtext( "with error = %s\n", strerror(errno) );
                        }
@@ -930,7 +1258,7 @@ int open_socket_in(int type,
                        if( DEBUGLVL( dlevel ) ) {
                                dbgtext( "open_socket_in(): setsockopt: ");
                                dbgtext( "SO_REUSEPORT = %s ",
-                                               val?"True":"False" );
+                                               val?"true":"false" );
                                dbgtext( "on port %d failed ", port );
                                dbgtext( "with error = %s\n", strerror(errno) );
                        }
@@ -984,7 +1312,7 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
        sock_out.sin_family = PF_INET;
 
        /* set it non-blocking */
-       set_blocking(res,False);
+       set_blocking(res,false);
 
        DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
 
@@ -1029,7 +1357,7 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
        }
 
        /* set it blocking again */
-       set_blocking(res,True);
+       set_blocking(res,true);
 
        return res;
 }
@@ -1040,12 +1368,12 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
  of DC's all of which are equivalent for our purposes.
 **************************************************************************/
 
-BOOL open_any_socket_out(struct sockaddr_in *addrs, int num_addrs,
+bool open_any_socket_out(struct sockaddr_in *addrs, int num_addrs,
                         int timeout, int *fd_index, int *fd)
 {
        int i, resulting_index, res;
        int *sockets;
-       BOOL good_connect;
+       bool good_connect;
 
        fd_set r_fds, wr_fds;
        struct timeval tv;
@@ -1058,7 +1386,7 @@ BOOL open_any_socket_out(struct sockaddr_in *addrs, int num_addrs,
        sockets = SMB_MALLOC_ARRAY(int, num_addrs);
 
        if (sockets == NULL)
-               return False;
+               return false;
 
        resulting_index = -1;
 
@@ -1069,11 +1397,11 @@ BOOL open_any_socket_out(struct sockaddr_in *addrs, int num_addrs,
                sockets[i] = socket(PF_INET, SOCK_STREAM, 0);
                if (sockets[i] < 0)
                        goto done;
-               set_blocking(sockets[i], False);
+               set_blocking(sockets[i], false);
        }
 
  connect_again:
-       good_connect = False;
+       good_connect = false;
 
        for (i=0; i<num_addrs; i++) {
 
@@ -1095,7 +1423,7 @@ BOOL open_any_socket_out(struct sockaddr_in *addrs, int num_addrs,
                    errno == EAGAIN || errno == EINTR) {
                        /* These are the error messages that something is
                           progressing. */
-                       good_connect = True;
+                       good_connect = true;
                } else if (errno != 0) {
                        /* There was a direct error */
                        close(sockets[i]);
@@ -1180,7 +1508,7 @@ BOOL open_any_socket_out(struct sockaddr_in *addrs, int num_addrs,
        if (resulting_index >= 0) {
                *fd_index = resulting_index;
                *fd = sockets[*fd_index];
-               set_blocking(*fd, True);
+               set_blocking(*fd, true);
        }
 
        free(sockets);
@@ -1223,7 +1551,7 @@ int open_udp_socket(const char *host, int port)
  confirm a hostname lookup to prevent spoof attacks.
 ******************************************************************/
 
-static BOOL matchname(char *remotehost,struct in_addr  addr)
+static bool matchname(char *remotehost,struct in_addr  addr)
 {
        struct hostent *hp;
        int     i;
@@ -1231,7 +1559,7 @@ static BOOL matchname(char *remotehost,struct in_addr  addr)
        if ((hp = sys_gethostbyname(remotehost)) == 0) {
                DEBUG(0,("sys_gethostbyname(%s): lookup failure.\n",
                                        remotehost));
-               return False;
+               return false;
        }
 
        /*
@@ -1246,13 +1574,13 @@ static BOOL matchname(char *remotehost,struct in_addr  addr)
            && !strequal(remotehost, "localhost")) {
                DEBUG(0,("host name/name mismatch: %s != %s\n",
                         remotehost, hp->h_name));
-               return False;
+               return false;
        }
 
        /* Look up the host address in the address list we just got. */
        for (i = 0; hp->h_addr_list[i]; i++) {
                if (memcmp(hp->h_addr_list[i], (char *)&addr,sizeof(addr)) == 0)
-                       return True;
+                       return true;
        }
 
        /*
@@ -1263,14 +1591,14 @@ static BOOL matchname(char *remotehost,struct in_addr  addr)
 
        DEBUG(0,("host name/address mismatch: %s != %s\n",
                 inet_ntoa(addr), hp->h_name));
-       return False;
+       return false;
 }
 
 /*******************************************************************
  Return the DNS name of the remote end of a socket.
 ******************************************************************/
 
-char *get_peer_name(int fd, BOOL force_lookup)
+char *get_peer_name(int fd, bool force_lookup)
 {
        static pstring name_buf;
        pstring tmp_name;
@@ -1283,7 +1611,7 @@ char *get_peer_name(int fd, BOOL force_lookup)
           situations won't work because many networks don't link dhcp
           with dns. To avoid the delay we avoid the lookup if
           possible */
-       if (!lp_hostname_lookups() && (force_lookup == False)) {
+       if (!lp_hostname_lookups() && (force_lookup == false)) {
                return get_peer_addr(fd);
        }
 
@@ -1450,3 +1778,92 @@ out_umask:
         return -1;
 #endif /* HAVE_UNIXSOCKET */
 }
+
+/************************************************************
+ Is this my name ? Needs fixing for IPv6.
+************************************************************/
+
+bool is_myname_or_ipaddr(const char *s)
+{
+       fstring name, dnsname;
+       char *servername;
+
+       if ( !s )
+               return false;
+
+       /* santize the string from '\\name' */
+
+       fstrcpy( name, s );
+
+       servername = strrchr_m( name, '\\' );
+       if ( !servername )
+               servername = name;
+       else
+               servername++;
+
+       /* optimize for the common case */
+
+       if (strequal(servername, global_myname()))
+               return true;
+
+       /* check for an alias */
+
+       if (is_myname(servername))
+               return true;
+
+       /* check for loopback */
+
+       if (strequal(servername, "127.0.0.1"))
+               return true;
+
+       if (strequal(servername, "localhost"))
+               return true;
+
+       /* maybe it's my dns name */
+
+       if ( get_mydnsfullname( dnsname ) )
+               if ( strequal( servername, dnsname ) )
+                       return true;
+
+       /* handle possible CNAME records */
+
+       if ( !is_ipaddress_v4( servername ) ) {
+               /* use DNS to resolve the name, but only the first address */
+               struct hostent *hp;
+
+               if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
+                       struct in_addr return_ip;
+                       putip( (char*)&return_ip, (char*)hp->h_addr );
+                       fstrcpy( name, inet_ntoa( return_ip ) );
+                       servername = name;
+               }
+       }
+
+       /* maybe its an IP address? */
+       if (is_ipaddress_v4(servername)) {
+               struct sockaddr_storage ss;
+               struct iface_struct nics[MAX_INTERFACES];
+               int i, n;
+               struct in_addr ip;
+
+               ip = *interpret_addr2(servername);
+               if (is_zero_ip_v4(ip) || is_loopback_ip_v4(ip)) {
+                       return false;
+               }
+
+               in_addr_to_sockaddr_storage(&ss, ip);
+
+               n = get_interfaces(nics, MAX_INTERFACES);
+               for (i=0; i<n; i++) {
+                       if (nics[i].ip.ss_family != AF_INET) {
+                               continue;
+                       }
+                       if (addr_equal(&nics[i].ip, &ss)) {
+                               return true;
+                       }
+               }
+       }
+
+       /* no match */
+       return false;
+}
index 4faa65c18d4ac8b2560f4d4ca45b9de39261cd37..6344568122b4a5b105c4f8bf4553684cf5fa3169 100644 (file)
@@ -21,8 +21,6 @@
 
 #include "includes.h"
 
-extern struct in_addr loopback_ip;
-
 /*
   This is pretty much a complete rewrite of the earlier code. The main
   aim of the rewrite is to add support for having multiple wins server
@@ -134,7 +132,7 @@ void wins_srv_died(struct in_addr wins_ip, struct in_addr src_ip)
 {
        char *keystr;
 
-       if (is_zero_ip(wins_ip) || wins_srv_is_dead(wins_ip, src_ip))
+       if (is_zero_ip_v4(wins_ip) || wins_srv_is_dead(wins_ip, src_ip))
                return;
 
        keystr = wins_srv_keystr(wins_ip, src_ip);
@@ -284,13 +282,15 @@ struct in_addr wins_srv_ip_tag(const char *tag, struct in_addr src_ip)
 
        /* if we are a wins server then we always just talk to ourselves */
        if (lp_wins_support()) {
+               struct in_addr loopback_ip;
+               loopback_ip.s_addr = htonl(INADDR_LOOPBACK);
                return loopback_ip;
        }
 
        list = lp_wins_server_list();
        if (!list || !list[0]) {
                struct in_addr ip;
-               zero_ip(&ip);
+               zero_ip_v4(&ip);
                return ip;
        }
 
@@ -322,7 +322,7 @@ struct in_addr wins_srv_ip_tag(const char *tag, struct in_addr src_ip)
        }
 
        /* this can't happen?? */
-       zero_ip(&t_ip.ip);
+       zero_ip_v4(&t_ip.ip);
        return t_ip.ip;
 }
 
index 5785e5c1ea1dd6ff9d1e6d31bd56b601c8621ee4..e036eae7040234e6b843c4c8b028cd57b5601c24 100644 (file)
@@ -595,7 +595,7 @@ NTSTATUS ndr_pull_ipv4address(struct ndr_pull *ndr, int ndr_flags, const char **
 NTSTATUS ndr_push_ipv4address(struct ndr_push *ndr, int ndr_flags, const char *address)
 {
        uint32_t addr;
-       if (!is_ipaddress(address)) {
+       if (!is_ipaddress_v4(address)) {
                return ndr_push_error(ndr, NDR_ERR_IPV4ADDRESS,
                                      "Invalid IPv4 address: '%s'", 
                                      address);
index 78cc63de50f8d2dcfdfa81275432378d7a0f3851..16c3bed4383cc4607b9e02a2c76aaee737cd08ed 100644 (file)
@@ -1421,7 +1421,7 @@ NTSTATUS cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip
                *p = 0;
        }
        
-       if (!ip || is_zero_ip(*ip)) {
+       if (!ip || is_zero_ip_v4(*ip)) {
                 if (!resolve_name(cli->desthost, &cli->dest_ip, name_type)) {
                        return NT_STATUS_BAD_NETWORK_NAME;
                 }
@@ -1522,7 +1522,7 @@ again:
                char *p;
                DEBUG(1,("session request to %s failed (%s)\n", 
                         called.name, cli_errstr(cli)));
-               if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) {
+               if ((p=strchr(called.name, '.')) && !is_ipaddress_v4(called.name)) {
                        *p = 0;
                        goto again;
                }
@@ -1650,7 +1650,7 @@ BOOL attempt_netbios_session_request(struct cli_state **ppcli, const char *srcho
         * then use *SMBSERVER immediately.
         */
 
-       if(is_ipaddress(desthost)) {
+       if(is_ipaddress_v4(desthost)) {
                make_nmb_name(&called, "*SMBSERVER", 0x20);
        } else {
                make_nmb_name(&called, desthost, 0x20);
@@ -1764,7 +1764,7 @@ struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip,
 
        if (NT_STATUS_IS_OK(nt_status)) {
                return cli;
-       } else if (is_ipaddress(server)) {
+       } else if (is_ipaddress_v4(server)) {
            /* windows 9* needs a correct NMB name for connections */
            fstring remote_name;
 
index d32629b139e988325aacd2cbcb02d05955ee17e9..db4a9dfbd531e061eaf397e5954cceb385916b62 100644 (file)
@@ -83,13 +83,13 @@ static struct cli_state *do_connect( const char *server, const char *share,
 
        server_n = server;
        
-       zero_ip(&ip);
+       zero_ip_v4(&ip);
 
        make_nmb_name(&calling, global_myname(), 0x0);
        make_nmb_name(&called , server, name_type);
 
  again:
-       zero_ip(&ip);
+       zero_ip_v4(&ip);
        if (have_ip) 
                ip = dest_ip;
 
index 384b9ec48d5e8b1a4a916c6a042266432431f112..89bb65006dc2307ee64ebfe817114169e4fd0c87 100644 (file)
@@ -650,7 +650,7 @@ static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx,
                 * back to netbios lookups is that our DNS server doesn't know
                 * anything about the DC's   -- jerry */
 
-               if (!is_zero_ip(r->ip)) {
+               if (!is_zero_ip_v4(r->ip)) {
                        (*return_count)++;
                        continue;
                }
index 45226a028cbc57289596cfd1b657cb91ea7310b2..49384e2728c5175ce09bdb6e1d9be4b1e8a705b8 100644 (file)
@@ -654,7 +654,7 @@ smbc_server(SMBCCTX *context,
         const char *username_used;
        NTSTATUS status;
 
-       zero_ip(&ip);
+       zero_ip_v4(&ip);
        ZERO_STRUCT(c);
 
        if (server[0] == 0) {
@@ -742,7 +742,7 @@ smbc_server(SMBCCTX *context,
  again:
        slprintf(ipenv,sizeof(ipenv)-1,"HOST_%s", server_n);
 
-       zero_ip(&ip);
+       zero_ip_v4(&ip);
 
        /* have to open a new connection */
        if ((c = cli_initialise()) == NULL) {
@@ -796,7 +796,7 @@ smbc_server(SMBCCTX *context,
 
                        /* Only try this if server is an IP address ... */
 
-                       if (is_ipaddress(server) && !tried_reverse) {
+                       if (is_ipaddress_v4(server) && !tried_reverse) {
                                fstring remote_name;
                                struct in_addr rem_ip;
 
@@ -962,7 +962,7 @@ smbc_attr_server(SMBCCTX *context,
                         flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
                 }
 
-                zero_ip(&ip);
+                zero_ip_v4(&ip);
                 nt_status = cli_full_connection(&ipc_cli,
                                                 global_myname(), server, 
                                                 &ip, 0, "IPC$", "?????",  
@@ -2761,7 +2761,7 @@ smbc_opendir_ctx(SMBCCTX *context,
                          * LMB or DMB
                          */
                        if (!srv &&
-                            !is_ipaddress(server) &&
+                            !is_ipaddress_v4(server) &&
                            (resolve_name(server, &rem_ip, 0x1d) ||   /* LMB */
                              resolve_name(server, &rem_ip, 0x1b) )) { /* DMB */
 
index 49e3375f508d2cc4423efc47489e491071ec9705..182d3641f71bbb0161b7d843ac1efc0858ded6ba 100644 (file)
@@ -352,12 +352,18 @@ static int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
 {
        int max_bits1=0, max_bits2=0;
        int num_interfaces = iface_count();
+       struct sockaddr_storage ss;
        int i;
 
        for (i=0;i<num_interfaces;i++) {
+               const struct sockaddr_storage *pss = iface_n_bcast(i);
                struct in_addr ip;
                int bits1, bits2;
-               ip = *iface_n_bcast(i);
+
+               if (pss->ss_family != AF_INET) {
+                       continue;
+               }
+               ip = ((const struct sockaddr_in *)pss)->sin_addr;
                bits1 = matching_quad_bits((uchar *)&ip1->s_addr, (uchar *)&ip.s_addr);
                bits2 = matching_quad_bits((uchar *)&ip2->s_addr, (uchar *)&ip.s_addr);
                max_bits1 = MAX(bits1, max_bits1);
@@ -365,10 +371,12 @@ static int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
        }       
        
        /* bias towards directly reachable IPs */
-       if (iface_local(*ip1)) {
+       in_addr_to_sockaddr_storage(&ss, *ip1);
+       if (iface_local(&ss)) {
                max_bits1 += 32;
        }
-       if (iface_local(*ip2)) {
+       in_addr_to_sockaddr_storage(&ss, *ip1);
+       if (iface_local(&ss)) {
                max_bits2 += 32;
        }
 
@@ -431,19 +439,19 @@ static int remove_duplicate_addrs2( struct ip_service *iplist, int count )
        
        /* one loop to remove duplicates */
        for ( i=0; i<count; i++ ) {
-               if ( is_zero_ip(iplist[i].ip) )
+               if ( is_zero_ip_v4(iplist[i].ip) )
                        continue;
                                        
                for ( j=i+1; j<count; j++ ) {
                        if ( ip_service_equal(iplist[i], iplist[j]) )
-                               zero_ip(&iplist[j].ip);
+                               zero_ip_v4(&iplist[j].ip);
                }
        }
                        
        /* one loop to clean up any holes we left */
        /* first ip should never be a zero_ip() */
        for (i = 0; i<count; ) {
-               if ( is_zero_ip(iplist[i].ip) ) {
+               if ( is_zero_ip_v4(iplist[i].ip) ) {
                        if (i != count-1 )
                                memmove(&iplist[i], &iplist[i+1], (count - i - 1)*sizeof(iplist[i]));
                        count--;
@@ -812,9 +820,14 @@ NTSTATUS name_resolve_bcast(const char *name, int name_type,
         */
        for( i = num_interfaces-1; i >= 0; i--) {
                struct in_addr sendto_ip;
+               const struct sockaddr_storage *ss = iface_n_bcast(i);
                int flags;
+
                /* Done this way to fix compiler error on IRIX 5.x */
-               sendto_ip = *iface_n_bcast(i);
+               if (!ss || ss->ss_family != AF_INET) {
+                       continue;
+               }
+               sendto_ip = ((const struct sockaddr_in *)ss)->sin_addr;
                ip_list = name_query(sock, name, name_type, True, 
                                    True, sendto_ip, return_count, &flags, NULL);
                if( ip_list ) 
@@ -886,7 +899,7 @@ NTSTATUS resolve_wins(const char *name, int name_type,
 
                        wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
 
-                       if (global_in_nmbd && ismyip(wins_ip)) {
+                       if (global_in_nmbd && ismyip_v4(wins_ip)) {
                                /* yikes! we'll loop forever */
                                continue;
                        }
@@ -1144,7 +1157,7 @@ NTSTATUS resolve_ads(const char *name, int name_type,
                   The standard reason for falling back to netbios lookups is that 
                   our DNS server doesn't know anything about the DC's   -- jerry */    
                           
-               if ( ! is_zero_ip(r->ip) )
+               if ( ! is_zero_ip_v4(r->ip) )
                        (*return_count)++;
        }
                
@@ -1173,7 +1186,7 @@ NTSTATUS internal_resolve_name(const char *name, int name_type,
        const char *ptr;
        BOOL allones = (strcmp(name,"255.255.255.255") == 0);
        BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
-       BOOL is_address = is_ipaddress(name);
+       BOOL is_address = is_ipaddress_v4(name);
        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
        int i;
 
@@ -1347,7 +1360,7 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
        char *sitename = sitename_fetch(lp_realm()); /* wild guess */
        int count = 0;
 
-       if (is_ipaddress(name)) {
+       if (is_ipaddress_v4(name)) {
                *return_ip = *interpret_addr2(name);
                SAFE_FREE(sitename);
                return True;
index bdac833d13c7e21850130b4233260b34d4fd8531..39215aaa8f66b42ac8c8de845da5b3e665881710 100644 (file)
@@ -155,7 +155,7 @@ static BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip
        int count, i;
        NTSTATUS result;
        
-       zero_ip(&exclude_ip);
+       zero_ip_v4(&exclude_ip);
 
        /* get a list of all domain controllers */
        
@@ -168,7 +168,7 @@ static BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip
        /* Remove the entry we've already failed with (should be the PDC). */
 
        for (i = 0; i < count; i++) {
-               if (is_zero_ip(ip_list[i].ip))
+               if (is_zero_ip_v4(ip_list[i].ip))
                        continue;
 
                if (name_status_find(domain, 0x1c, 0x20, ip_list[i].ip, srv_name)) {
@@ -212,7 +212,7 @@ BOOL get_dc_name(const char *domain, const char *realm, fstring srv_name, struct
        BOOL ret;
        BOOL our_domain = False;
 
-       zero_ip(&dc_ip);
+       zero_ip_v4(&dc_ip);
 
        ret = False;
        
index dc03506194b278f422ab59ac2133675e8fec4149..f0de0b8485f54949e6479a6f0911e2706f33c472 100644 (file)
@@ -27,7 +27,6 @@ int ClientDGRAM     = -1;
 int global_nmb_port = -1;
 
 extern BOOL rescan_listen_set;
-extern struct in_addr loopback_ip;
 extern BOOL global_in_nmbd;
 
 extern BOOL override_logfile;
@@ -192,33 +191,49 @@ static BOOL reload_interfaces(time_t t)
 
        /* find any interfaces that need adding */
        for (n=iface_count() - 1; n >= 0; n--) {
-               struct interface *iface = get_interface(n);
+               char str[INET6_ADDRSTRLEN];
+               const struct interface *iface = get_interface(n);
+               struct in_addr ip, nmask;
 
                if (!iface) {
                        DEBUG(2,("reload_interfaces: failed to get interface %d\n", n));
                        continue;
                }
 
+               /* Ensure we're only dealing with IPv4 here. */
+               if (iface->ip.ss_family != AF_INET) {
+                       DEBUG(2,("reload_interfaces: "
+                               "ignoring non IPv4 interface.\n"));
+                       continue;
+               }
+
+               ip = ((struct sockaddr_in *)&iface->ip)->sin_addr;
+               nmask = ((struct sockaddr_in *)&iface->netmask)->sin_addr;
+
                /*
                 * We don't want to add a loopback interface, in case
                 * someone has added 127.0.0.1 for smbd, nmbd needs to
                 * ignore it here. JRA.
                 */
 
-               if (ip_equal(iface->ip, loopback_ip)) {
-                       DEBUG(2,("reload_interfaces: Ignoring loopback interface %s\n", inet_ntoa(iface->ip)));
+               if (is_loopback_addr(&iface->ip)) {
+                       DEBUG(2,("reload_interfaces: Ignoring loopback "
+                               "interface %s\n",
+                               print_sockaddr(str, sizeof(str),
+                                       &iface->ip, sizeof(iface->ip)) ));
                        continue;
                }
 
                for (subrec=subnetlist; subrec; subrec=subrec->next) {
-                       if (ip_equal(iface->ip, subrec->myip) &&
-                           ip_equal(iface->nmask, subrec->mask_ip)) break;
+                       if (ip_equal(ip, subrec->myip) &&
+                           ip_equal(nmask, subrec->mask_ip)) break;
                }
 
                if (!subrec) {
                        /* it wasn't found! add it */
                        DEBUG(2,("Found new interface %s\n", 
-                                inet_ntoa(iface->ip)));
+                                print_sockaddr(str, sizeof(str),
+                                        &iface->ip, sizeof(iface->ip)) ));
                        subrec = make_normal_subnet(iface);
                        if (subrec)
                                register_my_workgroup_one_subnet(subrec);
@@ -229,8 +244,20 @@ static BOOL reload_interfaces(time_t t)
        for (subrec=subnetlist; subrec; subrec=subrec->next) {
                for (n=iface_count() - 1; n >= 0; n--) {
                        struct interface *iface = get_interface(n);
-                       if (ip_equal(iface->ip, subrec->myip) &&
-                           ip_equal(iface->nmask, subrec->mask_ip)) break;
+                       struct in_addr ip, nmask;
+                       if (!iface) {
+                               continue;
+                       }
+                       /* Ensure we're only dealing with IPv4 here. */
+                       if (iface->ip.ss_family != AF_INET) {
+                               DEBUG(2,("reload_interfaces: "
+                                       "ignoring non IPv4 interface.\n"));
+                               continue;
+                       }
+                       ip = ((struct sockaddr_in *)&iface->ip)->sin_addr;
+                       nmask = ((struct sockaddr_in *)&iface->netmask)->sin_addr;
+                       if (ip_equal(ip, subrec->myip) &&
+                           ip_equal(nmask, subrec->mask_ip)) break;
                }
                if (n == -1) {
                        /* oops, an interface has disapeared. This is
@@ -322,7 +349,9 @@ static void msg_nmbd_send_packet(struct messaging_context *msg,
 {
        struct packet_struct *p = (struct packet_struct *)data->data;
        struct subnet_record *subrec;
-       struct in_addr *local_ip;
+       struct sockaddr_storage ss;
+       const struct sockaddr_storage *pss;
+       const struct in_addr *local_ip;
 
        DEBUG(10, ("Received send_packet from %d\n", procid_to_pid(&src)));
 
@@ -339,14 +368,16 @@ static void msg_nmbd_send_packet(struct messaging_context *msg,
                return;
        }
 
-       local_ip = iface_ip(p->ip);
+       in_addr_to_sockaddr_storage(&ss, p->ip);
+       pss = iface_ip(&ss);
 
-       if (local_ip == NULL) {
+       if (pss == NULL) {
                DEBUG(2, ("Could not find ip for packet from %d\n",
                          procid_to_pid(&src)));
                return;
        }
 
+       local_ip = &((const struct sockaddr_in *)pss)->sin_addr;
        subrec = FIRST_SUBNET;
 
        p->fd = (p->packet_type == NMB_PACKET) ?
index a0250f205a8cc87c68b234d65d2fb6e69a8259f1..fb87927436d745b60f04202ca40688e6038cc56f 100644 (file)
@@ -22,8 +22,6 @@
 
 #include "includes.h"
 
-extern struct in_addr allones_ip;
-
 extern uint16 samba_nb_type; /* Samba's NetBIOS type. */
 
 static void become_domain_master_browser_bcast(const char *);
@@ -119,7 +117,7 @@ in workgroup %s on subnet %s\n",
        if( subrec == unicast_subnet ) {
                struct nmb_name nmbname;
                struct in_addr my_first_ip;
-               struct in_addr *nip;
+               const struct in_addr *nip;
 
                /* Put our name and first IP address into the 
                   workgroup struct as domain master browser. This
@@ -129,14 +127,14 @@ in workgroup %s on subnet %s\n",
                make_nmb_name(&nmbname, global_myname(), 0x20);
 
                work->dmb_name = nmbname;
-               /* Pick the first interface ip address as the domain master browser ip. */
-               nip = iface_n_ip(0);
 
+               /* Pick the first interface IPv4 address as the domain master browser ip. */
+               nip = first_ipv4_iface();
                if (!nip) {
-                       DEBUG(0,("become_domain_master_stage2: Error. iface_n_ip returned NULL\n"));
+                       DEBUG(0,("become_domain_master_stage2: "
+                               "Error. get_interface returned NULL\n"));
                        return;
                }
-
                my_first_ip = *nip;
 
                putip((char *)&work->dmb_addr, &my_first_ip);
@@ -204,10 +202,12 @@ workgroup %s on subnet %s\n", wg_name, subrec->subnet_name));
 
 static void become_domain_master_query_success(struct subnet_record *subrec,
                         struct userdata_struct *userdata,
-                        struct nmb_name *nmbname, struct in_addr ip, 
+                        struct nmb_name *nmbname, struct in_addr ip,
                         struct res_rec *rrec)
 {
        unstring name;
+       struct in_addr allones_ip;
+
        pull_ascii_nstring(name, sizeof(name), nmbname->name);
 
        /* If the given ip is not ours, then we can't become a domain
@@ -217,7 +217,9 @@ static void become_domain_master_query_success(struct subnet_record *subrec,
        /* BUG note. Samba 1.9.16p11 servers seem to return the broadcast
                address or zero ip for this query. Pretend this is ok. */
 
-       if(ismyip(ip) || ip_equal(allones_ip, ip) || is_zero_ip(ip)) {
+       allones_ip.s_addr = htonl(INADDR_BROADCAST);
+
+       if(ismyip_v4(ip) || ip_equal(allones_ip, ip) || is_zero_ip_v4(ip)) {
                if( DEBUGLVL( 3 ) ) {
                        dbgtext( "become_domain_master_query_success():\n" );
                        dbgtext( "Our address (%s) ", inet_ntoa(ip) );
index 2e12f72b33d50446be5297def3e86fed35f8e0d1..e141b3e288eea36ac2a9e98735c9c06f244a079a 100644 (file)
@@ -103,7 +103,7 @@ static void announce_local_master_browser_to_domain_master_browser( struct work_
        unstring dmb_name;
        char *p;
 
-       if(ismyip(work->dmb_addr)) {
+       if(ismyip_v4(work->dmb_addr)) {
                if( DEBUGLVL( 2 ) ) {
                        dbgtext( "announce_local_master_browser_to_domain_master_browser:\n" );
                        dbgtext( "We are both a domain and a local master browser for " );
@@ -291,7 +291,7 @@ static void find_domain_master_name_query_success(struct subnet_record *subrec,
 
   /* First check if we already have a dmb for this workgroup. */
 
-       if(!is_zero_ip(work->dmb_addr) && ip_equal(work->dmb_addr, answer_ip)) {
+       if(!is_zero_ip_v4(work->dmb_addr) && ip_equal(work->dmb_addr, answer_ip)) {
                /* Do the local master browser announcement to the domain
                        master browser name and IP. */
                announce_local_master_browser_to_domain_master_browser( work );
@@ -300,7 +300,7 @@ static void find_domain_master_name_query_success(struct subnet_record *subrec,
                sync_with_dmb(work);
                return;
        } else {
-               zero_ip(&work->dmb_addr);
+               zero_ip_v4(&work->dmb_addr);
        }
 
        /* Now initiate the node status request. */
@@ -526,7 +526,7 @@ static void find_all_domain_master_names_query_success(struct subnet_record *sub
                 * Don't send node status requests to ourself.
                 */
 
-               if(ismyip( send_ip )) {
+               if(ismyip_v4( send_ip )) {
                        if( DEBUGLVL( 5 ) ) {
                                dbgtext( "find_all_domain_master_names_query_succes:\n" );
                                dbgtext( "Not sending node status to our own IP " );
index 956d0ab1e9192e73aa7ee3ddb97f55a45de5dee5..292a580ef9b5d12b608b9efa5ae64cce8006c1a2 100644 (file)
@@ -88,7 +88,7 @@ subnet %s from owner IP %s\n",
                subrec->subnet_name, inet_ntoa(owner_ip)));
   
        /* If someone is releasing a broadcast group name, just ignore it. */
-       if( group && !ismyip(owner_ip) )
+       if( group && !ismyip_v4(owner_ip) )
                return;
 
        /*
@@ -98,7 +98,7 @@ subnet %s from owner IP %s\n",
         */
 
        pull_ascii_nstring(qname, sizeof(qname), question->name);
-       if( !group && !ismyip(owner_ip) && strequal(qname, lp_workgroup()) && 
+       if( !group && !ismyip_v4(owner_ip) && strequal(qname, lp_workgroup()) && 
                        ((question->name_type == 0x0) || (question->name_type == 0x1e))) {
                DEBUG(6,("process_name_release_request: FTP OnNet bug workaround. Ignoring \
 group release name %s from IP %s on subnet %s with no group bit set.\n",
@@ -497,7 +497,7 @@ void process_name_query_request(struct subnet_record *subrec, struct packet_stru
                        
                        if (namerec->data.source == WINS_PROXY_NAME) {
                                for( i = 0; i < namerec->data.num_ips; i++) {
-                                       if (same_net(namerec->data.ip[i], subrec->myip, subrec->mask_ip)) {
+                                       if (same_net_v4(namerec->data.ip[i], subrec->myip, subrec->mask_ip)) {
                                                DEBUG(5,("process_name_query_request: name %s is a WINS proxy name and is also on the same subnet (%s) as the requestor. Not replying.\n", 
                                                         nmb_namestr(&namerec->name), subrec->subnet_name ));
                                                return;
index 4785df6cba2558a240ae5ea5a0beacec03a448de..eba732941883cf0061d6408f93ee92006dfb6d37 100644 (file)
@@ -48,7 +48,7 @@ void load_lmhosts_file(const char *fname)
                /* We find a relevent subnet to put this entry on, then add it. */
                /* Go through all the broadcast subnets and see if the mask matches. */
                for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
-                       if(same_net(ipaddr, subrec->bcast_ip, subrec->mask_ip))
+                       if(same_net_v4(ipaddr, subrec->bcast_ip, subrec->mask_ip))
                                break;
                }
   
index 71b69ebd8736be01c6db3b2848d4819e75764282..f0350af3b81949479a1eb2ecfc667b06b6c8fd83 100644 (file)
@@ -22,8 +22,6 @@
 
 #include "includes.h"
 
-extern struct in_addr allones_ip;
-
 extern uint16 samba_nb_type; /* Samba's NetBIOS type. */
 
 /****************************************************************************
index 4dcae87220aef9c41fa0469b5d8569078a326a8d..ea170d3aaa39b713e8cb60332ae4284cdb74cfd6 100644 (file)
@@ -35,7 +35,7 @@ static void query_name_response( struct subnet_record   *subrec,
        struct nmb_name *question_name = &rrec->packet->packet.nmb.question.question_name;
        struct in_addr answer_ip;
 
-       zero_ip(&answer_ip);
+       zero_ip_v4(&answer_ip);
 
        /* Ensure we don't retry the query but leave the response record cleanup
                to the timeout code. We may get more answer responses in which case
index 875e13fdc8861f0a4128b54a41e7b45d4ec8c30e..cb13febe466830eadb4750f572be98c841363148 100644 (file)
@@ -28,8 +28,6 @@ extern int global_nmb_port;
 
 extern int num_response_packets;
 
-extern struct in_addr loopback_ip;
-
 static void queue_packet(struct packet_struct *packet);
 
 BOOL rescan_listen_set = False;
@@ -148,7 +146,7 @@ static BOOL send_netbios_packet(struct packet_struct *p)
        BOOL loopback_this_packet = False;
 
        /* Check if we are sending to or from ourselves as a WINS server. */
-       if(ismyip(p->ip) && (p->port == global_nmb_port))
+       if(ismyip_v4(p->ip) && (p->port == global_nmb_port))
                loopback_this_packet = True;
 
        if(loopback_this_packet) {
@@ -225,12 +223,12 @@ static struct packet_struct *create_and_init_netbios_packet(struct nmb_name *nmb
 
 static BOOL create_and_init_additional_record(struct packet_struct *packet,
                                                      uint16 nb_flags,
-                                                     struct in_addr *register_ip)
+                                                     const struct in_addr *register_ip)
 {
        struct nmb_packet *nmb = &packet->packet.nmb;
 
        if((nmb->additional = SMB_MALLOC_P(struct res_rec)) == NULL) {
-               DEBUG(0,("initiate_name_register_packet: malloc fail for additional record.\n"));
+               DEBUG(0,("create_and_init_additional_record: malloc fail for additional record.\n"));
                return False;
        }
 
@@ -316,7 +314,7 @@ static BOOL initiate_name_query_packet_from_wins_server( struct packet_struct *p
 **************************************************************************/
 
 static BOOL initiate_name_register_packet( struct packet_struct *packet,
-                                    uint16 nb_flags, struct in_addr *register_ip)
+                                    uint16 nb_flags, const struct in_addr *register_ip)
 {
        struct nmb_packet *nmb = &packet->packet.nmb;
 
@@ -469,7 +467,8 @@ struct response_record *queue_register_name( struct subnet_record *subrec,
 {
        struct packet_struct *p;
        struct response_record *rrec;
-
+       struct sockaddr_storage ss;
+       const struct sockaddr_storage *pss = NULL;
        if(assert_check_subnet(subrec))
                return NULL;
 
@@ -478,7 +477,16 @@ struct response_record *queue_register_name( struct subnet_record *subrec,
                                subrec->bcast_ip)) == NULL)
                return NULL;
 
-       if(initiate_name_register_packet( p, nb_flags, iface_ip(subrec->bcast_ip)) == False) {
+       in_addr_to_sockaddr_storage(&ss, subrec->bcast_ip);
+       pss = iface_ip(&ss);
+       if (!pss || pss->ss_family != AF_INET) {
+               p->locked = False;
+               free_packet(p);
+               return NULL;
+       }
+
+       if(initiate_name_register_packet(p, nb_flags,
+                       &((const struct sockaddr_in *)pss)->sin_addr) == False) {
                p->locked = False;
                free_packet(p);
                return NULL;
@@ -698,7 +706,7 @@ struct response_record *queue_query_name( struct subnet_record *subrec,
   
        /* queries to the WINS server turn up here as queries to IP 0.0.0.0 
                        These need to be handled a bit differently */
-       if (subrec->type == UNICAST_SUBNET && is_zero_ip(to_ip)) {
+       if (subrec->type == UNICAST_SUBNET && is_zero_ip_v4(to_ip)) {
                /* What we really need to do is loop over each of our wins
                 * servers and wins server tags here, but that just doesn't
                 * fit our architecture at the moment (userdata may already
@@ -724,14 +732,14 @@ struct response_record *queue_query_name( struct subnet_record *subrec,
 
                DEBUG(10,("queue_query_name: bind_interfaces_only is set, looking for suitable source IP\n"));
                for(i = 0; i < iface_count(); i++) {
-                       struct in_addr *ifip = iface_n_ip(i);
+                       const struct in_addr *ifip = iface_n_ip_v4(i);
 
-                       if(ifip == NULL) {
+                       if (ifip == NULL) {
                                DEBUG(0,("queue_query_name: interface %d has NULL IP address !\n", i));
                                continue;
                        }
 
-                       if (ip_equal(*ifip,loopback_ip)) {
+                       if (is_loopback_ip_v4(*ifip)) {
                                DEBUG(5,("queue_query_name: ignoring loopback interface (%d)\n", i));
                                continue;
                        }
@@ -869,7 +877,7 @@ void reply_netbios_packet(struct packet_struct *orig_packet,
        const char *packet_type = "unknown";
 
        /* Check if we are sending to or from ourselves. */
-       if(ismyip(orig_packet->ip) && (orig_packet->port == global_nmb_port))
+       if(ismyip_v4(orig_packet->ip) && (orig_packet->port == global_nmb_port))
                loopback_this_packet = True;
 
        nmb = &packet.packet.nmb;
@@ -1020,7 +1028,7 @@ static struct subnet_record *find_subnet_for_dgram_browse_packet(struct packet_s
 
        /* Go through all the broadcast subnets and see if the mask matches. */
        for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
-               if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
+               if(same_net_v4(p->ip, subrec->bcast_ip, subrec->mask_ip))
                        return subrec;
        }
 
@@ -1176,7 +1184,7 @@ static BOOL listening(struct packet_struct *p,struct nmb_name *nbname)
        struct subnet_record *subrec = NULL;
 
        for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
-               if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
+               if(same_net_v4(p->ip, subrec->bcast_ip, subrec->mask_ip))
                        break;
        }
 
@@ -1439,7 +1447,7 @@ static struct subnet_record *find_subnet_for_nmb_packet( struct packet_struct *p
 
        /* Go through all the broadcast subnets and see if the mask matches. */
        for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
-               if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
+               if(same_net_v4(p->ip, subrec->bcast_ip, subrec->mask_ip))
                        return subrec;
        }
 
@@ -1814,12 +1822,12 @@ BOOL listen_for_packets(BOOL run_election)
                                         * only is set then check it came from one of our local nets. 
                                         */
                                        if(lp_bind_interfaces_only() && (sock_array[i] == ClientNMB) && 
-                                                               (!is_local_net(packet->ip))) {
+                                                               (!is_local_net_v4(packet->ip))) {
                                                DEBUG(7,("discarding nmb packet sent to broadcast socket from %s:%d\n",
                                                        inet_ntoa(packet->ip),packet->port));     
                                                free_packet(packet);
-                                       } else if ((ip_equal(loopback_ip, packet->ip) || 
-                                                               ismyip(packet->ip)) && packet->port == global_nmb_port &&
+                                       } else if ((is_loopback_ip_v4(packet->ip) || 
+                                                               ismyip_v4(packet->ip)) && packet->port == global_nmb_port &&
                                                                packet->packet.nmb.header.nm_flags.bcast) {
                                                DEBUG(7,("discarding own bcast packet from %s:%d\n",
                                                        inet_ntoa(packet->ip),packet->port));     
@@ -1841,12 +1849,12 @@ BOOL listen_for_packets(BOOL run_election)
                                         * only is set then check it came from one of our local nets. 
                                         */
                                        if(lp_bind_interfaces_only() && (sock_array[i] == ClientDGRAM) && 
-                                                               (!is_local_net(packet->ip))) {
+                                                               (!is_local_net_v4(packet->ip))) {
                                                DEBUG(7,("discarding dgram packet sent to broadcast socket from %s:%d\n",
                                                inet_ntoa(packet->ip),packet->port));     
                                                free_packet(packet);
-                                       } else if ((ip_equal(loopback_ip, packet->ip) || 
-                                                       ismyip(packet->ip)) && packet->port == DGRAM_PORT) {
+                                       } else if ((is_loopback_ip_v4(packet->ip) || 
+                                                       ismyip_v4(packet->ip)) && packet->port == DGRAM_PORT) {
                                                DEBUG(7,("discarding own dgram packet from %s:%d\n",
                                                        inet_ntoa(packet->ip),packet->port));     
                                                free_packet(packet);
@@ -1880,7 +1888,7 @@ BOOL send_mailslot(BOOL unique, const char *mailslot,char *buf, size_t len,
 
        memset((char *)&p,'\0',sizeof(p));
 
-       if(ismyip(dest_ip) && (dest_port == DGRAM_PORT)) /* Only if to DGRAM_PORT */
+       if(ismyip_v4(dest_ip) && (dest_port == DGRAM_PORT)) /* Only if to DGRAM_PORT */
                loopback_this_packet = True;
 
        /* generate_name_trn_id(); */ /* Not used, so gone, RJS */
index abac2ac7764265c2b1d3c742749098b8e40f731d..4b5fe28d4e9dcb16acc73421ced3ab3ba22e377a 100644 (file)
@@ -54,6 +54,19 @@ void process_logon_packet(struct packet_struct *p, char *buf,int len,
        pstring ascuser;
        char *unicomp; /* Unicode computer name. */
        size_t size;
+       struct sockaddr_storage ss;
+       const struct sockaddr_storage *pss;
+       struct in_addr ip;
+
+       in_addr_to_sockaddr_storage(&ss, p->ip);
+       pss = iface_ip(&ss);
+       if (!pss) {
+               DEBUG(5,("process_logon_packet:can't find outgoing interface "
+                       "for packet from IP %s\n",
+                       inet_ntoa(p->ip) ));
+               return;
+       }
+       ip = ((struct sockaddr_in *)pss)->sin_addr;
 
        memset(outbuf, 0, sizeof(outbuf));
 
@@ -127,7 +140,7 @@ logons are not enabled.\n", inet_ntoa(p->ip) ));
                                                global_myname(), 0x0,
                                                mach_str,
                                                dgram->source_name.name_type,
-                                               p->ip, *iface_ip(p->ip), p->port);  
+                                               p->ip, ip, p->port);
                                break;
                        }
 
@@ -258,7 +271,7 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
                                        global_myname(), 0x0,
                                        source_name,
                                        dgram->source_name.name_type,
-                                       p->ip, *iface_ip(p->ip), p->port);  
+                                       p->ip, ip, p->port);
                                return;
                        }
 
@@ -543,7 +556,7 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
 
                                        SIVAL(q, 0, 0x00000002);
                                        q += 4; /* unknown */
-                                       SIVAL(q, 0, (iface_ip(p->ip))->s_addr);
+                                       SIVAL(q, 0, ntohl(ip.s_addr));
                                        q += 4;
                                        SIVAL(q, 0, 0x00000000);
                                        q += 4; /* unknown */
@@ -573,7 +586,7 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
                                        global_myname(), 0x0,
                                        source_name,
                                        dgram->source_name.name_type,
-                                       p->ip, *iface_ip(p->ip), p->port);
+                                       p->ip, ip, p->port);
                                break;
                        }
 
index 690ca5b62182de301d74d7beccc89aabb538a414..7fd241cf624c58cc0f1f6b4d87b8b120fdf28cb3 100644 (file)
@@ -24,7 +24,6 @@
 
 #include "includes.h"
 
-extern struct in_addr loopback_ip;
 extern int global_nmb_port;
 
 /* This is the broadcast subnets database. */
@@ -169,12 +168,16 @@ static struct subnet_record *make_subnet(const char *name, enum subnet_type type
   Create a normal subnet
 **************************************************************************/
 
-struct subnet_record *make_normal_subnet(struct interface *iface)
+struct subnet_record *make_normal_subnet(const struct interface *iface)
 {
+
        struct subnet_record *subrec;
+       const struct in_addr *pip = &((const struct sockaddr_in *)&iface->ip)->sin_addr;
+       const struct in_addr *pbcast = &((const struct sockaddr_in *)&iface->bcast)->sin_addr;
+       const struct in_addr *pnmask = &((const struct sockaddr_in *)&iface->netmask)->sin_addr;
 
-       subrec = make_subnet(inet_ntoa(iface->ip), NORMAL_SUBNET,
-                            iface->ip, iface->bcast, iface->nmask);
+       subrec = make_subnet(inet_ntoa(*pip), NORMAL_SUBNET,
+                            *pip, *pbcast, *pnmask);
        if (subrec) {
                add_subnet(subrec);
        }
@@ -186,8 +189,9 @@ struct subnet_record *make_normal_subnet(struct interface *iface)
 **************************************************************************/
 
 BOOL create_subnets(void)
-{    
-       int num_interfaces = iface_count();
+{
+       /* We only count IPv4 interfaces whilst we're waiting. */
+       int num_interfaces = iface_count_v4();
        int i;
        struct in_addr unicast_ip, ipzero;
 
@@ -197,47 +201,59 @@ BOOL create_subnets(void)
                DEBUG(0,("create_subnets: No local interfaces !\n"));
                DEBUG(0,("create_subnets: Waiting for an interface to appear ...\n"));
 
-               /* 
+               /*
                 * Whilst we're waiting for an interface, allow SIGTERM to
                 * cause us to exit.
                 */
 
                saved_handler = CatchSignal( SIGTERM, SIGNAL_CAST SIG_DFL );
 
-               while (iface_count() == 0) {
+               /* We only count IPv4 interfaces here. */
+               while (iface_count_v4() == 0) {
                        sleep(5);
                        load_interfaces();
                }
 
-               /* 
+               /*
                 * We got an interface, restore our normal term handler.
                 */
 
                CatchSignal( SIGTERM, SIGNAL_CAST saved_handler );
        }
 
+       /*
+        * Here we count v4 and v6 - we know there's at least one
+        * IPv4 interface and we filter on it below.
+        */
        num_interfaces = iface_count();
 
-       /* 
+       /*
         * Create subnets from all the local interfaces and thread them onto
-        * the linked list. 
+        * the linked list.
         */
 
        for (i = 0 ; i < num_interfaces; i++) {
-               struct interface *iface = get_interface(i);
+               const struct interface *iface = get_interface(i);
 
                if (!iface) {
                        DEBUG(2,("create_subnets: can't get interface %d.\n", i ));
                        continue;
                }
 
+               /* Ensure we're only dealing with IPv4 here. */
+               if (iface->ip.ss_family != AF_INET) {
+                       DEBUG(2,("create_subnets: "
+                               "ignoring non IPv4 interface.\n"));
+                       continue;
+               }
+
                /*
                 * We don't want to add a loopback interface, in case
                 * someone has added 127.0.0.1 for smbd, nmbd needs to
                 * ignore it here. JRA.
                 */
 
-               if (ip_equal(iface->ip, loopback_ip)) {
+               if (is_loopback_addr(&iface->ip)) {
                        DEBUG(2,("create_subnets: Ignoring loopback interface.\n" ));
                        continue;
                }
@@ -254,8 +270,8 @@ BOOL create_subnets(void)
        }
 
        if (lp_we_are_a_wins_server()) {
-               /* Pick the first interface ip address as the WINS server ip. */
-               struct in_addr *nip = iface_n_ip(0);
+               /* Pick the first interface IPv4 address as the WINS server ip. */
+               const struct in_addr *nip = first_ipv4_iface();
 
                if (!nip) {
                        return False;
@@ -266,7 +282,7 @@ BOOL create_subnets(void)
                /* note that we do not set the wins server IP here. We just
                        set it at zero and let the wins registration code cope
                        with getting the IPs right for each packet */
-               zero_ip(&unicast_ip);
+               zero_ip_v4(&unicast_ip);
        }
 
        /*
@@ -279,7 +295,7 @@ BOOL create_subnets(void)
        unicast_subnet = make_subnet( "UNICAST_SUBNET", UNICAST_SUBNET, 
                                unicast_ip, unicast_ip, unicast_ip);
 
-       zero_ip(&ipzero);
+       zero_ip_v4(&ipzero);
 
        remote_broadcast_subnet = make_subnet( "REMOTE_BROADCAST_SUBNET",
                                REMOTE_BROADCAST_SUBNET,
index 60d1d3fd8dc84e916daccaa024f6862355b0ddcd..6b716bdf3554140d55ef22b77493740eeac33a13 100644 (file)
@@ -149,7 +149,7 @@ void sync_browse_lists(struct work_record *work,
        START_PROFILE(sync_browse_lists);
        /* Check we're not trying to sync with ourselves. This can
           happen if we are a domain *and* a local master browser. */
-       if (ismyip(ip)) {
+       if (ismyip_v4(ip)) {
 done:
                END_PROFILE(sync_browse_lists);
                return;
index 2c57c4649a0bfde42dd10c83153daabe7df5a1cd..ff80c15ffff4ecbf9c29312918e848e0c1837c37 100644 (file)
@@ -107,7 +107,7 @@ returned for name %s.\n", nmb_namestr(nmbname) ));
 
        if(namerec && original_packet->packet.nmb.header.nm_flags.bcast) {
                for( i = 0; i < namerec->data.num_ips; i++) {
-                       if( same_net( namerec->data.ip[i], orig_broadcast_subnet->myip,
+                       if( same_net_v4( namerec->data.ip[i], orig_broadcast_subnet->myip,
                                        orig_broadcast_subnet->mask_ip ) ) {
                                DEBUG( 5, ( "wins_proxy_name_query_request_success: name %s is a WINS \
 proxy name and is also on the same subnet (%s) as the requestor. \
index cd07549b301c0dafbd6dc2751e791d1799e10504..66c060f65278b15dbee0b1ad6ad29ac4a837dfbf 100644 (file)
@@ -1273,7 +1273,7 @@ already exists in WINS as a GROUP name.\n", nmb_namestr(question) ));
        if ( namerec != NULL ) {
                pull_ascii_nstring(name, sizeof(name), namerec->name.name);
                if( is_myname(name) ) {
-                       if(!ismyip(from_ip)) {
+                       if(!ismyip_v4(from_ip)) {
                                DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
 is one of our (WINS server) names. Denying registration.\n", nmb_namestr(question) ));
                                send_wins_name_registration_response(RFS_ERR, 0, p);
@@ -1595,7 +1595,7 @@ already exists in WINS as a GROUP name.\n", nmb_namestr(question) ));
         */
 
        if((namerec != NULL) && (is_myname(namerec->name.name)) ) {
-               if(!ismyip(from_ip)) {
+               if(!ismyip_v4(from_ip)) {
                        DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
 is one of our (WINS server) names. Denying registration.\n", nmb_namestr(question) ));
                        send_wins_name_registration_response(RFS_ERR, 0, p);
index 60194e991550206bdda757f85a19e036f710f025..82c3a31669d52e36783dcb769ac8749d30171ba4 100644 (file)
@@ -110,7 +110,7 @@ static struct work_record *create_workgroup(const char *name, int ttl)
 
        /* No known domain master browser as yet. */
        *work->dmb_name.name = '\0';
-       zero_ip(&work->dmb_addr);
+       zero_ip_v4(&work->dmb_addr);
 
        /* WfWg  uses 01040b01 */
        /* Win95 uses 01041501 */
index 8e4d75e545a9648884d75f3f7eb444ca958706fd..9502a5d17eafacd16f0eb0e07abf5821d7337add 100644 (file)
@@ -120,7 +120,10 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count)
 
        /* uggh, we have to broadcast to each interface in turn */
        for (j=iface_count() - 1;j >= 0;j--) {
-               struct in_addr *bcast = iface_n_bcast(j);
+               const struct in_addr *bcast = iface_n_bcast_v4(j);
+               if (!bcast) {
+                       continue;
+               }
                ret = name_query(fd,name,0x00,True,True,*bcast,count, &flags, NULL);
                if (ret) break;
        }
index 11827c223bb19320ec3cc485739b2611e0fa7610..1bed2bf095f6463b19a9ef7b81aab3c183346ee0 100644 (file)
@@ -2534,13 +2534,13 @@ static BOOL spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
        struct cli_state *the_cli;
        struct in_addr rm_addr;
 
-       if ( is_zero_ip(*client_ip) ) {
+       if ( is_zero_ip_v4(*client_ip) ) {
                if ( !resolve_name( remote_machine, &rm_addr, 0x20) ) {
                        DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
                        return False;
                }
 
-               if ( ismyip( rm_addr )) {
+               if ( ismyip_v4( rm_addr )) {
                        DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine));
                        return False;
                }
index 0f47a550e9621af04ea87e458bd53a9bc9aedcc2..8c92c91577db1dc1bd1cbb6547c2f0bbaf9b746a 100644 (file)
@@ -348,15 +348,24 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
                /* Now open a listen socket for each of the
                   interfaces. */
                for(i = 0; i < num_interfaces; i++) {
-                       struct in_addr *ifip = iface_n_ip(i);
+                       const struct sockaddr_storage *ifss =
+                                       iface_n_sockaddr_storage(i);
+                       const struct in_addr *ifip;
                        fstring tok;
                        const char *ptr;
 
-                       if(ifip == NULL) {
+                       if (ifss == NULL) {
                                DEBUG(0,("open_sockets_smbd: interface %d has NULL IP address !\n", i));
                                continue;
                        }
 
+                       /* For now only deal with IPv4. */
+                       if (ifss->ss_family != AF_INET) {
+                               continue;
+                       }
+
+                       ifip = &((const struct sockaddr_in *)ifss)->sin_addr;
+
                        for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) {
                                unsigned port = atoi(tok);
                                if (port == 0 || port > 0xffff) {
index 9e4b8953162b0c304a03c2f856b0a91240e3fb1c..394a237a03e6d77cd7eccd96ebeefe25e9947f38 100644 (file)
@@ -174,7 +174,7 @@ static struct cli_state *connect_one(char *share, int snum)
 
        server_n = server;
        
-        zero_ip(&ip);
+        zero_ip_v4(&ip);
 
        slprintf(myname,sizeof(myname), "lock-%lu-%u", (unsigned long)getpid(), count++);
 
@@ -182,7 +182,7 @@ static struct cli_state *connect_one(char *share, int snum)
        make_nmb_name(&called , server, 0x20);
 
  again:
-        zero_ip(&ip);
+        zero_ip_v4(&ip);
 
        /* have to open a new connection */
        if (!(c=cli_initialise())) {
index 4913f60025d50873c5f76d8aea1e5427e283f8d3..bab488f7bb2beb2c171a59e0e75f0822b7527d46 100644 (file)
@@ -179,13 +179,13 @@ static struct cli_state *connect_one(char *share)
 
        server_n = server;
        
-        zero_ip(&ip);
+        zero_ip_v4(&ip);
 
        make_nmb_name(&calling, "masktest", 0x0);
        make_nmb_name(&called , server, 0x20);
 
  again:
-        zero_ip(&ip);
+        zero_ip_v4(&ip);
 
        /* have to open a new connection */
        if (!(c=cli_initialise())) {
index 991dadf9e31319a5cd71200a4374e115c03c9100..a0167e8aabe3d795b74e6121e1147255533c998a 100644 (file)
@@ -106,7 +106,7 @@ static struct cli_state *open_nbt_connection(void)
        make_nmb_name(&calling, myname, 0x0);
        make_nmb_name(&called , host, 0x20);
 
-        zero_ip(&ip);
+        zero_ip_v4(&ip);
 
        if (!(c = cli_initialise())) {
                printf("Failed initialize cli_struct to connect with %s\n", host);
index 88283ac1458ea0a54c5c3173ad8c9efa3c8dbb80..f9af7a41caf8ce7cf9677a37b99d8a0996147899 100644 (file)
@@ -89,7 +89,6 @@ BOOL opt_testmode = False;
 BOOL opt_have_ip = False;
 struct in_addr opt_dest_ip;
 
-extern struct in_addr loopback_ip;
 extern BOOL AllowDebugChange;
 
 uint32 get_sec_channel_type(const char *param) 
@@ -407,7 +406,7 @@ BOOL net_find_server(const char *domain, unsigned flags, struct in_addr *server_
                if (get_pdc_ip(d, &pdc_ip)) {
                        fstring dc_name;
                        
-                       if (is_zero_ip(pdc_ip))
+                       if (is_zero_ip_v4(pdc_ip))
                                return False;
                        
                        if ( !name_status_find(d, 0x1b, 0x20, pdc_ip, dc_name) )
@@ -437,7 +436,7 @@ BOOL net_find_server(const char *domain, unsigned flags, struct in_addr *server_
                }
                *server_name = SMB_STRDUP(inet_ntoa(opt_dest_ip));
        } else if (!(flags & NET_FLAGS_LOCALHOST_DEFAULT_INSANE)) {
-               *server_ip = loopback_ip;
+               (*server_ip).s_addr = htonl(INADDR_LOOPBACK);
                *server_name = SMB_STRDUP("127.0.0.1");
        }
 
@@ -453,7 +452,7 @@ BOOL net_find_server(const char *domain, unsigned flags, struct in_addr *server_
 BOOL net_find_pdc(struct in_addr *server_ip, fstring server_name, const char *domain_name)
 {
        if (get_pdc_ip(domain_name, server_ip)) {
-               if (is_zero_ip(*server_ip))
+               if (is_zero_ip_v4(*server_ip))
                        return False;
                
                if (!name_status_find(domain_name, 0x1b, 0x20, *server_ip, server_name))
@@ -990,7 +989,7 @@ static struct functable net_func[] = {
 
        TALLOC_CTX *frame = talloc_stackframe();
 
-       zero_ip(&opt_dest_ip);
+       zero_ip_v4(&opt_dest_ip);
 
        load_case_tables();
 
@@ -1009,7 +1008,7 @@ static struct functable net_func[] = {
                        break;
                case 'I':
                        opt_dest_ip = *interpret_addr2(poptGetOptArg(pc));
-                       if (is_zero_ip(opt_dest_ip))
+                       if (is_zero_ip_v4(opt_dest_ip))
                                d_fprintf(stderr, "\nInvalid ip address specified\n");
                        else
                                opt_have_ip = True;
index e1993488f5b093bbadf8ccb9aed4279bc120005c..716192b057097b23f733c36448888656c3858ed1 100644 (file)
@@ -145,7 +145,6 @@ int get_my_ip_address( struct in_addr **ips )
 {
        struct iface_struct nics[MAX_INTERFACES];
        int i, n;
-       struct in_addr loopback_ip = *interpret_addr2("127.0.0.1");
        struct in_addr *list;
        int count = 0;
 
@@ -158,7 +157,7 @@ int get_my_ip_address( struct in_addr **ips )
        }
 
        for ( i=0; i<n; i++ ) {
-               if ( nics[i].iface_addr.ip.s_addr != loopback_ip.s_addr ) {
+               if (!is_loopback_ip_v4(nics[i].iface_addr.ip.s_addr)) {
                        memcpy( &list[count++], &nics[i].iface_addr.ip, sizeof( struct in_addr ) );
                }
        }
index 58c0f010191b5d1c7a713308ef0e36aabd897194..998e77c68e4ae5e178358758c98350eaddede7e9 100644 (file)
@@ -56,8 +56,9 @@ static int cs_destructor(struct con_struct *p)
 static struct con_struct *create_cs(TALLOC_CTX *ctx, NTSTATUS *perr)
 {
        NTSTATUS nt_status;
-       struct in_addr loopback_ip = *interpret_addr2("127.0.0.1");
+       struct in_addr loopback_ip;
 
+       loopback_ip.s_addr = htonl(INADDR_LOOPBACK);
        *perr = NT_STATUS_OK;
 
        if (cs) {
index bf158fe4a06258197e1102eafa4044f2aaeb8077..52d7ad1a3c7dce98118ad0f5148a98d146dfd75b 100644 (file)
@@ -141,11 +141,14 @@ static BOOL query_one(const char *lookup, unsigned int lookup_type)
                                     use_bcast?True:recursion_desired,
                                     bcast_addr,&count, &flags, NULL);
        } else {
-               struct in_addr *bcast;
+               const struct in_addr *bcast;
                for (j=iface_count() - 1;
                     !ip_list && j >= 0;
                     j--) {
-                       bcast = iface_n_bcast(j);
+                       bcast = iface_n_bcast_v4(j);
+                       if (!bcast) {
+                               continue;
+                       }
                        d_printf("querying %s on %s\n", 
                               lookup, inet_ntoa(*bcast));
                        ip_list = name_query(ServerFD,lookup,lookup_type,
index 6324dcc19270884b12bb921a5fa952f4c08d09fb..dbb067477eeb74b2e029467dcb4754fc07c90522 100644 (file)
@@ -768,7 +768,7 @@ static struct cli_state *connect_one(const char *share)
        struct cli_state *c;
        struct in_addr ip;
        NTSTATUS nt_status;
-       zero_ip(&ip);
+       zero_ip_v4(&ip);
        
        if (!cmdline_auth_info.got_pass) {
                char *pass = getpass("Password: ");
index 8d954ac20ae93e5bdb03156719ed3ac91b4e6cab..1f718b7cefc89e58c1a41d54432dd341ccb74a9f 100644 (file)
@@ -360,7 +360,7 @@ static struct cli_state *connect_one(const char *share)
        struct cli_state *c;
        struct in_addr ip;
        NTSTATUS nt_status;
-       zero_ip(&ip);
+       zero_ip_v4(&ip);
        
        if (!cmdline_auth_info.got_pass) {
                char *pass = getpass("Password: ");
index 227c68dd6d9427da7ca222c5427e23cf133cba45..9aba27c774b96d83d0379e710aa261a97aa3d5af 100644 (file)
@@ -20,8 +20,6 @@
 #include "includes.h"
 #include "web/swat_proto.h"
 
-extern struct in_addr loopback_ip;
-
 #ifdef WITH_WINBIND
 
 /* check to see if winbind is running by pinging it */
@@ -36,9 +34,12 @@ BOOL winbindd_running(void)
    response */
 BOOL nmbd_running(void)
 {
+       struct in_addr loopback_ip;
        int fd, count, flags;
        struct in_addr *ip_list;
 
+       loopback_ip.s_addr = htonl(INADDR_LOOPBACK);
+
        if ((fd = open_socket_in(SOCK_DGRAM, 0, 3,
                                 interpret_addr("127.0.0.1"), True)) != -1) {
                if ((ip_list = name_query(fd, "__SAMBA__", 0, 
@@ -59,9 +60,12 @@ BOOL nmbd_running(void)
    then closing it */
 BOOL smbd_running(void)
 {
+       struct in_addr loopback_ip;
        NTSTATUS status;
        struct cli_state *cli;
 
+       loopback_ip.s_addr = htonl(INADDR_LOOPBACK);
+
        if ((cli = cli_initialise()) == NULL)
                return False;
 
index e12b13cbbd1b16ef5c7f7c5e7a543fc6bb2c37b6..4ff9fce96fd477d29fd756b09925d3569c07620c 100644 (file)
@@ -1292,7 +1292,7 @@ static BOOL find_new_dc(TALLOC_CTX *mem_ctx,
 
        *addr = addrs[fd_index];
 
-       if (*dcnames[fd_index] != '\0' && !is_ipaddress(dcnames[fd_index])) {
+       if (*dcnames[fd_index] != '\0' && !is_ipaddress_v4(dcnames[fd_index])) {
                /* Ok, we've got a name for the DC */
                fstrcpy(dcname, dcnames[fd_index]);
                return True;
@@ -1336,7 +1336,7 @@ static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
                        saf_servername, domain->name ));
 
                /* convert an ip address to a name */
-               if ( is_ipaddress( saf_servername ) ) {
+               if ( is_ipaddress_v4( saf_servername ) ) {
                        fstring saf_name;
                        struct in_addr ip;
 
index f84dfdf2deb40fb19801cd5f966eca237382b22f..2ee6f69b66a77ff75b25ce2b8a3f7e06e3df60cf 100644 (file)
@@ -118,7 +118,10 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count)
        for (j=iface_count() - 1;
             j >= 0;
             j--) {
-               struct in_addr *bcast = iface_n_bcast(j);
+               const struct in_addr *bcast = iface_n_bcast_v4(j);
+               if (!bcast) {
+                       continue;
+               }
                return_ip = name_query(fd,name,0x20,True,True,*bcast,count, &flags, NULL);
                if (return_ip) {
                        break;