From 47e6b7733a2d063e5858da1f5af3408f46611b61 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 18 Sep 2006 22:12:56 +0000 Subject: r18640: move to socket_wrapper to lib/socket_wrapper/ and sync it with samba4 metze (This used to be commit 9c0e5b29f1451a90605cce7e1e032e5516b6970d) --- source3/lib/socket_wrapper/config.m4 | 22 + source3/lib/socket_wrapper/socket_wrapper.c | 891 ++++++++++++++++++++++++++++ source3/lib/socket_wrapper/socket_wrapper.h | 104 ++++ 3 files changed, 1017 insertions(+) create mode 100644 source3/lib/socket_wrapper/config.m4 create mode 100644 source3/lib/socket_wrapper/socket_wrapper.c create mode 100644 source3/lib/socket_wrapper/socket_wrapper.h (limited to 'source3/lib/socket_wrapper') diff --git a/source3/lib/socket_wrapper/config.m4 b/source3/lib/socket_wrapper/config.m4 new file mode 100644 index 0000000000..42212abc7f --- /dev/null +++ b/source3/lib/socket_wrapper/config.m4 @@ -0,0 +1,22 @@ +AC_ARG_ENABLE(socket-wrapper, +[ --enable-socket-wrapper Turn on socket wrapper library (default=no)]) + +DEFAULT_TEST_TARGET=test-noswrap +HAVE_SOCKET_WRAPPER=no + +if eval "test x$developer = xyes"; then + enable_socket_wrapper=yes +fi + +if eval "test x$enable_socket_wrapper = xyes"; then + AC_DEFINE(SOCKET_WRAPPER,1,[Use socket wrapper library]) + DEFAULT_TEST_TARGET=test-swrap + HAVE_SOCKET_WRAPPER=yes + + # this is only used for samba3 + SOCKET_WRAPPER_OBJS="lib/socket_wrapper/socket_wrapper.o" +fi + +AC_SUBST(DEFAULT_TEST_TARGET) +AC_SUBST(HAVE_SOCKET_WRAPPER) +AC_SUBST(SOCKET_WRAPPER_OBJS) diff --git a/source3/lib/socket_wrapper/socket_wrapper.c b/source3/lib/socket_wrapper/socket_wrapper.c new file mode 100644 index 0000000000..af774e1927 --- /dev/null +++ b/source3/lib/socket_wrapper/socket_wrapper.c @@ -0,0 +1,891 @@ +/* + 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_ + +#define SOCKET_WRAPPER_NOT_REPLACE +#include "includes.h" +/* +#include "system/network.h" +#include "system/filesys.h" +*/ +#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 +#include +#include +#include +#include +#include +#include +#include +#include + +#error "dlinklist.h missing" + +#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_recv recv +#define real_send send +#define real_socket socket +#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 "%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) +{ + struct sockaddr *ret = (struct sockaddr *)malloc(len); + memcpy(ret, data, len); + return ret; +} + +struct socket_info +{ + int fd; + + int family; + int type; + int protocol; + int bound; + int bcast; + + char *path; + char *tmp_path; + + struct sockaddr *myname; + socklen_t myname_len; + + struct sockaddr *peername; + socklen_t peername_len; + + struct socket_info *prev, *next; +}; + +static struct socket_info *sockets; + + +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 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"); + 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; + char type; + + if ((*len) < sizeof(struct sockaddr_in)) { + return 0; + } + + p = strrchr(un->sun_path, '/'); + if (p) p++; else p = un->sun_path; + + 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_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, + 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 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) { + /* handle auto-allocation of ephemeral ports */ + for (prt = 5001; prt < 10000; prt++) { + snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, + 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, iface, 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(struct socket_info *si, const struct sockaddr *in_addr, socklen_t in_len, + struct sockaddr_un *out_addr, int alloc_sock, int *bcast) +{ + if (!out_addr) + return 0; + + out_addr->sun_family = AF_UNIX; + + switch (in_addr->sa_family) { + case AF_INET: + 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); + } + default: + break; + } + + errno = EAFNOSUPPORT; + return -1; +} + +static int sockaddr_convert_from_un(const struct socket_info *si, + const struct sockaddr_un *in_addr, + socklen_t un_addrlen, + int family, + struct sockaddr *out_addr, + socklen_t *_out_addrlen) +{ + socklen_t out_addrlen; + + if (out_addr == NULL || _out_addrlen == NULL) + return 0; + + if (un_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: + 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_addrlen); + default: + break; + } + + errno = EAFNOSUPPORT; + return -1; +} + +enum swrap_packet_type { + SWRAP_CONNECT, + SWRAP_ACCEPT, + SWRAP_RECVFROM, + SWRAP_SENDTO, + SWRAP_RECV, + 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; + } + +} + +_PUBLIC_ int swrap_socket(int family, int type, int protocol) +{ + struct socket_info *si; + int fd; + + if (!socket_wrapper_dir()) { + return real_socket(family, type, protocol); + } + + switch (family) { + case AF_INET: + break; + case AF_UNIX: + return real_socket(family, type, protocol); + default: + errno = EAFNOSUPPORT; + return -1; + } + + fd = real_socket(AF_UNIX, type, 0); + + if (fd == -1) return -1; + + si = calloc(1, sizeof(struct socket_info)); + + si->family = family; + si->type = type; + si->protocol = protocol; + si->fd = fd; + + DLIST_ADD(sockets, si); + + return si->fd; +} + +_PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) +{ + struct socket_info *parent_si, *child_si; + int fd; + 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); + if (!parent_si) { + return real_accept(s, addr, 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; + + fd = ret; + + ret = sockaddr_convert_from_un(parent_si, &un_addr, un_addrlen, + parent_si->family, addr, addrlen); + if (ret == -1) { + close(fd); + return ret; + } + + child_si = malloc(sizeof(struct socket_info)); + memset(child_si, 0, sizeof(*child_si)); + + child_si->fd = fd; + child_si->family = parent_si->family; + child_si->type = parent_si->type; + child_si->protocol = parent_si->protocol; + child_si->bound = 1; + + ret = real_getsockname(fd, (struct sockaddr *)&un_my_addr, &un_my_addrlen); + 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) { + free(child_si); + 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); + + DLIST_ADD(sockets, child_si); + + swrap_dump_packet(child_si, addr, SWRAP_ACCEPT, NULL, 0, 0); + + 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; + char type; + int ret; + int port; + 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++) { + port = 10000 + i; + snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), + "%s/"SOCKET_FORMAT, socket_wrapper_dir(), + 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)); + 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(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); + si->bound = 1; + return 0; +} + + +_PUBLIC_ 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); + } + + if (si->bound == 0) { + ret = swrap_auto_bind(si); + if (ret == -1) return -1; + } + + 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 (ret == -1 && errno == ENOENT) { + errno = EHOSTUNREACH; + } + + 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); + + return ret; +} + +_PUBLIC_ 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); + } + + si->myname_len = addrlen; + si->myname = sockaddr_dup(myaddr, addrlen); + + 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); + + ret = real_bind(s, (struct sockaddr *)&un_addr, + sizeof(struct sockaddr_un)); + + if (ret == 0) { + si->bound = 1; + } + + return ret; +} + +_PUBLIC_ 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; +} + +_PUBLIC_ int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen) +{ + struct socket_info *si = find_socket_info(s); + + if (!si) { + return real_getsockname(s, name, addrlen); + } + + memcpy(name, si->myname, si->myname_len); + *addrlen = si->myname_len; + + return 0; +} + +_PUBLIC_ 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) { + return real_getsockopt(s, level, optname, optval, optlen); + } + + errno = ENOPROTOOPT; + return -1; +} + +_PUBLIC_ 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) { + return real_setsockopt(s, level, optname, optval, optlen); + } + + switch (si->family) { + case AF_INET: + return 0; + default: + errno = ENOPROTOOPT; + return -1; + } +} + +_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); + int ret; + struct socket_info *si = find_socket_info(s); + + if (!si) { + 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; + + if (sockaddr_convert_from_un(si, &un_addr, un_addrlen, + si->family, 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) +{ + 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); + } + + 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; + + 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)); + } + + swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len, len); + + return len; + } + + 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; + } + + 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; +} + +_PUBLIC_ int swrap_close(int fd) +{ + struct socket_info *si = find_socket_info(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); + if (si->tmp_path) { + unlink(si->tmp_path); + free(si->tmp_path); + } + free(si); + } + + return real_close(fd); +} diff --git a/source3/lib/socket_wrapper/socket_wrapper.h b/source3/lib/socket_wrapper/socket_wrapper.h new file mode 100644 index 0000000000..23a261faaf --- /dev/null +++ b/source3/lib/socket_wrapper/socket_wrapper.h @@ -0,0 +1,104 @@ +/* + 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. +*/ + +#ifndef __SOCKET_WRAPPER_H__ +#define __SOCKET_WRAPPER_H__ + +int swrap_socket(int family, int type, int protocol); +int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen); +int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen); +int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen); +int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen); +int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen); +int swrap_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen); +int swrap_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen); +ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen); +ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen); +ssize_t swrap_recv(int s, void *buf, size_t len, int flags); +ssize_t swrap_send(int s, const void *buf, size_t len, int flags); +int swrap_close(int); + +#ifdef SOCKET_WRAPPER_REPLACE + +#ifdef accept +#undef accept +#endif +#define accept(s,addr,addrlen) swrap_accept(s,addr,addrlen) + +#ifdef connect +#undef connect +#endif +#define connect(s,serv_addr,addrlen) swrap_connect(s,serv_addr,addrlen) + +#ifdef bind +#undef bind +#endif +#define bind(s,myaddr,addrlen) swrap_bind(s,myaddr,addrlen) + +#ifdef getpeername +#undef getpeername +#endif +#define getpeername(s,name,addrlen) swrap_getpeername(s,name,addrlen) + +#ifdef getsockname +#undef getsockname +#endif +#define getsockname(s,name,addrlen) swrap_getsockname(s,name,addrlen) + +#ifdef getsockopt +#undef getsockopt +#endif +#define getsockopt(s,level,optname,optval,optlen) swrap_getsockopt(s,level,optname,optval,optlen) + +#ifdef setsockopt +#undef setsockopt +#endif +#define setsockopt(s,level,optname,optval,optlen) swrap_setsockopt(s,level,optname,optval,optlen) + +#ifdef recvfrom +#undef recvfrom +#endif +#define recvfrom(s,buf,len,flags,from,fromlen) swrap_recvfrom(s,buf,len,flags,from,fromlen) + +#ifdef sendto +#undef sendto +#endif +#define sendto(s,buf,len,flags,to,tolen) swrap_sendto(s,buf,len,flags,to,tolen) + +#ifdef recv +#undef recv +#endif +#define recv(s,buf,len,flags) swrap_recv(s,buf,len,flags) + +#ifdef send +#undef send +#endif +#define send(s,buf,len,flags) swrap_send(s,buf,len,flags) + +#ifdef socket +#undef socket +#endif +#define socket(domain,type,protocol) swrap_socket(domain,type,protocol) + +#ifdef close +#undef close +#endif +#define close(s) swrap_close(s) +#endif + +#endif /* __SOCKET_WRAPPER_H__ */ -- cgit From 0638207bc40b3a7034801a73baf76cfd44e8e1a9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 18 Sep 2006 22:55:10 +0000 Subject: r18646: now we can have the socket_wrapper.c completely in sync with samba4 metze (This used to be commit d4d9b7e02614e30ab410a26654db3ca66ffe06e6) --- source3/lib/socket_wrapper/socket_wrapper.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/lib/socket_wrapper') diff --git a/source3/lib/socket_wrapper/socket_wrapper.c b/source3/lib/socket_wrapper/socket_wrapper.c index af774e1927..5417f70a06 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.c +++ b/source3/lib/socket_wrapper/socket_wrapper.c @@ -24,10 +24,9 @@ #define SOCKET_WRAPPER_NOT_REPLACE #include "includes.h" -/* #include "system/network.h" #include "system/filesys.h" -*/ + #ifndef _DLINKLIST_H #include "lib/util/dlinklist.h" #endif -- cgit From 4d451bd2139d4ffbb274355e7f6f275be5b5d0eb 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 6004b8025de3207f5af2d62087ec13c5e444fec7) --- source3/lib/socket_wrapper/socket_wrapper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/lib/socket_wrapper') diff --git a/source3/lib/socket_wrapper/socket_wrapper.c b/source3/lib/socket_wrapper/socket_wrapper.c index 5417f70a06..331e23aa48 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.c +++ b/source3/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 52d45a51d3994aa99d2b348ce484a8b7a3830ff3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 26 Sep 2006 15:23:59 +0000 Subject: r18920: merge socket_wrapper changes from samba4 metze (This used to be commit b36d47c698b01a577af04205c9bdf0d588bd20e6) --- source3/lib/socket_wrapper/socket_wrapper.c | 79 +++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 21 deletions(-) (limited to 'source3/lib/socket_wrapper') diff --git a/source3/lib/socket_wrapper/socket_wrapper.c b/source3/lib/socket_wrapper/socket_wrapper.c index 331e23aa48..224d521b30 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.c +++ b/source3/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; } @@ -468,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; @@ -555,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 @@ -568,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) { @@ -582,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); @@ -595,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); @@ -609,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; } @@ -804,7 +838,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; @@ -870,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 cb99b612f874bd1d88e50ff1f2c0331cd56e72ca Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 27 Sep 2006 12:43:51 +0000 Subject: r18953: sync socket_wrapper with samba4 metze (This used to be commit 77b0af43f0f7e52b9040a1d3edfb556a232e64f1) --- source3/lib/socket_wrapper/socket_wrapper.c | 30 +++++++++++++++++++++++++++++ source3/lib/socket_wrapper/socket_wrapper.h | 12 ++++++++++++ 2 files changed, 42 insertions(+) (limited to 'source3/lib/socket_wrapper') diff --git a/source3/lib/socket_wrapper/socket_wrapper.c b/source3/lib/socket_wrapper/socket_wrapper.c index 224d521b30..c884b96c6c 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.c +++ b/source3/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; diff --git a/source3/lib/socket_wrapper/socket_wrapper.h b/source3/lib/socket_wrapper/socket_wrapper.h index 23a261faaf..07cf2c6601 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.h +++ b/source3/lib/socket_wrapper/socket_wrapper.h @@ -23,12 +23,14 @@ int swrap_socket(int family, int type, int protocol); int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen); int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen); int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen); +int swrap_listen(int s, int backlog); int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen); int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen); int swrap_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen); int swrap_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen); ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen); ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen); +int swrap_ioctl(int s, int req, void *ptr); ssize_t swrap_recv(int s, void *buf, size_t len, int flags); ssize_t swrap_send(int s, const void *buf, size_t len, int flags); int swrap_close(int); @@ -50,6 +52,11 @@ int swrap_close(int); #endif #define bind(s,myaddr,addrlen) swrap_bind(s,myaddr,addrlen) +#ifdef listen +#undef listen +#endif +#define listen(s,blog) swrap_listen(s,blog) + #ifdef getpeername #undef getpeername #endif @@ -80,6 +87,11 @@ int swrap_close(int); #endif #define sendto(s,buf,len,flags,to,tolen) swrap_sendto(s,buf,len,flags,to,tolen) +#ifdef ioctl +#undef ioctl +#endif +#define ioctl(s,req,ptr) swrap_ioctl(s,req,ptr) + #ifdef recv #undef recv #endif -- cgit From da6c811eca4b03395bc76a34eaeaedf5566154ba Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 29 Sep 2006 09:48:46 +0000 Subject: r18993: merge from samba4: prepare SOCKET_WRAPPER_PCAP_FILE support metze (This used to be commit 372471cbad34b1d0d2159e75994c481de6eaed05) --- source3/lib/socket_wrapper/socket_wrapper.c | 112 +++++++++++++++++++++------- 1 file changed, 83 insertions(+), 29 deletions(-) (limited to 'source3/lib/socket_wrapper') diff --git a/source3/lib/socket_wrapper/socket_wrapper.c b/source3/lib/socket_wrapper/socket_wrapper.c index c884b96c6c..7054068218 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.c +++ b/source3/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 5b77d0a856c398105568e8e6c22a1a398eea8e4a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 5 Oct 2006 07:05:26 +0000 Subject: r19085: merge from samba4: - source and destination address handling - tcp handling metze (This used to be commit 98154fd43350f3edae54423756620a48e089f96d) --- source3/lib/socket_wrapper/socket_wrapper.c | 242 ++++++++++++++++++++++++++++ 1 file changed, 242 insertions(+) (limited to 'source3/lib/socket_wrapper') diff --git a/source3/lib/socket_wrapper/socket_wrapper.c b/source3/lib/socket_wrapper/socket_wrapper.c index 7054068218..fd80892d28 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.c +++ b/source3/lib/socket_wrapper/socket_wrapper.c @@ -120,6 +120,11 @@ struct socket_info struct sockaddr *peername; socklen_t peername_len; + struct { + unsigned long pck_snd; + unsigned 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; + unsigned long tcp_seq = 0; + unsigned long tcp_ack = 0; + unsigned char 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 f9449b752f7ebab56361f0aa75de4f424217dfec Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 5 Oct 2006 11:50:39 +0000 Subject: r19099: merge socket wrapper changes from samba4 including SOCKET_WRAPPER_PCAP_FILE support but I just noticed that samba don't use recv()/send() on the socket, so the capture only contain connect()/close() metze (This used to be commit b894e33023738b5d6121c56e9c0b34b12f3e0005) --- source3/lib/socket_wrapper/socket_wrapper.c | 320 ++++++++++++++++++++++++++-- 1 file changed, 306 insertions(+), 14 deletions(-) (limited to 'source3/lib/socket_wrapper') diff --git a/source3/lib/socket_wrapper/socket_wrapper.c b/source3/lib/socket_wrapper/socket_wrapper.c index fd80892d28..006aba1e9d 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.c +++ b/source3/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 43141d64ca7a0477cac2d5316ac53ec162a54e7b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 6 Oct 2006 12:18:59 +0000 Subject: r19126: Fix some uninitialized variable warnings (This used to be commit 90bfa3461038f5d179525dec0cf5b3f137e927e0) --- source3/lib/socket_wrapper/socket_wrapper.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'source3/lib/socket_wrapper') diff --git a/source3/lib/socket_wrapper/socket_wrapper.c b/source3/lib/socket_wrapper/socket_wrapper.c index 006aba1e9d..9915789f0b 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.c +++ b/source3/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 e4e3dc064d7348e7267a4f42a78c0c059f1e6ec1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 8 Oct 2006 20:49:05 +0000 Subject: r19172: merge from samba4: change the socket wrapper license to what heimdal uses... metze (This used to be commit d19c19ae4be3f3ad349b72ba3181051bb4da335e) --- source3/lib/socket_wrapper/socket_wrapper.c | 57 +++++++++++++++++++---------- source3/lib/socket_wrapper/socket_wrapper.h | 51 +++++++++++++++++--------- 2 files changed, 72 insertions(+), 36 deletions(-) (limited to 'source3/lib/socket_wrapper') diff --git a/source3/lib/socket_wrapper/socket_wrapper.c b/source3/lib/socket_wrapper/socket_wrapper.c index 9915789f0b..68ee400a7b 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.c +++ b/source3/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_ diff --git a/source3/lib/socket_wrapper/socket_wrapper.h b/source3/lib/socket_wrapper/socket_wrapper.h index 07cf2c6601..1d8dac1763 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.h +++ b/source3/lib/socket_wrapper/socket_wrapper.h @@ -1,20 +1,37 @@ -/* - 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. -*/ +/* + * 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. + * + */ #ifndef __SOCKET_WRAPPER_H__ #define __SOCKET_WRAPPER_H__ -- cgit From ebc2f440e79677a3d25e99f9a9f154e05ec67226 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 8 Oct 2006 21:50:22 +0000 Subject: r19177: merge from samba4: fix the standalone build of socket_wrapper by not using samba's DLIST_ macros metze (This used to be commit bc7b2e8db8fb34d6f321cd6b13b74e58945d7124) --- source3/lib/socket_wrapper/socket_wrapper.c | 43 +++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 9 deletions(-) (limited to 'source3/lib/socket_wrapper') diff --git a/source3/lib/socket_wrapper/socket_wrapper.c b/source3/lib/socket_wrapper/socket_wrapper.c index 68ee400a7b..20205b8f9e 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.c +++ b/source3/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 @@ -74,10 +70,39 @@ #include #include -#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 @@ -1072,7 +1097,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; } @@ -1141,7 +1166,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); @@ -1541,7 +1566,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 354ddf6c57f555f9c98c89a728a77ced8c30ce3d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 8 Oct 2006 21:54:19 +0000 Subject: r19179: remove difference with samba4 metze (This used to be commit e97e1ffea8e124c8001cf33ecac7500ae875f42f) --- source3/lib/socket_wrapper/socket_wrapper.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/lib/socket_wrapper') diff --git a/source3/lib/socket_wrapper/socket_wrapper.c b/source3/lib/socket_wrapper/socket_wrapper.c index 20205b8f9e..3a72c5a74a 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.c +++ b/source3/lib/socket_wrapper/socket_wrapper.c @@ -61,15 +61,19 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include #include +#define _PUBLIC_ + #endif #define SWRAP_DLIST_ADD(list,item) do { \ -- cgit From addf598cde41d17ad4cf497a64b9a2b27e4028c5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 20 Dec 2007 22:17:16 +0100 Subject: Some C++ warnings (This used to be commit 5ab82d4f574f2a2e2761e9e414c66a70aeffb05d) --- source3/lib/socket_wrapper/socket_wrapper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/lib/socket_wrapper') diff --git a/source3/lib/socket_wrapper/socket_wrapper.c b/source3/lib/socket_wrapper/socket_wrapper.c index 3a72c5a74a..a84c460114 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.c +++ b/source3/lib/socket_wrapper/socket_wrapper.c @@ -571,8 +571,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 0c3f431abaf2f33e11f74cbc868b5e1da255bfff Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 21 Dec 2007 12:11:23 -0800 Subject: Fix initialization warnings. Jeremy. (This used to be commit 832c093830cb3978641be3d87670fa900105da25) --- source3/lib/socket_wrapper/socket_wrapper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/socket_wrapper') diff --git a/source3/lib/socket_wrapper/socket_wrapper.c b/source3/lib/socket_wrapper/socket_wrapper.c index a84c460114..5b8052e5ed 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.c +++ b/source3/lib/socket_wrapper/socket_wrapper.c @@ -572,7 +572,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 From 8e308b64c015141dd4d557f287433e728974bbce 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 (cherry picked from commit 61a87bed61ef661d98131239976be95c6a8b4d96) (This used to be commit c22204aa85d4bb33534b6974dcfed9aad0c28cc4) --- source3/lib/socket_wrapper/socket_wrapper.c | 79 +++++++++++++++-------------- 1 file changed, 40 insertions(+), 39 deletions(-) (limited to 'source3/lib/socket_wrapper') diff --git a/source3/lib/socket_wrapper/socket_wrapper.c b/source3/lib/socket_wrapper/socket_wrapper.c index 5b8052e5ed..c0a7c16a2a 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.c +++ b/source3/lib/socket_wrapper/socket_wrapper.c @@ -71,6 +71,7 @@ #include #include #include +#include #define _PUBLIC_ @@ -499,67 +500,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 4084b467c502e8e73567f2f78135a3bb0fe38a43 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. (cherry picked from commit e2866ce78851a84c937408c0781fcc1e7107f663) (This used to be commit 3db8b246c8abfc4efed08d7630e61a81b9d8bf48) --- source3/lib/socket_wrapper/socket_wrapper.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/lib/socket_wrapper') diff --git a/source3/lib/socket_wrapper/socket_wrapper.c b/source3/lib/socket_wrapper/socket_wrapper.c index c0a7c16a2a..beb890d135 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.c +++ b/source3/lib/socket_wrapper/socket_wrapper.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include -- cgit From 1410d8e7992112a4c07c6ef8e80b49be492a50c7 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) (cherry picked from commit 5052d2d10693e67f1b7c6c71277c8d1bc9c8b612) (This used to be commit d22701b196bded3294776b144a7a990de23741e9) --- source3/lib/socket_wrapper/socket_wrapper.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/lib/socket_wrapper') diff --git a/source3/lib/socket_wrapper/socket_wrapper.c b/source3/lib/socket_wrapper/socket_wrapper.c index beb890d135..c8259e060e 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.c +++ b/source3/lib/socket_wrapper/socket_wrapper.c @@ -59,6 +59,7 @@ #else /* _SAMBA_BUILD_ */ #include +#include #include #include #include -- cgit From bd793fb235cd18da8e9d779c767cac81fa3f758e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 10 Jun 2008 08:53:34 +0200 Subject: r21671: Add initial simple tests for socket wrapper (partly cherry picked from commit 872e2ad541478597191ca9e31872d5c8e2bbb832) metze (This used to be commit 8003f00a28bb7237ec1b1f4eb9687c542a86c2b2) --- source3/lib/socket_wrapper/socket_wrapper.c | 2 +- source3/lib/socket_wrapper/socket_wrapper.h | 1 + source3/lib/socket_wrapper/testsuite.c | 82 +++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 source3/lib/socket_wrapper/testsuite.c (limited to 'source3/lib/socket_wrapper') diff --git a/source3/lib/socket_wrapper/socket_wrapper.c b/source3/lib/socket_wrapper/socket_wrapper.c index c8259e060e..ad5c3c177c 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.c +++ b/source3/lib/socket_wrapper/socket_wrapper.c @@ -188,7 +188,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) { diff --git a/source3/lib/socket_wrapper/socket_wrapper.h b/source3/lib/socket_wrapper/socket_wrapper.h index 1d8dac1763..fd1e48610b 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.h +++ b/source3/lib/socket_wrapper/socket_wrapper.h @@ -36,6 +36,7 @@ #ifndef __SOCKET_WRAPPER_H__ #define __SOCKET_WRAPPER_H__ +const char *socket_wrapper_dir(void); int swrap_socket(int family, int type, int protocol); int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen); int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen); diff --git a/source3/lib/socket_wrapper/testsuite.c b/source3/lib/socket_wrapper/testsuite.c new file mode 100644 index 0000000000..a3e6580409 --- /dev/null +++ b/source3/lib/socket_wrapper/testsuite.c @@ -0,0 +1,82 @@ +/* + Unix SMB/CIFS implementation. + + local testing of the socket wrapper + + Copyright (C) Jelmer Vernooij 2007 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 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. +*/ + +#include "includes.h" +#include "system/network.h" +#include "lib/socket_wrapper/socket_wrapper.h" +#include "torture/torture.h" + +static char *old_dir = NULL; + +static void backup_env(void) +{ + old_dir = getenv("SOCKET_WRAPPER_DIR"); +} + +static void restore_env(void) +{ + setenv("SOCKET_WRAPPER_DIR", old_dir, 1); +} + +static bool test_socket_wrapper_dir(struct torture_context *tctx) +{ + backup_env(); + + setenv("SOCKET_WRAPPER_DIR", "foo", 1); + torture_assert_str_equal(tctx, socket_wrapper_dir(), "foo", "setting failed"); + setenv("SOCKET_WRAPPER_DIR", "./foo", 1); + torture_assert_str_equal(tctx, socket_wrapper_dir(), "foo", "setting failed"); + unsetenv("SOCKET_WRAPPER_DIR"); + torture_assert_str_equal(tctx, socket_wrapper_dir(), NULL, "resetting failed"); + + restore_env(); + + return true; +} + +static bool test_swrap_socket(struct torture_context *tctx) +{ + backup_env(); + setenv("SOCKET_WRAPPER_DIR", "foo", 1); + + torture_assert_int_equal(tctx, swrap_socket(1337, 1337, 0), -1, "unknown address family fails"); + torture_assert_int_equal(tctx, errno, EAFNOSUPPORT, "correct errno set"); + torture_assert_int_equal(tctx, swrap_socket(AF_INET, 1337, 0), -1, "unknown type fails"); + torture_assert_int_equal(tctx, errno, EPROTONOSUPPORT, "correct errno set"); + torture_assert_int_equal(tctx, swrap_socket(AF_INET, SOCK_DGRAM, 10), -1, "unknown protocol fails"); + torture_assert_int_equal(tctx, errno, EPROTONOSUPPORT, "correct errno set"); + + restore_env(); + + return true; +} + +struct torture_suite *torture_local_socket_wrapper(TALLOC_CTX *mem_ctx) +{ + struct torture_suite *suite = torture_suite_create(mem_ctx, + "SOCKET-WRAPPER"); + + torture_suite_add_simple_test(suite, "socket_wrapper_dir", test_socket_wrapper_dir); + torture_suite_add_simple_test(suite, "socket", test_swrap_socket); + + return suite; +} -- cgit From 235915063957dc9ff31a8e6777e0f63b7f3bf07c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 6 Mar 2007 23:03:34 +0000 Subject: r21729: Some more tests (cherry picked from commit d2baa8218cf504d6631d610f9fd393ad8c61574c) (This used to be commit cf6d815ba82a25c1e1f1dfdb8548cc588d44d1aa) --- source3/lib/socket_wrapper/socket_wrapper.c | 9 ++++----- source3/lib/socket_wrapper/testsuite.c | 26 +++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 6 deletions(-) (limited to 'source3/lib/socket_wrapper') diff --git a/source3/lib/socket_wrapper/socket_wrapper.c b/source3/lib/socket_wrapper/socket_wrapper.c index ad5c3c177c..b6b88fbcd1 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.c +++ b/source3/lib/socket_wrapper/socket_wrapper.c @@ -200,15 +200,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; } } diff --git a/source3/lib/socket_wrapper/testsuite.c b/source3/lib/socket_wrapper/testsuite.c index a3e6580409..65ae9a0584 100644 --- a/source3/lib/socket_wrapper/testsuite.c +++ b/source3/lib/socket_wrapper/testsuite.c @@ -26,15 +26,24 @@ #include "torture/torture.h" static char *old_dir = NULL; +static char *old_iface = NULL; static void backup_env(void) { old_dir = getenv("SOCKET_WRAPPER_DIR"); + old_iface = getenv("SOCKET_WRAPPER_DEFAULT_IFACE"); } static void restore_env(void) { - setenv("SOCKET_WRAPPER_DIR", old_dir, 1); + if (old_dir == NULL) + unsetenv("SOCKET_WRAPPER_DIR"); + else + setenv("SOCKET_WRAPPER_DIR", old_dir, 1); + if (old_iface == NULL) + unsetenv("SOCKET_WRAPPER_DEFAULT_IFACE"); + else + setenv("SOCKET_WRAPPER_DEFAULT_IFACE", old_iface, 1); } static bool test_socket_wrapper_dir(struct torture_context *tctx) @@ -70,6 +79,20 @@ static bool test_swrap_socket(struct torture_context *tctx) return true; } +unsigned int socket_wrapper_default_iface(void); +static bool test_socket_wrapper_default_iface(struct torture_context *tctx) +{ + backup_env(); + unsetenv("SOCKET_WRAPPER_DEFAULT_IFACE"); + torture_assert_int_equal(tctx, socket_wrapper_default_iface(), 1, "unset"); + setenv("SOCKET_WRAPPER_DEFAULT_IFACE", "2", 1); + torture_assert_int_equal(tctx, socket_wrapper_default_iface(), 2, "unset"); + setenv("SOCKET_WRAPPER_DEFAULT_IFACE", "bla", 1); + torture_assert_int_equal(tctx, socket_wrapper_default_iface(), 1, "unset"); + restore_env(); + return true; +} + struct torture_suite *torture_local_socket_wrapper(TALLOC_CTX *mem_ctx) { struct torture_suite *suite = torture_suite_create(mem_ctx, @@ -77,6 +100,7 @@ struct torture_suite *torture_local_socket_wrapper(TALLOC_CTX *mem_ctx) torture_suite_add_simple_test(suite, "socket_wrapper_dir", test_socket_wrapper_dir); torture_suite_add_simple_test(suite, "socket", test_swrap_socket); + torture_suite_add_simple_test(suite, "socket_wrapper_default_iface", test_socket_wrapper_default_iface); return suite; } -- cgit From c8eccf53810bef0d5b5245a3b8538cfb0e6879fb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 10 Jun 2008 09:00:37 +0200 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 (partly cherry picked from commit 2254e61a1e5b29a64c5a24aac029ace193057e24) metze (This used to be commit 66b9f6f3722defd0863b055916b302478715704b) --- source3/lib/socket_wrapper/socket_wrapper.c | 552 ++++++++++++++++++++-------- 1 file changed, 391 insertions(+), 161 deletions(-) (limited to 'source3/lib/socket_wrapper') diff --git a/source3/lib/socket_wrapper/socket_wrapper.c b/source3/lib/socket_wrapper/socket_wrapper.c index b6b88fbcd1..f0fa85a8be 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.c +++ b/source3/lib/socket_wrapper/socket_wrapper.c @@ -147,9 +147,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); @@ -157,6 +161,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; @@ -205,26 +238,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; @@ -233,80 +263,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", @@ -321,60 +416,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) { @@ -384,11 +515,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, @@ -417,6 +550,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: @@ -426,9 +562,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; @@ -443,25 +579,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: @@ -470,7 +602,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; } @@ -802,7 +934,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; } @@ -1066,6 +1204,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); @@ -1087,6 +1228,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; @@ -1116,8 +1265,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); @@ -1125,18 +1274,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; } @@ -1151,6 +1319,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); @@ -1158,19 +1336,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); @@ -1191,7 +1369,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; @@ -1207,13 +1384,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; @@ -1243,13 +1462,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; } @@ -1269,6 +1483,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; @@ -1447,38 +1666,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 9b7b444e35493100df2258dc78db59f0f6237d0d 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 (cherry picked from commit 96f1a0dfaa18a432fca4b5432d929d8daed0abb1) (This used to be commit 801ed0b79956133f2baa6b2db4a7dd5a68060edc) --- source3/lib/socket_wrapper/socket_wrapper.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'source3/lib/socket_wrapper') diff --git a/source3/lib/socket_wrapper/socket_wrapper.c b/source3/lib/socket_wrapper/socket_wrapper.c index f0fa85a8be..2ad6a2e9e5 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.c +++ b/source3/lib/socket_wrapper/socket_wrapper.c @@ -175,7 +175,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: @@ -185,7 +185,7 @@ static int socket_length(int family) return sizeof(struct sockaddr_in6); #endif } - return -1; + return 0; } @@ -789,6 +789,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) { @@ -1232,10 +1235,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; @@ -1279,7 +1284,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 a7967bc84ce6e5177659060c8c2baf120d9686a2 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 (cherry picked from commit 47f865165e772540334dcbcf80cfc1999b0132fa) (This used to be commit 4d5bfcc731b44267e2c30fccdca72b6058b16bfb) --- source3/lib/socket_wrapper/socket_wrapper.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'source3/lib/socket_wrapper') diff --git a/source3/lib/socket_wrapper/socket_wrapper.c b/source3/lib/socket_wrapper/socket_wrapper.c index 2ad6a2e9e5..f433b0e41f 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.c +++ b/source3/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_ */ @@ -75,8 +66,10 @@ #include #include -#define _PUBLIC_ +#endif +#ifndef _PUBLIC_ +#define _PUBLIC_ #endif #define SWRAP_DLIST_ADD(list,item) do { \ -- cgit From e2fe170423c7ac1b11a1a601c5c383e99e9682a2 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. (cherry picked from commit 2548c2a1e7dab8abc00f8f49374a08cc0b427552) (This used to be commit e4e015caac88f6e31ca6d8fcda5a97a11aee226d) --- source3/lib/socket_wrapper/socket_wrapper.c | 79 ++++++++++++++++------------- 1 file changed, 43 insertions(+), 36 deletions(-) (limited to 'source3/lib/socket_wrapper') diff --git a/source3/lib/socket_wrapper/socket_wrapper.c b/source3/lib/socket_wrapper/socket_wrapper.c index f433b0e41f..d0326be495 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.c +++ b/source3/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. @@ -213,7 +213,6 @@ struct socket_info static struct socket_info *sockets; - const char *socket_wrapper_dir(void) { const char *s = getenv("SOCKET_WRAPPER_DIR"); @@ -909,40 +908,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; @@ -956,7 +946,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; @@ -970,7 +960,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; @@ -984,7 +974,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; @@ -996,7 +986,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; @@ -1010,7 +1000,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; @@ -1024,7 +1014,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; @@ -1052,10 +1042,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; @@ -1069,7 +1058,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; @@ -1095,7 +1084,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; @@ -1129,7 +1118,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; @@ -1143,7 +1132,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; @@ -1157,7 +1146,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; @@ -1168,15 +1157,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 d57b8280d6ded808ab82767789f45629abe95dde Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 10 Jun 2008 09:21:05 +0200 Subject: socket_wrapper: sync missing stuff from v4-0-test metze (This used to be commit b03c2793548834a1dc0483b03081d872ab1e17f0) --- source3/lib/socket_wrapper/config.m4 | 8 ++++---- source3/lib/socket_wrapper/config.mk | 8 ++++++++ source3/lib/socket_wrapper/socket_wrapper.c | 2 +- source3/lib/socket_wrapper/socket_wrapper.h | 2 ++ source3/lib/socket_wrapper/testsuite.c | 5 ++--- 5 files changed, 17 insertions(+), 8 deletions(-) create mode 100644 source3/lib/socket_wrapper/config.mk (limited to 'source3/lib/socket_wrapper') diff --git a/source3/lib/socket_wrapper/config.m4 b/source3/lib/socket_wrapper/config.m4 index 42212abc7f..f3ffb895a9 100644 --- a/source3/lib/socket_wrapper/config.m4 +++ b/source3/lib/socket_wrapper/config.m4 @@ -1,22 +1,22 @@ AC_ARG_ENABLE(socket-wrapper, [ --enable-socket-wrapper Turn on socket wrapper library (default=no)]) -DEFAULT_TEST_TARGET=test-noswrap +DEFAULT_TEST_OPTIONS= HAVE_SOCKET_WRAPPER=no if eval "test x$developer = xyes"; then enable_socket_wrapper=yes fi - + if eval "test x$enable_socket_wrapper = xyes"; then AC_DEFINE(SOCKET_WRAPPER,1,[Use socket wrapper library]) - DEFAULT_TEST_TARGET=test-swrap + DEFAULT_TEST_OPTIONS=--socket-wrapper HAVE_SOCKET_WRAPPER=yes # this is only used for samba3 SOCKET_WRAPPER_OBJS="lib/socket_wrapper/socket_wrapper.o" fi -AC_SUBST(DEFAULT_TEST_TARGET) +AC_SUBST(DEFAULT_TEST_OPTIONS) AC_SUBST(HAVE_SOCKET_WRAPPER) AC_SUBST(SOCKET_WRAPPER_OBJS) diff --git a/source3/lib/socket_wrapper/config.mk b/source3/lib/socket_wrapper/config.mk new file mode 100644 index 0000000000..60cfb3209a --- /dev/null +++ b/source3/lib/socket_wrapper/config.mk @@ -0,0 +1,8 @@ +############################## +# Start SUBSYSTEM SOCKET_WRAPPER +[SUBSYSTEM::SOCKET_WRAPPER] +PRIVATE_DEPENDENCIES = LIBREPLACE_NETWORK +# End SUBSYSTEM SOCKET_WRAPPER +############################## + +SOCKET_WRAPPER_OBJ_FILES = $(socketwrappersrcdir)/socket_wrapper.o diff --git a/source3/lib/socket_wrapper/socket_wrapper.c b/source3/lib/socket_wrapper/socket_wrapper.c index d0326be495..5ac9965bd6 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.c +++ b/source3/lib/socket_wrapper/socket_wrapper.c @@ -1289,7 +1289,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; } diff --git a/source3/lib/socket_wrapper/socket_wrapper.h b/source3/lib/socket_wrapper/socket_wrapper.h index fd1e48610b..cc8b937608 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.h +++ b/source3/lib/socket_wrapper/socket_wrapper.h @@ -37,6 +37,7 @@ #define __SOCKET_WRAPPER_H__ const char *socket_wrapper_dir(void); +unsigned int socket_wrapper_default_iface(void); int swrap_socket(int family, int type, int protocol); int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen); int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen); @@ -131,4 +132,5 @@ int swrap_close(int); #define close(s) swrap_close(s) #endif + #endif /* __SOCKET_WRAPPER_H__ */ diff --git a/source3/lib/socket_wrapper/testsuite.c b/source3/lib/socket_wrapper/testsuite.c index 65ae9a0584..8877418e4c 100644 --- a/source3/lib/socket_wrapper/testsuite.c +++ b/source3/lib/socket_wrapper/testsuite.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" -- cgit From 5380fd800d90f0463f99dbd9efb78feb177b1790 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 (cherry picked from commit 5b01206f1bb2e62c08bda34b45904ec4f83ac5de) (This used to be commit eb8c37a1ca97b41de00ec937a90bfdbe9cd21531) --- source3/lib/socket_wrapper/socket_wrapper.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/lib/socket_wrapper') diff --git a/source3/lib/socket_wrapper/socket_wrapper.c b/source3/lib/socket_wrapper/socket_wrapper.c index 5ac9965bd6..336179d837 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.c +++ b/source3/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 863a6aa07e543e30f2075a597129f6c39222beef Mon Sep 17 00:00:00 2001 From: Zach Loafman Date: Thu, 3 Jul 2008 12:21:33 -0700 Subject: Fix warnings on FreeBSD-based platforms Fix two shadowed declaration warnings on FreeBSD-based platform: 'reboot' is a 4.0BSD syscall in unistd.h and 'tcp_seq' is a typedef in netinet/tcp.h. (This used to be commit 14d2a4da1da38d6f69c63505d35990322f253e5d) --- source3/lib/socket_wrapper/socket_wrapper.c | 38 ++++++++++++++--------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'source3/lib/socket_wrapper') diff --git a/source3/lib/socket_wrapper/socket_wrapper.c b/source3/lib/socket_wrapper/socket_wrapper.c index 336179d837..33e4b38370 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.c +++ b/source3/lib/socket_wrapper/socket_wrapper.c @@ -750,7 +750,7 @@ static struct swrap_packet *swrap_packet_init(struct timeval *tval, int socket_type, const unsigned char *payload, size_t payload_len, - unsigned long tcp_seq, + unsigned long tcp_seqno, unsigned long tcp_ack, unsigned char tcp_ctl, int unreachable, @@ -852,7 +852,7 @@ static struct swrap_packet *swrap_packet_init(struct timeval *tval, 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.seq_num = htonl(tcp_seqno); 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; @@ -916,7 +916,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, { const struct sockaddr_in *src_addr; const struct sockaddr_in *dest_addr; - unsigned long tcp_seq = 0; + unsigned long tcp_seqno = 0; unsigned long tcp_ack = 0; unsigned char tcp_ctl = 0; int unreachable = 0; @@ -937,7 +937,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, src_addr = (const struct sockaddr_in *)si->myname; dest_addr = (const struct sockaddr_in *)addr; - tcp_seq = si->io.pck_snd; + tcp_seqno = si->io.pck_snd; tcp_ack = si->io.pck_rcv; tcp_ctl = 0x02; /* SYN */ @@ -951,7 +951,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, dest_addr = (const struct sockaddr_in *)si->myname; src_addr = (const struct sockaddr_in *)addr; - tcp_seq = si->io.pck_rcv; + tcp_seqno = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x12; /** SYN,ACK */ @@ -966,7 +966,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, src_addr = (const struct sockaddr_in *)addr; /* Unreachable: resend the data of SWRAP_CONNECT_SEND */ - tcp_seq = si->io.pck_snd - 1; + tcp_seqno = si->io.pck_snd - 1; tcp_ack = si->io.pck_rcv; tcp_ctl = 0x02; /* SYN */ unreachable = 1; @@ -979,7 +979,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, src_addr = (const struct sockaddr_in *)si->myname; dest_addr = (const struct sockaddr_in *)addr; - tcp_seq = si->io.pck_snd; + tcp_seqno = si->io.pck_snd; tcp_ack = si->io.pck_rcv; tcp_ctl = 0x10; /* ACK */ @@ -991,7 +991,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, dest_addr = (const struct sockaddr_in *)si->myname; src_addr = (const struct sockaddr_in *)addr; - tcp_seq = si->io.pck_rcv; + tcp_seqno = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x02; /* SYN */ @@ -1005,7 +1005,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, src_addr = (const struct sockaddr_in *)si->myname; dest_addr = (const struct sockaddr_in *)addr; - tcp_seq = si->io.pck_snd; + tcp_seqno = si->io.pck_snd; tcp_ack = si->io.pck_rcv; tcp_ctl = 0x12; /* SYN,ACK */ @@ -1019,7 +1019,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, dest_addr = (const struct sockaddr_in *)si->myname; src_addr = (const struct sockaddr_in *)addr; - tcp_seq = si->io.pck_rcv; + tcp_seqno = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x10; /* ACK */ @@ -1029,7 +1029,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, src_addr = (const struct sockaddr_in *)si->myname; dest_addr = (const struct sockaddr_in *)si->peername; - tcp_seq = si->io.pck_snd; + tcp_seqno = si->io.pck_snd; tcp_ack = si->io.pck_rcv; tcp_ctl = 0x18; /* PSH,ACK */ @@ -1047,7 +1047,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, buf, len, packet_len); } - tcp_seq = si->io.pck_rcv; + tcp_seqno = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x14; /** RST,ACK */ @@ -1061,7 +1061,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, return NULL; } - tcp_seq = si->io.pck_rcv; + tcp_seqno = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x14; /* RST,ACK */ @@ -1071,7 +1071,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, dest_addr = (const struct sockaddr_in *)si->myname; src_addr = (const struct sockaddr_in *)si->peername; - tcp_seq = si->io.pck_rcv; + tcp_seqno = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x18; /* PSH,ACK */ @@ -1087,7 +1087,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, return NULL; } - tcp_seq = si->io.pck_rcv; + tcp_seqno = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x14; /* RST,ACK */ @@ -1123,7 +1123,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, src_addr = (const struct sockaddr_in *)si->myname; dest_addr = (const struct sockaddr_in *)si->peername; - tcp_seq = si->io.pck_snd; + tcp_seqno = si->io.pck_snd; tcp_ack = si->io.pck_rcv; tcp_ctl = 0x11; /* FIN, ACK */ @@ -1137,7 +1137,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, dest_addr = (const struct sockaddr_in *)si->myname; src_addr = (const struct sockaddr_in *)si->peername; - tcp_seq = si->io.pck_rcv; + tcp_seqno = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x11; /* FIN,ACK */ @@ -1151,7 +1151,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, src_addr = (const struct sockaddr_in *)si->myname; dest_addr = (const struct sockaddr_in *)si->peername; - tcp_seq = si->io.pck_snd; + tcp_seqno = si->io.pck_snd; tcp_ack = si->io.pck_rcv; tcp_ctl = 0x10; /* ACK */ @@ -1164,7 +1164,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, return swrap_packet_init(&tv, src_addr, dest_addr, si->type, (const unsigned char *)buf, len, - tcp_seq, tcp_ack, tcp_ctl, unreachable, + tcp_seqno, tcp_ack, tcp_ctl, unreachable, packet_len); } -- cgit