diff options
Diffstat (limited to 'source/lib/socket_wrapper/socket_wrapper.c')
-rw-r--r-- | source/lib/socket_wrapper/socket_wrapper.c | 692 |
1 files changed, 224 insertions, 468 deletions
diff --git a/source/lib/socket_wrapper/socket_wrapper.c b/source/lib/socket_wrapper/socket_wrapper.c index 33e4b38370..c0a7c16a2a 100644 --- a/source/lib/socket_wrapper/socket_wrapper.c +++ b/source/lib/socket_wrapper/socket_wrapper.c @@ -1,5 +1,5 @@ /* - * Copyright (C) Jelmer Vernooij 2005,2008 <jelmer@samba.org> + * Copyright (C) Jelmer Vernooij 2005 <jelmer@samba.org> * Copyright (C) Stefan Metzmacher 2006 <metze@samba.org> * * All rights reserved. @@ -42,19 +42,26 @@ #ifdef _SAMBA_BUILD_ #define SOCKET_WRAPPER_NOT_REPLACE -#include "lib/replace/replace.h" +#include "includes.h" #include "system/network.h" #include "system/filesys.h" -#include "system/time.h" + +#ifdef malloc +#undef malloc +#endif +#ifdef calloc +#undef calloc +#endif +#ifdef strdup +#undef strdup +#endif #else /* _SAMBA_BUILD_ */ #include <sys/types.h> -#include <sys/time.h> #include <sys/stat.h> #include <sys/socket.h> #include <sys/ioctl.h> -#include <sys/filio.h> #include <errno.h> #include <sys/un.h> #include <netinet/in.h> @@ -66,10 +73,8 @@ #include <stdio.h> #include <stdint.h> -#endif - -#ifndef _PUBLIC_ #define _PUBLIC_ + #endif #define SWRAP_DLIST_ADD(list,item) do { \ @@ -140,13 +145,9 @@ #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); @@ -154,35 +155,6 @@ 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 size_t 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 0; -} - - - struct socket_info { int fd; @@ -213,7 +185,8 @@ struct socket_info static struct socket_info *sockets; -const char *socket_wrapper_dir(void) + +static const char *socket_wrapper_dir(void) { const char *s = getenv("SOCKET_WRAPPER_DIR"); if (s == NULL) { @@ -225,7 +198,7 @@ const char *socket_wrapper_dir(void) return s; } -unsigned int socket_wrapper_default_iface(void) +static unsigned int socket_wrapper_default_iface(void) { const char *s = getenv("SOCKET_WRAPPER_DEFAULT_IFACE"); if (s) { @@ -240,13 +213,17 @@ unsigned int socket_wrapper_default_iface(void) return 1;/* 127.0.0.1 */ } -static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, socklen_t *len) +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; @@ -255,145 +232,80 @@ static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, sock return -1; } - if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) { + if (type != SOCKET_TYPE_CHAR_TCP && type != SOCKET_TYPE_CHAR_UDP) { errno = EINVAL; return -1; } - if (prt > 0xFFFF) { + if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) { errno = EINVAL; return -1; } - 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: + 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 *inaddr, struct sockaddr_un *un, +static int convert_in_un_remote(struct socket_info *si, const struct sockaddr_in *in, struct sockaddr_un *un, int *bcast) { + char u_type = '\0'; + char b_type = '\0'; + char a_type = '\0'; char type = '\0'; - unsigned int prt; + 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; - 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; - 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; + if (prt == 0) { + errno = EINVAL; + return -1; } -#ifdef HAVE_IPV6 - case AF_INET6: { - const struct sockaddr_in6 *in = - (const struct sockaddr_in6 *)inaddr; - - 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; - + 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; } -#endif - default: + + 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 (prt == 0) { - errno = EINVAL; - return -1; - } + if (bcast) *bcast = is_bcast; if (is_bcast) { snprintf(un->sun_path, sizeof(un->sun_path), "%s/EINVAL", @@ -408,96 +320,60 @@ static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *i return 0; } -static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un, +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 prt; + 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->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; - } + switch (si->type) { + case SOCK_STREAM: + u_type = SOCKET_TYPE_CHAR_TCP; + d_type = SOCKET_TYPE_CHAR_TCP; break; - } -#ifdef HAVE_IPV6 - case AF_INET6: { - const struct sockaddr_in6 *in = - (const struct sockaddr_in6 *)inaddr; - - 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; - + 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; } -#endif - default: - errno = ENETUNREACH; + + 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) { @@ -507,13 +383,11 @@ 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; - set_port(si->family, prt, si->myname); - break; - } - if (prt == 10000) { - errno = ENFILE; - return -1; + ((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, @@ -542,9 +416,6 @@ 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: @@ -554,9 +425,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, in_addr, out_addr, bcast); + return convert_in_un_alloc(si, (const struct sockaddr_in *)in_addr, out_addr, bcast); } else { - return convert_in_un_remote(si, in_addr, out_addr, bcast); + return convert_in_un_remote(si, (const struct sockaddr_in *)in_addr, out_addr, bcast); } default: break; @@ -571,21 +442,25 @@ 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) { - if (out_addr == NULL || out_addrlen == NULL) + socklen_t out_addrlen; + + 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: @@ -594,7 +469,7 @@ static int sockaddr_convert_from_un(const struct socket_info *si, errno = ESOCKTNOSUPPORT; return -1; } - return convert_un_in(in_addr, out_addr, out_addrlen); + return convert_un_in(in_addr, (struct sockaddr_in *)out_addr, _out_addrlen); default: break; } @@ -750,7 +625,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_seqno, + unsigned long tcp_seq, unsigned long tcp_ack, unsigned char tcp_ctl, int unreachable, @@ -781,9 +656,6 @@ 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) { @@ -852,7 +724,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_seqno); + 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; @@ -908,36 +780,39 @@ static int swrap_get_pcap_fd(const char *fname) return fd; } -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) +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 struct sockaddr_in *src_addr; const struct sockaddr_in *dest_addr; - unsigned long tcp_seqno = 0; + 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; - switch (si->family) { - case AF_INET: - break; - default: - return NULL; + file_name = socket_wrapper_pcap_file(); + if (!file_name) { + return; + } + + if (si->family != AF_INET) { + return; } switch (type) { case SWRAP_CONNECT_SEND: - if (si->type != SOCK_STREAM) return NULL; + if (si->type != SOCK_STREAM) return; src_addr = (const struct sockaddr_in *)si->myname; dest_addr = (const struct sockaddr_in *)addr; - tcp_seqno = si->io.pck_snd; + tcp_seq = si->io.pck_snd; tcp_ack = si->io.pck_rcv; tcp_ctl = 0x02; /* SYN */ @@ -946,12 +821,12 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, break; case SWRAP_CONNECT_RECV: - if (si->type != SOCK_STREAM) return NULL; + if (si->type != SOCK_STREAM) return; dest_addr = (const struct sockaddr_in *)si->myname; src_addr = (const struct sockaddr_in *)addr; - tcp_seqno = si->io.pck_rcv; + tcp_seq = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x12; /** SYN,ACK */ @@ -960,13 +835,13 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, break; case SWRAP_CONNECT_UNREACH: - if (si->type != SOCK_STREAM) return NULL; + 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_seqno = si->io.pck_snd - 1; + tcp_seq = si->io.pck_snd - 1; tcp_ack = si->io.pck_rcv; tcp_ctl = 0x02; /* SYN */ unreachable = 1; @@ -974,24 +849,24 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, break; case SWRAP_CONNECT_ACK: - if (si->type != SOCK_STREAM) return NULL; + if (si->type != SOCK_STREAM) return; src_addr = (const struct sockaddr_in *)si->myname; dest_addr = (const struct sockaddr_in *)addr; - tcp_seqno = si->io.pck_snd; + 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 NULL; + if (si->type != SOCK_STREAM) return; dest_addr = (const struct sockaddr_in *)si->myname; src_addr = (const struct sockaddr_in *)addr; - tcp_seqno = si->io.pck_rcv; + tcp_seq = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x02; /* SYN */ @@ -1000,12 +875,12 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, break; case SWRAP_ACCEPT_RECV: - if (si->type != SOCK_STREAM) return NULL; + if (si->type != SOCK_STREAM) return; src_addr = (const struct sockaddr_in *)si->myname; dest_addr = (const struct sockaddr_in *)addr; - tcp_seqno = si->io.pck_snd; + tcp_seq = si->io.pck_snd; tcp_ack = si->io.pck_rcv; tcp_ctl = 0x12; /* SYN,ACK */ @@ -1014,12 +889,12 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, break; case SWRAP_ACCEPT_ACK: - if (si->type != SOCK_STREAM) return NULL; + if (si->type != SOCK_STREAM) return; dest_addr = (const struct sockaddr_in *)si->myname; src_addr = (const struct sockaddr_in *)addr; - tcp_seqno = si->io.pck_rcv; + tcp_seq = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x10; /* ACK */ @@ -1029,7 +904,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_seqno = si->io.pck_snd; + tcp_seq = si->io.pck_snd; tcp_ack = si->io.pck_rcv; tcp_ctl = 0x18; /* PSH,ACK */ @@ -1042,12 +917,13 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, src_addr = (const struct sockaddr_in *)si->peername; if (si->type == SOCK_DGRAM) { - return swrap_marshall_packet(si, si->peername, + swrap_dump_packet(si, si->peername, SWRAP_SENDTO_UNREACH, - buf, len, packet_len); + buf, len); + return; } - tcp_seqno = si->io.pck_rcv; + tcp_seq = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x14; /** RST,ACK */ @@ -1058,10 +934,10 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, src_addr = (const struct sockaddr_in *)si->peername; if (si->type == SOCK_DGRAM) { - return NULL; + return; } - tcp_seqno = si->io.pck_rcv; + tcp_seq = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x14; /* RST,ACK */ @@ -1071,7 +947,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_seqno = si->io.pck_rcv; + tcp_seq = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x18; /* PSH,ACK */ @@ -1084,10 +960,10 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, src_addr = (const struct sockaddr_in *)si->peername; if (si->type == SOCK_DGRAM) { - return NULL; + return; } - tcp_seqno = si->io.pck_rcv; + tcp_seq = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x14; /* RST,ACK */ @@ -1118,12 +994,12 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, break; case SWRAP_CLOSE_SEND: - if (si->type != SOCK_STREAM) return NULL; + if (si->type != SOCK_STREAM) return; src_addr = (const struct sockaddr_in *)si->myname; dest_addr = (const struct sockaddr_in *)si->peername; - tcp_seqno = si->io.pck_snd; + tcp_seq = si->io.pck_snd; tcp_ack = si->io.pck_rcv; tcp_ctl = 0x11; /* FIN, ACK */ @@ -1132,12 +1008,12 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, break; case SWRAP_CLOSE_RECV: - if (si->type != SOCK_STREAM) return NULL; + if (si->type != SOCK_STREAM) return; dest_addr = (const struct sockaddr_in *)si->myname; src_addr = (const struct sockaddr_in *)si->peername; - tcp_seqno = si->io.pck_rcv; + tcp_seq = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x11; /* FIN,ACK */ @@ -1146,44 +1022,26 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, break; case SWRAP_CLOSE_ACK: - if (si->type != SOCK_STREAM) return NULL; + if (si->type != SOCK_STREAM) return; src_addr = (const struct sockaddr_in *)si->myname; dest_addr = (const struct sockaddr_in *)si->peername; - tcp_seqno = si->io.pck_snd; + tcp_seq = si->io.pck_snd; tcp_ack = si->io.pck_rcv; tcp_ctl = 0x10; /* ACK */ break; default: - return NULL; + return; } swrapGetTimeOfDay(&tv); - return swrap_packet_init(&tv, src_addr, dest_addr, si->type, + packet = swrap_packet_init(&tv, src_addr, dest_addr, si->type, (const unsigned char *)buf, len, - tcp_seqno, tcp_ack, tcp_ctl, unreachable, - 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); + tcp_seq, tcp_ack, tcp_ctl, unreachable, + &packet_len); if (!packet) { return; } @@ -1207,9 +1065,6 @@ _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); @@ -1231,16 +1086,6 @@ _PUBLIC_ int swrap_socket(int family, int type, int protocol) switch (protocol) { case 0: break; - case 6: - if (type == SOCK_STREAM) { - break; - } - /*fall through*/ - case 17: - if (type == SOCK_DGRAM) { - break; - } - /*fall through*/ default: errno = EPROTONOSUPPORT; return -1; @@ -1270,8 +1115,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, len; + struct sockaddr my_addr; + socklen_t my_addrlen = sizeof(my_addr); int ret; parent_si = find_socket_info(s); @@ -1279,37 +1124,18 @@ _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 = (struct sockaddr *)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) { - free(my_addr); - return ret; - } + if (ret == -1) return ret; fd = ret; - len = my_addrlen; ret = sockaddr_convert_from_un(parent_si, &un_addr, un_addrlen, - parent_si->family, my_addr, &len); + parent_si->family, addr, addrlen); if (ret == -1) { - free(my_addr); close(fd); return ret; } @@ -1324,16 +1150,6 @@ _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); @@ -1341,19 +1157,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, &len); + child_si->family, &my_addr, &my_addrlen); if (ret == -1) { free(child_si); - free(my_addr); close(fd); return ret; } - child_si->myname_len = len; - child_si->myname = sockaddr_dup(my_addr, len); - free(my_addr); + 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); SWRAP_DLIST_ADD(sockets, child_si); @@ -1374,6 +1190,7 @@ 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; @@ -1389,55 +1206,13 @@ static int swrap_auto_bind(struct socket_info *si) un_addr.sun_family = AF_UNIX; - 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); + switch (si->type) { + case SOCK_STREAM: + type = SOCKET_TYPE_CHAR_TCP; break; - } -#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); + case SOCK_DGRAM: + type = SOCKET_TYPE_CHAR_UDP; break; - } -#endif default: errno = ESOCKTNOSUPPORT; return -1; @@ -1467,8 +1242,13 @@ static int swrap_auto_bind(struct socket_info *si) return -1; } - set_port(si->family, port, si->myname); - + 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); return 0; } @@ -1488,11 +1268,6 @@ _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; @@ -1643,8 +1418,6 @@ _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); @@ -1673,51 +1446,38 @@ _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); - 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 (si->bound == 0) { + ret = swrap_auto_bind(si); 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)); - } - - swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len); - - return len; + } + + 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)); } - - ret = real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr)); - break; - default: - ret = -1; - errno = EHOSTUNREACH; - break; + + 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)); + /* to give better errors */ if (ret == -1 && errno == ENOENT) { errno = EHOSTUNREACH; @@ -1768,8 +1528,6 @@ _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); @@ -1792,8 +1550,6 @@ _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) { |