From 44d7f4f23829d98b95d9153970849a9681e4ef26 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 30 Mar 2005 22:09:16 +0000 Subject: r6139: Move socket_wrapper to a seperate directory (This used to be commit a2ef9225f15e369af7b884262b997ab321fd24d6) --- source4/lib/socket_wrapper/socket_wrapper.c | 401 ++++++++++++++++++++++++++++ 1 file changed, 401 insertions(+) create mode 100644 source4/lib/socket_wrapper/socket_wrapper.c (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c new file mode 100644 index 0000000000..5decde2cea --- /dev/null +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -0,0 +1,401 @@ +/* + Socket wrapper library. Passes all socket communication over + unix domain sockets if the environment variable SOCKET_WRAPPER_DIR + is set. + Copyright (C) Jelmer Vernooij 2005 + + 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 2 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, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef SAMBA_MAJOR_VERSION +#include "includes.h" +#include "system/network.h" +#else +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dlinklist.h" +#endif + +/* LD_PRELOAD doesn't work yet, so REWRITE_CALLS is all we support + * for now */ +#define REWRITE_CALLS + +#ifdef REWRITE_CALLS +#define real_accept accept +#define real_connect connect +#define real_bind bind +#define real_getpeername getpeername +#define real_getsockname getsockname +#define real_getsockopt getsockopt +#define real_setsockopt setsockopt +#define real_recvfrom recvfrom +#define real_sendto sendto +#define real_socket socket +#define real_close close +#endif + +static struct sockaddr *memdup(const void *data, socklen_t len) +{ + struct sockaddr *ret = (struct sockaddr *)malloc(len); + memcpy(ret, data, len); + return ret; +} + +struct socket_info +{ + int fd; + + int domain; + int type; + int protocol; + + char *path; + + struct sockaddr *myname; + socklen_t myname_len; + + struct sockaddr *peername; + socklen_t peername_len; + + struct socket_info *prev, *next; +} *sockets = NULL; + +static int convert_un_in(const struct sockaddr_un *un, struct sockaddr_in *in, socklen_t *len) +{ + unsigned int prt; + const char *p; + + if ((*len) < sizeof(struct sockaddr_in)) { + return 0; + } + + in->sin_family = AF_INET; + in->sin_port = 1025; /* Default to 1025 */ + p = strchr(un->sun_path, '/'); + if (p) p++; else p = un->sun_path; + + if(sscanf(p, "sock_ip_%u", &prt) == 1) + { + in->sin_port = htons(prt); + } + in->sin_addr.s_addr = INADDR_LOOPBACK; + *len = sizeof(struct sockaddr_in); + return 0; +} + +static int convert_in_un(const struct sockaddr_in *in, struct sockaddr_un *un) +{ + uint16_t prt = ntohs(in->sin_port); + /* FIXME: ENETUNREACH if in->sin_addr is not loopback */ + un->sun_family = AF_LOCAL; + snprintf(un->sun_path, sizeof(un->sun_path), "%s/sock_ip_%u", getenv("SOCKET_WRAPPER_DIR"), prt); + return 0; +} + +static struct socket_info *find_socket_info(int fd) +{ + struct socket_info *i; + for (i = sockets; i; i = i->next) { + if (i->fd == fd) + return i; + } + + return NULL; +} + +static int sockaddr_convert_to_un(const struct sockaddr *in_addr, socklen_t in_len, + struct sockaddr_un *out_addr) +{ + if (!out_addr) + return 0; + + switch (in_addr->sa_family) { + case AF_INET: + return convert_in_un((const struct sockaddr_in *)in_addr, out_addr); + case AF_LOCAL: + memcpy(out_addr, in_addr, sizeof(*out_addr)); + return 0; + default: + break; + } + + errno = EAFNOSUPPORT; + return -1; +} + +static int sockaddr_convert_from_un(const struct sockaddr_un *in_addr, + int family, + struct sockaddr *out_addr, + socklen_t *out_len) +{ + if (!out_addr) + return 0; + + switch (family) { + case AF_INET: + return convert_un_in(in_addr, (struct sockaddr_in *)out_addr, out_len); + case AF_LOCAL: + memcpy(out_addr, in_addr, sizeof(*in_addr)); + *out_len = sizeof(*in_addr); + return 0; + default: + break; + } + + errno = EAFNOSUPPORT; + return -1; +} + +int swrap_socket(int domain, int type, int protocol) +{ + struct socket_info *si; + int fd; + + if (!getenv("SOCKET_WRAPPER_DIR")) { + return real_socket(domain, type, protocol); + } + + fd = real_socket(PF_LOCAL, type, 0); + + if (fd < 0) + return fd; + + si = malloc(sizeof(struct socket_info)); + memset(si, 0, sizeof(*si)); + + si->domain = domain; + si->type = type; + si->protocol = protocol; + si->fd = fd; + + DLIST_ADD(sockets, si); + + return si->fd; +} + +int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) +{ + struct socket_info *parent_si, *child_si; + int fd; + socklen_t un_addrlen = sizeof(struct sockaddr_un); + struct sockaddr_un un_addr; + int ret; + + parent_si = find_socket_info(s); + if (!parent_si) { + return real_accept(s, addr, addrlen); + } + + ret = real_accept(s, (struct sockaddr *)&un_addr, &un_addrlen); + if (ret < 0) return ret; + + fd = ret; + + ret = sockaddr_convert_from_un(&un_addr, parent_si->domain, addr, addrlen); + + if (ret < 0) return ret; + + child_si = malloc(sizeof(struct socket_info)); + memset(child_si, 0, sizeof(*child_si)); + + child_si->fd = fd; + + if (addr && addrlen) { + child_si->myname_len = *addrlen; + child_si->myname = memdup(addr, *addrlen); + } + + return fd; +} + +int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen) +{ + int ret; + struct sockaddr_un un_addr; + struct socket_info *si = find_socket_info(s); + + if (!si) { + return real_connect(s, serv_addr, addrlen); + } + + ret = sockaddr_convert_to_un((const struct sockaddr *)serv_addr, addrlen, &un_addr); + if (ret < 0) return ret; + + ret = real_connect(s, + (struct sockaddr *)&un_addr, + sizeof(struct sockaddr_un)); + + if (ret >= 0) { + si->peername_len = addrlen; + si->peername = memdup(serv_addr, addrlen); + } + + return ret; +} + +int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen) +{ + int ret; + struct sockaddr_un un_addr; + struct socket_info *si = find_socket_info(s); + + if (!si) { + return real_bind(s, myaddr, addrlen); + } + + ret = sockaddr_convert_to_un((const struct sockaddr *)myaddr, addrlen, &un_addr); + if (ret < 0) return ret; + + unlink(un_addr.sun_path); + + ret = real_bind(s, + (struct sockaddr *)&un_addr, + sizeof(struct sockaddr_un)); + + if (ret >= 0) { + si->myname_len = addrlen; + si->myname = memdup(myaddr, addrlen); + } + + return ret; +} + +int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen) +{ + struct socket_info *si = find_socket_info(s); + + if (!si) { + return real_getpeername(s, name, addrlen); + } + + if (!si->peername) + { + errno = ENOTCONN; + return -1; + } + + memcpy(name, si->peername, si->peername_len); + *addrlen = si->peername_len; + + return 0; +} + +int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen) +{ + struct socket_info *si = find_socket_info(s); + + if (!si) { + return real_getpeername(s, name, addrlen); + } + + memcpy(name, si->myname, si->myname_len); + *addrlen = si->myname_len; + + return 0; +} + +int swrap_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) +{ + struct socket_info *si = find_socket_info(s); + + if (!si) { + return real_getsockopt(s, level, optname, optval, optlen); + } + + if (level != SOL_SOCKET) { + errno = ENOPROTOOPT; + return -1; + } + + return real_getsockopt(s, level, optname, optval, optlen); +} + +int swrap_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) +{ + struct socket_info *si = find_socket_info(s); + + if (!si) { + return real_setsockopt(s, level, optname, optval, optlen); + } + + if (level != SOL_SOCKET) { + errno = ENOPROTOOPT; + return -1; + } + + return real_setsockopt(s, level, optname, optval, optlen); +} + +ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen) +{ + socklen_t un_addrlen; + struct sockaddr_un un_addr; + int ret; + struct socket_info *si = find_socket_info(s); + + if (!si) { + return real_recvfrom(s, buf, len, flags, from, fromlen); + } + + ret = real_recvfrom(s, buf, len, flags, (struct sockaddr *)&un_addr, &un_addrlen); + if (ret < 0) + return ret; + + ret = sockaddr_convert_from_un(&un_addr, si->domain, from, fromlen); + + return ret; +} + +ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen) +{ + struct sockaddr_un un_addr; + int ret; + struct socket_info *si = find_socket_info(s); + + if (!si) { + return real_sendto(s, buf, len, flags, to, tolen); + } + + ret = sockaddr_convert_to_un(to, tolen, &un_addr); + if (ret < 0) + return ret; + + ret = real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr)); + + return ret; +} + +int swrap_close(int fd) +{ + struct socket_info *si = find_socket_info(fd); + + if (si) { + DLIST_REMOVE(sockets, si); + + free(si->path); + free(si->myname); + free(si->peername); + free(si); + } + + return real_close(fd); +} -- cgit From 848329b9a0a66281f699d1ae2c9e267c91ce0f43 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 30 Mar 2005 23:28:15 +0000 Subject: r6140: - Add configure option for enabling the socket-wrapper library, so it can be enabled on the buildfarm without requiring --enable-developer - Support tcp and udp being used on the same port - FIx some portability issues (should fix the build on some hosts on the buildfarm) - Ignore setting TCP_NODELAY on (semi-)TCP sockets rather then complain about it not being supported (saves us from a couple of error messages for each connection that is opened) (This used to be commit 443fb7853b8d3cb516c442fdc595038544b75738) --- source4/lib/socket_wrapper/socket_wrapper.c | 66 +++++++++++++++++++---------- 1 file changed, 43 insertions(+), 23 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 5decde2cea..b91ff2cb0e 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -19,7 +19,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifdef SAMBA_MAJOR_VERSION +#ifdef _SAMBA_BUILD #include "includes.h" #include "system/network.h" #else @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -53,7 +54,7 @@ #define real_close close #endif -static struct sockaddr *memdup(const void *data, socklen_t len) +static struct sockaddr *sockaddr_dup(const void *data, socklen_t len) { struct sockaddr *ret = (struct sockaddr *)malloc(len); memcpy(ret, data, len); @@ -83,6 +84,7 @@ static int convert_un_in(const struct sockaddr_un *un, struct sockaddr_in *in, s { unsigned int prt; const char *p; + int type; if ((*len) < sizeof(struct sockaddr_in)) { return 0; @@ -93,7 +95,7 @@ static int convert_un_in(const struct sockaddr_un *un, struct sockaddr_in *in, s p = strchr(un->sun_path, '/'); if (p) p++; else p = un->sun_path; - if(sscanf(p, "sock_ip_%u", &prt) == 1) + if(sscanf(p, "sock_ip_%d_%u", &type, &prt) == 1) { in->sin_port = htons(prt); } @@ -102,12 +104,11 @@ static int convert_un_in(const struct sockaddr_un *un, struct sockaddr_in *in, s return 0; } -static int convert_in_un(const struct sockaddr_in *in, struct sockaddr_un *un) +static int convert_in_un(int type, const struct sockaddr_in *in, struct sockaddr_un *un) { uint16_t prt = ntohs(in->sin_port); /* FIXME: ENETUNREACH if in->sin_addr is not loopback */ - un->sun_family = AF_LOCAL; - snprintf(un->sun_path, sizeof(un->sun_path), "%s/sock_ip_%u", getenv("SOCKET_WRAPPER_DIR"), prt); + snprintf(un->sun_path, sizeof(un->sun_path), "%s/sock_ip_%d_%u", getenv("SOCKET_WRAPPER_DIR"), type, prt); return 0; } @@ -122,15 +123,17 @@ static struct socket_info *find_socket_info(int fd) return NULL; } -static int sockaddr_convert_to_un(const struct sockaddr *in_addr, socklen_t in_len, +static int sockaddr_convert_to_un(const struct socket_info *si, const struct sockaddr *in_addr, socklen_t in_len, struct sockaddr_un *out_addr) { if (!out_addr) return 0; + out_addr->sun_family = AF_LOCAL; + switch (in_addr->sa_family) { case AF_INET: - return convert_in_un((const struct sockaddr_in *)in_addr, out_addr); + return convert_in_un(si->type, (const struct sockaddr_in *)in_addr, out_addr); case AF_LOCAL: memcpy(out_addr, in_addr, sizeof(*out_addr)); return 0; @@ -142,7 +145,8 @@ static int sockaddr_convert_to_un(const struct sockaddr *in_addr, socklen_t in_l return -1; } -static int sockaddr_convert_from_un(const struct sockaddr_un *in_addr, +static int sockaddr_convert_from_un(const struct socket_info *si, + const struct sockaddr_un *in_addr, int family, struct sockaddr *out_addr, socklen_t *out_len) @@ -210,7 +214,7 @@ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) fd = ret; - ret = sockaddr_convert_from_un(&un_addr, parent_si->domain, addr, addrlen); + ret = sockaddr_convert_from_un(parent_si, &un_addr, parent_si->domain, addr, addrlen); if (ret < 0) return ret; @@ -221,7 +225,7 @@ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) if (addr && addrlen) { child_si->myname_len = *addrlen; - child_si->myname = memdup(addr, *addrlen); + child_si->myname = sockaddr_dup(addr, *addrlen); } return fd; @@ -237,7 +241,7 @@ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen) return real_connect(s, serv_addr, addrlen); } - ret = sockaddr_convert_to_un((const struct sockaddr *)serv_addr, addrlen, &un_addr); + ret = sockaddr_convert_to_un(si, (const struct sockaddr *)serv_addr, addrlen, &un_addr); if (ret < 0) return ret; ret = real_connect(s, @@ -246,7 +250,7 @@ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen) if (ret >= 0) { si->peername_len = addrlen; - si->peername = memdup(serv_addr, addrlen); + si->peername = sockaddr_dup(serv_addr, addrlen); } return ret; @@ -262,7 +266,7 @@ int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen) return real_bind(s, myaddr, addrlen); } - ret = sockaddr_convert_to_un((const struct sockaddr *)myaddr, addrlen, &un_addr); + ret = sockaddr_convert_to_un(si, (const struct sockaddr *)myaddr, addrlen, &un_addr); if (ret < 0) return ret; unlink(un_addr.sun_path); @@ -273,7 +277,7 @@ int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen) if (ret >= 0) { si->myname_len = addrlen; - si->myname = memdup(myaddr, addrlen); + si->myname = sockaddr_dup(myaddr, addrlen); } return ret; @@ -321,12 +325,17 @@ int swrap_getsockopt(int s, int level, int optname, void *optval, socklen_t *opt return real_getsockopt(s, level, optname, optval, optlen); } - if (level != SOL_SOCKET) { + if (level == SOL_SOCKET) { + return real_getsockopt(s, level, optname, optval, optlen); + } + + switch (si->domain) { + case AF_LOCAL: + return real_getsockopt(s, level, optname, optval, optlen); + default: errno = ENOPROTOOPT; return -1; } - - return real_getsockopt(s, level, optname, optval, optlen); } int swrap_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) @@ -337,12 +346,23 @@ int swrap_setsockopt(int s, int level, int optname, const void *optval, so return real_setsockopt(s, level, optname, optval, optlen); } - if (level != SOL_SOCKET) { + if (level == SOL_SOCKET) { + return real_setsockopt(s, level, optname, optval, optlen); + } + + switch (si->domain) { + case AF_LOCAL: + return real_setsockopt(s, level, optname, optval, optlen); + case AF_INET: + /* Silence some warnings */ +#ifdef TCP_NODELAY + if (optname == TCP_NODELAY) + return 0; +#endif + default: errno = ENOPROTOOPT; return -1; } - - return real_setsockopt(s, level, optname, optval, optlen); } ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen) @@ -360,7 +380,7 @@ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr if (ret < 0) return ret; - ret = sockaddr_convert_from_un(&un_addr, si->domain, from, fromlen); + ret = sockaddr_convert_from_un(si, &un_addr, si->domain, from, fromlen); return ret; } @@ -375,7 +395,7 @@ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const str return real_sendto(s, buf, len, flags, to, tolen); } - ret = sockaddr_convert_to_un(to, tolen, &un_addr); + ret = sockaddr_convert_to_un(si, to, tolen, &un_addr); if (ret < 0) return ret; -- cgit From 07e3fa214673fde54c13273c5f95418011d56080 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 31 Mar 2005 00:43:26 +0000 Subject: r6144: Apparently there are more systems that have AF_UNIX then AF_LOCAL (we already use AF_UNIX in other places). (This used to be commit 88d93b9782766ab1159a233307ef508881caa615) --- source4/lib/socket_wrapper/socket_wrapper.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index b91ff2cb0e..238155b26b 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -129,12 +129,12 @@ static int sockaddr_convert_to_un(const struct socket_info *si, const struct soc if (!out_addr) return 0; - out_addr->sun_family = AF_LOCAL; + out_addr->sun_family = AF_UNIX; switch (in_addr->sa_family) { case AF_INET: return convert_in_un(si->type, (const struct sockaddr_in *)in_addr, out_addr); - case AF_LOCAL: + case AF_UNIX: memcpy(out_addr, in_addr, sizeof(*out_addr)); return 0; default: @@ -157,7 +157,7 @@ static int sockaddr_convert_from_un(const struct socket_info *si, switch (family) { case AF_INET: return convert_un_in(in_addr, (struct sockaddr_in *)out_addr, out_len); - case AF_LOCAL: + case AF_UNIX: memcpy(out_addr, in_addr, sizeof(*in_addr)); *out_len = sizeof(*in_addr); return 0; @@ -178,7 +178,7 @@ int swrap_socket(int domain, int type, int protocol) return real_socket(domain, type, protocol); } - fd = real_socket(PF_LOCAL, type, 0); + fd = real_socket(AF_UNIX, type, 0); if (fd < 0) return fd; @@ -330,7 +330,7 @@ int swrap_getsockopt(int s, int level, int optname, void *optval, socklen_t *opt } switch (si->domain) { - case AF_LOCAL: + case AF_UNIX: return real_getsockopt(s, level, optname, optval, optlen); default: errno = ENOPROTOOPT; @@ -351,7 +351,7 @@ int swrap_setsockopt(int s, int level, int optname, const void *optval, so } switch (si->domain) { - case AF_LOCAL: + case AF_UNIX: return real_setsockopt(s, level, optname, optval, optlen); case AF_INET: /* Silence some warnings */ -- cgit From 4b96d831479f31ae6e0f2039f4b91c1bed643bea Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 31 Mar 2005 12:40:12 +0000 Subject: r6150: fixed a few socket_wrapper bugs. - now works properly with UDP, so the NBT tests work - fixed byte order in a few places - connect() now fails to non-localhost - fixed some places that tested for < 0, which should be == -1 (most syscalls return -1 on error, not "negative") (This used to be commit 61e1eea0fdb13577de2506472c5443ee92656263) --- source4/lib/socket_wrapper/socket_wrapper.c | 115 +++++++++++++++++++--------- 1 file changed, 80 insertions(+), 35 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 238155b26b..b7b0aa07b6 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -68,8 +68,10 @@ struct socket_info int domain; int type; int protocol; + int bound; char *path; + char *tmp_path; struct sockaddr *myname; socklen_t myname_len; @@ -78,7 +80,9 @@ struct socket_info socklen_t peername_len; struct socket_info *prev, *next; -} *sockets = NULL; +}; + +static struct socket_info *sockets = NULL; static int convert_un_in(const struct sockaddr_un *un, struct sockaddr_in *in, socklen_t *len) { @@ -95,11 +99,10 @@ static int convert_un_in(const struct sockaddr_un *un, struct sockaddr_in *in, s p = strchr(un->sun_path, '/'); if (p) p++; else p = un->sun_path; - if(sscanf(p, "sock_ip_%d_%u", &type, &prt) == 1) - { + if (sscanf(p, "sock_ip_%d_%u", &type, &prt) == 2) { in->sin_port = htons(prt); } - in->sin_addr.s_addr = INADDR_LOOPBACK; + in->sin_addr.s_addr = htonl(INADDR_LOOPBACK); *len = sizeof(struct sockaddr_in); return 0; } @@ -107,8 +110,8 @@ static int convert_un_in(const struct sockaddr_un *un, struct sockaddr_in *in, s static int convert_in_un(int type, const struct sockaddr_in *in, struct sockaddr_un *un) { uint16_t prt = ntohs(in->sin_port); - /* FIXME: ENETUNREACH if in->sin_addr is not loopback */ - snprintf(un->sun_path, sizeof(un->sun_path), "%s/sock_ip_%d_%u", getenv("SOCKET_WRAPPER_DIR"), type, prt); + snprintf(un->sun_path, sizeof(un->sun_path), "%s/sock_ip_%d_%u", + getenv("SOCKET_WRAPPER_DIR"), type, prt); return 0; } @@ -146,14 +149,20 @@ static int sockaddr_convert_to_un(const struct socket_info *si, const struct soc } static int sockaddr_convert_from_un(const struct socket_info *si, - const struct sockaddr_un *in_addr, - int family, - struct sockaddr *out_addr, - socklen_t *out_len) + const struct sockaddr_un *in_addr, + socklen_t un_addrlen, + int family, + struct sockaddr *out_addr, + socklen_t *out_len) { - if (!out_addr) + if (out_addr == NULL || out_len == NULL) return 0; + if (un_addrlen == 0) { + *out_len = 0; + return 0; + } + switch (family) { case AF_INET: return convert_un_in(in_addr, (struct sockaddr_in *)out_addr, out_len); @@ -180,11 +189,9 @@ int swrap_socket(int domain, int type, int protocol) fd = real_socket(AF_UNIX, type, 0); - if (fd < 0) - return fd; + if (fd == -1) return -1; - si = malloc(sizeof(struct socket_info)); - memset(si, 0, sizeof(*si)); + si = calloc(1, sizeof(struct socket_info)); si->domain = domain; si->type = type; @@ -210,13 +217,13 @@ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) } ret = real_accept(s, (struct sockaddr *)&un_addr, &un_addrlen); - if (ret < 0) return ret; + if (ret == -1) return ret; fd = ret; - ret = sockaddr_convert_from_un(parent_si, &un_addr, parent_si->domain, addr, addrlen); - - if (ret < 0) return ret; + ret = sockaddr_convert_from_un(parent_si, &un_addr, un_addrlen, + parent_si->domain, addr, addrlen); + if (ret == -1) return ret; child_si = malloc(sizeof(struct socket_info)); memset(child_si, 0, sizeof(*child_si)); @@ -241,14 +248,20 @@ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen) return real_connect(s, serv_addr, addrlen); } + /* only allow pseudo loopback connections */ + if (((const struct sockaddr_in *)serv_addr)->sin_addr.s_addr != + htonl(INADDR_LOOPBACK)) { + errno = ENETUNREACH; + return -1; + } + ret = sockaddr_convert_to_un(si, (const struct sockaddr *)serv_addr, addrlen, &un_addr); - if (ret < 0) return ret; + if (ret == -1) return -1; - ret = real_connect(s, - (struct sockaddr *)&un_addr, - sizeof(struct sockaddr_un)); + ret = real_connect(s, (struct sockaddr *)&un_addr, + sizeof(struct sockaddr_un)); - if (ret >= 0) { + if (ret == 0) { si->peername_len = addrlen; si->peername = sockaddr_dup(serv_addr, addrlen); } @@ -267,17 +280,17 @@ int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen) } ret = sockaddr_convert_to_un(si, (const struct sockaddr *)myaddr, addrlen, &un_addr); - if (ret < 0) return ret; + if (ret == -1) return -1; unlink(un_addr.sun_path); - ret = real_bind(s, - (struct sockaddr *)&un_addr, - sizeof(struct sockaddr_un)); + ret = real_bind(s, (struct sockaddr *)&un_addr, + sizeof(struct sockaddr_un)); - if (ret >= 0) { + if (ret == 0) { si->myname_len = addrlen; si->myname = sockaddr_dup(myaddr, addrlen); + si->bound = 1; } return ret; @@ -367,8 +380,8 @@ int swrap_setsockopt(int s, int level, int optname, const void *optval, so ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen) { - socklen_t un_addrlen; struct sockaddr_un un_addr; + socklen_t un_addrlen = sizeof(un_addr); int ret; struct socket_info *si = find_socket_info(s); @@ -377,10 +390,13 @@ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr } ret = real_recvfrom(s, buf, len, flags, (struct sockaddr *)&un_addr, &un_addrlen); - if (ret < 0) + if (ret == -1) return ret; - ret = sockaddr_convert_from_un(si, &un_addr, si->domain, from, fromlen); + if (sockaddr_convert_from_un(si, &un_addr, un_addrlen, + si->domain, from, fromlen) == -1) { + return -1; + } return ret; } @@ -395,12 +411,37 @@ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const str return real_sendto(s, buf, len, flags, to, tolen); } + /* using sendto() on an unbound DGRAM socket would give the + recipient no way to reply, as unlike UDP, a unix domain socket + can't auto-assign emphemeral port numbers, so we need to assign + it here */ + if (si->bound == 0 && si->type == SOCK_DGRAM) { + int i; + + un_addr.sun_family = AF_UNIX; + + for (i=0;i<1000;i++) { + snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), + "%s/sock_ip_%u_%u", getenv("SOCKET_WRAPPER_DIR"), + SOCK_DGRAM, i + 10000); + if (bind(si->fd, (struct sockaddr *)&un_addr, + sizeof(un_addr)) == 0) { + si->tmp_path = strdup(un_addr.sun_path); + si->bound = 1; + break; + } + } + if (i == 1000) { + return -1; + } + } + + ret = sockaddr_convert_to_un(si, to, tolen, &un_addr); - if (ret < 0) - return ret; + if (ret == -1) return -1; ret = real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr)); - + return ret; } @@ -414,6 +455,10 @@ int swrap_close(int fd) free(si->path); free(si->myname); free(si->peername); + if (si->tmp_path) { + unlink(si->tmp_path); + free(si->tmp_path); + } free(si); } -- cgit From 567a74690c9536f464844d647b9fe21ca56b53f3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 6 Apr 2005 10:06:08 +0000 Subject: r6222: fixed the socket wrapper code for getsockname() (This used to be commit 11e245a3f0e1523eba3a042db140dec8732aa985) --- source4/lib/socket_wrapper/socket_wrapper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index b7b0aa07b6..4814f6c929 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -321,7 +321,7 @@ int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen) struct socket_info *si = find_socket_info(s); if (!si) { - return real_getpeername(s, name, addrlen); + return real_getsockname(s, name, addrlen); } memcpy(name, si->myname, si->myname_len); -- cgit From 7fca1d46cea38229faf9a7092d86a452658f2ca0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 1 May 2005 19:08:35 +0000 Subject: r6564: - Fix bug in socket_wrapper - Add options --quiet and --outputdir options to the provisioning script - Add simple 'make test' and 'make test-swrap' (This used to be commit 7d2d4a57e0e58a51c76c2e86ea447e81a1d79544) --- source4/lib/socket_wrapper/socket_wrapper.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 4814f6c929..2a26ba1534 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -249,7 +249,8 @@ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen) } /* only allow pseudo loopback connections */ - if (((const struct sockaddr_in *)serv_addr)->sin_addr.s_addr != + if (serv_addr->sa_family == AF_INET && + ((const struct sockaddr_in *)serv_addr)->sin_addr.s_addr != htonl(INADDR_LOOPBACK)) { errno = ENETUNREACH; return -1; -- cgit From d543e4a26510da5293b5c884f026f3e40ec869d7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 10 Jun 2005 12:21:46 +0000 Subject: r7460: fixed several problems with the socket wrapper code and unbound sockets This should fix the LOCAL-SOCKET test in the build farm (This used to be commit 417e967afb457ee505c2302cdc83d7060033b0aa) --- source4/lib/socket_wrapper/socket_wrapper.c | 110 ++++++++++++++++++++-------- 1 file changed, 79 insertions(+), 31 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 2a26ba1534..882ef462ea 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -22,8 +22,10 @@ #ifdef _SAMBA_BUILD #include "includes.h" #include "system/network.h" +#include "system/filesys.h" #else #include +#include #include #include #include @@ -95,8 +97,8 @@ static int convert_un_in(const struct sockaddr_un *un, struct sockaddr_in *in, s } in->sin_family = AF_INET; - in->sin_port = 1025; /* Default to 1025 */ - p = strchr(un->sun_path, '/'); + in->sin_port = htons(1025); /* Default to 1025 */ + p = strrchr(un->sun_path, '/'); if (p) p++; else p = un->sun_path; if (sscanf(p, "sock_ip_%d_%u", &type, &prt) == 2) { @@ -107,9 +109,20 @@ static int convert_un_in(const struct sockaddr_un *un, struct sockaddr_in *in, s return 0; } -static int convert_in_un(int type, const struct sockaddr_in *in, struct sockaddr_un *un) +static int convert_in_un(struct socket_info *si, const struct sockaddr_in *in, struct sockaddr_un *un) { + int type = si->type; uint16_t prt = ntohs(in->sin_port); + if (prt == 0) { + struct stat st; + /* handle auto-allocation of ephemeral ports */ + prt = 5000; + do { + snprintf(un->sun_path, sizeof(un->sun_path), "%s/sock_ip_%d_%u", + getenv("SOCKET_WRAPPER_DIR"), type, ++prt); + } while (stat(un->sun_path, &st) == 0 && prt < 10000); + ((struct sockaddr_in *)si->myname)->sin_port = htons(prt); + } snprintf(un->sun_path, sizeof(un->sun_path), "%s/sock_ip_%d_%u", getenv("SOCKET_WRAPPER_DIR"), type, prt); return 0; @@ -126,7 +139,7 @@ static struct socket_info *find_socket_info(int fd) return NULL; } -static int sockaddr_convert_to_un(const struct socket_info *si, const struct sockaddr *in_addr, socklen_t in_len, +static int sockaddr_convert_to_un(struct socket_info *si, const struct sockaddr *in_addr, socklen_t in_len, struct sockaddr_un *out_addr) { if (!out_addr) @@ -136,7 +149,7 @@ static int sockaddr_convert_to_un(const struct socket_info *si, const struct soc switch (in_addr->sa_family) { case AF_INET: - return convert_in_un(si->type, (const struct sockaddr_in *)in_addr, out_addr); + return convert_in_un(si, (const struct sockaddr_in *)in_addr, out_addr); case AF_UNIX: memcpy(out_addr, in_addr, sizeof(*out_addr)); return 0; @@ -235,9 +248,53 @@ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) child_si->myname = sockaddr_dup(addr, *addrlen); } + child_si->peername_len = *addrlen; + child_si->peername = sockaddr_dup(addr, *addrlen); + + DLIST_ADD(sockets, child_si); + return fd; } +/* using sendto() or connect() on an unbound socket would give the + recipient no way to reply, as unlike UDP and TCP, a unix domain + socket can't auto-assign emphemeral port numbers, so we need to + assign it here */ +static int swrap_auto_bind(struct socket_info *si) +{ + struct sockaddr_un un_addr; + struct sockaddr_in in; + int i; + + un_addr.sun_family = AF_UNIX; + + for (i=0;i<1000;i++) { + snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), + "%s/sock_ip_%u_%u", getenv("SOCKET_WRAPPER_DIR"), + SOCK_DGRAM, i + 10000); + if (bind(si->fd, (struct sockaddr *)&un_addr, + sizeof(un_addr)) == 0) { + si->tmp_path = strdup(un_addr.sun_path); + si->bound = 1; + break; + } + } + if (i == 1000) { + return -1; + } + + memset(&in, 0, sizeof(in)); + in.sin_family = AF_INET; + in.sin_port = htons(i); + in.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + si->myname_len = sizeof(in); + si->myname = sockaddr_dup(&in, si->myname_len); + si->bound = 1; + return 0; +} + + int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen) { int ret; @@ -256,6 +313,11 @@ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen) return -1; } + if (si->bound == 0 && si->domain != AF_UNIX) { + ret = swrap_auto_bind(si); + if (ret == -1) return -1; + } + ret = sockaddr_convert_to_un(si, (const struct sockaddr *)serv_addr, addrlen, &un_addr); if (ret == -1) return -1; @@ -280,6 +342,14 @@ int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen) return real_bind(s, myaddr, addrlen); } + si->myname_len = addrlen; + si->myname = sockaddr_dup(myaddr, addrlen); + + if (myaddr->sa_family == AF_INET && + ((const struct sockaddr_in *)myaddr)->sin_addr.s_addr == 0) { + ((struct sockaddr_in *)si->myname)->sin_addr.s_addr = + htonl(INADDR_LOOPBACK); + } ret = sockaddr_convert_to_un(si, (const struct sockaddr *)myaddr, addrlen, &un_addr); if (ret == -1) return -1; @@ -289,8 +359,6 @@ int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen) sizeof(struct sockaddr_un)); if (ret == 0) { - si->myname_len = addrlen; - si->myname = sockaddr_dup(myaddr, addrlen); si->bound = 1; } @@ -402,6 +470,7 @@ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr return ret; } + ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen) { struct sockaddr_un un_addr; @@ -412,31 +481,10 @@ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const str return real_sendto(s, buf, len, flags, to, tolen); } - /* using sendto() on an unbound DGRAM socket would give the - recipient no way to reply, as unlike UDP, a unix domain socket - can't auto-assign emphemeral port numbers, so we need to assign - it here */ - if (si->bound == 0 && si->type == SOCK_DGRAM) { - int i; - - un_addr.sun_family = AF_UNIX; - - for (i=0;i<1000;i++) { - snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), - "%s/sock_ip_%u_%u", getenv("SOCKET_WRAPPER_DIR"), - SOCK_DGRAM, i + 10000); - if (bind(si->fd, (struct sockaddr *)&un_addr, - sizeof(un_addr)) == 0) { - si->tmp_path = strdup(un_addr.sun_path); - si->bound = 1; - break; - } - } - if (i == 1000) { - return -1; - } + if (si->bound == 0 && si->domain != AF_UNIX) { + ret = swrap_auto_bind(si); + if (ret == -1) return -1; } - ret = sockaddr_convert_to_un(si, to, tolen, &un_addr); if (ret == -1) return -1; -- cgit From 683f3bc96ee8b388d547a64734b8c0bf356e85f1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 19 Jun 2005 12:34:59 +0000 Subject: r7754: fixed the local port of accepted sockets in socket_wrapper. This fixes the problem with the ldap tests in 'make test' (This used to be commit 56fe27623ce31015a5a14f176f1445f51d57b0b8) --- source4/lib/socket_wrapper/socket_wrapper.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 882ef462ea..42bac4bfae 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -242,11 +242,10 @@ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) memset(child_si, 0, sizeof(*child_si)); child_si->fd = fd; + child_si->bound = 1; - if (addr && addrlen) { - child_si->myname_len = *addrlen; - child_si->myname = sockaddr_dup(addr, *addrlen); - } + child_si->myname_len = parent_si->myname_len; + child_si->myname = sockaddr_dup(parent_si->myname, parent_si->myname_len); child_si->peername_len = *addrlen; child_si->peername = sockaddr_dup(addr, *addrlen); -- cgit From fbb0ecd418286499d5e251893f46a7a4352d719c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 25 Jun 2005 23:38:03 +0000 Subject: r7910: fixed typo in _SAMBA_BUILD_ macro (This used to be commit d2e9e95ea2cab80badc23f0f1d416295f0a4bf9c) --- source4/lib/socket_wrapper/socket_wrapper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 42bac4bfae..d283e12f23 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -19,7 +19,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifdef _SAMBA_BUILD +#ifdef _SAMBA_BUILD_ #include "includes.h" #include "system/network.h" #include "system/filesys.h" @@ -35,8 +35,8 @@ #include #include #include -#include "dlinklist.h" #endif +#include "dlinklist.h" /* LD_PRELOAD doesn't work yet, so REWRITE_CALLS is all we support * for now */ -- cgit From eb11eeb5dbeccd7710f92dc0639df36aad06c46b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 26 Jun 2005 00:20:22 +0000 Subject: r7913: prevent recursion in the socket wrapper code (This used to be commit c1a0c2042d5bfce5781197919482481c007ff1b3) --- source4/lib/socket_wrapper/socket_wrapper.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index d283e12f23..940883a45f 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -21,6 +21,7 @@ #ifdef _SAMBA_BUILD_ #include "includes.h" +#undef SOCKET_WRAPPER #include "system/network.h" #include "system/filesys.h" #else -- cgit From a78558321a994dd02713c04ed3626b6d20d57cc7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 21 Jul 2005 08:42:17 +0000 Subject: r8671: use much shorter names for the selftest directory and socket wrapper code. I'm afraid this is needed by irix 6.4 which silently truncates names in unix domain sockets in recvfrom() to 16 chars. My apologies for having to move to such short names :-( (This used to be commit f9693e313da67e1347a607db5d3ebbf36e02a77a) --- source4/lib/socket_wrapper/socket_wrapper.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 940883a45f..d0d08d22b9 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -57,6 +57,14 @@ #define real_close close #endif +/* we need to use a very terse format here as IRIX 6.4 silently + truncates names to 16 chars, so if we use a longer name then we + can't tell which port a packet came from with recvfrom() + + with this format we have 8 chars left for the directory name +*/ +#define SOCKET_FORMAT "%u_%u" + static struct sockaddr *sockaddr_dup(const void *data, socklen_t len) { struct sockaddr *ret = (struct sockaddr *)malloc(len); @@ -102,7 +110,7 @@ static int convert_un_in(const struct sockaddr_un *un, struct sockaddr_in *in, s p = strrchr(un->sun_path, '/'); if (p) p++; else p = un->sun_path; - if (sscanf(p, "sock_ip_%d_%u", &type, &prt) == 2) { + if (sscanf(p, SOCKET_FORMAT, &type, &prt) == 2) { in->sin_port = htons(prt); } in->sin_addr.s_addr = htonl(INADDR_LOOPBACK); @@ -119,12 +127,12 @@ static int convert_in_un(struct socket_info *si, const struct sockaddr_in *in, s /* handle auto-allocation of ephemeral ports */ prt = 5000; do { - snprintf(un->sun_path, sizeof(un->sun_path), "%s/sock_ip_%d_%u", + snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, getenv("SOCKET_WRAPPER_DIR"), type, ++prt); } while (stat(un->sun_path, &st) == 0 && prt < 10000); ((struct sockaddr_in *)si->myname)->sin_port = htons(prt); } - snprintf(un->sun_path, sizeof(un->sun_path), "%s/sock_ip_%d_%u", + snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, getenv("SOCKET_WRAPPER_DIR"), type, prt); return 0; } @@ -230,6 +238,8 @@ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) return real_accept(s, addr, addrlen); } + memset(&un_addr, 0, sizeof(un_addr)); + ret = real_accept(s, (struct sockaddr *)&un_addr, &un_addrlen); if (ret == -1) return ret; @@ -270,7 +280,7 @@ static int swrap_auto_bind(struct socket_info *si) for (i=0;i<1000;i++) { snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), - "%s/sock_ip_%u_%u", getenv("SOCKET_WRAPPER_DIR"), + "%s/"SOCKET_FORMAT, getenv("SOCKET_WRAPPER_DIR"), SOCK_DGRAM, i + 10000); if (bind(si->fd, (struct sockaddr *)&un_addr, sizeof(un_addr)) == 0) { @@ -458,6 +468,8 @@ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr return real_recvfrom(s, buf, len, flags, from, fromlen); } + /* irix 6.4 forgets to null terminate the sun_path string :-( */ + memset(&un_addr, 0, sizeof(un_addr)); ret = real_recvfrom(s, buf, len, flags, (struct sockaddr *)&un_addr, &un_addrlen); if (ret == -1) return ret; -- cgit From 5086945689f10db74fbb2a4340c7e22469f9e8d8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 21 Jul 2005 13:45:07 +0000 Subject: r8681: if SOCKET_WRAPPER_DIR starts with ./ then strip it internally. This saves us 2 more chars in the name, which is enough to get IRIX 6.4 working (This used to be commit e6d9cde482ad9f3fa91d9ce3638e2ec6530b3a9c) --- source4/lib/socket_wrapper/socket_wrapper.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index d0d08d22b9..1c3d5c3bfc 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -95,6 +95,19 @@ struct socket_info static struct socket_info *sockets = NULL; + +static const char *socket_wrapper_dir(void) +{ + const char *s = getenv("SOCKET_WRAPPER_DIR"); + if (s == NULL) { + return NULL; + } + if (strncmp(s, "./", 2) == 0) { + s += 2; + } + return s; +} + static int convert_un_in(const struct sockaddr_un *un, struct sockaddr_in *in, socklen_t *len) { unsigned int prt; @@ -128,12 +141,12 @@ static int convert_in_un(struct socket_info *si, const struct sockaddr_in *in, s prt = 5000; do { snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, - getenv("SOCKET_WRAPPER_DIR"), type, ++prt); + socket_wrapper_dir(), type, ++prt); } while (stat(un->sun_path, &st) == 0 && prt < 10000); ((struct sockaddr_in *)si->myname)->sin_port = htons(prt); } snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, - getenv("SOCKET_WRAPPER_DIR"), type, prt); + socket_wrapper_dir(), type, prt); return 0; } @@ -205,7 +218,7 @@ int swrap_socket(int domain, int type, int protocol) struct socket_info *si; int fd; - if (!getenv("SOCKET_WRAPPER_DIR")) { + if (!socket_wrapper_dir()) { return real_socket(domain, type, protocol); } @@ -280,7 +293,7 @@ static int swrap_auto_bind(struct socket_info *si) for (i=0;i<1000;i++) { snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), - "%s/"SOCKET_FORMAT, getenv("SOCKET_WRAPPER_DIR"), + "%s/"SOCKET_FORMAT, socket_wrapper_dir(), SOCK_DGRAM, i + 10000); if (bind(si->fd, (struct sockaddr *)&un_addr, sizeof(un_addr)) == 0) { -- cgit From 5f653c145618b474b753a3b2b42481e9b5309cdd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 4 Nov 2005 08:02:20 +0000 Subject: r11502: make sure we always use the 7 chars for the unix socket name. this is to test if that works on irix 6.4 where we can only use 16 chars for the sun_path of the unix sockets. the plan is to make multiple interfaces possible with socket wrapper, and the format will change to ("%c%02X%04X", type, iface, port), which is also 7 char to the file name metze (This used to be commit e60d491864ad7ea7f981bc1918ace4ee3fb2d77a) --- source4/lib/socket_wrapper/socket_wrapper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 1c3d5c3bfc..d95806783d 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -63,7 +63,7 @@ with this format we have 8 chars left for the directory name */ -#define SOCKET_FORMAT "%u_%u" +#define SOCKET_FORMAT "%u_%05u" static struct sockaddr *sockaddr_dup(const void *data, socklen_t len) { -- cgit From 14b59bcbec1a288810efee5c9442dff30f1a474a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 7 Nov 2005 15:36:51 +0000 Subject: r11555: - change socket_wrapper to support multiple IP's - SOCKET_WRAPPER_DEFAULT_IFACE=X specifies the default interface for 127.0.0.X - we now use multiple interfaces for smbtorture in make test 127.0.0.26-127.0.0.31 - and 127.0.0.1 only for smbd the are more work needed for better support for broacast messages... but this is enough for the winsrepl tests metze (This used to be commit dbd01110d1a3e0f5914ae8d156723d6d6edf160c) --- source4/lib/socket_wrapper/socket_wrapper.c | 304 ++++++++++++++++++++++++---- 1 file changed, 260 insertions(+), 44 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index d95806783d..d9f61f7e3c 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -63,7 +63,9 @@ with this format we have 8 chars left for the directory name */ -#define SOCKET_FORMAT "%u_%05u" +#define SOCKET_FORMAT "%c%02X%04X" +#define SOCKET_TYPE_CHAR_TCP 'T' +#define SOCKET_TYPE_CHAR_UDP 'U' static struct sockaddr *sockaddr_dup(const void *data, socklen_t len) { @@ -80,6 +82,7 @@ struct socket_info int type; int protocol; int bound; + int bcast; char *path; char *tmp_path; @@ -108,45 +111,199 @@ static const char *socket_wrapper_dir(void) return s; } +static unsigned int socket_wrapper_default_iface(void) +{ + const char *s = getenv("SOCKET_WRAPPER_DEFAULT_IFACE"); + if (s) { + unsigned int iface; + if (sscanf(s, "%u", &iface) == 1) { + if (iface >= 1 && iface <= 0xFF) { + return iface; + } + } + } + + return 1;/* 127.0.0.1 */ +} + static int convert_un_in(const struct sockaddr_un *un, struct sockaddr_in *in, socklen_t *len) { + unsigned int iface; unsigned int prt; const char *p; - int type; + char type; if ((*len) < sizeof(struct sockaddr_in)) { return 0; } - in->sin_family = AF_INET; - in->sin_port = htons(1025); /* Default to 1025 */ p = strrchr(un->sun_path, '/'); if (p) p++; else p = un->sun_path; - if (sscanf(p, SOCKET_FORMAT, &type, &prt) == 2) { - in->sin_port = htons(prt); + if (sscanf(p, SOCKET_FORMAT, &type, &iface, &prt) != 3) { + errno = EINVAL; + return -1; + } + + if (type != SOCKET_TYPE_CHAR_TCP && type != SOCKET_TYPE_CHAR_UDP) { + errno = EINVAL; + return -1; + } + + if (iface == 0 || iface > 0xFF) { + errno = EINVAL; + return -1; + } + + if (prt > 0xFFFF) { + errno = EINVAL; + return -1; } - in->sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + in->sin_addr.s_addr = htonl((127<<24) | iface); + in->sin_port = htons(prt); + *len = sizeof(struct sockaddr_in); return 0; } -static int convert_in_un(struct socket_info *si, const struct sockaddr_in *in, struct sockaddr_un *un) +static int convert_in_un_remote(struct socket_info *si, const struct sockaddr_in *in, struct sockaddr_un *un, + int *bcast) { - int type = si->type; - uint16_t prt = ntohs(in->sin_port); + char u_type = '\0'; + char b_type = '\0'; + char a_type = '\0'; + char type = '\0'; + unsigned int addr= ntohl(in->sin_addr.s_addr); + unsigned int prt = ntohs(in->sin_port); + unsigned int iface; + int is_bcast = 0; + + if (bcast) *bcast = 0; + + if (prt == 0) { + errno = EINVAL; + return -1; + } + + switch (si->type) { + case SOCK_STREAM: + u_type = SOCKET_TYPE_CHAR_TCP; + break; + case SOCK_DGRAM: + u_type = SOCKET_TYPE_CHAR_UDP; + a_type = SOCKET_TYPE_CHAR_UDP; + b_type = SOCKET_TYPE_CHAR_UDP; + break; + } + + if (a_type && addr == 0xFFFFFFFF) { + /* 255.255.255.255 only udp */ + is_bcast = 2; + type = a_type; + iface = socket_wrapper_default_iface(); + } else if (b_type && addr == 0x7FFFFFFF) { + /* 127.255.255.255 only udp */ + is_bcast = 1; + type = b_type; + iface = socket_wrapper_default_iface(); + } else if ((addr & 0xFFFFFF00) == 0x7F000000) { + /* 127.0.0.X */ + is_bcast = 0; + type = u_type; + iface = (addr & 0x000000FF); + } else { + errno = ENETUNREACH; + return -1; + } + + if (bcast) *bcast = is_bcast; + + if (is_bcast) { + snprintf(un->sun_path, sizeof(un->sun_path), "%s/EINVAL", + socket_wrapper_dir()); + /* the caller need to do more processing */ + return 0; + } + + snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, + socket_wrapper_dir(), type, iface, prt); + + return 0; +} + +static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr_in *in, struct sockaddr_un *un, + int *bcast) +{ + char u_type = '\0'; + char d_type = '\0'; + char b_type = '\0'; + char a_type = '\0'; + char type = '\0'; + unsigned int addr= ntohl(in->sin_addr.s_addr); + unsigned int prt = ntohs(in->sin_port); + unsigned int iface; + struct stat st; + int is_bcast = 0; + + if (bcast) *bcast = 0; + + switch (si->type) { + case SOCK_STREAM: + u_type = SOCKET_TYPE_CHAR_TCP; + d_type = SOCKET_TYPE_CHAR_TCP; + break; + case SOCK_DGRAM: + u_type = SOCKET_TYPE_CHAR_UDP; + d_type = SOCKET_TYPE_CHAR_UDP; + a_type = SOCKET_TYPE_CHAR_UDP; + b_type = SOCKET_TYPE_CHAR_UDP; + break; + } + + if (addr == 0) { + /* 0.0.0.0 */ + is_bcast = 0; + type = d_type; + iface = socket_wrapper_default_iface(); + } else if (a_type && addr == 0xFFFFFFFF) { + /* 255.255.255.255 only udp */ + is_bcast = 2; + type = a_type; + iface = socket_wrapper_default_iface(); + } else if (b_type && addr == 0x7FFFFFFF) { + /* 127.255.255.255 only udp */ + is_bcast = 1; + type = b_type; + iface = socket_wrapper_default_iface(); + } else if ((addr & 0xFFFFFF00) == 0x7F000000) { + /* 127.0.0.X */ + is_bcast = 0; + type = u_type; + iface = (addr & 0x000000FF); + } else { + errno = EADDRNOTAVAIL; + return -1; + } + + if (bcast) *bcast = is_bcast; + if (prt == 0) { - struct stat st; /* handle auto-allocation of ephemeral ports */ - prt = 5000; - do { + for (prt = 5001; prt < 10000; prt++) { snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, - socket_wrapper_dir(), type, ++prt); - } while (stat(un->sun_path, &st) == 0 && prt < 10000); - ((struct sockaddr_in *)si->myname)->sin_port = htons(prt); - } + socket_wrapper_dir(), type, iface, prt); + if (stat(un->sun_path, &st) == 0) continue; + + ((struct sockaddr_in *)si->myname)->sin_port = htons(prt); + return 0; + } + errno = ENFILE; + return -1; + } + snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, - socket_wrapper_dir(), type, prt); + socket_wrapper_dir(), type, iface, prt); return 0; } @@ -162,7 +319,7 @@ static struct socket_info *find_socket_info(int fd) } static int sockaddr_convert_to_un(struct socket_info *si, const struct sockaddr *in_addr, socklen_t in_len, - struct sockaddr_un *out_addr) + struct sockaddr_un *out_addr, int alloc_sock, int *bcast) { if (!out_addr) return 0; @@ -171,7 +328,19 @@ static int sockaddr_convert_to_un(struct socket_info *si, const struct sockaddr switch (in_addr->sa_family) { case AF_INET: - return convert_in_un(si, (const struct sockaddr_in *)in_addr, out_addr); + switch (si->type) { + case SOCK_STREAM: + case SOCK_DGRAM: + break; + default: + errno = ESOCKTNOSUPPORT; + return -1; + } + if (alloc_sock) { + return convert_in_un_alloc(si, (const struct sockaddr_in *)in_addr, out_addr, bcast); + } else { + return convert_in_un_remote(si, (const struct sockaddr_in *)in_addr, out_addr, bcast); + } case AF_UNIX: memcpy(out_addr, in_addr, sizeof(*out_addr)); return 0; @@ -200,6 +369,14 @@ static int sockaddr_convert_from_un(const struct socket_info *si, switch (family) { case AF_INET: + switch (si->type) { + case SOCK_STREAM: + case SOCK_DGRAM: + break; + default: + errno = ESOCKTNOSUPPORT; + return -1; + } return convert_un_in(in_addr, (struct sockaddr_in *)out_addr, out_len); case AF_UNIX: memcpy(out_addr, in_addr, sizeof(*in_addr)); @@ -288,28 +465,46 @@ static int swrap_auto_bind(struct socket_info *si) struct sockaddr_un un_addr; struct sockaddr_in in; int i; + char type; + int ret; + struct stat st; un_addr.sun_family = AF_UNIX; + + switch (si->type) { + case SOCK_STREAM: + type = SOCKET_TYPE_CHAR_TCP; + break; + case SOCK_DGRAM: + type = SOCKET_TYPE_CHAR_UDP; + break; + default: + errno = ESOCKTNOSUPPORT; + return -1; + } for (i=0;i<1000;i++) { snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT, socket_wrapper_dir(), - SOCK_DGRAM, i + 10000); - if (bind(si->fd, (struct sockaddr *)&un_addr, - sizeof(un_addr)) == 0) { - si->tmp_path = strdup(un_addr.sun_path); - si->bound = 1; - break; - } + type, socket_wrapper_default_iface(), i + 10000); + if (stat(un_addr.sun_path, &st) == 0) continue; + + ret = real_bind(si->fd, (struct sockaddr *)&un_addr, sizeof(un_addr)); + if (ret == -1) return ret; + + si->tmp_path = strdup(un_addr.sun_path); + si->bound = 1; + break; } if (i == 1000) { + errno = ENFILE; return -1; } memset(&in, 0, sizeof(in)); in.sin_family = AF_INET; in.sin_port = htons(i); - in.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + in.sin_addr.s_addr = htonl(127<<24 | socket_wrapper_default_iface()); si->myname_len = sizeof(in); si->myname = sockaddr_dup(&in, si->myname_len); @@ -328,25 +523,24 @@ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen) return real_connect(s, serv_addr, addrlen); } - /* only allow pseudo loopback connections */ - if (serv_addr->sa_family == AF_INET && - ((const struct sockaddr_in *)serv_addr)->sin_addr.s_addr != - htonl(INADDR_LOOPBACK)) { - errno = ENETUNREACH; - return -1; - } - if (si->bound == 0 && si->domain != AF_UNIX) { ret = swrap_auto_bind(si); if (ret == -1) return -1; } - ret = sockaddr_convert_to_un(si, (const struct sockaddr *)serv_addr, addrlen, &un_addr); + ret = sockaddr_convert_to_un(si, (const struct sockaddr *)serv_addr, addrlen, &un_addr, 0, NULL); if (ret == -1) return -1; ret = real_connect(s, (struct sockaddr *)&un_addr, sizeof(struct sockaddr_un)); + /* to give better errors */ + if (serv_addr->sa_family == AF_INET) { + if (ret == -1 && errno == ENOENT) { + errno = EHOSTUNREACH; + } + } + if (ret == 0) { si->peername_len = addrlen; si->peername = sockaddr_dup(serv_addr, addrlen); @@ -368,12 +562,7 @@ int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen) si->myname_len = addrlen; si->myname = sockaddr_dup(myaddr, addrlen); - if (myaddr->sa_family == AF_INET && - ((const struct sockaddr_in *)myaddr)->sin_addr.s_addr == 0) { - ((struct sockaddr_in *)si->myname)->sin_addr.s_addr = - htonl(INADDR_LOOPBACK); - } - ret = sockaddr_convert_to_un(si, (const struct sockaddr *)myaddr, addrlen, &un_addr); + ret = sockaddr_convert_to_un(si, (const struct sockaddr *)myaddr, addrlen, &un_addr, 1, &si->bcast); if (ret == -1) return -1; unlink(un_addr.sun_path); @@ -501,6 +690,7 @@ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const str struct sockaddr_un un_addr; int ret; struct socket_info *si = find_socket_info(s); + int bcast = 0; if (!si) { return real_sendto(s, buf, len, flags, to, tolen); @@ -511,11 +701,37 @@ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const str if (ret == -1) return -1; } - ret = sockaddr_convert_to_un(si, to, tolen, &un_addr); + ret = sockaddr_convert_to_un(si, to, tolen, &un_addr, 0, &bcast); if (ret == -1) return -1; + if (bcast) { + struct stat st; + unsigned int iface; + unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port); + char type; + + type = SOCKET_TYPE_CHAR_UDP; + + for(iface=0; iface <= 0xFF; iface++) { + snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT, + socket_wrapper_dir(), type, iface, prt); + if (stat(un_addr.sun_path, &st) != 0) continue; + + /* ignore the any errors in broadcast sends */ + real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr)); + } + return len; + } + ret = real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr)); + /* to give better errors */ + if (to->sa_family == AF_INET) { + if (ret == -1 && errno == ENOENT) { + errno = EHOSTUNREACH; + } + } + return ret; } -- cgit From c53a5c4f3e17496fa944c80cf911f8780de7ae67 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 5 Dec 2005 15:22:38 +0000 Subject: r12073: fix vlgrind error, calculate the correct size for memcpy() and don't assume out_len is >= sizeof(*in_addr) metze (This used to be commit 61dbe9e5070085117b12b5b37cf0e7fe4342e2a3) --- source4/lib/socket_wrapper/socket_wrapper.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index d9f61f7e3c..d517a4c1b5 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -357,16 +357,23 @@ static int sockaddr_convert_from_un(const struct socket_info *si, socklen_t un_addrlen, int family, struct sockaddr *out_addr, - socklen_t *out_len) + socklen_t *_out_addrlen) { - if (out_addr == NULL || out_len == NULL) + socklen_t out_addrlen; + + if (out_addr == NULL || _out_addrlen == NULL) return 0; if (un_addrlen == 0) { - *out_len = 0; + *_out_addrlen = 0; return 0; } + out_addrlen = *_out_addrlen; + if (out_addrlen > un_addrlen) { + out_addrlen = un_addrlen; + } + switch (family) { case AF_INET: switch (si->type) { @@ -377,10 +384,10 @@ static int sockaddr_convert_from_un(const struct socket_info *si, errno = ESOCKTNOSUPPORT; return -1; } - return convert_un_in(in_addr, (struct sockaddr_in *)out_addr, out_len); + return convert_un_in(in_addr, (struct sockaddr_in *)out_addr, _out_addrlen); case AF_UNIX: - memcpy(out_addr, in_addr, sizeof(*in_addr)); - *out_len = sizeof(*in_addr); + memcpy(out_addr, in_addr, out_addrlen); + *_out_addrlen = out_addrlen; return 0; default: break; -- cgit From 529b03be1363396ab8c1df811c44891deeb238b5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 5 Dec 2005 15:26:49 +0000 Subject: r12074: in accept() we need to set socket name of the child socket by looking up what address the client has used, as the socket is maybe bound to '0.0.0.0' metze (This used to be commit 81d322f91aa7097a51c13648211a0556b0424fa4) --- source4/lib/socket_wrapper/socket_wrapper.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index d517a4c1b5..1114234437 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -426,8 +426,12 @@ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) { struct socket_info *parent_si, *child_si; int fd; - socklen_t un_addrlen = sizeof(struct sockaddr_un); struct sockaddr_un un_addr; + socklen_t un_addrlen = sizeof(un_addr); + struct sockaddr_un un_my_addr; + socklen_t un_my_addrlen = sizeof(un_my_addr); + struct sockaddr my_addr; + socklen_t my_addrlen = sizeof(my_addr); int ret; parent_si = find_socket_info(s); @@ -436,6 +440,8 @@ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) } memset(&un_addr, 0, sizeof(un_addr)); + memset(&un_my_addr, 0, sizeof(un_my_addr)); + memset(&my_addr, 0, sizeof(my_addr)); ret = real_accept(s, (struct sockaddr *)&un_addr, &un_addrlen); if (ret == -1) return ret; @@ -450,10 +456,20 @@ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) memset(child_si, 0, sizeof(*child_si)); child_si->fd = fd; + child_si->domain = parent_si->domain; + child_si->type = parent_si->type; + child_si->protocol = parent_si->protocol; child_si->bound = 1; - child_si->myname_len = parent_si->myname_len; - child_si->myname = sockaddr_dup(parent_si->myname, parent_si->myname_len); + ret = real_getsockname(fd, &un_my_addr, &un_my_addrlen); + if (ret == -1) return ret; + + ret = sockaddr_convert_from_un(child_si, &un_my_addr, un_my_addrlen, + child_si->domain, &my_addr, &my_addrlen); + if (ret == -1) return ret; + + child_si->myname_len = my_addrlen; + child_si->myname = sockaddr_dup(&my_addr, my_addrlen); child_si->peername_len = *addrlen; child_si->peername = sockaddr_dup(addr, *addrlen); -- cgit From c5a6c7f61ccf7baf92ea201d4463fbe453ca60e2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 4 Jan 2006 05:40:35 +0000 Subject: r12710: Fix socket_wrapper: Make sure to fill in the socket family on the returned address. Andrew Bartlett (This used to be commit 57b0aae0d4b52d9a9879c4606d2e4b3ef0d3d0d7) --- source4/lib/socket_wrapper/socket_wrapper.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 1114234437..a2ca07b083 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -160,6 +160,7 @@ static int convert_un_in(const struct sockaddr_un *un, struct sockaddr_in *in, s return -1; } + in->sin_family = AF_INET; in->sin_addr.s_addr = htonl((127<<24) | iface); in->sin_port = htons(prt); -- cgit From af30a32b6924b0f2b701186e435defbca2ebd1aa Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 5 Mar 2006 17:15:19 +0000 Subject: r13840: Mark some functions as public. (This used to be commit 9a188eb1f48a50d92a67a4fc2b3899b90074059a) --- source4/lib/socket_wrapper/socket_wrapper.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index a2ca07b083..f28343d6c4 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -398,7 +398,7 @@ static int sockaddr_convert_from_un(const struct socket_info *si, return -1; } -int swrap_socket(int domain, int type, int protocol) +_PUBLIC_ int swrap_socket(int domain, int type, int protocol) { struct socket_info *si; int fd; @@ -423,7 +423,7 @@ int swrap_socket(int domain, int type, int protocol) return si->fd; } -int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) +_PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) { struct socket_info *parent_si, *child_si; int fd; @@ -537,7 +537,7 @@ static int swrap_auto_bind(struct socket_info *si) } -int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen) +_PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen) { int ret; struct sockaddr_un un_addr; @@ -573,7 +573,7 @@ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen) return ret; } -int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen) +_PUBLIC_ int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen) { int ret; struct sockaddr_un un_addr; @@ -601,7 +601,7 @@ int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen) return ret; } -int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen) +_PUBLIC_ int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen) { struct socket_info *si = find_socket_info(s); @@ -621,7 +621,7 @@ int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen) return 0; } -int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen) +_PUBLIC_ int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen) { struct socket_info *si = find_socket_info(s); @@ -635,7 +635,7 @@ int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen) return 0; } -int swrap_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) +_PUBLIC_ int swrap_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) { struct socket_info *si = find_socket_info(s); @@ -656,7 +656,7 @@ int swrap_getsockopt(int s, int level, int optname, void *optval, socklen_t *opt } } -int swrap_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) +_PUBLIC_ int swrap_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) { struct socket_info *si = find_socket_info(s); @@ -683,7 +683,7 @@ int swrap_setsockopt(int s, int level, int optname, const void *optval, so } } -ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen) +_PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen) { struct sockaddr_un un_addr; socklen_t un_addrlen = sizeof(un_addr); @@ -709,7 +709,7 @@ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr } -ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen) +_PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen) { struct sockaddr_un un_addr; int ret; @@ -759,7 +759,7 @@ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const str return ret; } -int swrap_close(int fd) +_PUBLIC_ int swrap_close(int fd) { struct socket_info *si = find_socket_info(fd); -- cgit From 14594c7b85e661aa8370103089fb817f2842d892 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 8 Apr 2006 02:44:37 +0000 Subject: r14977: more IBM checker fixes (This used to be commit cd106509b664e9ca53419a62550b256b7e5bde3c) --- source4/lib/socket_wrapper/socket_wrapper.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index f28343d6c4..6e6711834b 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -672,11 +672,7 @@ _PUBLIC_ int swrap_setsockopt(int s, int level, int optname, const void *o case AF_UNIX: return real_setsockopt(s, level, optname, optval, optlen); case AF_INET: - /* Silence some warnings */ -#ifdef TCP_NODELAY - if (optname == TCP_NODELAY) - return 0; -#endif + return 0; default: errno = ENOPROTOOPT; return -1; -- cgit From cf0f4ec073b694e43daeeddf9aab51cd3e51fd2b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 30 Apr 2006 13:54:03 +0000 Subject: r15358: Fix some compiler warnings / type safety. Found by tcc (This used to be commit 12ba42de5886f9f4f9b1698476557e0c217d06f3) --- source4/lib/socket_wrapper/socket_wrapper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 6e6711834b..6bb7f6464f 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -462,7 +462,7 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) child_si->protocol = parent_si->protocol; child_si->bound = 1; - ret = real_getsockname(fd, &un_my_addr, &un_my_addrlen); + ret = real_getsockname(fd, (struct sockaddr *)&un_my_addr, &un_my_addrlen); if (ret == -1) return ret; ret = sockaddr_convert_from_un(child_si, &un_my_addr, un_my_addrlen, -- cgit From 0329d755a7611ba3897fc1ee9bdce410cc33d7f8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 30 Aug 2006 11:29:34 +0000 Subject: r17930: Merge noinclude branch: * Move dlinklist.h, smb.h to subsystem-specific directories * Clean up ads.h and move what is left of it to dsdb/ (only place where it's used) (This used to be commit f7afa1cb77f3cfa7020b57de12e6003db7cfcc42) --- source4/lib/socket_wrapper/socket_wrapper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 6bb7f6464f..702b192aff 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -37,7 +37,7 @@ #include #include #endif -#include "dlinklist.h" +#include "lib/util/dlinklist.h" /* LD_PRELOAD doesn't work yet, so REWRITE_CALLS is all we support * for now */ -- cgit From b5ea572f450a9161b96c9c08789791054d24df37 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 12 Sep 2006 06:19:11 +0000 Subject: r18417: overload send() and recv() by socket wrapper and add a dummy swrap_dump_packet() function which can later dump the packet content, so that a script can then generate a capture file for wireshark metze (This used to be commit d05cab5c626b5960448f206e8c17b89edbf78733) --- source4/lib/socket_wrapper/socket_wrapper.c | 64 ++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 2 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 702b192aff..5ba1624af6 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -53,6 +53,8 @@ #define real_setsockopt setsockopt #define real_recvfrom recvfrom #define real_sendto sendto +#define real_recv recv +#define real_send send #define real_socket socket #define real_close close #endif @@ -398,6 +400,20 @@ static int sockaddr_convert_from_un(const struct socket_info *si, return -1; } +enum swrap_packet_type { + SWRAP_RECVFROM, + SWRAP_SENDTO, + SWRAP_RECV, + SWRAP_SEND +}; + +static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *addr, + enum swrap_packet_type type, + const void *buf, size_t len, ssize_t ret) +{ + +} + _PUBLIC_ int swrap_socket(int domain, int type, int protocol) { struct socket_info *si; @@ -700,12 +716,14 @@ _PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct si->domain, from, fromlen) == -1) { return -1; } - + + swrap_dump_packet(si, from, SWRAP_RECVFROM, buf, len, ret); + return ret; } -_PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen) +_PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen) { struct sockaddr_un un_addr; int ret; @@ -740,6 +758,9 @@ _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, /* ignore the any errors in broadcast sends */ real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr)); } + + swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len, len); + return len; } @@ -752,6 +773,45 @@ _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, } } + swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len, ret); + + return ret; +} + +_PUBLIC_ ssize_t swrap_recv(int s, void *buf, size_t len, int flags) +{ + int ret; + struct socket_info *si = find_socket_info(s); + + if (!si) { + return real_recv(s, buf, len, flags); + } + + ret = real_recv(s, buf, len, flags); + if (ret == -1) + return ret; + + swrap_dump_packet(si, NULL, SWRAP_RECV, buf, len, ret); + + return ret; +} + + +_PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags) +{ + int ret; + struct socket_info *si = find_socket_info(s); + + if (!si) { + return real_send(s, buf, len, flags); + } + + ret = real_send(s, buf, len, flags); + if (ret == -1) + return ret; + + swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len, ret); + return ret; } -- cgit From ee67387d322cd08ae77ef11716331be7a850c5e9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 12 Sep 2006 09:08:55 +0000 Subject: r18423: record accept, connect and close events in socket wrapper metze (This used to be commit 7f29471f0b6b9158da52522984a6ab3f8ace4f42) --- source4/lib/socket_wrapper/socket_wrapper.c | 31 ++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 5ba1624af6..cedc2ecf9f 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -113,6 +113,23 @@ static const char *socket_wrapper_dir(void) return s; } +static const char *socket_wrapper_dump_dir(void) +{ + const char *s = getenv("SOCKET_WRAPPER_DUMP_DIR"); + + if (!socket_wrapper_dir()) { + return NULL; + } + + if (s == NULL) { + return NULL; + } + if (strncmp(s, "./", 2) == 0) { + s += 2; + } + return s; +} + static unsigned int socket_wrapper_default_iface(void) { const char *s = getenv("SOCKET_WRAPPER_DEFAULT_IFACE"); @@ -401,16 +418,22 @@ static int sockaddr_convert_from_un(const struct socket_info *si, } enum swrap_packet_type { + SWRAP_CONNECT, + SWRAP_ACCEPT, SWRAP_RECVFROM, SWRAP_SENDTO, SWRAP_RECV, - SWRAP_SEND + SWRAP_SEND, + SWRAP_CLOSE }; static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *addr, enum swrap_packet_type type, const void *buf, size_t len, ssize_t ret) { + if (!socket_wrapper_dump_dir()) { + return; + } } @@ -493,6 +516,8 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) DLIST_ADD(sockets, child_si); + swrap_dump_packet(child_si, addr, SWRAP_ACCEPT, NULL, 0, 0); + return fd; } @@ -586,6 +611,8 @@ _PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t ad si->peername = sockaddr_dup(serv_addr, addrlen); } + swrap_dump_packet(si, serv_addr, SWRAP_CONNECT, NULL, 0, ret); + return ret; } @@ -822,6 +849,8 @@ _PUBLIC_ int swrap_close(int fd) if (si) { DLIST_REMOVE(sockets, si); + swrap_dump_packet(si, NULL, SWRAP_CLOSE, NULL, 0, 0); + free(si->path); free(si->myname); free(si->peername); -- cgit From 894a64521a2a2f4e9e3685dab6695f81937e25bd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 12 Sep 2006 14:44:44 +0000 Subject: r18424: there's no need to allocate a wrapped socket for unix sockets, also this makes sure the socket file isn't unlinked if using socket wrapper. metze (This used to be commit 7670e9ae6e8e64ddb3c7d99b3d44048519629225) --- source4/lib/socket_wrapper/socket_wrapper.c | 37 +++++++++++++---------------- 1 file changed, 16 insertions(+), 21 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index cedc2ecf9f..230c40a72f 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -361,9 +361,6 @@ static int sockaddr_convert_to_un(struct socket_info *si, const struct sockaddr } else { return convert_in_un_remote(si, (const struct sockaddr_in *)in_addr, out_addr, bcast); } - case AF_UNIX: - memcpy(out_addr, in_addr, sizeof(*out_addr)); - return 0; default: break; } @@ -405,10 +402,6 @@ static int sockaddr_convert_from_un(const struct socket_info *si, return -1; } return convert_un_in(in_addr, (struct sockaddr_in *)out_addr, _out_addrlen); - case AF_UNIX: - memcpy(out_addr, in_addr, out_addrlen); - *_out_addrlen = out_addrlen; - return 0; default: break; } @@ -445,6 +438,16 @@ _PUBLIC_ int swrap_socket(int domain, int type, int protocol) if (!socket_wrapper_dir()) { return real_socket(domain, type, protocol); } + + switch (domain) { + case AF_INET: + break; + case AF_UNIX: + return real_socket(domain, type, protocol); + default: + errno = EAFNOSUPPORT; + return -1; + } fd = real_socket(AF_UNIX, type, 0); @@ -588,7 +591,7 @@ _PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t ad return real_connect(s, serv_addr, addrlen); } - if (si->bound == 0 && si->domain != AF_UNIX) { + if (si->bound == 0) { ret = swrap_auto_bind(si); if (ret == -1) return -1; } @@ -600,10 +603,8 @@ _PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t ad sizeof(struct sockaddr_un)); /* to give better errors */ - if (serv_addr->sa_family == AF_INET) { - if (ret == -1 && errno == ENOENT) { - errno = EHOSTUNREACH; - } + if (ret == -1 && errno == ENOENT) { + errno = EHOSTUNREACH; } if (ret == 0) { @@ -691,8 +692,6 @@ _PUBLIC_ int swrap_getsockopt(int s, int level, int optname, void *optval, sockl } switch (si->domain) { - case AF_UNIX: - return real_getsockopt(s, level, optname, optval, optlen); default: errno = ENOPROTOOPT; return -1; @@ -712,8 +711,6 @@ _PUBLIC_ int swrap_setsockopt(int s, int level, int optname, const void *o } switch (si->domain) { - case AF_UNIX: - return real_setsockopt(s, level, optname, optval, optlen); case AF_INET: return 0; default: @@ -761,7 +758,7 @@ _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, con return real_sendto(s, buf, len, flags, to, tolen); } - if (si->bound == 0 && si->domain != AF_UNIX) { + if (si->bound == 0) { ret = swrap_auto_bind(si); if (ret == -1) return -1; } @@ -794,10 +791,8 @@ _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, con ret = real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr)); /* to give better errors */ - if (to->sa_family == AF_INET) { - if (ret == -1 && errno == ENOENT) { - errno = EHOSTUNREACH; - } + if (ret == -1 && errno == ENOENT) { + errno = EHOSTUNREACH; } swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len, ret); -- cgit From 3c096b3a9ac4980101677b5268a45e5fabfe607a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 12 Sep 2006 14:59:08 +0000 Subject: r18426: use 'family' consistantly instead of mixing 'domain' and 'family' metze (This used to be commit 224f26602ac78dbdabd4602bce42e31141102f6c) --- source4/lib/socket_wrapper/socket_wrapper.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 230c40a72f..65e7a8defd 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -80,7 +80,7 @@ struct socket_info { int fd; - int domain; + int family; int type; int protocol; int bound; @@ -430,20 +430,20 @@ static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *add } -_PUBLIC_ int swrap_socket(int domain, int type, int protocol) +_PUBLIC_ int swrap_socket(int family, int type, int protocol) { struct socket_info *si; int fd; if (!socket_wrapper_dir()) { - return real_socket(domain, type, protocol); + return real_socket(family, type, protocol); } - switch (domain) { + switch (family) { case AF_INET: break; case AF_UNIX: - return real_socket(domain, type, protocol); + return real_socket(family, type, protocol); default: errno = EAFNOSUPPORT; return -1; @@ -455,7 +455,7 @@ _PUBLIC_ int swrap_socket(int domain, int type, int protocol) si = calloc(1, sizeof(struct socket_info)); - si->domain = domain; + si->family = family; si->type = type; si->protocol = protocol; si->fd = fd; @@ -492,14 +492,14 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) fd = ret; ret = sockaddr_convert_from_un(parent_si, &un_addr, un_addrlen, - parent_si->domain, addr, addrlen); + parent_si->family, addr, addrlen); if (ret == -1) return ret; child_si = malloc(sizeof(struct socket_info)); memset(child_si, 0, sizeof(*child_si)); child_si->fd = fd; - child_si->domain = parent_si->domain; + child_si->family = parent_si->family; child_si->type = parent_si->type; child_si->protocol = parent_si->protocol; child_si->bound = 1; @@ -508,7 +508,7 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) if (ret == -1) return ret; ret = sockaddr_convert_from_un(child_si, &un_my_addr, un_my_addrlen, - child_si->domain, &my_addr, &my_addrlen); + child_si->family, &my_addr, &my_addrlen); if (ret == -1) return ret; child_si->myname_len = my_addrlen; @@ -691,11 +691,8 @@ _PUBLIC_ int swrap_getsockopt(int s, int level, int optname, void *optval, sockl return real_getsockopt(s, level, optname, optval, optlen); } - switch (si->domain) { - default: - errno = ENOPROTOOPT; - return -1; - } + errno = ENOPROTOOPT; + return -1; } _PUBLIC_ int swrap_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) @@ -710,7 +707,7 @@ _PUBLIC_ int swrap_setsockopt(int s, int level, int optname, const void *o return real_setsockopt(s, level, optname, optval, optlen); } - switch (si->domain) { + switch (si->family) { case AF_INET: return 0; default: @@ -737,7 +734,7 @@ _PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct return ret; if (sockaddr_convert_from_un(si, &un_addr, un_addrlen, - si->domain, from, fromlen) == -1) { + si->family, from, fromlen) == -1) { return -1; } -- cgit From 6924a30bb50560c277db12522f899924e9a43b03 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 12 Sep 2006 16:25:50 +0000 Subject: r18427: set sin_port correctly on autobound socket metze (This used to be commit d373890fb26f3a593bacdb374f10d4279822b97d) --- source4/lib/socket_wrapper/socket_wrapper.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 65e7a8defd..53ccb5396d 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -535,6 +535,7 @@ static int swrap_auto_bind(struct socket_info *si) int i; char type; int ret; + int port; struct stat st; un_addr.sun_family = AF_UNIX; @@ -552,9 +553,10 @@ static int swrap_auto_bind(struct socket_info *si) } for (i=0;i<1000;i++) { + port = 10000 + i; snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT, socket_wrapper_dir(), - type, socket_wrapper_default_iface(), i + 10000); + type, socket_wrapper_default_iface(), port); if (stat(un_addr.sun_path, &st) == 0) continue; ret = real_bind(si->fd, (struct sockaddr *)&un_addr, sizeof(un_addr)); @@ -571,7 +573,7 @@ static int swrap_auto_bind(struct socket_info *si) memset(&in, 0, sizeof(in)); in.sin_family = AF_INET; - in.sin_port = htons(i); + in.sin_port = htons(port); in.sin_addr.s_addr = htonl(127<<24 | socket_wrapper_default_iface()); si->myname_len = sizeof(in); -- cgit From fdc7677fecc3e4b6c475f858cba4d28cc5e219d9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 12 Sep 2006 16:33:24 +0000 Subject: r18428: add my copyright metze (This used to be commit d222fab2b5fcd44ad7825e605a9febbe9d211e7a) --- source4/lib/socket_wrapper/socket_wrapper.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 53ccb5396d..4fecc90980 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -3,6 +3,7 @@ unix domain sockets if the environment variable SOCKET_WRAPPER_DIR is set. Copyright (C) Jelmer Vernooij 2005 + Copyright (C) Stefan Metzmacher 2006 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 @@ -98,7 +99,7 @@ struct socket_info struct socket_info *prev, *next; }; -static struct socket_info *sockets = NULL; +static struct socket_info *sockets; static const char *socket_wrapper_dir(void) -- cgit From 3d6cdc9e97d13052c3e15d72a6e550e9c10319a1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 16 Sep 2006 17:57:50 +0000 Subject: r18586: fixed a potential fd and memory leak in the socket_wrapper code (This used to be commit 6d53f2f5bc3a008f957be9e32df6830e1e29e8ed) --- source4/lib/socket_wrapper/socket_wrapper.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 4fecc90980..fe0b4dfe76 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -494,7 +494,10 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) ret = sockaddr_convert_from_un(parent_si, &un_addr, un_addrlen, parent_si->family, addr, addrlen); - if (ret == -1) return ret; + if (ret == -1) { + close(fd); + return ret; + } child_si = malloc(sizeof(struct socket_info)); memset(child_si, 0, sizeof(*child_si)); @@ -506,11 +509,19 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) child_si->bound = 1; ret = real_getsockname(fd, (struct sockaddr *)&un_my_addr, &un_my_addrlen); - if (ret == -1) return ret; + if (ret == -1) { + free(child_si); + close(fd); + return ret; + } ret = sockaddr_convert_from_un(child_si, &un_my_addr, un_my_addrlen, child_si->family, &my_addr, &my_addrlen); - if (ret == -1) return ret; + if (ret == -1) { + free(child_si); + close(fd); + return ret; + } child_si->myname_len = my_addrlen; child_si->myname = sockaddr_dup(&my_addr, my_addrlen); -- cgit From 4a854fe809ba617336db3e1d277e00c7ef95c55f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 17 Sep 2006 05:11:57 +0000 Subject: r18593: try to get the same socket_wrapper file building in samba3 and samba4 this is preparation of adding libreplace to samba3 later. metze (This used to be commit 26228e4b2e8debd84caebe84bb34bfbbf2ad405c) --- source4/lib/socket_wrapper/socket_wrapper.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index fe0b4dfe76..5417f70a06 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -21,11 +21,28 @@ */ #ifdef _SAMBA_BUILD_ + +#define SOCKET_WRAPPER_NOT_REPLACE #include "includes.h" -#undef SOCKET_WRAPPER #include "system/network.h" #include "system/filesys.h" -#else + +#ifndef _DLINKLIST_H +#include "lib/util/dlinklist.h" +#endif + +#ifdef malloc +#undef malloc +#endif +#ifdef calloc +#undef calloc +#endif +#ifdef strdup +#undef strdup +#endif + +#else /* _SAMBA_BUILD_ */ + #include #include #include @@ -37,8 +54,10 @@ #include #include #include + +#error "dlinklist.h missing" + #endif -#include "lib/util/dlinklist.h" /* LD_PRELOAD doesn't work yet, so REWRITE_CALLS is all we support * for now */ -- cgit From 4209af5a84baddd8537f3658975af3e068034c89 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 19 Sep 2006 00:55:40 +0000 Subject: r18661: C++ warnings (This used to be commit 771d30ca0c9d108b800bcfe33069f38dc4382662) --- source4/lib/socket_wrapper/socket_wrapper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 5417f70a06..331e23aa48 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -473,7 +473,7 @@ _PUBLIC_ int swrap_socket(int family, int type, int protocol) if (fd == -1) return -1; - si = calloc(1, sizeof(struct socket_info)); + si = (struct socket_info *)calloc(1, sizeof(struct socket_info)); si->family = family; si->type = type; @@ -518,7 +518,7 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) return ret; } - child_si = malloc(sizeof(struct socket_info)); + child_si = (struct socket_info *)malloc(sizeof(struct socket_info)); memset(child_si, 0, sizeof(*child_si)); child_si->fd = fd; -- cgit From c4ebedc7e19dcbc92061da4662b6c998d2c02bae Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 26 Sep 2006 11:31:14 +0000 Subject: r18917: having 255 virtual interfaces available in socket wrapper means we stat() 240 files that don't exist on every broadcast. That's a bit excessive! reduce max virtual interfaces to 16 (This used to be commit 3c4100027c7d3806a2021cb4d70ec6adf9dd2dc6) --- source4/lib/socket_wrapper/socket_wrapper.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 331e23aa48..6c23cebc81 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -89,6 +89,8 @@ #define SOCKET_TYPE_CHAR_TCP 'T' #define SOCKET_TYPE_CHAR_UDP 'U' +#define MAX_WRAPPED_INTERFACES 16 + static struct sockaddr *sockaddr_dup(const void *data, socklen_t len) { struct sockaddr *ret = (struct sockaddr *)malloc(len); @@ -156,7 +158,7 @@ static unsigned int socket_wrapper_default_iface(void) if (s) { unsigned int iface; if (sscanf(s, "%u", &iface) == 1) { - if (iface >= 1 && iface <= 0xFF) { + if (iface >= 1 && iface <= MAX_WRAPPED_INTERFACES) { return iface; } } @@ -189,7 +191,7 @@ static int convert_un_in(const struct sockaddr_un *un, struct sockaddr_in *in, s return -1; } - if (iface == 0 || iface > 0xFF) { + if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) { errno = EINVAL; return -1; } @@ -804,7 +806,7 @@ _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, con type = SOCKET_TYPE_CHAR_UDP; - for(iface=0; iface <= 0xFF; iface++) { + for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) { snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT, socket_wrapper_dir(), type, iface, prt); if (stat(un_addr.sun_path, &st) != 0) continue; -- cgit From 06de0f0b743056ba845de000339d4c3beb7cb845 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 26 Sep 2006 13:15:31 +0000 Subject: r18918: - bail out with unsupported option to socket() - don't reuse portnumbers in the autobind code - use if (!...) return; logic instead of if (...) { do everything } return for swrap_close metze (This used to be commit 68a65aa4490c12ca70db335f928f3ac507902337) --- source4/lib/socket_wrapper/socket_wrapper.c | 71 +++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 18 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 6c23cebc81..224d521b30 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -470,7 +470,25 @@ _PUBLIC_ int swrap_socket(int family, int type, int protocol) errno = EAFNOSUPPORT; return -1; } - + + switch (type) { + case SOCK_STREAM: + break; + case SOCK_DGRAM: + break; + default: + errno = EPROTONOSUPPORT; + return -1; + } + + switch (protocol) { + case 0: + break; + default: + errno = EPROTONOSUPPORT; + return -1; + } + fd = real_socket(AF_UNIX, type, 0); if (fd == -1) return -1; @@ -557,6 +575,9 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) return fd; } +static int autobind_start_init; +static int autobind_start; + /* using sendto() or connect() on an unbound socket would give the recipient no way to reply, as unlike UDP and TCP, a unix domain socket can't auto-assign emphemeral port numbers, so we need to @@ -570,7 +591,14 @@ static int swrap_auto_bind(struct socket_info *si) int ret; int port; struct stat st; - + + if (autobind_start_init != 1) { + autobind_start_init = 1; + autobind_start = getpid(); + autobind_start %= 50000; + autobind_start += 10000; + } + un_addr.sun_family = AF_UNIX; switch (si->type) { @@ -584,9 +612,13 @@ static int swrap_auto_bind(struct socket_info *si) errno = ESOCKTNOSUPPORT; return -1; } - + + if (autobind_start > 60000) { + autobind_start = 10000; + } + for (i=0;i<1000;i++) { - port = 10000 + i; + port = autobind_start + i; snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT, socket_wrapper_dir(), type, socket_wrapper_default_iface(), port); @@ -597,13 +629,14 @@ static int swrap_auto_bind(struct socket_info *si) si->tmp_path = strdup(un_addr.sun_path); si->bound = 1; + autobind_start = port + 1; break; } if (i == 1000) { errno = ENFILE; return -1; } - + memset(&in, 0, sizeof(in)); in.sin_family = AF_INET; in.sin_port = htons(port); @@ -611,7 +644,6 @@ static int swrap_auto_bind(struct socket_info *si) si->myname_len = sizeof(in); si->myname = sockaddr_dup(&in, si->myname_len); - si->bound = 1; return 0; } @@ -872,21 +904,24 @@ _PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags) _PUBLIC_ int swrap_close(int fd) { struct socket_info *si = find_socket_info(fd); + int ret; + + if (!si) { + return real_close(fd); + } - if (si) { - DLIST_REMOVE(sockets, si); + DLIST_REMOVE(sockets, si); - swrap_dump_packet(si, NULL, SWRAP_CLOSE, NULL, 0, 0); + ret = real_close(fd); - free(si->path); - free(si->myname); - free(si->peername); - if (si->tmp_path) { - unlink(si->tmp_path); - free(si->tmp_path); - } - free(si); + free(si->path); + free(si->myname); + free(si->peername); + if (si->tmp_path) { + unlink(si->tmp_path); + free(si->tmp_path); } + free(si); - return real_close(fd); + return ret; } -- cgit From 174742a74ce448d1944ada9dd602aadf20bce6f8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 27 Sep 2006 10:13:45 +0000 Subject: r18947: overload listen() and ioctl() in socket_wrapper metze (This used to be commit dfaccdca1b6954cd61828749d7b000f804f3b066) --- source4/lib/socket_wrapper/socket_wrapper.c | 30 +++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 224d521b30..c884b96c6c 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -67,12 +67,14 @@ #define real_accept accept #define real_connect connect #define real_bind bind +#define real_listen listen #define real_getpeername getpeername #define real_getsockname getsockname #define real_getsockopt getsockopt #define real_setsockopt setsockopt #define real_recvfrom recvfrom #define real_sendto sendto +#define real_ioctl ioctl #define real_recv recv #define real_send send #define real_socket socket @@ -712,6 +714,20 @@ _PUBLIC_ int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen) return ret; } +_PUBLIC_ int swrap_listen(int s, int backlog) +{ + int ret; + struct socket_info *si = find_socket_info(s); + + if (!si) { + return real_listen(s, backlog); + } + + ret = real_listen(s, backlog); + + return ret; +} + _PUBLIC_ int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen) { struct socket_info *si = find_socket_info(s); @@ -864,6 +880,20 @@ _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, con return ret; } +_PUBLIC_ int swrap_ioctl(int s, int r, void *p) +{ + int ret; + struct socket_info *si = find_socket_info(s); + + if (!si) { + return real_ioctl(s, r, p); + } + + ret = real_ioctl(s, r, p); + + return ret; +} + _PUBLIC_ ssize_t swrap_recv(int s, void *buf, size_t len, int flags) { int ret; -- cgit From bbafa2ce6bf052b7cf73a5c7f0da91c5954063db Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 29 Sep 2006 09:31:20 +0000 Subject: r18992: prepare SOCKET_WRAPPER_PCAP_FILE support metze (This used to be commit 400098416c1a4d7ae51b86eced51bffd6134296a) --- source4/lib/socket_wrapper/socket_wrapper.c | 112 +++++++++++++++++++++------- 1 file changed, 83 insertions(+), 29 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index c884b96c6c..7054068218 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -109,6 +109,7 @@ struct socket_info int protocol; int bound; int bcast; + int is_server; char *path; char *tmp_path; @@ -137,13 +138,9 @@ static const char *socket_wrapper_dir(void) return s; } -static const char *socket_wrapper_dump_dir(void) +static const char *socket_wrapper_pcap_file(void) { - const char *s = getenv("SOCKET_WRAPPER_DUMP_DIR"); - - if (!socket_wrapper_dir()) { - return NULL; - } + const char *s = getenv("SOCKET_WRAPPER_PCAP_FILE"); if (s == NULL) { return NULL; @@ -435,23 +432,40 @@ static int sockaddr_convert_from_un(const struct socket_info *si, } enum swrap_packet_type { - SWRAP_CONNECT, - SWRAP_ACCEPT, + SWRAP_CONNECT_SEND, + SWRAP_CONNECT_UNREACH, + SWRAP_CONNECT_RECV, + SWRAP_CONNECT_ACK, + SWRAP_ACCEPT_SEND, + SWRAP_ACCEPT_RECV, + SWRAP_ACCEPT_ACK, SWRAP_RECVFROM, SWRAP_SENDTO, + SWRAP_SENDTO_UNREACH, + SWRAP_PENDING_RST, SWRAP_RECV, + SWRAP_RECV_RST, SWRAP_SEND, - SWRAP_CLOSE + SWRAP_SEND_RST, + SWRAP_CLOSE_SEND, + SWRAP_CLOSE_RECV, + SWRAP_CLOSE_ACK }; static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *addr, enum swrap_packet_type type, - const void *buf, size_t len, ssize_t ret) + const void *buf, size_t len) { - if (!socket_wrapper_dump_dir()) { + const char *file_name; + + file_name = socket_wrapper_pcap_file(); + if (!file_name) { return; } + if (si->family != AF_INET) { + return; + } } _PUBLIC_ int swrap_socket(int family, int type, int protocol) @@ -548,6 +562,7 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) child_si->type = parent_si->type; child_si->protocol = parent_si->protocol; child_si->bound = 1; + child_si->is_server = 1; ret = real_getsockname(fd, (struct sockaddr *)&un_my_addr, &un_my_addrlen); if (ret == -1) { @@ -572,7 +587,9 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) DLIST_ADD(sockets, child_si); - swrap_dump_packet(child_si, addr, SWRAP_ACCEPT, NULL, 0, 0); + swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0); + swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_RECV, NULL, 0); + swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_ACK, NULL, 0); return fd; } @@ -668,6 +685,8 @@ _PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t ad ret = sockaddr_convert_to_un(si, (const struct sockaddr *)serv_addr, addrlen, &un_addr, 0, NULL); if (ret == -1) return -1; + swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0); + ret = real_connect(s, (struct sockaddr *)&un_addr, sizeof(struct sockaddr_un)); @@ -679,9 +698,12 @@ _PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t ad if (ret == 0) { si->peername_len = addrlen; si->peername = sockaddr_dup(serv_addr, addrlen); - } - swrap_dump_packet(si, serv_addr, SWRAP_CONNECT, NULL, 0, ret); + swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0); + swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0); + } else { + swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0); + } return ret; } @@ -736,7 +758,7 @@ _PUBLIC_ int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen) return real_getpeername(s, name, addrlen); } - if (!si->peername) + if (!si->peername) { errno = ENOTCONN; return -1; @@ -821,7 +843,7 @@ _PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct return -1; } - swrap_dump_packet(si, from, SWRAP_RECVFROM, buf, len, ret); + swrap_dump_packet(si, from, SWRAP_RECVFROM, buf, ret); return ret; } @@ -863,7 +885,7 @@ _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, con real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr)); } - swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len, len); + swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len); return len; } @@ -875,7 +897,12 @@ _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, con errno = EHOSTUNREACH; } - swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len, ret); + if (ret == -1) { + swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len); + swrap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len); + } else { + swrap_dump_packet(si, to, SWRAP_SENDTO, buf, ret); + } return ret; } @@ -883,7 +910,8 @@ _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, con _PUBLIC_ int swrap_ioctl(int s, int r, void *p) { int ret; - struct socket_info *si = find_socket_info(s); + struct socket_info *si = find_socket_info(s); + int value; if (!si) { return real_ioctl(s, r, p); @@ -891,6 +919,17 @@ _PUBLIC_ int swrap_ioctl(int s, int r, void *p) ret = real_ioctl(s, r, p); + switch (r) { + case FIONREAD: + value = *((int *)p); + if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) { + swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0); + } else if (value == 0) { /* END OF FILE */ + swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0); + } + break; + } + return ret; } @@ -904,10 +943,13 @@ _PUBLIC_ ssize_t swrap_recv(int s, void *buf, size_t len, int flags) } ret = real_recv(s, buf, len, flags); - if (ret == -1) - return ret; - - swrap_dump_packet(si, NULL, SWRAP_RECV, buf, len, ret); + if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) { + swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0); + } else if (ret == 0) { /* END OF FILE */ + swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0); + } else { + swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret); + } return ret; } @@ -923,10 +965,13 @@ _PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags) } ret = real_send(s, buf, len, flags); - if (ret == -1) - return ret; - swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len, ret); + if (ret == -1) { + swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len); + swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0); + } else { + swrap_dump_packet(si, NULL, SWRAP_SEND, buf, ret); + } return ret; } @@ -942,11 +987,20 @@ _PUBLIC_ int swrap_close(int fd) DLIST_REMOVE(sockets, si); + if (si->myname && si->peername) { + swrap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0); + } + ret = real_close(fd); - free(si->path); - free(si->myname); - free(si->peername); + if (si->myname && si->peername) { + swrap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0); + swrap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0); + } + + if (si->path) free(si->path); + if (si->myname) free(si->myname); + if (si->peername) free(si->peername); if (si->tmp_path) { unlink(si->tmp_path); free(si->tmp_path); -- cgit From 42b1e2c806ce71322398ac7e15f71c15459105f4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 5 Oct 2006 06:27:41 +0000 Subject: r19082: add the source vs. destination address and tcp logic for SOCKET_WRAPPER_PCAP_FILE support. metze (This used to be commit 20945409b89be094c958f5f43c8c158f223f7911) --- source4/lib/socket_wrapper/socket_wrapper.c | 242 ++++++++++++++++++++++++++++ 1 file changed, 242 insertions(+) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 7054068218..84e1cb9fd9 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -120,6 +120,11 @@ struct socket_info struct sockaddr *peername; socklen_t peername_len; + struct { + unsigned long long pck_snd; + unsigned long long pck_rcv; + } io; + struct socket_info *prev, *next; }; @@ -456,7 +461,13 @@ static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *add enum swrap_packet_type type, const void *buf, size_t len) { + const struct sockaddr_in *src_addr; + const struct sockaddr_in *dest_addr; const char *file_name; + uint32_t tcp_seq = 0; + uint32_t tcp_ack = 0; + uint8_t tcp_ctl = 0; + int unreachable = 0; file_name = socket_wrapper_pcap_file(); if (!file_name) { @@ -466,6 +477,237 @@ static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *add if (si->family != AF_INET) { return; } + + switch (type) { + case SWRAP_CONNECT_SEND: + if (si->type != SOCK_STREAM) return; + + src_addr = (const struct sockaddr_in *)si->myname; + dest_addr = (const struct sockaddr_in *)addr; + + tcp_seq = si->io.pck_snd; + tcp_ack = si->io.pck_rcv; + tcp_ctl = 0x02; /* SYN */ + + si->io.pck_snd += 1; + + break; + + case SWRAP_CONNECT_RECV: + if (si->type != SOCK_STREAM) return; + + dest_addr = (const struct sockaddr_in *)si->myname; + src_addr = (const struct sockaddr_in *)addr; + + tcp_seq = si->io.pck_rcv; + tcp_ack = si->io.pck_snd; + tcp_ctl = 0x12; /** SYN,ACK */ + + si->io.pck_rcv += 1; + + break; + + case SWRAP_CONNECT_UNREACH: + if (si->type != SOCK_STREAM) return; + + dest_addr = (const struct sockaddr_in *)si->myname; + src_addr = (const struct sockaddr_in *)addr; + + /* Unreachable: resend the data of SWRAP_CONNECT_SEND */ + tcp_seq = si->io.pck_snd - 1; + tcp_ack = si->io.pck_rcv; + tcp_ctl = 0x02; /* SYN */ + unreachable = 1; + + break; + + case SWRAP_CONNECT_ACK: + if (si->type != SOCK_STREAM) return; + + src_addr = (const struct sockaddr_in *)si->myname; + dest_addr = (const struct sockaddr_in *)addr; + + tcp_seq = si->io.pck_snd; + tcp_ack = si->io.pck_rcv; + tcp_ctl = 0x10; /* ACK */ + + break; + + case SWRAP_ACCEPT_SEND: + if (si->type != SOCK_STREAM) return; + + dest_addr = (const struct sockaddr_in *)si->myname; + src_addr = (const struct sockaddr_in *)addr; + + tcp_seq = si->io.pck_rcv; + tcp_ack = si->io.pck_snd; + tcp_ctl = 0x02; /* SYN */ + + si->io.pck_rcv += 1; + + break; + + case SWRAP_ACCEPT_RECV: + if (si->type != SOCK_STREAM) return; + + src_addr = (const struct sockaddr_in *)si->myname; + dest_addr = (const struct sockaddr_in *)addr; + + tcp_seq = si->io.pck_snd; + tcp_ack = si->io.pck_rcv; + tcp_ctl = 0x12; /* SYN,ACK */ + + si->io.pck_snd += 1; + + break; + + case SWRAP_ACCEPT_ACK: + if (si->type != SOCK_STREAM) return; + + dest_addr = (const struct sockaddr_in *)si->myname; + src_addr = (const struct sockaddr_in *)addr; + + tcp_seq = si->io.pck_rcv; + tcp_ack = si->io.pck_snd; + tcp_ctl = 0x10; /* ACK */ + + break; + + case SWRAP_SEND: + src_addr = (const struct sockaddr_in *)si->myname; + dest_addr = (const struct sockaddr_in *)si->peername; + + tcp_seq = si->io.pck_snd; + tcp_ack = si->io.pck_rcv; + tcp_ctl = 0x18; /* PSH,ACK */ + + si->io.pck_snd += len; + + break; + + case SWRAP_SEND_RST: + dest_addr = (const struct sockaddr_in *)si->myname; + src_addr = (const struct sockaddr_in *)si->peername; + + if (si->type == SOCK_DGRAM) { + swrap_dump_packet(si, si->peername, + SWRAP_SENDTO_UNREACH, + buf, len); + return; + } + + tcp_seq = si->io.pck_rcv; + tcp_ack = si->io.pck_snd; + tcp_ctl = 0x14; /** RST,ACK */ + + break; + + case SWRAP_PENDING_RST: + dest_addr = (const struct sockaddr_in *)si->myname; + src_addr = (const struct sockaddr_in *)si->peername; + + if (si->type == SOCK_DGRAM) { + return; + } + + tcp_seq = si->io.pck_rcv; + tcp_ack = si->io.pck_snd; + tcp_ctl = 0x14; /* RST,ACK */ + + break; + + case SWRAP_RECV: + dest_addr = (const struct sockaddr_in *)si->myname; + src_addr = (const struct sockaddr_in *)si->peername; + + tcp_seq = si->io.pck_rcv; + tcp_ack = si->io.pck_snd; + tcp_ctl = 0x18; /* PSH,ACK */ + + si->io.pck_rcv += len; + + break; + + case SWRAP_RECV_RST: + dest_addr = (const struct sockaddr_in *)si->myname; + src_addr = (const struct sockaddr_in *)si->peername; + + if (si->type == SOCK_DGRAM) { + return; + } + + tcp_seq = si->io.pck_rcv; + tcp_ack = si->io.pck_snd; + tcp_ctl = 0x14; /* RST,ACK */ + + break; + + case SWRAP_SENDTO: + src_addr = (const struct sockaddr_in *)si->myname; + dest_addr = (const struct sockaddr_in *)addr; + + si->io.pck_snd += len; + + break; + + case SWRAP_SENDTO_UNREACH: + dest_addr = (const struct sockaddr_in *)si->myname; + src_addr = (const struct sockaddr_in *)addr; + + unreachable = 1; + + break; + + case SWRAP_RECVFROM: + dest_addr = (const struct sockaddr_in *)si->myname; + src_addr = (const struct sockaddr_in *)addr; + + si->io.pck_rcv += len; + + break; + + case SWRAP_CLOSE_SEND: + if (si->type != SOCK_STREAM) return; + + src_addr = (const struct sockaddr_in *)si->myname; + dest_addr = (const struct sockaddr_in *)si->peername; + + tcp_seq = si->io.pck_snd; + tcp_ack = si->io.pck_rcv; + tcp_ctl = 0x11; /* FIN, ACK */ + + si->io.pck_snd += 1; + + break; + + case SWRAP_CLOSE_RECV: + if (si->type != SOCK_STREAM) return; + + dest_addr = (const struct sockaddr_in *)si->myname; + src_addr = (const struct sockaddr_in *)si->peername; + + tcp_seq = si->io.pck_rcv; + tcp_ack = si->io.pck_snd; + tcp_ctl = 0x11; /* FIN,ACK */ + + si->io.pck_rcv += 1; + + break; + + case SWRAP_CLOSE_ACK: + if (si->type != SOCK_STREAM) return; + + src_addr = (const struct sockaddr_in *)si->myname; + dest_addr = (const struct sockaddr_in *)si->peername; + + tcp_seq = si->io.pck_snd; + tcp_ack = si->io.pck_rcv; + tcp_ctl = 0x10; /* ACK */ + + break; + } + + /* TODO: contruct the blob and write to the file */ } _PUBLIC_ int swrap_socket(int family, int type, int protocol) -- cgit From a484b8367b21728de7c6dcd744d43edf0d7d1ede Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 5 Oct 2006 07:03:41 +0000 Subject: r19084: make socket_wrapper more portable (standalone) and not use uintX_t metze (This used to be commit 7e89a0a28263e36ef7410122f987edf369154651) --- source4/lib/socket_wrapper/socket_wrapper.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 84e1cb9fd9..fd80892d28 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -121,8 +121,8 @@ struct socket_info socklen_t peername_len; struct { - unsigned long long pck_snd; - unsigned long long pck_rcv; + unsigned long pck_snd; + unsigned long pck_rcv; } io; struct socket_info *prev, *next; @@ -464,9 +464,9 @@ static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *add const struct sockaddr_in *src_addr; const struct sockaddr_in *dest_addr; const char *file_name; - uint32_t tcp_seq = 0; - uint32_t tcp_ack = 0; - uint8_t tcp_ctl = 0; + unsigned long tcp_seq = 0; + unsigned long tcp_ack = 0; + unsigned char tcp_ctl = 0; int unreachable = 0; file_name = socket_wrapper_pcap_file(); -- cgit From e6f16b74212832790b97998c1b1bdf6b74adc4e3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 5 Oct 2006 11:39:59 +0000 Subject: r19097: add support for SUCKET_WRAPPER_PCAP_FILE we may need to rework the code to use something like PUSH_U32() into a data blob instead of the structs for the header layout. metze (This used to be commit 990dfc98e42a1c2369e77aa5cc2139680f4b16af) --- source4/lib/socket_wrapper/socket_wrapper.c | 320 ++++++++++++++++++++++++++-- 1 file changed, 306 insertions(+), 14 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index fd80892d28..006aba1e9d 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -81,6 +81,12 @@ #define real_close close #endif +#ifdef HAVE_GETTIMEOFDAY_TZ +#define swrapGetTimeOfDay(tval) gettimeofday(tval,NULL) +#else +#define swrapGetTimeOfDay(tval) gettimeofday(tval) +#endif + /* we need to use a very terse format here as IRIX 6.4 silently truncates names to 16 chars, so if we use a longer name then we can't tell which port a packet came from with recvfrom() @@ -143,19 +149,6 @@ static const char *socket_wrapper_dir(void) return s; } -static const char *socket_wrapper_pcap_file(void) -{ - const char *s = getenv("SOCKET_WRAPPER_PCAP_FILE"); - - if (s == NULL) { - return NULL; - } - if (strncmp(s, "./", 2) == 0) { - s += 2; - } - return s; -} - static unsigned int socket_wrapper_default_iface(void) { const char *s = getenv("SOCKET_WRAPPER_DEFAULT_IFACE"); @@ -457,6 +450,287 @@ enum swrap_packet_type { SWRAP_CLOSE_ACK }; +struct swrap_file_hdr { + unsigned long magic; + unsigned short version_major; + unsigned short version_minor; + long timezone; + unsigned long sigfigs; + unsigned long frame_max_len; +#define SWRAP_FRAME_LENGTH_MAX 0xFFFF + unsigned long link_type; +}; +#define SWRAP_FILE_HDR_SIZE 24 + +struct swrap_packet { + struct { + unsigned long seconds; + unsigned long micro_seconds; + unsigned long recorded_length; + unsigned long full_length; + } frame; +#define SWRAP_PACKET__FRAME_SIZE 16 + + struct { + struct { + unsigned char ver_hdrlen; + unsigned char tos; + unsigned short packet_length; + unsigned short identification; + unsigned char flags; + unsigned char fragment; + unsigned char ttl; + unsigned char protocol; + unsigned short hdr_checksum; + unsigned long src_addr; + unsigned long dest_addr; + } hdr; +#define SWRAP_PACKET__IP_HDR_SIZE 20 + + union { + struct { + unsigned short source_port; + unsigned short dest_port; + unsigned long seq_num; + unsigned long ack_num; + unsigned char hdr_length; + unsigned char control; + unsigned short window; + unsigned short checksum; + unsigned short urg; + } tcp; +#define SWRAP_PACKET__IP_P_TCP_SIZE 20 + struct { + unsigned short source_port; + unsigned short dest_port; + unsigned short length; + unsigned short checksum; + } udp; +#define SWRAP_PACKET__IP_P_UDP_SIZE 8 + struct { + unsigned char type; + unsigned char code; + unsigned short checksum; + unsigned long unused; + } icmp; +#define SWRAP_PACKET__IP_P_ICMP_SIZE 8 + } p; + } ip; +}; +#define SWRAP_PACKET_SIZE 56 + +static const char *socket_wrapper_pcap_file(void) +{ + static int initialized = 0; + static const char *s = NULL; + static const struct swrap_file_hdr h; + static const struct swrap_packet p; + + if (initialized == 1) { + return s; + } + initialized = 1; + + /* + * TODO: don't use the structs use plain buffer offsets + * and PUSH_U8(), PUSH_U16() and PUSH_U32() + * + * for now make sure we disable PCAP support + * if the struct has alignment! + */ + if (sizeof(h) != SWRAP_FILE_HDR_SIZE) { + return NULL; + } + if (sizeof(p) != SWRAP_PACKET_SIZE) { + return NULL; + } + if (sizeof(p.frame) != SWRAP_PACKET__FRAME_SIZE) { + return NULL; + } + if (sizeof(p.ip.hdr) != SWRAP_PACKET__IP_HDR_SIZE) { + return NULL; + } + if (sizeof(p.ip.p.tcp) != SWRAP_PACKET__IP_P_TCP_SIZE) { + return NULL; + } + if (sizeof(p.ip.p.udp) != SWRAP_PACKET__IP_P_UDP_SIZE) { + return NULL; + } + if (sizeof(p.ip.p.icmp) != SWRAP_PACKET__IP_P_ICMP_SIZE) { + return NULL; + } + + s = getenv("SOCKET_WRAPPER_PCAP_FILE"); + if (s == NULL) { + return NULL; + } + if (strncmp(s, "./", 2) == 0) { + s += 2; + } + return s; +} + +static struct swrap_packet *swrap_packet_init(struct timeval *tval, + const struct sockaddr_in *src_addr, + const struct sockaddr_in *dest_addr, + int socket_type, + const unsigned char *payload, + size_t payload_len, + unsigned long tcp_seq, + unsigned long tcp_ack, + unsigned char tcp_ctl, + int unreachable, + size_t *_packet_len) +{ + struct swrap_packet *ret; + struct swrap_packet *packet; + size_t packet_len; + size_t alloc_len; + size_t nonwire_len = sizeof(packet->frame); + size_t wire_hdr_len; + size_t wire_len; + size_t icmp_hdr_len = 0; + size_t icmp_truncate_len = 0; + unsigned char protocol, icmp_protocol; + unsigned short src_port = src_addr->sin_port; + unsigned short dest_port = dest_addr->sin_port; + + switch (socket_type) { + case SOCK_STREAM: + protocol = 0x06; /* TCP */ + wire_hdr_len = sizeof(packet->ip.hdr) + sizeof(packet->ip.p.tcp); + wire_len = wire_hdr_len + payload_len; + break; + + case SOCK_DGRAM: + protocol = 0x11; /* UDP */ + wire_hdr_len = sizeof(packet->ip.hdr) + sizeof(packet->ip.p.udp); + wire_len = wire_hdr_len + payload_len; + break; + } + + if (unreachable) { + icmp_protocol = protocol; + protocol = 0x01; /* ICMP */ + if (wire_len > 64 ) { + icmp_truncate_len = wire_len - 64; + } + icmp_hdr_len = sizeof(packet->ip.hdr) + sizeof(packet->ip.p.icmp); + wire_hdr_len += icmp_hdr_len; + wire_len += icmp_hdr_len; + } + + packet_len = nonwire_len + wire_len; + alloc_len = packet_len; + if (alloc_len < sizeof(struct swrap_packet)) { + alloc_len = sizeof(struct swrap_packet); + } + ret = (struct swrap_packet *)malloc(alloc_len); + if (!ret) return NULL; + + packet = ret; + + packet->frame.seconds = tval->tv_sec; + packet->frame.micro_seconds = tval->tv_usec; + packet->frame.recorded_length = wire_len - icmp_truncate_len; + packet->frame.full_length = wire_len - icmp_truncate_len; + + packet->ip.hdr.ver_hdrlen = 0x45; /* version 4 and 5 * 32 bit words */ + packet->ip.hdr.tos = 0x00; + packet->ip.hdr.packet_length = htons(wire_len - icmp_truncate_len); + packet->ip.hdr.identification = htons(0xFFFF); + packet->ip.hdr.flags = 0x40; /* BIT 1 set - means don't fraqment */ + packet->ip.hdr.fragment = htons(0x0000); + packet->ip.hdr.ttl = 0xFF; + packet->ip.hdr.protocol = protocol; + packet->ip.hdr.hdr_checksum = htons(0x0000); + packet->ip.hdr.src_addr = src_addr->sin_addr.s_addr; + packet->ip.hdr.dest_addr = dest_addr->sin_addr.s_addr; + + if (unreachable) { + packet->ip.p.icmp.type = 0x03; /* destination unreachable */ + packet->ip.p.icmp.code = 0x01; /* host unreachable */ + packet->ip.p.icmp.checksum = htons(0x0000); + packet->ip.p.icmp.unused = htonl(0x00000000); + + /* set the ip header in the ICMP payload */ + packet = (struct swrap_packet *)(((unsigned char *)ret) + icmp_hdr_len); + packet->ip.hdr.ver_hdrlen = 0x45; /* version 4 and 5 * 32 bit words */ + packet->ip.hdr.tos = 0x00; + packet->ip.hdr.packet_length = htons(wire_len - icmp_hdr_len); + packet->ip.hdr.identification = htons(0xFFFF); + packet->ip.hdr.flags = 0x40; /* BIT 1 set - means don't fraqment */ + packet->ip.hdr.fragment = htons(0x0000); + packet->ip.hdr.ttl = 0xFF; + packet->ip.hdr.protocol = icmp_protocol; + packet->ip.hdr.hdr_checksum = htons(0x0000); + packet->ip.hdr.src_addr = dest_addr->sin_addr.s_addr; + packet->ip.hdr.dest_addr = src_addr->sin_addr.s_addr; + + src_port = dest_addr->sin_port; + dest_port = src_addr->sin_port; + } + + switch (socket_type) { + case SOCK_STREAM: + packet->ip.p.tcp.source_port = src_port; + packet->ip.p.tcp.dest_port = dest_port; + packet->ip.p.tcp.seq_num = htonl(tcp_seq); + packet->ip.p.tcp.ack_num = htonl(tcp_ack); + packet->ip.p.tcp.hdr_length = 0x50; /* 5 * 32 bit words */ + packet->ip.p.tcp.control = tcp_ctl; + packet->ip.p.tcp.window = htons(0x7FFF); + packet->ip.p.tcp.checksum = htons(0x0000); + packet->ip.p.tcp.urg = htons(0x0000); + + break; + + case SOCK_DGRAM: + packet->ip.p.udp.source_port = src_addr->sin_port; + packet->ip.p.udp.dest_port = dest_addr->sin_port; + packet->ip.p.udp.length = htons(8 + payload_len); + packet->ip.p.udp.checksum = htons(0x0000); + + break; + } + + if (payload && payload_len > 0) { + unsigned char *p = (unsigned char *)ret; + p += nonwire_len; + p += wire_hdr_len; + memcpy(p, payload, payload_len); + } + + *_packet_len = packet_len - icmp_truncate_len; + return ret; +} + +static int swrap_get_pcap_fd(const char *fname) +{ + static int fd = -1; + + if (fd != -1) return fd; + + fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0644); + if (fd != -1) { + struct swrap_file_hdr file_hdr; + file_hdr.magic = 0xA1B2C3D4; + file_hdr.version_major = 0x0002; + file_hdr.version_minor = 0x0004; + file_hdr.timezone = 0x00000000; + file_hdr.sigfigs = 0x00000000; + file_hdr.frame_max_len = SWRAP_FRAME_LENGTH_MAX; + file_hdr.link_type = 0x0065; /* 101 RAW IP */ + + write(fd, &file_hdr, sizeof(file_hdr)); + return fd; + } + + fd = open(fname, O_WRONLY|O_APPEND, 0644); + + return fd; +} + static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *addr, enum swrap_packet_type type, const void *buf, size_t len) @@ -468,6 +742,10 @@ static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *add unsigned long tcp_ack = 0; unsigned char tcp_ctl = 0; int unreachable = 0; + struct timeval tv; + struct swrap_packet *packet; + size_t packet_len = 0; + int fd; file_name = socket_wrapper_pcap_file(); if (!file_name) { @@ -707,7 +985,21 @@ static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *add break; } - /* TODO: contruct the blob and write to the file */ + swrapGetTimeOfDay(&tv); + + packet = swrap_packet_init(&tv, src_addr, dest_addr, si->type, buf, len, + tcp_seq, tcp_ack, tcp_ctl, unreachable, + &packet_len); + if (!packet) { + return; + } + + fd = swrap_get_pcap_fd(file_name); + if (fd != -1) { + write(fd, packet, packet_len); + } + + free(packet); } _PUBLIC_ int swrap_socket(int family, int type, int protocol) -- cgit From 59b6b665d6f043bc372ab868e0ecd8ad4da5f2ef Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 6 Oct 2006 15:16:18 +0000 Subject: r19136: No conflict, after "svn up" it applied correctly", merge 19126 from 3_0 (This used to be commit 042a22b6dd34bb147cf4f8cc10f98d4cda3ccd55) --- source4/lib/socket_wrapper/socket_wrapper.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 006aba1e9d..9915789f0b 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -587,11 +587,11 @@ static struct swrap_packet *swrap_packet_init(struct timeval *tval, size_t packet_len; size_t alloc_len; size_t nonwire_len = sizeof(packet->frame); - size_t wire_hdr_len; - size_t wire_len; + size_t wire_hdr_len = 0; + size_t wire_len = 0; size_t icmp_hdr_len = 0; size_t icmp_truncate_len = 0; - unsigned char protocol, icmp_protocol; + unsigned char protocol = 0, icmp_protocol = 0; unsigned short src_port = src_addr->sin_port; unsigned short dest_port = dest_addr->sin_port; @@ -983,11 +983,14 @@ static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *add tcp_ctl = 0x10; /* ACK */ break; + default: + return; } swrapGetTimeOfDay(&tv); - packet = swrap_packet_init(&tv, src_addr, dest_addr, si->type, buf, len, + packet = swrap_packet_init(&tv, src_addr, dest_addr, si->type, + (const unsigned char *)buf, len, tcp_seq, tcp_ack, tcp_ctl, unreachable, &packet_len); if (!packet) { -- cgit From a3a619a3643edbf87882550d04e34484bd251fc4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 8 Oct 2006 20:48:34 +0000 Subject: r19171: change the socket wrapper license to what heimdal uses... metze (This used to be commit 9f8809a16ef837f5cdf07ed2e383893d035e96d6) --- source4/lib/socket_wrapper/socket_wrapper.c | 57 +++++++++++++++++++---------- 1 file changed, 38 insertions(+), 19 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 9915789f0b..68ee400a7b 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -1,23 +1,42 @@ -/* - Socket wrapper library. Passes all socket communication over - unix domain sockets if the environment variable SOCKET_WRAPPER_DIR +/* + * Copyright (C) Jelmer Vernooij 2005 + * Copyright (C) Stefan Metzmacher 2006 + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the author nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/* + Socket wrapper library. Passes all socket communication over + unix domain sockets if the environment variable SOCKET_WRAPPER_DIR is set. - Copyright (C) Jelmer Vernooij 2005 - Copyright (C) Stefan Metzmacher 2006 - - 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 2 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, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef _SAMBA_BUILD_ -- cgit From 5b34e585fc4b334ee4e1978bccfc39125c8408d7 Mon Sep 17 00:00:00 2001 From: Love Hörnquist Åstrand Date: Sun, 8 Oct 2006 21:09:54 +0000 Subject: r19175: If not in _SAMBA_BUILD_, define _PUBLIC_ to nothing. (This used to be commit 8c2585f0cfb7ae229de066965a732904545f0869) --- source4/lib/socket_wrapper/socket_wrapper.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 68ee400a7b..d2ef84ac22 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -74,6 +74,8 @@ #include #include +#define _PUBLIC_ + #error "dlinklist.h missing" #endif -- cgit From 9058263a6bf8d44dc8e822d0f7b871b8f1a92bc1 Mon Sep 17 00:00:00 2001 From: Love Hörnquist Åstrand Date: Sun, 8 Oct 2006 21:45:07 +0000 Subject: r19176: Also require and for non samba builds. (This used to be commit fe621c1ab277407fb62ad7bced829815b6625f22) --- source4/lib/socket_wrapper/socket_wrapper.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index d2ef84ac22..e3c0592085 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -65,10 +65,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include -- cgit From e770df4c87254598b7b88a15db3dd1e64d2ea0f6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 8 Oct 2006 21:53:09 +0000 Subject: r19178: fix the standalone build of socket_wrapper by not using samba's DLIST_ macros metze (This used to be commit 82abc39b559ccae832dd749495ebcfdffc2e5755) --- source4/lib/socket_wrapper/socket_wrapper.c | 43 +++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 9 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index e3c0592085..3a72c5a74a 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -46,10 +46,6 @@ #include "system/network.h" #include "system/filesys.h" -#ifndef _DLINKLIST_H -#include "lib/util/dlinklist.h" -#endif - #ifdef malloc #undef malloc #endif @@ -78,10 +74,39 @@ #define _PUBLIC_ -#error "dlinklist.h missing" - #endif +#define SWRAP_DLIST_ADD(list,item) do { \ + if (!(list)) { \ + (item)->prev = NULL; \ + (item)->next = NULL; \ + (list) = (item); \ + } else { \ + (item)->prev = NULL; \ + (item)->next = (list); \ + (list)->prev = (item); \ + (list) = (item); \ + } \ +} while (0) + +#define SWRAP_DLIST_REMOVE(list,item) do { \ + if ((list) == (item)) { \ + (list) = (item)->next; \ + if (list) { \ + (list)->prev = NULL; \ + } \ + } else { \ + if ((item)->prev) { \ + (item)->prev->next = (item)->next; \ + } \ + if ((item)->next) { \ + (item)->next->prev = (item)->prev; \ + } \ + } \ + (item)->prev = NULL; \ + (item)->next = NULL; \ +} while (0) + /* LD_PRELOAD doesn't work yet, so REWRITE_CALLS is all we support * for now */ #define REWRITE_CALLS @@ -1076,7 +1101,7 @@ _PUBLIC_ int swrap_socket(int family, int type, int protocol) si->protocol = protocol; si->fd = fd; - DLIST_ADD(sockets, si); + SWRAP_DLIST_ADD(sockets, si); return si->fd; } @@ -1145,7 +1170,7 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) child_si->peername_len = *addrlen; child_si->peername = sockaddr_dup(addr, *addrlen); - DLIST_ADD(sockets, child_si); + SWRAP_DLIST_ADD(sockets, child_si); swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0); swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_RECV, NULL, 0); @@ -1545,7 +1570,7 @@ _PUBLIC_ int swrap_close(int fd) return real_close(fd); } - DLIST_REMOVE(sockets, si); + SWRAP_DLIST_REMOVE(sockets, si); if (si->myname && si->peername) { swrap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0); -- cgit From 38d4fe0d53818110463fbf56e59ab597fde4e624 Mon Sep 17 00:00:00 2001 From: Love Hörnquist Åstrand Date: Tue, 17 Oct 2006 09:35:45 +0000 Subject: r19367: Solaris needs for FIONREAD. (This used to be commit e2866ce78851a84c937408c0781fcc1e7107f663) --- source4/lib/socket_wrapper/socket_wrapper.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 3a72c5a74a..36d6801d69 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include -- cgit From 97ccda014dd3e2c1a8f18cc79e67f2a13244fc4b Mon Sep 17 00:00:00 2001 From: Love Hörnquist Åstrand Date: Thu, 19 Oct 2006 04:56:21 +0000 Subject: r19409: Pull in for struct timeval for non samba build (don't depend on namespace pollution) (This used to be commit 5052d2d10693e67f1b7c6c71277c8d1bc9c8b612) --- source4/lib/socket_wrapper/socket_wrapper.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 36d6801d69..3f2020d266 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -59,6 +59,7 @@ #else /* _SAMBA_BUILD_ */ #include +#include #include #include #include -- cgit From 1cc7b6e7397444a859c78e5ecc61f53dd1017436 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 3 Mar 2007 01:20:36 +0000 Subject: r21671: Add initial simple tests for socket wrapper (This used to be commit 872e2ad541478597191ca9e31872d5c8e2bbb832) --- source4/lib/socket_wrapper/socket_wrapper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 3f2020d266..8eff6a49ac 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -187,7 +187,7 @@ struct socket_info static struct socket_info *sockets; -static const char *socket_wrapper_dir(void) +const char *socket_wrapper_dir(void) { const char *s = getenv("SOCKET_WRAPPER_DIR"); if (s == NULL) { -- cgit From effbda4fd8c648dd9900e5451e04bc8438ac7c73 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 6 Mar 2007 23:03:34 +0000 Subject: r21729: Some more tests (This used to be commit d2baa8218cf504d6631d610f9fd393ad8c61574c) --- source4/lib/socket_wrapper/socket_wrapper.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 8eff6a49ac..3e3d384f85 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -199,15 +199,14 @@ const char *socket_wrapper_dir(void) return s; } -static unsigned int socket_wrapper_default_iface(void) +unsigned int socket_wrapper_default_iface(void) { const char *s = getenv("SOCKET_WRAPPER_DEFAULT_IFACE"); if (s) { unsigned int iface; - if (sscanf(s, "%u", &iface) == 1) { - if (iface >= 1 && iface <= MAX_WRAPPED_INTERFACES) { - return iface; - } + iface = atoi(s); + if (iface >= 1 && iface <= MAX_WRAPPED_INTERFACES) { + return iface; } } -- cgit From cb8ed81b64e78c85c2ffbcacd92b23e35a2b89af Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 16 Apr 2007 04:59:47 +0000 Subject: r22236: Update to Heimdal's socket_wrapper, which supports IPv6. To make this pass, I needed to add support for 6 and 17 as valid protocol values to socket(). Andrew Bartlett (This used to be commit 2254e61a1e5b29a64c5a24aac029ace193057e24) --- source4/lib/socket_wrapper/socket_wrapper.c | 552 ++++++++++++++++++++-------- 1 file changed, 391 insertions(+), 161 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 3e3d384f85..84c323cfed 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -146,9 +146,13 @@ #define SOCKET_FORMAT "%c%02X%04X" #define SOCKET_TYPE_CHAR_TCP 'T' #define SOCKET_TYPE_CHAR_UDP 'U' +#define SOCKET_TYPE_CHAR_TCP_V6 'X' +#define SOCKET_TYPE_CHAR_UDP_V6 'Y' #define MAX_WRAPPED_INTERFACES 16 +#define SW_IPV6_ADDRESS 1 + static struct sockaddr *sockaddr_dup(const void *data, socklen_t len) { struct sockaddr *ret = (struct sockaddr *)malloc(len); @@ -156,6 +160,35 @@ static struct sockaddr *sockaddr_dup(const void *data, socklen_t len) return ret; } +static void set_port(int family, int prt, struct sockaddr *addr) +{ + switch (family) { + case AF_INET: + ((struct sockaddr_in *)addr)->sin_port = htons(prt); + break; +#ifdef HAVE_IPV6 + case AF_INET6: + ((struct sockaddr_in6 *)addr)->sin6_port = htons(prt); + break; +#endif + } +} + +static int socket_length(int family) +{ + switch (family) { + case AF_INET: + return sizeof(struct sockaddr_in); +#ifdef HAVE_IPV6 + case AF_INET6: + return sizeof(struct sockaddr_in6); +#endif + } + return -1; +} + + + struct socket_info { int fd; @@ -204,26 +237,23 @@ unsigned int socket_wrapper_default_iface(void) const char *s = getenv("SOCKET_WRAPPER_DEFAULT_IFACE"); if (s) { unsigned int iface; - iface = atoi(s); - if (iface >= 1 && iface <= MAX_WRAPPED_INTERFACES) { - return iface; + if (sscanf(s, "%u", &iface) == 1) { + if (iface >= 1 && iface <= MAX_WRAPPED_INTERFACES) { + return iface; + } } } return 1;/* 127.0.0.1 */ } -static int convert_un_in(const struct sockaddr_un *un, struct sockaddr_in *in, socklen_t *len) +static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, socklen_t *len) { unsigned int iface; unsigned int prt; const char *p; char type; - if ((*len) < sizeof(struct sockaddr_in)) { - return 0; - } - p = strrchr(un->sun_path, '/'); if (p) p++; else p = un->sun_path; @@ -232,80 +262,145 @@ static int convert_un_in(const struct sockaddr_un *un, struct sockaddr_in *in, s return -1; } - if (type != SOCKET_TYPE_CHAR_TCP && type != SOCKET_TYPE_CHAR_UDP) { + if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) { errno = EINVAL; return -1; } - if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) { + if (prt > 0xFFFF) { errno = EINVAL; return -1; } - if (prt > 0xFFFF) { + switch(type) { + case SOCKET_TYPE_CHAR_TCP: + case SOCKET_TYPE_CHAR_UDP: { + struct sockaddr_in *in2 = (struct sockaddr_in *)in; + + if ((*len) < sizeof(*in2)) { + errno = EINVAL; + return -1; + } + + memset(in2, 0, sizeof(*in2)); + in2->sin_family = AF_INET; + in2->sin_addr.s_addr = htonl((127<<24) | iface); + in2->sin_port = htons(prt); + + *len = sizeof(*in2); + break; + } +#ifdef HAVE_IPV6 + case SOCKET_TYPE_CHAR_TCP_V6: + case SOCKET_TYPE_CHAR_UDP_V6: { + struct sockaddr_in6 *in2 = (struct sockaddr_in6 *)in; + + if ((*len) < sizeof(*in2)) { + errno = EINVAL; + return -1; + } + + memset(in2, 0, sizeof(*in2)); + in2->sin6_family = AF_INET6; + in2->sin6_addr.s6_addr[0] = SW_IPV6_ADDRESS; + in2->sin6_port = htons(prt); + + *len = sizeof(*in2); + break; + } +#endif + default: errno = EINVAL; return -1; } - in->sin_family = AF_INET; - in->sin_addr.s_addr = htonl((127<<24) | iface); - in->sin_port = htons(prt); - - *len = sizeof(struct sockaddr_in); return 0; } -static int convert_in_un_remote(struct socket_info *si, const struct sockaddr_in *in, struct sockaddr_un *un, +static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un, int *bcast) { - char u_type = '\0'; - char b_type = '\0'; - char a_type = '\0'; char type = '\0'; - unsigned int addr= ntohl(in->sin_addr.s_addr); - unsigned int prt = ntohs(in->sin_port); + unsigned int prt; unsigned int iface; int is_bcast = 0; if (bcast) *bcast = 0; - if (prt == 0) { - errno = EINVAL; - return -1; - } + switch (si->family) { + case AF_INET: { + const struct sockaddr_in *in = + (const struct sockaddr_in *)inaddr; + unsigned int addr = ntohl(in->sin_addr.s_addr); + char u_type = '\0'; + char b_type = '\0'; + char a_type = '\0'; - switch (si->type) { - case SOCK_STREAM: - u_type = SOCKET_TYPE_CHAR_TCP; - break; - case SOCK_DGRAM: - u_type = SOCKET_TYPE_CHAR_UDP; - a_type = SOCKET_TYPE_CHAR_UDP; - b_type = SOCKET_TYPE_CHAR_UDP; + switch (si->type) { + case SOCK_STREAM: + u_type = SOCKET_TYPE_CHAR_TCP; + break; + case SOCK_DGRAM: + u_type = SOCKET_TYPE_CHAR_UDP; + a_type = SOCKET_TYPE_CHAR_UDP; + b_type = SOCKET_TYPE_CHAR_UDP; + break; + } + + prt = ntohs(in->sin_port); + if (a_type && addr == 0xFFFFFFFF) { + /* 255.255.255.255 only udp */ + is_bcast = 2; + type = a_type; + iface = socket_wrapper_default_iface(); + } else if (b_type && addr == 0x7FFFFFFF) { + /* 127.255.255.255 only udp */ + is_bcast = 1; + type = b_type; + iface = socket_wrapper_default_iface(); + } else if ((addr & 0xFFFFFF00) == 0x7F000000) { + /* 127.0.0.X */ + is_bcast = 0; + type = u_type; + iface = (addr & 0x000000FF); + } else { + errno = ENETUNREACH; + return -1; + } + if (bcast) *bcast = is_bcast; break; } +#ifdef HAVE_IPV6 + case AF_INET6: { + const struct sockaddr_in6 *in = + (const struct sockaddr_in6 *)inaddr; - if (a_type && addr == 0xFFFFFFFF) { - /* 255.255.255.255 only udp */ - is_bcast = 2; - type = a_type; - iface = socket_wrapper_default_iface(); - } else if (b_type && addr == 0x7FFFFFFF) { - /* 127.255.255.255 only udp */ - is_bcast = 1; - type = b_type; - iface = socket_wrapper_default_iface(); - } else if ((addr & 0xFFFFFF00) == 0x7F000000) { - /* 127.0.0.X */ - is_bcast = 0; - type = u_type; - iface = (addr & 0x000000FF); - } else { + switch (si->type) { + case SOCK_STREAM: + type = SOCKET_TYPE_CHAR_TCP_V6; + break; + case SOCK_DGRAM: + type = SOCKET_TYPE_CHAR_UDP_V6; + break; + } + + /* XXX no multicast/broadcast */ + + prt = ntohs(in->sin6_port); + iface = SW_IPV6_ADDRESS; + + break; + } +#endif + default: errno = ENETUNREACH; return -1; } - if (bcast) *bcast = is_bcast; + if (prt == 0) { + errno = EINVAL; + return -1; + } if (is_bcast) { snprintf(un->sun_path, sizeof(un->sun_path), "%s/EINVAL", @@ -320,60 +415,96 @@ static int convert_in_un_remote(struct socket_info *si, const struct sockaddr_in return 0; } -static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr_in *in, struct sockaddr_un *un, +static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un, int *bcast) { - char u_type = '\0'; - char d_type = '\0'; - char b_type = '\0'; - char a_type = '\0'; char type = '\0'; - unsigned int addr= ntohl(in->sin_addr.s_addr); - unsigned int prt = ntohs(in->sin_port); + unsigned int prt; unsigned int iface; struct stat st; int is_bcast = 0; if (bcast) *bcast = 0; - switch (si->type) { - case SOCK_STREAM: - u_type = SOCKET_TYPE_CHAR_TCP; - d_type = SOCKET_TYPE_CHAR_TCP; - break; - case SOCK_DGRAM: - u_type = SOCKET_TYPE_CHAR_UDP; - d_type = SOCKET_TYPE_CHAR_UDP; - a_type = SOCKET_TYPE_CHAR_UDP; - b_type = SOCKET_TYPE_CHAR_UDP; + switch (si->family) { + case AF_INET: { + const struct sockaddr_in *in = + (const struct sockaddr_in *)inaddr; + unsigned int addr = ntohl(in->sin_addr.s_addr); + char u_type = '\0'; + char d_type = '\0'; + char b_type = '\0'; + char a_type = '\0'; + + prt = ntohs(in->sin_port); + + switch (si->type) { + case SOCK_STREAM: + u_type = SOCKET_TYPE_CHAR_TCP; + d_type = SOCKET_TYPE_CHAR_TCP; + break; + case SOCK_DGRAM: + u_type = SOCKET_TYPE_CHAR_UDP; + d_type = SOCKET_TYPE_CHAR_UDP; + a_type = SOCKET_TYPE_CHAR_UDP; + b_type = SOCKET_TYPE_CHAR_UDP; + break; + } + + if (addr == 0) { + /* 0.0.0.0 */ + is_bcast = 0; + type = d_type; + iface = socket_wrapper_default_iface(); + } else if (a_type && addr == 0xFFFFFFFF) { + /* 255.255.255.255 only udp */ + is_bcast = 2; + type = a_type; + iface = socket_wrapper_default_iface(); + } else if (b_type && addr == 0x7FFFFFFF) { + /* 127.255.255.255 only udp */ + is_bcast = 1; + type = b_type; + iface = socket_wrapper_default_iface(); + } else if ((addr & 0xFFFFFF00) == 0x7F000000) { + /* 127.0.0.X */ + is_bcast = 0; + type = u_type; + iface = (addr & 0x000000FF); + } else { + errno = EADDRNOTAVAIL; + return -1; + } break; } +#ifdef HAVE_IPV6 + case AF_INET6: { + const struct sockaddr_in6 *in = + (const struct sockaddr_in6 *)inaddr; - if (addr == 0) { - /* 0.0.0.0 */ - is_bcast = 0; - type = d_type; - iface = socket_wrapper_default_iface(); - } else if (a_type && addr == 0xFFFFFFFF) { - /* 255.255.255.255 only udp */ - is_bcast = 2; - type = a_type; - iface = socket_wrapper_default_iface(); - } else if (b_type && addr == 0x7FFFFFFF) { - /* 127.255.255.255 only udp */ - is_bcast = 1; - type = b_type; - iface = socket_wrapper_default_iface(); - } else if ((addr & 0xFFFFFF00) == 0x7F000000) { - /* 127.0.0.X */ - is_bcast = 0; - type = u_type; - iface = (addr & 0x000000FF); - } else { - errno = EADDRNOTAVAIL; + switch (si->type) { + case SOCK_STREAM: + type = SOCKET_TYPE_CHAR_TCP_V6; + break; + case SOCK_DGRAM: + type = SOCKET_TYPE_CHAR_UDP_V6; + break; + } + + /* XXX no multicast/broadcast */ + + prt = ntohs(in->sin6_port); + iface = SW_IPV6_ADDRESS; + + break; + } +#endif + default: + errno = ENETUNREACH; return -1; } + if (bcast) *bcast = is_bcast; if (prt == 0) { @@ -383,11 +514,13 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr_in socket_wrapper_dir(), type, iface, prt); if (stat(un->sun_path, &st) == 0) continue; - ((struct sockaddr_in *)si->myname)->sin_port = htons(prt); - return 0; + set_port(si->family, prt, si->myname); + break; + } + if (prt == 10000) { + errno = ENFILE; + return -1; } - errno = ENFILE; - return -1; } snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, @@ -416,6 +549,9 @@ static int sockaddr_convert_to_un(struct socket_info *si, const struct sockaddr switch (in_addr->sa_family) { case AF_INET: +#ifdef HAVE_IPV6 + case AF_INET6: +#endif switch (si->type) { case SOCK_STREAM: case SOCK_DGRAM: @@ -425,9 +561,9 @@ static int sockaddr_convert_to_un(struct socket_info *si, const struct sockaddr return -1; } if (alloc_sock) { - return convert_in_un_alloc(si, (const struct sockaddr_in *)in_addr, out_addr, bcast); + return convert_in_un_alloc(si, in_addr, out_addr, bcast); } else { - return convert_in_un_remote(si, (const struct sockaddr_in *)in_addr, out_addr, bcast); + return convert_in_un_remote(si, in_addr, out_addr, bcast); } default: break; @@ -442,25 +578,21 @@ static int sockaddr_convert_from_un(const struct socket_info *si, socklen_t un_addrlen, int family, struct sockaddr *out_addr, - socklen_t *_out_addrlen) + socklen_t *out_addrlen) { - socklen_t out_addrlen; - - if (out_addr == NULL || _out_addrlen == NULL) + if (out_addr == NULL || out_addrlen == NULL) return 0; if (un_addrlen == 0) { - *_out_addrlen = 0; + *out_addrlen = 0; return 0; } - out_addrlen = *_out_addrlen; - if (out_addrlen > un_addrlen) { - out_addrlen = un_addrlen; - } - switch (family) { case AF_INET: +#ifdef HAVE_IPV6 + case AF_INET6: +#endif switch (si->type) { case SOCK_STREAM: case SOCK_DGRAM: @@ -469,7 +601,7 @@ static int sockaddr_convert_from_un(const struct socket_info *si, errno = ESOCKTNOSUPPORT; return -1; } - return convert_un_in(in_addr, (struct sockaddr_in *)out_addr, _out_addrlen); + return convert_un_in(in_addr, out_addr, out_addrlen); default: break; } @@ -801,7 +933,13 @@ static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *add return; } - if (si->family != AF_INET) { + switch (si->family) { + case AF_INET: +#ifdef HAVE_IPV6 + case AF_INET6: +#endif + break; + default: return; } @@ -1065,6 +1203,9 @@ _PUBLIC_ int swrap_socket(int family, int type, int protocol) switch (family) { case AF_INET: +#ifdef HAVE_IPV6 + case AF_INET6: +#endif break; case AF_UNIX: return real_socket(family, type, protocol); @@ -1086,6 +1227,14 @@ _PUBLIC_ int swrap_socket(int family, int type, int protocol) switch (protocol) { case 0: break; + case 6: + if (type == SOCK_STREAM) { + break; + } + case 17: + if (type == SOCK_DGRAM) { + break; + } default: errno = EPROTONOSUPPORT; return -1; @@ -1115,8 +1264,8 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) socklen_t un_addrlen = sizeof(un_addr); struct sockaddr_un un_my_addr; socklen_t un_my_addrlen = sizeof(un_my_addr); - struct sockaddr my_addr; - socklen_t my_addrlen = sizeof(my_addr); + struct sockaddr *my_addr; + socklen_t my_addrlen, len; int ret; parent_si = find_socket_info(s); @@ -1124,18 +1273,37 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) return real_accept(s, addr, addrlen); } + /* + * assume out sockaddr have the same size as the in parent + * socket family + */ + my_addrlen = socket_length(parent_si->family); + if (my_addrlen < 0) { + errno = EINVAL; + return -1; + } + + my_addr = malloc(my_addrlen); + if (my_addr == NULL) { + return -1; + } + memset(&un_addr, 0, sizeof(un_addr)); memset(&un_my_addr, 0, sizeof(un_my_addr)); - memset(&my_addr, 0, sizeof(my_addr)); ret = real_accept(s, (struct sockaddr *)&un_addr, &un_addrlen); - if (ret == -1) return ret; + if (ret == -1) { + free(my_addr); + return ret; + } fd = ret; + len = my_addrlen; ret = sockaddr_convert_from_un(parent_si, &un_addr, un_addrlen, - parent_si->family, addr, addrlen); + parent_si->family, my_addr, &len); if (ret == -1) { + free(my_addr); close(fd); return ret; } @@ -1150,6 +1318,16 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) child_si->bound = 1; child_si->is_server = 1; + child_si->peername_len = len; + child_si->peername = sockaddr_dup(my_addr, len); + + if (addr != NULL && addrlen != NULL) { + *addrlen = len; + if (*addrlen >= len) + memcpy(addr, my_addr, len); + *addrlen = 0; + } + ret = real_getsockname(fd, (struct sockaddr *)&un_my_addr, &un_my_addrlen); if (ret == -1) { free(child_si); @@ -1157,19 +1335,19 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) return ret; } + len = my_addrlen; ret = sockaddr_convert_from_un(child_si, &un_my_addr, un_my_addrlen, - child_si->family, &my_addr, &my_addrlen); + child_si->family, my_addr, &len); if (ret == -1) { free(child_si); + free(my_addr); close(fd); return ret; } - child_si->myname_len = my_addrlen; - child_si->myname = sockaddr_dup(&my_addr, my_addrlen); - - child_si->peername_len = *addrlen; - child_si->peername = sockaddr_dup(addr, *addrlen); + child_si->myname_len = len; + child_si->myname = sockaddr_dup(my_addr, len); + free(my_addr); SWRAP_DLIST_ADD(sockets, child_si); @@ -1190,7 +1368,6 @@ static int autobind_start; static int swrap_auto_bind(struct socket_info *si) { struct sockaddr_un un_addr; - struct sockaddr_in in; int i; char type; int ret; @@ -1206,13 +1383,55 @@ static int swrap_auto_bind(struct socket_info *si) un_addr.sun_family = AF_UNIX; - switch (si->type) { - case SOCK_STREAM: - type = SOCKET_TYPE_CHAR_TCP; + switch (si->family) { + case AF_INET: { + struct sockaddr_in in; + + switch (si->type) { + case SOCK_STREAM: + type = SOCKET_TYPE_CHAR_TCP; + break; + case SOCK_DGRAM: + type = SOCKET_TYPE_CHAR_UDP; + break; + default: + errno = ESOCKTNOSUPPORT; + return -1; + } + + memset(&in, 0, sizeof(in)); + in.sin_family = AF_INET; + in.sin_addr.s_addr = htonl(127<<24 | + socket_wrapper_default_iface()); + + si->myname_len = sizeof(in); + si->myname = sockaddr_dup(&in, si->myname_len); break; - case SOCK_DGRAM: - type = SOCKET_TYPE_CHAR_UDP; + } +#ifdef HAVE_IPV6 + case AF_INET6: { + struct sockaddr_in6 in6; + + switch (si->type) { + case SOCK_STREAM: + type = SOCKET_TYPE_CHAR_TCP_V6; + break; + case SOCK_DGRAM: + type = SOCKET_TYPE_CHAR_UDP_V6; + break; + default: + errno = ESOCKTNOSUPPORT; + return -1; + } + + memset(&in6, 0, sizeof(in6)); + in6.sin6_family = AF_INET6; + in6.sin6_addr.s6_addr[0] = SW_IPV6_ADDRESS; + si->myname_len = sizeof(in6); + si->myname = sockaddr_dup(&in6, si->myname_len); break; + } +#endif default: errno = ESOCKTNOSUPPORT; return -1; @@ -1242,13 +1461,8 @@ static int swrap_auto_bind(struct socket_info *si) return -1; } - memset(&in, 0, sizeof(in)); - in.sin_family = AF_INET; - in.sin_port = htons(port); - in.sin_addr.s_addr = htonl(127<<24 | socket_wrapper_default_iface()); - - si->myname_len = sizeof(in); - si->myname = sockaddr_dup(&in, si->myname_len); + set_port(si->family, port, si->myname); + return 0; } @@ -1268,6 +1482,11 @@ _PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t ad if (ret == -1) return -1; } + if (si->family != serv_addr->sa_family) { + errno = EINVAL; + return -1; + } + ret = sockaddr_convert_to_un(si, (const struct sockaddr *)serv_addr, addrlen, &un_addr, 0, NULL); if (ret == -1) return -1; @@ -1446,38 +1665,49 @@ _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, con return real_sendto(s, buf, len, flags, to, tolen); } - if (si->bound == 0) { - ret = swrap_auto_bind(si); + switch (si->type) { + case SOCK_STREAM: + ret = real_send(s, buf, len, flags); + break; + case SOCK_DGRAM: + if (si->bound == 0) { + ret = swrap_auto_bind(si); + if (ret == -1) return -1; + } + + ret = sockaddr_convert_to_un(si, to, tolen, &un_addr, 0, &bcast); if (ret == -1) return -1; - } - - ret = sockaddr_convert_to_un(si, to, tolen, &un_addr, 0, &bcast); - if (ret == -1) return -1; - - if (bcast) { - struct stat st; - unsigned int iface; - unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port); - char type; - - type = SOCKET_TYPE_CHAR_UDP; - - for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) { - snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT, - socket_wrapper_dir(), type, iface, prt); - if (stat(un_addr.sun_path, &st) != 0) continue; - - /* ignore the any errors in broadcast sends */ - real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr)); + + if (bcast) { + struct stat st; + unsigned int iface; + unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port); + char type; + + type = SOCKET_TYPE_CHAR_UDP; + + for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) { + snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT, + socket_wrapper_dir(), type, iface, prt); + if (stat(un_addr.sun_path, &st) != 0) continue; + + /* ignore the any errors in broadcast sends */ + real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr)); + } + + swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len); + + return len; } - - swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len); - - return len; + + ret = real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr)); + break; + default: + ret = -1; + errno = EHOSTUNREACH; + break; } - - ret = real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr)); - + /* to give better errors */ if (ret == -1 && errno == ENOENT) { errno = EHOSTUNREACH; -- cgit From ac00b6517e08977f44e7a3b106b97b899881d6aa Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 11 Jun 2007 14:41:14 +0000 Subject: r23420: try to make the IBM checker happy metze (This used to be commit 96f1a0dfaa18a432fca4b5432d929d8daed0abb1) --- source4/lib/socket_wrapper/socket_wrapper.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 84c323cfed..ec074ecaeb 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -174,7 +174,7 @@ static void set_port(int family, int prt, struct sockaddr *addr) } } -static int socket_length(int family) +static size_t socket_length(int family) { switch (family) { case AF_INET: @@ -184,7 +184,7 @@ static int socket_length(int family) return sizeof(struct sockaddr_in6); #endif } - return -1; + return 0; } @@ -788,6 +788,9 @@ static struct swrap_packet *swrap_packet_init(struct timeval *tval, wire_hdr_len = sizeof(packet->ip.hdr) + sizeof(packet->ip.p.udp); wire_len = wire_hdr_len + payload_len; break; + + default: + return NULL; } if (unreachable) { @@ -1231,10 +1234,12 @@ _PUBLIC_ int swrap_socket(int family, int type, int protocol) if (type == SOCK_STREAM) { break; } + /*fall through*/ case 17: if (type == SOCK_DGRAM) { break; } + /*fall through*/ default: errno = EPROTONOSUPPORT; return -1; @@ -1278,7 +1283,7 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) * socket family */ my_addrlen = socket_length(parent_si->family); - if (my_addrlen < 0) { + if (my_addrlen <= 0) { errno = EINVAL; return -1; } -- cgit From dccf3f99e45137b6cd18c1de1c79808ad67130d1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Sep 2007 13:27:14 +0000 Subject: r25027: Fix more warnings. (This used to be commit 5085c53fcfade614e83d21fc2c1a5bc43bb2a729) --- source4/lib/socket_wrapper/socket_wrapper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index ec074ecaeb..8458c61592 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -232,7 +232,7 @@ const char *socket_wrapper_dir(void) return s; } -unsigned int socket_wrapper_default_iface(void) +static unsigned int socket_wrapper_default_iface(void) { const char *s = getenv("SOCKET_WRAPPER_DEFAULT_IFACE"); if (s) { @@ -1288,7 +1288,7 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) return -1; } - my_addr = malloc(my_addrlen); + my_addr = (struct sockaddr *)malloc(my_addrlen); if (my_addr == NULL) { return -1; } -- cgit From 7a287e07043cf937e22f8051c1a324d8a30c53e1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Sep 2007 13:34:42 +0000 Subject: r25028: Fix more warnings. (This used to be commit 3aa7ee4a0d8837471deeaa1c5a1f4a0d2a14aa6e) --- source4/lib/socket_wrapper/socket_wrapper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 8458c61592..c13cb6a3b0 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -232,7 +232,7 @@ const char *socket_wrapper_dir(void) return s; } -static unsigned int socket_wrapper_default_iface(void) +unsigned int socket_wrapper_default_iface(void) { const char *s = getenv("SOCKET_WRAPPER_DEFAULT_IFACE"); if (s) { -- cgit From f603a0c579745c1ee910075f6a40fdd904658317 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 1 Nov 2007 13:10:59 +0100 Subject: r25783: socket_wrapper: don't include "includes.h" metze (This used to be commit 47f865165e772540334dcbcf80cfc1999b0132fa) --- source4/lib/socket_wrapper/socket_wrapper.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index c13cb6a3b0..574d8ec5e4 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -42,19 +42,10 @@ #ifdef _SAMBA_BUILD_ #define SOCKET_WRAPPER_NOT_REPLACE -#include "includes.h" +#include "lib/replace/replace.h" #include "system/network.h" #include "system/filesys.h" - -#ifdef malloc -#undef malloc -#endif -#ifdef calloc -#undef calloc -#endif -#ifdef strdup -#undef strdup -#endif +#include "system/time.h" #else /* _SAMBA_BUILD_ */ @@ -74,8 +65,10 @@ #include #include -#define _PUBLIC_ +#endif +#ifndef _PUBLIC_ +#define _PUBLIC_ #endif #define SWRAP_DLIST_ADD(list,item) do { \ -- cgit From 15b86081cd2df734479fcaf92a482c7896bef605 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 19 Feb 2008 23:53:04 +0100 Subject: Factor out IP marshalling into separate function. (This used to be commit 2548c2a1e7dab8abc00f8f49374a08cc0b427552) --- source4/lib/socket_wrapper/socket_wrapper.c | 79 ++++++++++++++++------------- 1 file changed, 43 insertions(+), 36 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 574d8ec5e4..644365a665 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -1,5 +1,5 @@ /* - * Copyright (C) Jelmer Vernooij 2005 + * Copyright (C) Jelmer Vernooij 2005,2008 * Copyright (C) Stefan Metzmacher 2006 * * All rights reserved. @@ -212,7 +212,6 @@ struct socket_info static struct socket_info *sockets; - const char *socket_wrapper_dir(void) { const char *s = getenv("SOCKET_WRAPPER_DIR"); @@ -908,40 +907,31 @@ static int swrap_get_pcap_fd(const char *fname) return fd; } -static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *addr, - enum swrap_packet_type type, - const void *buf, size_t len) +static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, + const struct sockaddr *addr, + enum swrap_packet_type type, + const void *buf, size_t len, + size_t *packet_len) { const struct sockaddr_in *src_addr; const struct sockaddr_in *dest_addr; - const char *file_name; unsigned long tcp_seq = 0; unsigned long tcp_ack = 0; unsigned char tcp_ctl = 0; int unreachable = 0; - struct timeval tv; - struct swrap_packet *packet; - size_t packet_len = 0; - int fd; - file_name = socket_wrapper_pcap_file(); - if (!file_name) { - return; - } + struct timeval tv; switch (si->family) { case AF_INET: -#ifdef HAVE_IPV6 - case AF_INET6: -#endif break; default: - return; + return NULL; } switch (type) { case SWRAP_CONNECT_SEND: - if (si->type != SOCK_STREAM) return; + if (si->type != SOCK_STREAM) return NULL; src_addr = (const struct sockaddr_in *)si->myname; dest_addr = (const struct sockaddr_in *)addr; @@ -955,7 +945,7 @@ static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *add break; case SWRAP_CONNECT_RECV: - if (si->type != SOCK_STREAM) return; + if (si->type != SOCK_STREAM) return NULL; dest_addr = (const struct sockaddr_in *)si->myname; src_addr = (const struct sockaddr_in *)addr; @@ -969,7 +959,7 @@ static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *add break; case SWRAP_CONNECT_UNREACH: - if (si->type != SOCK_STREAM) return; + if (si->type != SOCK_STREAM) return NULL; dest_addr = (const struct sockaddr_in *)si->myname; src_addr = (const struct sockaddr_in *)addr; @@ -983,7 +973,7 @@ static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *add break; case SWRAP_CONNECT_ACK: - if (si->type != SOCK_STREAM) return; + if (si->type != SOCK_STREAM) return NULL; src_addr = (const struct sockaddr_in *)si->myname; dest_addr = (const struct sockaddr_in *)addr; @@ -995,7 +985,7 @@ static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *add break; case SWRAP_ACCEPT_SEND: - if (si->type != SOCK_STREAM) return; + if (si->type != SOCK_STREAM) return NULL; dest_addr = (const struct sockaddr_in *)si->myname; src_addr = (const struct sockaddr_in *)addr; @@ -1009,7 +999,7 @@ static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *add break; case SWRAP_ACCEPT_RECV: - if (si->type != SOCK_STREAM) return; + if (si->type != SOCK_STREAM) return NULL; src_addr = (const struct sockaddr_in *)si->myname; dest_addr = (const struct sockaddr_in *)addr; @@ -1023,7 +1013,7 @@ static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *add break; case SWRAP_ACCEPT_ACK: - if (si->type != SOCK_STREAM) return; + if (si->type != SOCK_STREAM) return NULL; dest_addr = (const struct sockaddr_in *)si->myname; src_addr = (const struct sockaddr_in *)addr; @@ -1051,10 +1041,9 @@ static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *add src_addr = (const struct sockaddr_in *)si->peername; if (si->type == SOCK_DGRAM) { - swrap_dump_packet(si, si->peername, + return swrap_marshall_packet(si, si->peername, SWRAP_SENDTO_UNREACH, - buf, len); - return; + buf, len, packet_len); } tcp_seq = si->io.pck_rcv; @@ -1068,7 +1057,7 @@ static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *add src_addr = (const struct sockaddr_in *)si->peername; if (si->type == SOCK_DGRAM) { - return; + return NULL; } tcp_seq = si->io.pck_rcv; @@ -1094,7 +1083,7 @@ static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *add src_addr = (const struct sockaddr_in *)si->peername; if (si->type == SOCK_DGRAM) { - return; + return NULL; } tcp_seq = si->io.pck_rcv; @@ -1128,7 +1117,7 @@ static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *add break; case SWRAP_CLOSE_SEND: - if (si->type != SOCK_STREAM) return; + if (si->type != SOCK_STREAM) return NULL; src_addr = (const struct sockaddr_in *)si->myname; dest_addr = (const struct sockaddr_in *)si->peername; @@ -1142,7 +1131,7 @@ static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *add break; case SWRAP_CLOSE_RECV: - if (si->type != SOCK_STREAM) return; + if (si->type != SOCK_STREAM) return NULL; dest_addr = (const struct sockaddr_in *)si->myname; src_addr = (const struct sockaddr_in *)si->peername; @@ -1156,7 +1145,7 @@ static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *add break; case SWRAP_CLOSE_ACK: - if (si->type != SOCK_STREAM) return; + if (si->type != SOCK_STREAM) return NULL; src_addr = (const struct sockaddr_in *)si->myname; dest_addr = (const struct sockaddr_in *)si->peername; @@ -1167,15 +1156,33 @@ static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *add break; default: - return; + return NULL; } swrapGetTimeOfDay(&tv); - packet = swrap_packet_init(&tv, src_addr, dest_addr, si->type, + return swrap_packet_init(&tv, src_addr, dest_addr, si->type, (const unsigned char *)buf, len, tcp_seq, tcp_ack, tcp_ctl, unreachable, - &packet_len); + packet_len); +} + +static void swrap_dump_packet(struct socket_info *si, + const struct sockaddr *addr, + enum swrap_packet_type type, + const void *buf, size_t len) +{ + const char *file_name; + struct swrap_packet *packet; + size_t packet_len = 0; + int fd; + + file_name = socket_wrapper_pcap_file(); + if (!file_name) { + return; + } + + packet = swrap_marshall_packet(si, addr, type, buf, len, &packet_len); if (!packet) { return; } -- cgit From 3e8124bc66503f1531ace71b64262aa2c26c3800 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 17 Mar 2008 14:08:57 +0100 Subject: socket_wrapper: make pcap code more portable Now the pcap support works on x86_64. metze (This used to be commit 61a87bed61ef661d98131239976be95c6a8b4d96) --- source4/lib/socket_wrapper/socket_wrapper.c | 79 +++++++++++++++-------------- 1 file changed, 40 insertions(+), 39 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 644365a665..86d9f7a312 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -64,6 +64,7 @@ #include #include #include +#include #endif @@ -624,67 +625,67 @@ enum swrap_packet_type { }; struct swrap_file_hdr { - unsigned long magic; - unsigned short version_major; - unsigned short version_minor; - long timezone; - unsigned long sigfigs; - unsigned long frame_max_len; + uint32_t magic; + uint16_t version_major; + uint16_t version_minor; + int32_t timezone; + uint32_t sigfigs; + uint32_t frame_max_len; #define SWRAP_FRAME_LENGTH_MAX 0xFFFF - unsigned long link_type; + uint32_t link_type; }; #define SWRAP_FILE_HDR_SIZE 24 struct swrap_packet { struct { - unsigned long seconds; - unsigned long micro_seconds; - unsigned long recorded_length; - unsigned long full_length; + uint32_t seconds; + uint32_t micro_seconds; + uint32_t recorded_length; + uint32_t full_length; } frame; #define SWRAP_PACKET__FRAME_SIZE 16 struct { struct { - unsigned char ver_hdrlen; - unsigned char tos; - unsigned short packet_length; - unsigned short identification; - unsigned char flags; - unsigned char fragment; - unsigned char ttl; - unsigned char protocol; - unsigned short hdr_checksum; - unsigned long src_addr; - unsigned long dest_addr; + uint8_t ver_hdrlen; + uint8_t tos; + uint16_t packet_length; + uint16_t identification; + uint8_t flags; + uint8_t fragment; + uint8_t ttl; + uint8_t protocol; + uint16_t hdr_checksum; + uint32_t src_addr; + uint32_t dest_addr; } hdr; #define SWRAP_PACKET__IP_HDR_SIZE 20 union { struct { - unsigned short source_port; - unsigned short dest_port; - unsigned long seq_num; - unsigned long ack_num; - unsigned char hdr_length; - unsigned char control; - unsigned short window; - unsigned short checksum; - unsigned short urg; + uint16_t source_port; + uint16_t dest_port; + uint32_t seq_num; + uint32_t ack_num; + uint8_t hdr_length; + uint8_t control; + uint16_t window; + uint16_t checksum; + uint16_t urg; } tcp; #define SWRAP_PACKET__IP_P_TCP_SIZE 20 struct { - unsigned short source_port; - unsigned short dest_port; - unsigned short length; - unsigned short checksum; + uint16_t source_port; + uint16_t dest_port; + uint16_t length; + uint16_t checksum; } udp; #define SWRAP_PACKET__IP_P_UDP_SIZE 8 struct { - unsigned char type; - unsigned char code; - unsigned short checksum; - unsigned long unused; + uint8_t type; + uint8_t code; + uint16_t checksum; + uint32_t unused; } icmp; #define SWRAP_PACKET__IP_P_ICMP_SIZE 8 } p; -- cgit From 47b106c0ae8b91c9cccfc21bf8e4e416b1abfd5d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 10 Jun 2008 08:33:24 +0200 Subject: socket_wrapper: truncate packets to a 1500 byte payload Truncate sendto(), recvfrom(), send() and recv() to 1500 bytes so that're getting a correctly formatted pcap file and the result look more like real network traffic. metze (This used to be commit 5b01206f1bb2e62c08bda34b45904ec4f83ac5de) --- source4/lib/socket_wrapper/socket_wrapper.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 86d9f7a312..981df523cd 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -1643,6 +1643,8 @@ _PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct return real_recvfrom(s, buf, len, flags, from, fromlen); } + len = MIN(len, 1500); + /* irix 6.4 forgets to null terminate the sun_path string :-( */ memset(&un_addr, 0, sizeof(un_addr)); ret = real_recvfrom(s, buf, len, flags, (struct sockaddr *)&un_addr, &un_addrlen); @@ -1671,6 +1673,8 @@ _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, con return real_sendto(s, buf, len, flags, to, tolen); } + len = MIN(len, 1500); + switch (si->type) { case SOCK_STREAM: ret = real_send(s, buf, len, flags); @@ -1764,6 +1768,8 @@ _PUBLIC_ ssize_t swrap_recv(int s, void *buf, size_t len, int flags) return real_recv(s, buf, len, flags); } + len = MIN(len, 1500); + ret = real_recv(s, buf, len, flags); if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) { swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0); @@ -1786,6 +1792,8 @@ _PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags) return real_send(s, buf, len, flags); } + len = MIN(len, 1500); + ret = real_send(s, buf, len, flags); if (ret == -1) { -- cgit From c8100b48d1a747b589779a129324e49590167ae8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 10 Jun 2008 09:13:08 +0200 Subject: Some C++ warnings (partialy cherry picked from commit 5ab82d4f574f2a2e2761e9e414c66a70aeffb05d) metze (This used to be commit 4933cd49ac81454cbd4b0fc33d888585a9437b9d) --- source4/lib/socket_wrapper/socket_wrapper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 981df523cd..22186872d6 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -697,8 +697,8 @@ static const char *socket_wrapper_pcap_file(void) { static int initialized = 0; static const char *s = NULL; - static const struct swrap_file_hdr h; - static const struct swrap_packet p; + static const struct swrap_file_hdr h = { 0, }; + static const struct swrap_packet p = { 0, }; if (initialized == 1) { return s; -- cgit From 85087ce095499dbadc5e9e394c22b08e6206a6f2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 21 Dec 2007 12:11:23 -0800 Subject: Fix initialization warnings. Jeremy. (cherry picked from commit 832c093830cb3978641be3d87670fa900105da25) (This used to be commit 3a4198b1181d6b97804afebbb91dac5a8242f615) --- source4/lib/socket_wrapper/socket_wrapper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/socket_wrapper/socket_wrapper.c') diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 22186872d6..336179d837 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -698,7 +698,7 @@ static const char *socket_wrapper_pcap_file(void) static int initialized = 0; static const char *s = NULL; static const struct swrap_file_hdr h = { 0, }; - static const struct swrap_packet p = { 0, }; + static const struct swrap_packet p = { { 0, }, { { 0, }, { { 0, } } } }; if (initialized == 1) { return s; -- cgit