summaryrefslogtreecommitdiffstats
path: root/source4/lib/socket
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2011-06-24 16:26:23 +1000
committerAndrew Bartlett <abartlet@samba.org>2011-06-24 16:26:23 +1000
commit6da26870e0ae5acd6ff49a30ec2f6886b44d095e (patch)
tree850c71039563c16a5d563c47e7ba2ab645baf198 /source4/lib/socket
parent6925a799d04c6fa59dd2ddef1f5510f9bb7d17d1 (diff)
parent2610c05b5b95cc7036b3d6dfb894c6cfbdb68483 (diff)
downloadsamba-6da26870e0ae5acd6ff49a30ec2f6886b44d095e.tar.gz
samba-6da26870e0ae5acd6ff49a30ec2f6886b44d095e.tar.xz
samba-6da26870e0ae5acd6ff49a30ec2f6886b44d095e.zip
Merge 2610c05b5b95cc7036b3d6dfb894c6cfbdb68483 as Samba-4.0alpha16samba-4.0.0alpha16
Diffstat (limited to 'source4/lib/socket')
-rw-r--r--source4/lib/socket/access.c8
-rw-r--r--source4/lib/socket/connect_multi.c4
-rw-r--r--source4/lib/socket/interface.c389
-rw-r--r--source4/lib/socket/netif.c127
-rw-r--r--source4/lib/socket/netif.h14
-rw-r--r--source4/lib/socket/socket.c169
-rw-r--r--source4/lib/socket/socket.h10
-rw-r--r--source4/lib/socket/socket_ip.c86
-rw-r--r--source4/lib/socket/socket_unix.c16
-rw-r--r--source4/lib/socket/testsuite.c14
-rw-r--r--source4/lib/socket/wscript_build10
11 files changed, 441 insertions, 406 deletions
diff --git a/source4/lib/socket/access.c b/source4/lib/socket/access.c
index ab39d63ef5b..589797763fc 100644
--- a/source4/lib/socket/access.c
+++ b/source4/lib/socket/access.c
@@ -249,9 +249,9 @@ static bool allow_access_internal(TALLOC_CTX *mem_ctx,
}
/* return true if access should be allowed */
-bool allow_access(TALLOC_CTX *mem_ctx,
- const char **deny_list, const char **allow_list,
- const char *cname, const char *caddr)
+bool socket_allow_access(TALLOC_CTX *mem_ctx,
+ const char **deny_list, const char **allow_list,
+ const char *cname, const char *caddr)
{
bool ret;
char *nc_cname = talloc_strdup(mem_ctx, cname);
@@ -346,7 +346,7 @@ bool socket_check_access(struct socket_context *sock,
return false;
}
- ret = allow_access(mem_ctx, deny_list, allow_list, name, addr->addr);
+ ret = socket_allow_access(mem_ctx, deny_list, allow_list, name, addr->addr);
if (ret) {
DEBUG(2,("socket_check_access: Allowed connection to '%s' from %s (%s)\n",
diff --git a/source4/lib/socket/connect_multi.c b/source4/lib/socket/connect_multi.c
index 300e5fb1e53..4ce5115e97d 100644
--- a/source4/lib/socket/connect_multi.c
+++ b/source4/lib/socket/connect_multi.c
@@ -136,7 +136,7 @@ static void connect_multi_next_socket(struct composite_context *result)
if (composite_nomem(state, result)) return;
state->result = result;
- result->status = socket_create("ipv4", SOCKET_TYPE_STREAM, &state->sock, 0);
+ result->status = socket_create(multi->server_address->family, SOCKET_TYPE_STREAM, &state->sock, 0);
if (!composite_is_ok(result)) return;
state->addr = socket_address_copy(state, multi->server_address);
@@ -162,7 +162,7 @@ static void connect_multi_next_socket(struct composite_context *result)
connect attempt state, so it will go away when this
request completes */
event_add_timed(result->event_ctx, state,
- timeval_current_ofs(0, MULTI_PORT_DELAY),
+ timeval_current_ofs_usec(MULTI_PORT_DELAY),
connect_multi_timer, result);
}
}
diff --git a/source4/lib/socket/interface.c b/source4/lib/socket/interface.c
index c4411b623c0..d5b610fea7f 100644
--- a/source4/lib/socket/interface.c
+++ b/source4/lib/socket/interface.c
@@ -21,15 +21,19 @@
#include "includes.h"
#include "system/network.h"
+#include "param/param.h"
#include "lib/socket/netif.h"
#include "../lib/util/util_net.h"
#include "../lib/util/dlinklist.h"
-/** used for network interfaces */
+/* used for network interfaces */
struct interface {
struct interface *next, *prev;
- struct in_addr ip;
- struct in_addr nmask;
+ char *name;
+ int flags;
+ struct sockaddr_storage ip;
+ struct sockaddr_storage netmask;
+ struct sockaddr_storage bcast;
const char *ip_s;
const char *bcast_s;
const char *nmask_s;
@@ -45,31 +49,51 @@ struct interface {
/****************************************************************************
Try and find an interface that matches an ip. If we cannot, return NULL
**************************************************************************/
-static struct interface *iface_find(struct interface *interfaces,
- struct in_addr ip, bool CheckMask)
+static struct interface *iface_list_find(struct interface *interfaces,
+ const struct sockaddr *ip,
+ bool check_mask)
{
struct interface *i;
- if (is_zero_ip_v4(ip)) return interfaces;
- for (i=interfaces;i;i=i->next)
- if (CheckMask) {
- if (same_net_v4(i->ip,ip,i->nmask)) return i;
- } else if (i->ip.s_addr == ip.s_addr) return i;
+ if (is_address_any(ip)) {
+ return interfaces;
+ }
+
+ for (i=interfaces;i;i=i->next) {
+ if (check_mask) {
+ if (same_net(ip, (struct sockaddr *)&i->ip, (struct sockaddr *)&i->netmask)) {
+ return i;
+ }
+ } else if (sockaddr_equal((struct sockaddr *)&i->ip, ip)) {
+ return i;
+ }
+ }
return NULL;
}
-
/****************************************************************************
add an interface to the linked list of interfaces
****************************************************************************/
-static void add_interface(TALLOC_CTX *mem_ctx, struct in_addr ip, struct in_addr nmask, struct interface **interfaces)
+static void add_interface(TALLOC_CTX *mem_ctx, const struct iface_struct *ifs, struct interface **interfaces,
+ bool enable_ipv6)
{
+ char addr[INET6_ADDRSTRLEN];
struct interface *iface;
- struct in_addr bcast;
- if (iface_find(*interfaces, ip, false)) {
- DEBUG(3,("not adding duplicate interface %s\n",inet_ntoa(ip)));
+ if (iface_list_find(*interfaces, (const struct sockaddr *)&ifs->ip, false)) {
+ DEBUG(3,("add_interface: not adding duplicate interface %s\n",
+ print_sockaddr(addr, sizeof(addr), &ifs->ip) ));
+ return;
+ }
+
+ if (!(ifs->flags & (IFF_BROADCAST|IFF_LOOPBACK))) {
+ DEBUG(3,("not adding non-broadcast interface %s\n",
+ ifs->name ));
+ return;
+ }
+
+ if (!enable_ipv6 && ifs->ip.ss_family != AF_INET) {
return;
}
@@ -79,26 +103,40 @@ static void add_interface(TALLOC_CTX *mem_ctx, struct in_addr ip, struct in_addr
ZERO_STRUCTPN(iface);
- iface->ip = ip;
- iface->nmask = nmask;
- bcast.s_addr = MKBCADDR(iface->ip.s_addr, iface->nmask.s_addr);
+ iface->name = talloc_strdup(iface, 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;
/* keep string versions too, to avoid people tripping over the implied
static in inet_ntoa() */
- iface->ip_s = talloc_strdup(iface, inet_ntoa(iface->ip));
- iface->nmask_s = talloc_strdup(iface, inet_ntoa(iface->nmask));
-
- if (nmask.s_addr != ~0) {
- iface->bcast_s = talloc_strdup(iface, inet_ntoa(bcast));
- }
-
- DLIST_ADD_END(*interfaces, iface, struct interface *);
-
- DEBUG(3,("added interface ip=%s nmask=%s\n", iface->ip_s, iface->nmask_s));
+ print_sockaddr(addr, sizeof(addr), &iface->ip);
+ DEBUG(4,("added interface %s ip=%s ",
+ iface->name, addr));
+ iface->ip_s = talloc_strdup(iface, addr);
+
+ print_sockaddr(addr, sizeof(addr),
+ &iface->bcast);
+ DEBUG(4,("bcast=%s ", addr));
+ iface->bcast_s = talloc_strdup(iface, addr);
+
+ print_sockaddr(addr, sizeof(addr),
+ &iface->netmask);
+ DEBUG(4,("netmask=%s\n", addr));
+ iface->nmask_s = talloc_strdup(iface, addr);
+
+ /*
+ this needs to be a ADD_END, as some tests (such as the
+ spoolss notify test) depend on the interfaces ordering
+ */
+ DLIST_ADD_END(*interfaces, iface, NULL);
}
-
-
/**
interpret a single element from a interfaces= config line
@@ -114,99 +152,155 @@ static void interpret_interface(TALLOC_CTX *mem_ctx,
const char *token,
struct iface_struct *probed_ifaces,
int total_probed,
- struct interface **local_interfaces)
+ struct interface **local_interfaces,
+ bool enable_ipv6)
{
- 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;
- char *address;
- int i, added=0;
+ int i;
+ bool added=false;
+ bool goodaddr = false;
- ip.s_addr = 0;
- nmask.s_addr = 0;
-
/* 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(mem_ctx, probed_ifaces[i].ip,
- probed_ifaces[i].netmask,
- local_interfaces);
- added = 1;
+ add_interface(mem_ctx, &probed_ifaces[i],
+ local_interfaces, enable_ipv6);
+ added = true;
}
}
- if (added) return;
+ if (added) {
+ return;
+ }
/* maybe it is a DNS name */
p = strchr_m(token,'/');
- if (!p) {
- /* don't try to do dns lookups on wildcard names */
- if (strpbrk(token, "*?") != NULL) {
+ if (p == NULL) {
+ if (!interpret_string_addr(&ss, token, 0)) {
+ DEBUG(2, ("interpret_interface: Can't find address "
+ "for %s\n", token));
return;
}
- ip.s_addr = interpret_addr2(token).s_addr;
+
for (i=0;i<total_probed;i++) {
- if (ip.s_addr == probed_ifaces[i].ip.s_addr) {
- add_interface(mem_ctx, probed_ifaces[i].ip,
- probed_ifaces[i].netmask,
- local_interfaces);
+ if (sockaddr_equal((struct sockaddr *)&ss, (struct sockaddr *)&probed_ifaces[i].ip)) {
+ add_interface(mem_ctx, &probed_ifaces[i],
+ local_interfaces, enable_ipv6);
return;
}
}
- DEBUG(2,("can't determine netmask for %s\n", token));
+ DEBUG(2,("interpret_interface: "
+ "can't determine interface for %s\n",
+ token));
return;
}
- address = talloc_strdup(mem_ctx, token);
- p = strchr_m(address,'/');
-
/* parse it into an IP address/netmasklength pair */
- *p++ = 0;
-
- ip.s_addr = interpret_addr2(address).s_addr;
+ *p = 0;
+ goodaddr = interpret_string_addr(&ss, token, 0);
+ *p++ = '/';
+
+ if (!goodaddr) {
+ DEBUG(2,("interpret_interface: "
+ "can't determine interface for %s\n",
+ token));
+ return;
+ }
if (strlen(p) > 2) {
- nmask.s_addr = interpret_addr2(p).s_addr;
+ goodaddr = interpret_string_addr(&ss_mask, p, 0);
+ 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 (sockaddr_equal((struct sockaddr *)&ss_bcast, (struct sockaddr *)&ss) ||
+ sockaddr_equal((struct sockaddr *)&ss_net, (struct sockaddr *)&ss)) {
for (i=0;i<total_probed;i++) {
- if (same_net_v4(ip, probed_ifaces[i].ip, nmask)) {
- add_interface(mem_ctx, probed_ifaces[i].ip, nmask,
- local_interfaces);
- talloc_free(address);
+ if (same_net((struct sockaddr *)&ss,
+ (struct sockaddr *)&probed_ifaces[i].ip,
+ (struct sockaddr *)&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(mem_ctx, &probed_ifaces[i],
+ local_interfaces, enable_ipv6);
+ probed_ifaces[i].netmask = saved_mask;
return;
}
}
- DEBUG(2,("Can't determine ip for broadcast address %s\n", address));
- talloc_free(address);
+ DEBUG(2,("interpret_interface: Can't determine ip for "
+ "broadcast address %s\n",
+ token));
return;
}
- add_interface(mem_ctx, ip, nmask, local_interfaces);
- talloc_free(address);
+ /* Just fake up the interface definition. User knows best. */
+
+ DEBUG(2,("interpret_interface: Adding interface %s\n",
+ token));
+
+ ZERO_STRUCT(ifs);
+ (void)strlcpy(ifs.name, token, sizeof(ifs.name));
+ ifs.flags = IFF_BROADCAST;
+ ifs.ip = ss;
+ ifs.netmask = ss_mask;
+ ifs.bcast = ss_bcast;
+ add_interface(mem_ctx, &ifs,
+ local_interfaces, enable_ipv6);
}
/**
load the list of network interfaces
**/
-void load_interfaces(TALLOC_CTX *mem_ctx, const char **interfaces, struct interface **local_interfaces)
+void load_interface_list(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct interface **local_interfaces)
{
- const char **ptr = interfaces;
+ const char **ptr = lpcfg_interfaces(lp_ctx);
int i;
- struct iface_struct ifaces[MAX_INTERFACES];
- struct in_addr loopback_ip;
+ struct iface_struct *ifaces;
int total_probed;
+ bool enable_ipv6 = lpcfg_parm_bool(lp_ctx, NULL, "ipv6", "enable", true);
*local_interfaces = NULL;
- loopback_ip = interpret_addr2("127.0.0.1");
-
/* probe the kernel for interfaces */
- total_probed = get_interfaces(ifaces, MAX_INTERFACES);
+ total_probed = get_interfaces(mem_ctx, &ifaces);
/* if we don't have a interfaces line then use all interfaces
except loopback */
@@ -215,27 +309,27 @@ void load_interfaces(TALLOC_CTX *mem_ctx, const char **interfaces, struct interf
DEBUG(0,("ERROR: Could not determine network interfaces, you must use a interfaces config line\n"));
}
for (i=0;i<total_probed;i++) {
- if (ifaces[i].ip.s_addr != loopback_ip.s_addr) {
- add_interface(mem_ctx, ifaces[i].ip,
- ifaces[i].netmask, local_interfaces);
+ if (!is_loopback_addr((struct sockaddr *)&ifaces[i].ip)) {
+ add_interface(mem_ctx, &ifaces[i], local_interfaces, enable_ipv6);
}
}
}
while (ptr && *ptr) {
- interpret_interface(mem_ctx, *ptr, ifaces, total_probed, local_interfaces);
+ interpret_interface(mem_ctx, *ptr, ifaces, total_probed, local_interfaces, enable_ipv6);
ptr++;
}
if (!*local_interfaces) {
DEBUG(0,("WARNING: no network interfaces found\n"));
}
+ talloc_free(ifaces);
}
/**
how many interfaces do we have
**/
-int iface_count(struct interface *ifaces)
+int iface_list_count(struct interface *ifaces)
{
int ret = 0;
struct interface *i;
@@ -248,7 +342,7 @@ int iface_count(struct interface *ifaces)
/**
return IP of the Nth interface
**/
-const char *iface_n_ip(struct interface *ifaces, int n)
+const char *iface_list_n_ip(struct interface *ifaces, int n)
{
struct interface *i;
@@ -261,10 +355,59 @@ const char *iface_n_ip(struct interface *ifaces, int n)
return NULL;
}
+
+/**
+ return the first IPv4 interface address we have registered
+ **/
+const char *iface_list_first_v4(struct interface *ifaces)
+{
+ struct interface *i;
+
+ for (i=ifaces; i; i=i->next) {
+ if (i->ip.ss_family == AF_INET) {
+ return i->ip_s;
+ }
+ }
+ return NULL;
+}
+
+/**
+ return the first IPv6 interface address we have registered
+ **/
+static const char *iface_list_first_v6(struct interface *ifaces)
+{
+ struct interface *i;
+
+#ifdef HAVE_IPV6
+ for (i=ifaces; i; i=i->next) {
+ if (i->ip.ss_family == AF_INET6) {
+ return i->ip_s;
+ }
+ }
+#endif
+ return NULL;
+}
+
+/**
+ check if an interface is IPv4
+ **/
+bool iface_list_n_is_v4(struct interface *ifaces, int n)
+{
+ struct interface *i;
+
+ for (i=ifaces;i && n;i=i->next)
+ n--;
+
+ if (i) {
+ return i->ip.ss_family == AF_INET;
+ }
+ return false;
+}
+
/**
return bcast of the Nth interface
**/
-const char *iface_n_bcast(struct interface *ifaces, int n)
+const char *iface_list_n_bcast(struct interface *ifaces, int n)
{
struct interface *i;
@@ -280,7 +423,7 @@ const char *iface_n_bcast(struct interface *ifaces, int n)
/**
return netmask of the Nth interface
**/
-const char *iface_n_netmask(struct interface *ifaces, int n)
+const char *iface_list_n_netmask(struct interface *ifaces, int n)
{
struct interface *i;
@@ -297,28 +440,37 @@ const char *iface_n_netmask(struct interface *ifaces, int n)
return the local IP address that best matches a destination IP, or
our first interface if none match
*/
-const char *iface_best_ip(struct interface *ifaces, const char *dest)
+const char *iface_list_best_ip(struct interface *ifaces, const char *dest)
{
struct interface *iface;
- struct in_addr ip;
+ struct sockaddr_storage ss;
- ip.s_addr = interpret_addr(dest);
- iface = iface_find(ifaces, ip, true);
+ if (!interpret_string_addr(&ss, dest, AI_NUMERICHOST)) {
+ return iface_list_n_ip(ifaces, 0);
+ }
+ iface = iface_list_find(ifaces, (const struct sockaddr *)&ss, true);
if (iface) {
return iface->ip_s;
}
- return iface_n_ip(ifaces, 0);
+#ifdef HAVE_IPV6
+ if (ss.ss_family == AF_INET6) {
+ return iface_list_first_v6(ifaces);
+ }
+#endif
+ return iface_list_first_v4(ifaces);
}
/**
return true if an IP is one one of our local networks
*/
-bool iface_is_local(struct interface *ifaces, const char *dest)
+bool iface_list_is_local(struct interface *ifaces, const char *dest)
{
- struct in_addr ip;
+ struct sockaddr_storage ss;
- ip.s_addr = interpret_addr(dest);
- if (iface_find(ifaces, ip, true)) {
+ if (!interpret_string_addr(&ss, dest, AI_NUMERICHOST)) {
+ return false;
+ }
+ if (iface_list_find(ifaces, (const struct sockaddr *)&ss, true)) {
return true;
}
return false;
@@ -327,9 +479,50 @@ bool iface_is_local(struct interface *ifaces, const char *dest)
/**
return true if a IP matches a IP/netmask pair
*/
-bool iface_same_net(const char *ip1, const char *ip2, const char *netmask)
+bool iface_list_same_net(const char *ip1, const char *ip2, const char *netmask)
{
- return same_net_v4(interpret_addr2(ip1),
- interpret_addr2(ip2),
- interpret_addr2(netmask));
+ struct sockaddr_storage ip1_ss, ip2_ss, nm_ss;
+
+ if (!interpret_string_addr(&ip1_ss, ip1, AI_NUMERICHOST)) {
+ return false;
+ }
+ if (!interpret_string_addr(&ip2_ss, ip2, AI_NUMERICHOST)) {
+ return false;
+ }
+ if (!interpret_string_addr(&nm_ss, netmask, AI_NUMERICHOST)) {
+ return false;
+ }
+
+ return same_net((struct sockaddr *)&ip1_ss,
+ (struct sockaddr *)&ip2_ss,
+ (struct sockaddr *)&nm_ss);
+}
+
+/**
+ return the list of wildcard interfaces
+ this will include the IPv4 0.0.0.0, and may include IPv6 ::
+ it is overridden by the 'socket address' option in smb.conf
+*/
+const char **iface_list_wildcard(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
+{
+ const char **ret;
+ const char *socket_address;
+
+ /* the user may have configured a specific address */
+ socket_address = lpcfg_socket_address(lp_ctx);
+ if (strcmp(socket_address, "") != 0) {
+ ret = (const char **)str_list_make(mem_ctx, socket_address, NULL);
+ return ret;
+ }
+
+ ret = (const char **)str_list_make(mem_ctx, "0.0.0.0", NULL);
+ if (ret == NULL) return NULL;
+
+#ifdef HAVE_IPV6
+ if (lpcfg_parm_bool(lp_ctx, NULL, "ipv6", "enable", true)) {
+ return str_list_add(ret, "::");
+ }
+#endif
+
+ return ret;
}
diff --git a/source4/lib/socket/netif.c b/source4/lib/socket/netif.c
deleted file mode 100644
index e36f268bde1..00000000000
--- a/source4/lib/socket/netif.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- return a list of network interfaces
- Copyright (C) Andrew Tridgell 1998
- Copyright (C) Jeremy Allison 2007
- Copyright (C) Jelmer Vernooij 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
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-
-/* working out the interfaces for a OS is an incredibly non-portable
- thing. We have several possible implementations below, and autoconf
- tries each of them to see what works
-
- Note that this file does _not_ include includes.h. That is so this code
- can be called directly from the autoconf tests. That also means
- this code cannot use any of the normal Samba debug stuff or defines.
- This is standalone code.
-
-*/
-
-#include "includes.h"
-#include "system/network.h"
-#include "netif.h"
-#include "lib/util/tsort.h"
-
-/****************************************************************************
- Try the "standard" getifaddrs/freeifaddrs interfaces.
- Also gets IPv6 interfaces.
-****************************************************************************/
-
-/****************************************************************************
- Get the netmask address for a local interface.
-****************************************************************************/
-
-static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces)
-{
- struct ifaddrs *iflist = NULL;
- struct ifaddrs *ifptr = NULL;
- int total = 0;
-
- if (getifaddrs(&iflist) < 0) {
- return -1;
- }
-
- /* Loop through interfaces, looking for given IP address */
- for (ifptr = iflist, total = 0;
- ifptr != NULL && total < max_interfaces;
- ifptr = ifptr->ifa_next) {
-
- memset(&ifaces[total], '\0', sizeof(ifaces[total]));
-
- if (!ifptr->ifa_addr || !ifptr->ifa_netmask) {
- continue;
- }
-
- /* Check the interface is up. */
- if (!(ifptr->ifa_flags & IFF_UP)) {
- continue;
- }
-
- /* We don't support IPv6 *yet* */
- if (ifptr->ifa_addr->sa_family != AF_INET) {
- continue;
- }
-
- ifaces[total].ip = ((struct sockaddr_in *)ifptr->ifa_addr)->sin_addr;
- ifaces[total].netmask = ((struct sockaddr_in *)ifptr->ifa_netmask)->sin_addr;
-
- strlcpy(ifaces[total].name, ifptr->ifa_name,
- sizeof(ifaces[total].name));
- total++;
- }
-
- freeifaddrs(iflist);
-
- return total;
-}
-
-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 = ntohl(i1->ip.s_addr) - ntohl(i2->ip.s_addr);
- if (r) return r;
- r = ntohl(i1->netmask.s_addr) - ntohl(i2->netmask.s_addr);
- return r;
-}
-
-/* this wrapper is used to remove duplicates from the interface list generated
- above */
-int get_interfaces(struct iface_struct *ifaces, int max_interfaces)
-{
- int total, i, j;
-
- total = _get_interfaces(ifaces, max_interfaces);
- if (total <= 0) return total;
-
- /* now we need to remove duplicates */
- TYPESAFE_QSORT(ifaces, total, iface_comp);
-
- for (i=1;i<total;) {
- if (iface_comp(&ifaces[i-1], &ifaces[i]) == 0) {
- for (j=i-1;j<total-1;j++) {
- ifaces[j] = ifaces[j+1];
- }
- total--;
- } else {
- i++;
- }
- }
-
- return total;
-}
diff --git a/source4/lib/socket/netif.h b/source4/lib/socket/netif.h
index 417c6e074fd..1d90a4fd139 100644
--- a/source4/lib/socket/netif.h
+++ b/source4/lib/socket/netif.h
@@ -20,17 +20,5 @@
*/
#include "system/network.h"
-
-struct iface_struct {
- char name[16];
- struct in_addr ip;
- struct in_addr netmask;
-};
-
-struct interface;
-
-#define MAX_INTERFACES 128
-
-#ifndef AUTOCONF_TEST
+#include "lib/socket/interfaces.h"
#include "lib/socket/netif_proto.h"
-#endif
diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c
index 4b5cecab343..2dbdaad11df 100644
--- a/source4/lib/socket/socket.c
+++ b/source4/lib/socket/socket.c
@@ -451,7 +451,7 @@ _PUBLIC_ NTSTATUS socket_dup(struct socket_context *sock)
}
fd = dup(sock->fd);
if (fd == -1) {
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
close(sock->fd);
sock->fd = fd;
@@ -473,6 +473,11 @@ _PUBLIC_ struct socket_address *socket_address_from_strings(TALLOC_CTX *mem_ctx,
return NULL;
}
+ if (strcmp(family, "ip") == 0 && is_ipaddress_v6(host)) {
+ /* leaving as "ip" would force IPv4 */
+ family = "ipv6";
+ }
+
addr->family = family;
addr->addr = talloc_strdup(addr, host);
if (!addr->addr) {
@@ -498,7 +503,19 @@ _PUBLIC_ struct socket_address *socket_address_from_sockaddr(TALLOC_CTX *mem_ctx
if (!addr) {
return NULL;
}
- addr->family = NULL;
+ switch (sockaddr->sa_family) {
+ case AF_INET:
+ addr->family = "ipv4";
+ break;
+#ifdef HAVE_IPV6
+ case AF_INET6:
+ addr->family = "ipv6";
+ break;
+#endif
+ case AF_UNIX:
+ addr->family = "unix";
+ break;
+ }
addr->addr = NULL;
addr->port = 0;
addr->sockaddr = (struct sockaddr *)talloc_memdup(addr, sockaddr, sockaddrlen);
@@ -510,6 +527,50 @@ _PUBLIC_ struct socket_address *socket_address_from_sockaddr(TALLOC_CTX *mem_ctx
return addr;
}
+
+/*
+ Create a new socket_address from sockaddr_storage
+ */
+_PUBLIC_ struct socket_address *socket_address_from_sockaddr_storage(TALLOC_CTX *mem_ctx,
+ const struct sockaddr_storage *sockaddr,
+ uint16_t port)
+{
+ struct socket_address *addr = talloc_zero(mem_ctx, struct socket_address);
+ char addr_str[INET6_ADDRSTRLEN+1];
+ const char *str;
+
+ if (!addr) {
+ return NULL;
+ }
+ addr->port = port;
+ switch (sockaddr->ss_family) {
+ case AF_INET:
+ addr->family = "ipv4";
+ break;
+#ifdef HAVE_IPV6
+ case AF_INET6:
+ addr->family = "ipv6";
+ break;
+#endif
+ default:
+ talloc_free(addr);
+ return NULL;
+ }
+
+ str = print_sockaddr(addr_str, sizeof(addr_str), sockaddr);
+ if (str == NULL) {
+ talloc_free(addr);
+ return NULL;
+ }
+ addr->addr = talloc_strdup(addr, str);
+ if (addr->addr == NULL) {
+ talloc_free(addr);
+ return NULL;
+ }
+
+ return addr;
+}
+
/* Copy a socket_address structure */
struct socket_address *socket_address_copy(TALLOC_CTX *mem_ctx,
const struct socket_address *oaddr)
@@ -567,110 +628,6 @@ _PUBLIC_ const struct socket_ops *socket_getops_byname(const char *family, enum
return NULL;
}
-enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
-
-static const struct {
- const char *name;
- int level;
- int option;
- int value;
- int opttype;
-} socket_options[] = {
- {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
- {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
- {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
-#ifdef TCP_NODELAY
- {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
-#endif
-#ifdef IPTOS_LOWDELAY
- {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
-#endif
-#ifdef IPTOS_THROUGHPUT
- {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
-#endif
-#ifdef SO_REUSEPORT
- {"SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT, 0, OPT_BOOL},
-#endif
-#ifdef SO_SNDBUF
- {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
-#endif
-#ifdef SO_RCVBUF
- {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
-#endif
-#ifdef SO_SNDLOWAT
- {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
-#endif
-#ifdef SO_RCVLOWAT
- {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
-#endif
-#ifdef SO_SNDTIMEO
- {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
-#endif
-#ifdef SO_RCVTIMEO
- {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
-#endif
- {NULL,0,0,0,0}};
-
-
-/**
- Set user socket options.
-**/
-_PUBLIC_ void set_socket_options(int fd, const char *options)
-{
- const char **options_list = (const char **)str_list_make(NULL, options, " \t,");
- int j;
-
- if (!options_list)
- return;
-
- for (j = 0; options_list[j]; j++) {
- const char *tok = options_list[j];
- int ret=0,i;
- int value = 1;
- char *p;
- bool got_value = false;
-
- if ((p = strchr(tok,'='))) {
- *p = 0;
- value = atoi(p+1);
- got_value = true;
- }
-
- for (i=0;socket_options[i].name;i++)
- if (strequal(socket_options[i].name,tok))
- break;
-
- if (!socket_options[i].name) {
- DEBUG(0,("Unknown socket option %s\n",tok));
- continue;
- }
-
- switch (socket_options[i].opttype) {
- case OPT_BOOL:
- case OPT_INT:
- ret = setsockopt(fd,socket_options[i].level,
- socket_options[i].option,(char *)&value,sizeof(int));
- break;
-
- case OPT_ON:
- if (got_value)
- DEBUG(0,("syntax error - %s does not take a value\n",tok));
-
- {
- int on = socket_options[i].value;
- ret = setsockopt(fd,socket_options[i].level,
- socket_options[i].option,(char *)&on,sizeof(int));
- }
- break;
- }
-
- if (ret != 0)
- DEBUG(0,("Failed to set socket option %s (Error %s)\n",tok, strerror(errno) ));
- }
-
- talloc_free(options_list);
-}
-
/*
set some flags on a socket
*/
diff --git a/source4/lib/socket/socket.h b/source4/lib/socket/socket.h
index 4a744797b3a..e00b61ba6cd 100644
--- a/source4/lib/socket/socket.h
+++ b/source4/lib/socket/socket.h
@@ -174,14 +174,18 @@ struct socket_address *socket_address_from_strings(TALLOC_CTX *mem_ctx,
struct socket_address *socket_address_from_sockaddr(TALLOC_CTX *mem_ctx,
struct sockaddr *sockaddr,
size_t addrlen);
+struct sockaddr_storage;
+struct socket_address *socket_address_from_sockaddr_storage(TALLOC_CTX *mem_ctx,
+ const struct sockaddr_storage *sockaddr,
+ uint16_t port);
_PUBLIC_ void socket_address_set_port(struct socket_address *a,
uint16_t port);
struct socket_address *socket_address_copy(TALLOC_CTX *mem_ctx,
const struct socket_address *oaddr);
const struct socket_ops *socket_getops_byname(const char *name, enum socket_type type);
-bool allow_access(TALLOC_CTX *mem_ctx,
- const char **deny_list, const char **allow_list,
- const char *cname, const char *caddr);
+bool socket_allow_access(TALLOC_CTX *mem_ctx,
+ const char **deny_list, const char **allow_list,
+ const char *cname, const char *caddr);
bool socket_check_access(struct socket_context *sock,
const char *service_name,
const char **allow_list, const char **deny_list);
diff --git a/source4/lib/socket/socket_ip.c b/source4/lib/socket/socket_ip.c
index 4e666532520..80f7d333f38 100644
--- a/source4/lib/socket/socket_ip.c
+++ b/source4/lib/socket/socket_ip.c
@@ -47,7 +47,7 @@ static NTSTATUS ipv4_init(struct socket_context *sock)
sock->fd = socket(PF_INET, type, 0);
if (sock->fd == -1) {
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
sock->backend_name = "ipv4";
@@ -70,16 +70,16 @@ static NTSTATUS ip_connect_complete(struct socket_context *sock, uint32_t flags)
for non-blocking connect */
ret = getsockopt(sock->fd, SOL_SOCKET, SO_ERROR, &error, &len);
if (ret == -1) {
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
if (error != 0) {
- return map_nt_error_from_unix(error);
+ return map_nt_error_from_unix_common(error);
}
if (!(flags & SOCKET_FLAG_BLOCK)) {
ret = set_blocking(sock->fd, false);
if (ret == -1) {
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
}
@@ -102,7 +102,7 @@ static NTSTATUS ipv4_connect(struct socket_context *sock,
if (my_address && my_address->sockaddr) {
ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen);
if (ret == -1) {
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
} else if (my_address) {
my_ip = interpret_addr2(my_address->addr);
@@ -119,7 +119,7 @@ static NTSTATUS ipv4_connect(struct socket_context *sock,
ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
if (ret == -1) {
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
}
}
@@ -127,7 +127,7 @@ static NTSTATUS ipv4_connect(struct socket_context *sock,
if (srv_address->sockaddr) {
ret = connect(sock->fd, srv_address->sockaddr, srv_address->sockaddrlen);
if (ret == -1) {
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
} else {
srv_ip = interpret_addr2(srv_address->addr);
@@ -147,7 +147,7 @@ static NTSTATUS ipv4_connect(struct socket_context *sock,
ret = connect(sock->fd, (const struct sockaddr *)&srv_addr, sizeof(srv_addr));
if (ret == -1) {
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
}
@@ -186,20 +186,20 @@ static NTSTATUS ipv4_listen(struct socket_context *sock,
}
if (ret == -1) {
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
if (sock->type == SOCKET_TYPE_STREAM) {
ret = listen(sock->fd, queue_size);
if (ret == -1) {
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
}
if (!(flags & SOCKET_FLAG_BLOCK)) {
ret = set_blocking(sock->fd, false);
if (ret == -1) {
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
}
@@ -220,14 +220,14 @@ static NTSTATUS ipv4_accept(struct socket_context *sock, struct socket_context *
new_fd = accept(sock->fd, (struct sockaddr *)&cli_addr, &cli_addr_len);
if (new_fd == -1) {
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
if (!(sock->flags & SOCKET_FLAG_BLOCK)) {
int ret = set_blocking(new_fd, false);
if (ret == -1) {
close(new_fd);
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
}
@@ -268,7 +268,7 @@ static NTSTATUS ip_recv(struct socket_context *sock, void *buf,
if (gotlen == 0) {
return NT_STATUS_END_OF_FILE;
} else if (gotlen == -1) {
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
*nread = gotlen;
@@ -311,7 +311,7 @@ static NTSTATUS ipv4_recvfrom(struct socket_context *sock, void *buf,
return NT_STATUS_END_OF_FILE;
} else if (gotlen == -1) {
talloc_free(src);
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
src->sockaddrlen = from_len;
@@ -342,7 +342,7 @@ static NTSTATUS ip_send(struct socket_context *sock,
len = send(sock->fd, blob->data, blob->length, 0);
if (len == -1) {
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
*sendlen = len;
@@ -383,7 +383,7 @@ static NTSTATUS ipv4_sendto(struct socket_context *sock,
(struct sockaddr *)&srv_addr, sizeof(srv_addr));
}
if (len == -1) {
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
*sendlen = len;
@@ -518,7 +518,7 @@ static NTSTATUS ip_pending(struct socket_context *sock, size_t *npending)
*npending = value;
return NT_STATUS_OK;
}
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
static const struct socket_ops ipv4_ops = {
@@ -604,7 +604,7 @@ static NTSTATUS ipv6_init(struct socket_context *sock)
sock->fd = socket(PF_INET6, type, 0);
if (sock->fd == -1) {
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
sock->backend_name = "ipv6";
@@ -623,7 +623,7 @@ static NTSTATUS ipv6_tcp_connect(struct socket_context *sock,
if (my_address && my_address->sockaddr) {
ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen);
if (ret == -1) {
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
} else if (my_address) {
struct in6_addr my_ip;
@@ -638,7 +638,7 @@ static NTSTATUS ipv6_tcp_connect(struct socket_context *sock,
ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
if (ret == -1) {
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
}
}
@@ -661,15 +661,28 @@ static NTSTATUS ipv6_tcp_connect(struct socket_context *sock,
ret = connect(sock->fd, (const struct sockaddr *)&srv_addr, sizeof(srv_addr));
}
if (ret == -1) {
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
return ip_connect_complete(sock, flags);
}
+/*
+ fix the sin6_scope_id based on the address interface
+ */
+static void fix_scope_id(struct sockaddr_in6 *in6,
+ const char *address)
+{
+ const char *p = strchr(address, '%');
+ if (p != NULL) {
+ in6->sin6_scope_id = if_nametoindex(p+1);
+ }
+}
+
+
static NTSTATUS ipv6_listen(struct socket_context *sock,
- const struct socket_address *my_address,
- int queue_size, uint32_t flags)
+ const struct socket_address *my_address,
+ int queue_size, uint32_t flags)
{
struct sockaddr_in6 my_addr;
struct in6_addr ip_addr;
@@ -680,31 +693,38 @@ static NTSTATUS ipv6_listen(struct socket_context *sock,
if (my_address->sockaddr) {
ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen);
} else {
+ int one = 1;
ip_addr = interpret_addr6(my_address->addr);
ZERO_STRUCT(my_addr);
my_addr.sin6_addr = ip_addr;
my_addr.sin6_port = htons(my_address->port);
my_addr.sin6_family = PF_INET6;
-
- ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
+ fix_scope_id(&my_addr, my_address->addr);
+
+ /* when binding on ipv6 we always want to only bind on v6 */
+ ret = setsockopt(sock->fd, IPPROTO_IPV6, IPV6_V6ONLY,
+ (const void *)&one, sizeof(one));
+ if (ret != -1) {
+ ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
+ }
}
if (ret == -1) {
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
if (sock->type == SOCKET_TYPE_STREAM) {
ret = listen(sock->fd, queue_size);
if (ret == -1) {
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
}
if (!(flags & SOCKET_FLAG_BLOCK)) {
ret = set_blocking(sock->fd, false);
if (ret == -1) {
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
}
@@ -725,14 +745,14 @@ static NTSTATUS ipv6_tcp_accept(struct socket_context *sock, struct socket_conte
new_fd = accept(sock->fd, (struct sockaddr *)&cli_addr, &cli_addr_len);
if (new_fd == -1) {
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
if (!(sock->flags & SOCKET_FLAG_BLOCK)) {
int ret = set_blocking(new_fd, false);
if (ret == -1) {
close(new_fd);
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
}
@@ -796,7 +816,7 @@ static NTSTATUS ipv6_recvfrom(struct socket_context *sock, void *buf,
return NT_STATUS_END_OF_FILE;
} else if (gotlen == -1) {
talloc_free(src);
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
src->sockaddrlen = from_len;
@@ -847,7 +867,7 @@ static NTSTATUS ipv6_sendto(struct socket_context *sock,
(struct sockaddr *)&srv_addr, sizeof(srv_addr));
}
if (len == -1) {
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
*sendlen = len;
diff --git a/source4/lib/socket/socket_unix.c b/source4/lib/socket/socket_unix.c
index f1fa0a3a30c..d492f012681 100644
--- a/source4/lib/socket/socket_unix.c
+++ b/source4/lib/socket/socket_unix.c
@@ -33,7 +33,7 @@ _PUBLIC_ const struct socket_ops *socket_unixdom_ops(enum socket_type type);
*/
static NTSTATUS unixdom_error(int ernum)
{
- return map_nt_error_from_unix(ernum);
+ return map_nt_error_from_unix_common(ernum);
}
static NTSTATUS unixdom_init(struct socket_context *sock)
@@ -53,7 +53,7 @@ static NTSTATUS unixdom_init(struct socket_context *sock)
sock->fd = socket(PF_UNIX, type, 0);
if (sock->fd == -1) {
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
sock->private_data = NULL;
@@ -76,16 +76,16 @@ static NTSTATUS unixdom_connect_complete(struct socket_context *sock, uint32_t f
for non-blocking connect */
ret = getsockopt(sock->fd, SOL_SOCKET, SO_ERROR, &error, &len);
if (ret == -1) {
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
if (error != 0) {
- return map_nt_error_from_unix(error);
+ return map_nt_error_from_unix_common(error);
}
if (!(flags & SOCKET_FLAG_BLOCK)) {
ret = set_blocking(sock->fd, false);
if (ret == -1) {
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
}
@@ -194,7 +194,7 @@ static NTSTATUS unixdom_accept(struct socket_context *sock,
int ret = set_blocking(new_fd, false);
if (ret == -1) {
close(new_fd);
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
}
@@ -280,7 +280,7 @@ static NTSTATUS unixdom_sendto(struct socket_context *sock,
(struct sockaddr *)&srv_addr, sizeof(srv_addr));
}
if (len == -1) {
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
*sendlen = len;
@@ -390,7 +390,7 @@ static NTSTATUS unixdom_pending(struct socket_context *sock, size_t *npending)
*npending = value;
return NT_STATUS_OK;
}
- return map_nt_error_from_unix(errno);
+ return map_nt_error_from_unix_common(errno);
}
static const struct socket_ops unixdom_ops = {
diff --git a/source4/lib/socket/testsuite.c b/source4/lib/socket/testsuite.c
index 2489277433f..357e4ae5df4 100644
--- a/source4/lib/socket/testsuite.c
+++ b/source4/lib/socket/testsuite.c
@@ -42,7 +42,7 @@ static bool test_udp(struct torture_context *tctx)
TALLOC_CTX *mem_ctx = tctx;
struct interface *ifaces;
- load_interfaces(tctx, lpcfg_interfaces(tctx->lp_ctx), &ifaces);
+ load_interface_list(tctx, tctx->lp_ctx, &ifaces);
status = socket_create("ip", SOCKET_TYPE_DGRAM, &sock1, 0);
torture_assert_ntstatus_ok(tctx, status, "creating DGRAM IP socket 1");
@@ -53,7 +53,7 @@ static bool test_udp(struct torture_context *tctx)
talloc_steal(mem_ctx, sock2);
localhost = socket_address_from_strings(sock1, sock1->backend_name,
- iface_best_ip(ifaces, "127.0.0.1"), 0);
+ iface_list_best_ip(ifaces, "127.0.0.1"), 0);
torture_assert(tctx, localhost, "Localhost not found");
@@ -62,10 +62,10 @@ static bool test_udp(struct torture_context *tctx)
srv_addr = socket_get_my_addr(sock1, mem_ctx);
torture_assert(tctx, srv_addr != NULL &&
- strcmp(srv_addr->addr, iface_best_ip(ifaces, "127.0.0.1")) == 0,
+ strcmp(srv_addr->addr, iface_list_best_ip(ifaces, "127.0.0.1")) == 0,
talloc_asprintf(tctx,
"Expected server address of %s but got %s",
- iface_best_ip(ifaces, "127.0.0.1"), srv_addr ? srv_addr->addr : NULL));
+ iface_list_best_ip(ifaces, "127.0.0.1"), srv_addr ? srv_addr->addr : NULL));
torture_comment(tctx, "server port is %d\n", srv_addr->port);
@@ -135,9 +135,9 @@ static bool test_tcp(struct torture_context *tctx)
torture_assert_ntstatus_ok(tctx, status, "creating IP stream socket 1");
talloc_steal(mem_ctx, sock2);
- load_interfaces(tctx, lpcfg_interfaces(tctx->lp_ctx), &ifaces);
+ load_interface_list(tctx, tctx->lp_ctx, &ifaces);
localhost = socket_address_from_strings(sock1, sock1->backend_name,
- iface_best_ip(ifaces, "127.0.0.1"), 0);
+ iface_list_best_ip(ifaces, "127.0.0.1"), 0);
torture_assert(tctx, localhost, "Localhost not found");
status = socket_listen(sock1, localhost, 0, 0);
@@ -147,7 +147,7 @@ static bool test_tcp(struct torture_context *tctx)
torture_assert(tctx, srv_addr && srv_addr->addr,
"Unexpected socket_get_my_addr NULL\n");
- torture_assert_str_equal(tctx, srv_addr->addr, iface_best_ip(ifaces, "127.0.0.1"),
+ torture_assert_str_equal(tctx, srv_addr->addr, iface_list_best_ip(ifaces, "127.0.0.1"),
"Unexpected server address");
torture_comment(tctx, "server port is %d\n", srv_addr->port);
diff --git a/source4/lib/socket/wscript_build b/source4/lib/socket/wscript_build
index e2ff9b078a7..c10970d17aa 100644
--- a/source4/lib/socket/wscript_build
+++ b/source4/lib/socket/wscript_build
@@ -1,11 +1,11 @@
#!/usr/bin/env python
bld.SAMBA_LIBRARY('netif',
- source='interface.c netif.c',
- autoproto='netif_proto.h',
- deps='samba-util',
- private_library=True
- )
+ source='interface.c',
+ deps='samba-util interfaces samba-hostconfig',
+ private_library=True,
+ autoproto='netif_proto.h'
+ )
bld.SAMBA_MODULE('socket_ip',
source='socket_ip.c',