2 * Copyright (C) Jelmer Vernooij 2005,2008 <jelmer@samba.org>
3 * Copyright (C) Stefan Metzmacher 2006-2009 <metze@samba.org>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the author nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 Socket wrapper library. Passes all socket communication over
38 unix domain sockets if the environment variable SOCKET_WRAPPER_DIR
44 #define SOCKET_WRAPPER_NOT_REPLACE
45 #include "../replace/replace.h"
46 #include "system/network.h"
47 #include "system/filesys.h"
48 #include "system/time.h"
50 #else /* _SAMBA_BUILD_ */
52 #include <sys/types.h>
55 #include <sys/socket.h>
56 #include <sys/ioctl.h>
57 #include <sys/filio.h>
60 #include <netinet/in.h>
61 #include <netinet/tcp.h>
75 #define SWRAP_DLIST_ADD(list,item) do { \
77 (item)->prev = NULL; \
78 (item)->next = NULL; \
81 (item)->prev = NULL; \
82 (item)->next = (list); \
83 (list)->prev = (item); \
88 #define SWRAP_DLIST_REMOVE(list,item) do { \
89 if ((list) == (item)) { \
90 (list) = (item)->next; \
92 (list)->prev = NULL; \
96 (item)->prev->next = (item)->next; \
99 (item)->next->prev = (item)->prev; \
102 (item)->prev = NULL; \
103 (item)->next = NULL; \
106 /* LD_PRELOAD doesn't work yet, so REWRITE_CALLS is all we support
108 #define REWRITE_CALLS
111 #define real_accept accept
112 #define real_connect connect
113 #define real_bind bind
114 #define real_listen listen
115 #define real_getpeername getpeername
116 #define real_getsockname getsockname
117 #define real_getsockopt getsockopt
118 #define real_setsockopt setsockopt
119 #define real_recvfrom recvfrom
120 #define real_sendto sendto
121 #define real_sendmsg sendmsg
122 #define real_ioctl ioctl
123 #define real_recv recv
124 #define real_send send
125 #define real_readv readv
126 #define real_writev writev
127 #define real_socket socket
128 #define real_close close
131 #ifdef HAVE_GETTIMEOFDAY_TZ
132 #define swrapGetTimeOfDay(tval) gettimeofday(tval,NULL)
134 #define swrapGetTimeOfDay(tval) gettimeofday(tval)
137 /* we need to use a very terse format here as IRIX 6.4 silently
138 truncates names to 16 chars, so if we use a longer name then we
139 can't tell which port a packet came from with recvfrom()
141 with this format we have 8 chars left for the directory name
143 #define SOCKET_FORMAT "%c%02X%04X"
144 #define SOCKET_TYPE_CHAR_TCP 'T'
145 #define SOCKET_TYPE_CHAR_UDP 'U'
146 #define SOCKET_TYPE_CHAR_TCP_V6 'X'
147 #define SOCKET_TYPE_CHAR_UDP_V6 'Y'
149 #define MAX_WRAPPED_INTERFACES 16
155 static const struct in6_addr *swrap_ipv6(void)
157 static struct in6_addr v;
158 static int initialized;
166 ret = inet_pton(AF_INET6, "FD00::5357:5F00", &v);
175 static struct sockaddr *sockaddr_dup(const void *data, socklen_t len)
177 struct sockaddr *ret = (struct sockaddr *)malloc(len);
178 memcpy(ret, data, len);
182 static void set_port(int family, int prt, struct sockaddr *addr)
186 ((struct sockaddr_in *)addr)->sin_port = htons(prt);
190 ((struct sockaddr_in6 *)addr)->sin6_port = htons(prt);
196 static size_t socket_length(int family)
200 return sizeof(struct sockaddr_in);
203 return sizeof(struct sockaddr_in6);
227 struct sockaddr *myname;
228 socklen_t myname_len;
230 struct sockaddr *peername;
231 socklen_t peername_len;
234 unsigned long pck_snd;
235 unsigned long pck_rcv;
238 struct socket_info *prev, *next;
241 static struct socket_info *sockets;
243 const char *socket_wrapper_dir(void)
245 const char *s = getenv("SOCKET_WRAPPER_DIR");
249 if (strncmp(s, "./", 2) == 0) {
255 unsigned int socket_wrapper_default_iface(void)
257 const char *s = getenv("SOCKET_WRAPPER_DEFAULT_IFACE");
260 if (sscanf(s, "%u", &iface) == 1) {
261 if (iface >= 1 && iface <= MAX_WRAPPED_INTERFACES) {
267 return 1;/* 127.0.0.1 */
270 static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, socklen_t *len)
277 p = strrchr(un->sun_path, '/');
278 if (p) p++; else p = un->sun_path;
280 if (sscanf(p, SOCKET_FORMAT, &type, &iface, &prt) != 3) {
285 if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
296 case SOCKET_TYPE_CHAR_TCP:
297 case SOCKET_TYPE_CHAR_UDP: {
298 struct sockaddr_in *in2 = (struct sockaddr_in *)in;
300 if ((*len) < sizeof(*in2)) {
305 memset(in2, 0, sizeof(*in2));
306 in2->sin_family = AF_INET;
307 in2->sin_addr.s_addr = htonl((127<<24) | iface);
308 in2->sin_port = htons(prt);
314 case SOCKET_TYPE_CHAR_TCP_V6:
315 case SOCKET_TYPE_CHAR_UDP_V6: {
316 struct sockaddr_in6 *in2 = (struct sockaddr_in6 *)in;
318 if ((*len) < sizeof(*in2)) {
323 memset(in2, 0, sizeof(*in2));
324 in2->sin6_family = AF_INET6;
325 in2->sin6_addr = *swrap_ipv6();
326 in2->sin6_addr.s6_addr[15] = iface;
327 in2->sin6_port = htons(prt);
341 static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un,
349 if (bcast) *bcast = 0;
351 switch (si->family) {
353 const struct sockaddr_in *in =
354 (const struct sockaddr_in *)inaddr;
355 unsigned int addr = ntohl(in->sin_addr.s_addr);
362 u_type = SOCKET_TYPE_CHAR_TCP;
365 u_type = SOCKET_TYPE_CHAR_UDP;
366 a_type = SOCKET_TYPE_CHAR_UDP;
367 b_type = SOCKET_TYPE_CHAR_UDP;
371 prt = ntohs(in->sin_port);
372 if (a_type && addr == 0xFFFFFFFF) {
373 /* 255.255.255.255 only udp */
376 iface = socket_wrapper_default_iface();
377 } else if (b_type && addr == 0x7FFFFFFF) {
378 /* 127.255.255.255 only udp */
381 iface = socket_wrapper_default_iface();
382 } else if ((addr & 0xFFFFFF00) == 0x7F000000) {
386 iface = (addr & 0x000000FF);
391 if (bcast) *bcast = is_bcast;
396 const struct sockaddr_in6 *in =
397 (const struct sockaddr_in6 *)inaddr;
402 type = SOCKET_TYPE_CHAR_TCP_V6;
405 type = SOCKET_TYPE_CHAR_UDP_V6;
409 /* XXX no multicast/broadcast */
411 prt = ntohs(in->sin6_port);
415 if (IN6_ARE_ADDR_EQUAL(swrap_ipv6(), &cmp)) {
416 iface = in->sin6_addr.s6_addr[15];
436 snprintf(un->sun_path, sizeof(un->sun_path), "%s/EINVAL",
437 socket_wrapper_dir());
438 /* the caller need to do more processing */
442 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT,
443 socket_wrapper_dir(), type, iface, prt);
448 static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un,
457 if (bcast) *bcast = 0;
459 switch (si->family) {
461 const struct sockaddr_in *in =
462 (const struct sockaddr_in *)inaddr;
463 unsigned int addr = ntohl(in->sin_addr.s_addr);
469 prt = ntohs(in->sin_port);
473 u_type = SOCKET_TYPE_CHAR_TCP;
474 d_type = SOCKET_TYPE_CHAR_TCP;
477 u_type = SOCKET_TYPE_CHAR_UDP;
478 d_type = SOCKET_TYPE_CHAR_UDP;
479 a_type = SOCKET_TYPE_CHAR_UDP;
480 b_type = SOCKET_TYPE_CHAR_UDP;
488 iface = socket_wrapper_default_iface();
489 } else if (a_type && addr == 0xFFFFFFFF) {
490 /* 255.255.255.255 only udp */
493 iface = socket_wrapper_default_iface();
494 } else if (b_type && addr == 0x7FFFFFFF) {
495 /* 127.255.255.255 only udp */
498 iface = socket_wrapper_default_iface();
499 } else if ((addr & 0xFFFFFF00) == 0x7F000000) {
503 iface = (addr & 0x000000FF);
505 errno = EADDRNOTAVAIL;
512 const struct sockaddr_in6 *in =
513 (const struct sockaddr_in6 *)inaddr;
518 type = SOCKET_TYPE_CHAR_TCP_V6;
521 type = SOCKET_TYPE_CHAR_UDP_V6;
525 /* XXX no multicast/broadcast */
527 prt = ntohs(in->sin6_port);
531 if (IN6_IS_ADDR_UNSPECIFIED(&in->sin6_addr)) {
532 iface = socket_wrapper_default_iface();
533 } else if (IN6_ARE_ADDR_EQUAL(swrap_ipv6(), &cmp)) {
534 iface = in->sin6_addr.s6_addr[15];
536 errno = EADDRNOTAVAIL;
544 errno = EADDRNOTAVAIL;
549 if (bcast) *bcast = is_bcast;
552 /* handle auto-allocation of ephemeral ports */
553 for (prt = 5001; prt < 10000; prt++) {
554 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT,
555 socket_wrapper_dir(), type, iface, prt);
556 if (stat(un->sun_path, &st) == 0) continue;
558 set_port(si->family, prt, si->myname);
567 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT,
568 socket_wrapper_dir(), type, iface, prt);
572 static struct socket_info *find_socket_info(int fd)
574 struct socket_info *i;
575 for (i = sockets; i; i = i->next) {
583 static int sockaddr_convert_to_un(struct socket_info *si, const struct sockaddr *in_addr, socklen_t in_len,
584 struct sockaddr_un *out_addr, int alloc_sock, int *bcast)
589 out_addr->sun_family = AF_UNIX;
591 switch (in_addr->sa_family) {
601 errno = ESOCKTNOSUPPORT;
605 return convert_in_un_alloc(si, in_addr, out_addr, bcast);
607 return convert_in_un_remote(si, in_addr, out_addr, bcast);
613 errno = EAFNOSUPPORT;
617 static int sockaddr_convert_from_un(const struct socket_info *si,
618 const struct sockaddr_un *in_addr,
619 socklen_t un_addrlen,
621 struct sockaddr *out_addr,
622 socklen_t *out_addrlen)
624 if (out_addr == NULL || out_addrlen == NULL)
627 if (un_addrlen == 0) {
642 errno = ESOCKTNOSUPPORT;
645 return convert_un_in(in_addr, out_addr, out_addrlen);
650 errno = EAFNOSUPPORT;
654 enum swrap_packet_type {
656 SWRAP_CONNECT_UNREACH,
664 SWRAP_SENDTO_UNREACH,
675 struct swrap_file_hdr {
677 uint16_t version_major;
678 uint16_t version_minor;
681 uint32_t frame_max_len;
682 #define SWRAP_FRAME_LENGTH_MAX 0xFFFF
685 #define SWRAP_FILE_HDR_SIZE 24
687 struct swrap_packet_frame {
689 uint32_t micro_seconds;
690 uint32_t recorded_length;
691 uint32_t full_length;
693 #define SWRAP_PACKET_FRAME_SIZE 16
695 union swrap_packet_ip {
699 uint16_t packet_length;
700 uint16_t identification;
705 uint16_t hdr_checksum;
709 #define SWRAP_PACKET_IP_V4_SIZE 20
712 uint8_t flow_label_high;
713 uint16_t flow_label_low;
714 uint16_t payload_length;
717 uint8_t src_addr[16];
718 uint8_t dest_addr[16];
720 #define SWRAP_PACKET_IP_V6_SIZE 40
722 #define SWRAP_PACKET_IP_SIZE 40
724 union swrap_packet_payload {
726 uint16_t source_port;
736 #define SWRAP_PACKET_PAYLOAD_TCP_SIZE 20
738 uint16_t source_port;
743 #define SWRAP_PACKET_PAYLOAD_UDP_SIZE 8
750 #define SWRAP_PACKET_PAYLOAD_ICMP4_SIZE 8
757 #define SWRAP_PACKET_PAYLOAD_ICMP6_SIZE 8
759 #define SWRAP_PACKET_PAYLOAD_SIZE 20
761 #define SWRAP_PACKET_MIN_ALLOC \
762 (SWRAP_PACKET_FRAME_SIZE + \
763 SWRAP_PACKET_IP_SIZE + \
764 SWRAP_PACKET_PAYLOAD_SIZE)
766 static const char *socket_wrapper_pcap_file(void)
768 static int initialized = 0;
769 static const char *s = NULL;
770 static const struct swrap_file_hdr h;
771 static const struct swrap_packet_frame f;
772 static const union swrap_packet_ip i;
773 static const union swrap_packet_payload p;
775 if (initialized == 1) {
781 * TODO: don't use the structs use plain buffer offsets
782 * and PUSH_U8(), PUSH_U16() and PUSH_U32()
784 * for now make sure we disable PCAP support
785 * if the struct has alignment!
787 if (sizeof(h) != SWRAP_FILE_HDR_SIZE) {
790 if (sizeof(f) != SWRAP_PACKET_FRAME_SIZE) {
793 if (sizeof(i) != SWRAP_PACKET_IP_SIZE) {
796 if (sizeof(i.v4) != SWRAP_PACKET_IP_V4_SIZE) {
799 if (sizeof(i.v6) != SWRAP_PACKET_IP_V6_SIZE) {
802 if (sizeof(p) != SWRAP_PACKET_PAYLOAD_SIZE) {
805 if (sizeof(p.tcp) != SWRAP_PACKET_PAYLOAD_TCP_SIZE) {
808 if (sizeof(p.udp) != SWRAP_PACKET_PAYLOAD_UDP_SIZE) {
811 if (sizeof(p.icmp4) != SWRAP_PACKET_PAYLOAD_ICMP4_SIZE) {
814 if (sizeof(p.icmp6) != SWRAP_PACKET_PAYLOAD_ICMP6_SIZE) {
818 s = getenv("SOCKET_WRAPPER_PCAP_FILE");
822 if (strncmp(s, "./", 2) == 0) {
828 static uint8_t *swrap_packet_init(struct timeval *tval,
829 const struct sockaddr *src,
830 const struct sockaddr *dest,
832 const uint8_t *payload,
834 unsigned long tcp_seqno,
835 unsigned long tcp_ack,
836 unsigned char tcp_ctl,
842 struct swrap_packet_frame *frame;
843 union swrap_packet_ip *ip;
844 union swrap_packet_payload *pay;
847 size_t nonwire_len = sizeof(*frame);
848 size_t wire_hdr_len = 0;
850 size_t ip_hdr_len = 0;
851 size_t icmp_hdr_len = 0;
852 size_t icmp_truncate_len = 0;
853 uint8_t protocol = 0, icmp_protocol = 0;
854 const struct sockaddr_in *src_in = NULL;
855 const struct sockaddr_in *dest_in = NULL;
857 const struct sockaddr_in6 *src_in6 = NULL;
858 const struct sockaddr_in6 *dest_in6 = NULL;
863 switch (src->sa_family) {
865 src_in = (const struct sockaddr_in *)src;
866 dest_in = (const struct sockaddr_in *)dest;
867 src_port = src_in->sin_port;
868 dest_port = dest_in->sin_port;
869 ip_hdr_len = sizeof(ip->v4);
873 src_in6 = (const struct sockaddr_in6 *)src;
874 dest_in6 = (const struct sockaddr_in6 *)dest;
875 src_port = src_in6->sin6_port;
876 dest_port = dest_in6->sin6_port;
877 ip_hdr_len = sizeof(ip->v6);
884 switch (socket_type) {
886 protocol = 0x06; /* TCP */
887 wire_hdr_len = ip_hdr_len + sizeof(pay->tcp);
888 wire_len = wire_hdr_len + payload_len;
892 protocol = 0x11; /* UDP */
893 wire_hdr_len = ip_hdr_len + sizeof(pay->udp);
894 wire_len = wire_hdr_len + payload_len;
902 icmp_protocol = protocol;
903 switch (src->sa_family) {
905 protocol = 0x01; /* ICMPv4 */
906 icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp4);
910 protocol = 0x3A; /* ICMPv6 */
911 icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp6);
915 if (wire_len > 64 ) {
916 icmp_truncate_len = wire_len - 64;
918 wire_hdr_len += icmp_hdr_len;
919 wire_len += icmp_hdr_len;
922 packet_len = nonwire_len + wire_len;
923 alloc_len = packet_len;
924 if (alloc_len < SWRAP_PACKET_MIN_ALLOC) {
925 alloc_len = SWRAP_PACKET_MIN_ALLOC;
928 base = (uint8_t *)malloc(alloc_len);
929 if (!base) return NULL;
933 frame = (struct swrap_packet_frame *)buf;
934 frame->seconds = tval->tv_sec;
935 frame->micro_seconds = tval->tv_usec;
936 frame->recorded_length = wire_len - icmp_truncate_len;
937 frame->full_length = wire_len - icmp_truncate_len;
938 buf += SWRAP_PACKET_FRAME_SIZE;
940 ip = (union swrap_packet_ip *)buf;
941 switch (src->sa_family) {
943 ip->v4.ver_hdrlen = 0x45; /* version 4 and 5 * 32 bit words */
945 ip->v4.packet_length = htons(wire_len - icmp_truncate_len);
946 ip->v4.identification = htons(0xFFFF);
947 ip->v4.flags = 0x40; /* BIT 1 set - means don't fraqment */
948 ip->v4.fragment = htons(0x0000);
950 ip->v4.protocol = protocol;
951 ip->v4.hdr_checksum = htons(0x0000);
952 ip->v4.src_addr = src_in->sin_addr.s_addr;
953 ip->v4.dest_addr = dest_in->sin_addr.s_addr;
954 buf += SWRAP_PACKET_IP_V4_SIZE;
958 ip->v6.ver_prio = 0x60; /* version 4 and 5 * 32 bit words */
959 ip->v6.flow_label_high = 0x00;
960 ip->v6.flow_label_low = 0x0000;
961 ip->v6.payload_length = htons(wire_len - icmp_truncate_len);//TODO
962 ip->v6.next_header = protocol;
963 memcpy(ip->v6.src_addr, src_in6->sin6_addr.s6_addr, 16);
964 memcpy(ip->v6.dest_addr, dest_in6->sin6_addr.s6_addr, 16);
965 buf += SWRAP_PACKET_IP_V6_SIZE;
971 pay = (union swrap_packet_payload *)buf;
972 switch (src->sa_family) {
974 pay->icmp4.type = 0x03; /* destination unreachable */
975 pay->icmp4.code = 0x01; /* host unreachable */
976 pay->icmp4.checksum = htons(0x0000);
977 pay->icmp4.unused = htonl(0x00000000);
978 buf += SWRAP_PACKET_PAYLOAD_ICMP4_SIZE;
980 /* set the ip header in the ICMP payload */
981 ip = (union swrap_packet_ip *)buf;
982 ip->v4.ver_hdrlen = 0x45; /* version 4 and 5 * 32 bit words */
984 ip->v4.packet_length = htons(wire_len - icmp_hdr_len);
985 ip->v4.identification = htons(0xFFFF);
986 ip->v4.flags = 0x40; /* BIT 1 set - means don't fraqment */
987 ip->v4.fragment = htons(0x0000);
989 ip->v4.protocol = icmp_protocol;
990 ip->v4.hdr_checksum = htons(0x0000);
991 ip->v4.src_addr = dest_in->sin_addr.s_addr;
992 ip->v4.dest_addr = src_in->sin_addr.s_addr;
993 buf += SWRAP_PACKET_IP_V4_SIZE;
995 src_port = dest_in->sin_port;
996 dest_port = src_in->sin_port;
1000 pay->icmp6.type = 0x01; /* destination unreachable */
1001 pay->icmp6.code = 0x03; /* address unreachable */
1002 pay->icmp6.checksum = htons(0x0000);
1003 pay->icmp6.unused = htonl(0x00000000);
1004 buf += SWRAP_PACKET_PAYLOAD_ICMP6_SIZE;
1006 /* set the ip header in the ICMP payload */
1007 ip = (union swrap_packet_ip *)buf;
1008 ip->v6.ver_prio = 0x60; /* version 4 and 5 * 32 bit words */
1009 ip->v6.flow_label_high = 0x00;
1010 ip->v6.flow_label_low = 0x0000;
1011 ip->v6.payload_length = htons(wire_len - icmp_truncate_len);//TODO
1012 ip->v6.next_header = protocol;
1013 memcpy(ip->v6.src_addr, dest_in6->sin6_addr.s6_addr, 16);
1014 memcpy(ip->v6.dest_addr, src_in6->sin6_addr.s6_addr, 16);
1015 buf += SWRAP_PACKET_IP_V6_SIZE;
1017 src_port = dest_in6->sin6_port;
1018 dest_port = src_in6->sin6_port;
1024 pay = (union swrap_packet_payload *)buf;
1026 switch (socket_type) {
1028 pay->tcp.source_port = src_port;
1029 pay->tcp.dest_port = dest_port;
1030 pay->tcp.seq_num = htonl(tcp_seqno);
1031 pay->tcp.ack_num = htonl(tcp_ack);
1032 pay->tcp.hdr_length = 0x50; /* 5 * 32 bit words */
1033 pay->tcp.control = tcp_ctl;
1034 pay->tcp.window = htons(0x7FFF);
1035 pay->tcp.checksum = htons(0x0000);
1036 pay->tcp.urg = htons(0x0000);
1037 buf += SWRAP_PACKET_PAYLOAD_TCP_SIZE;
1042 pay->udp.source_port = src_port;
1043 pay->udp.dest_port = dest_port;
1044 pay->udp.length = htons(8 + payload_len);
1045 pay->udp.checksum = htons(0x0000);
1046 buf += SWRAP_PACKET_PAYLOAD_UDP_SIZE;
1051 if (payload && payload_len > 0) {
1052 memcpy(buf, payload, payload_len);
1055 *_packet_len = packet_len - icmp_truncate_len;
1059 static int swrap_get_pcap_fd(const char *fname)
1063 if (fd != -1) return fd;
1065 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0644);
1067 struct swrap_file_hdr file_hdr;
1068 file_hdr.magic = 0xA1B2C3D4;
1069 file_hdr.version_major = 0x0002;
1070 file_hdr.version_minor = 0x0004;
1071 file_hdr.timezone = 0x00000000;
1072 file_hdr.sigfigs = 0x00000000;
1073 file_hdr.frame_max_len = SWRAP_FRAME_LENGTH_MAX;
1074 file_hdr.link_type = 0x0065; /* 101 RAW IP */
1076 if (write(fd, &file_hdr, sizeof(file_hdr)) != sizeof(file_hdr)) {
1083 fd = open(fname, O_WRONLY|O_APPEND, 0644);
1088 static uint8_t *swrap_marshall_packet(struct socket_info *si,
1089 const struct sockaddr *addr,
1090 enum swrap_packet_type type,
1091 const void *buf, size_t len,
1094 const struct sockaddr *src_addr;
1095 const struct sockaddr *dest_addr;
1096 unsigned long tcp_seqno = 0;
1097 unsigned long tcp_ack = 0;
1098 unsigned char tcp_ctl = 0;
1099 int unreachable = 0;
1103 switch (si->family) {
1115 case SWRAP_CONNECT_SEND:
1116 if (si->type != SOCK_STREAM) return NULL;
1118 src_addr = si->myname;
1121 tcp_seqno = si->io.pck_snd;
1122 tcp_ack = si->io.pck_rcv;
1123 tcp_ctl = 0x02; /* SYN */
1125 si->io.pck_snd += 1;
1129 case SWRAP_CONNECT_RECV:
1130 if (si->type != SOCK_STREAM) return NULL;
1132 dest_addr = si->myname;
1135 tcp_seqno = si->io.pck_rcv;
1136 tcp_ack = si->io.pck_snd;
1137 tcp_ctl = 0x12; /** SYN,ACK */
1139 si->io.pck_rcv += 1;
1143 case SWRAP_CONNECT_UNREACH:
1144 if (si->type != SOCK_STREAM) return NULL;
1146 dest_addr = si->myname;
1149 /* Unreachable: resend the data of SWRAP_CONNECT_SEND */
1150 tcp_seqno = si->io.pck_snd - 1;
1151 tcp_ack = si->io.pck_rcv;
1152 tcp_ctl = 0x02; /* SYN */
1157 case SWRAP_CONNECT_ACK:
1158 if (si->type != SOCK_STREAM) return NULL;
1160 src_addr = si->myname;
1163 tcp_seqno = si->io.pck_snd;
1164 tcp_ack = si->io.pck_rcv;
1165 tcp_ctl = 0x10; /* ACK */
1169 case SWRAP_ACCEPT_SEND:
1170 if (si->type != SOCK_STREAM) return NULL;
1172 dest_addr = si->myname;
1175 tcp_seqno = si->io.pck_rcv;
1176 tcp_ack = si->io.pck_snd;
1177 tcp_ctl = 0x02; /* SYN */
1179 si->io.pck_rcv += 1;
1183 case SWRAP_ACCEPT_RECV:
1184 if (si->type != SOCK_STREAM) return NULL;
1186 src_addr = si->myname;
1189 tcp_seqno = si->io.pck_snd;
1190 tcp_ack = si->io.pck_rcv;
1191 tcp_ctl = 0x12; /* SYN,ACK */
1193 si->io.pck_snd += 1;
1197 case SWRAP_ACCEPT_ACK:
1198 if (si->type != SOCK_STREAM) return NULL;
1200 dest_addr = si->myname;
1203 tcp_seqno = si->io.pck_rcv;
1204 tcp_ack = si->io.pck_snd;
1205 tcp_ctl = 0x10; /* ACK */
1210 src_addr = si->myname;
1211 dest_addr = si->peername;
1213 tcp_seqno = si->io.pck_snd;
1214 tcp_ack = si->io.pck_rcv;
1215 tcp_ctl = 0x18; /* PSH,ACK */
1217 si->io.pck_snd += len;
1221 case SWRAP_SEND_RST:
1222 dest_addr = si->myname;
1223 src_addr = si->peername;
1225 if (si->type == SOCK_DGRAM) {
1226 return swrap_marshall_packet(si, si->peername,
1227 SWRAP_SENDTO_UNREACH,
1228 buf, len, packet_len);
1231 tcp_seqno = si->io.pck_rcv;
1232 tcp_ack = si->io.pck_snd;
1233 tcp_ctl = 0x14; /** RST,ACK */
1237 case SWRAP_PENDING_RST:
1238 dest_addr = si->myname;
1239 src_addr = si->peername;
1241 if (si->type == SOCK_DGRAM) {
1245 tcp_seqno = si->io.pck_rcv;
1246 tcp_ack = si->io.pck_snd;
1247 tcp_ctl = 0x14; /* RST,ACK */
1252 dest_addr = si->myname;
1253 src_addr = si->peername;
1255 tcp_seqno = si->io.pck_rcv;
1256 tcp_ack = si->io.pck_snd;
1257 tcp_ctl = 0x18; /* PSH,ACK */
1259 si->io.pck_rcv += len;
1263 case SWRAP_RECV_RST:
1264 dest_addr = si->myname;
1265 src_addr = si->peername;
1267 if (si->type == SOCK_DGRAM) {
1271 tcp_seqno = si->io.pck_rcv;
1272 tcp_ack = si->io.pck_snd;
1273 tcp_ctl = 0x14; /* RST,ACK */
1278 src_addr = si->myname;
1281 si->io.pck_snd += len;
1285 case SWRAP_SENDTO_UNREACH:
1286 dest_addr = si->myname;
1293 case SWRAP_RECVFROM:
1294 dest_addr = si->myname;
1297 si->io.pck_rcv += len;
1301 case SWRAP_CLOSE_SEND:
1302 if (si->type != SOCK_STREAM) return NULL;
1304 src_addr = si->myname;
1305 dest_addr = si->peername;
1307 tcp_seqno = si->io.pck_snd;
1308 tcp_ack = si->io.pck_rcv;
1309 tcp_ctl = 0x11; /* FIN, ACK */
1311 si->io.pck_snd += 1;
1315 case SWRAP_CLOSE_RECV:
1316 if (si->type != SOCK_STREAM) return NULL;
1318 dest_addr = si->myname;
1319 src_addr = si->peername;
1321 tcp_seqno = si->io.pck_rcv;
1322 tcp_ack = si->io.pck_snd;
1323 tcp_ctl = 0x11; /* FIN,ACK */
1325 si->io.pck_rcv += 1;
1329 case SWRAP_CLOSE_ACK:
1330 if (si->type != SOCK_STREAM) return NULL;
1332 src_addr = si->myname;
1333 dest_addr = si->peername;
1335 tcp_seqno = si->io.pck_snd;
1336 tcp_ack = si->io.pck_rcv;
1337 tcp_ctl = 0x10; /* ACK */
1344 swrapGetTimeOfDay(&tv);
1346 return swrap_packet_init(&tv, src_addr, dest_addr, si->type,
1347 (const uint8_t *)buf, len,
1348 tcp_seqno, tcp_ack, tcp_ctl, unreachable,
1352 static void swrap_dump_packet(struct socket_info *si,
1353 const struct sockaddr *addr,
1354 enum swrap_packet_type type,
1355 const void *buf, size_t len)
1357 const char *file_name;
1359 size_t packet_len = 0;
1362 file_name = socket_wrapper_pcap_file();
1367 packet = swrap_marshall_packet(si, addr, type, buf, len, &packet_len);
1372 fd = swrap_get_pcap_fd(file_name);
1374 if (write(fd, packet, packet_len) != packet_len) {
1383 _PUBLIC_ int swrap_socket(int family, int type, int protocol)
1385 struct socket_info *si;
1387 int real_type = type;
1389 real_type &= ~SOCK_CLOEXEC;
1391 #ifdef SOCK_NONBLOCK
1392 real_type &= ~SOCK_NONBLOCK;
1395 if (!socket_wrapper_dir()) {
1396 return real_socket(family, type, protocol);
1406 return real_socket(family, type, protocol);
1408 errno = EAFNOSUPPORT;
1412 switch (real_type) {
1418 errno = EPROTONOSUPPORT;
1426 if (real_type == SOCK_STREAM) {
1431 if (real_type == SOCK_DGRAM) {
1436 errno = EPROTONOSUPPORT;
1440 /* We must call real_socket with type, from the caller, not the version we removed
1441 SOCK_CLOEXEC and SOCK_NONBLOCK from */
1442 fd = real_socket(AF_UNIX, type, 0);
1444 if (fd == -1) return -1;
1446 si = (struct socket_info *)calloc(1, sizeof(struct socket_info));
1448 si->family = family;
1450 /* however, the rest of the socket_wrapper code expects just
1451 * the type, not the flags */
1452 si->type = real_type;
1453 si->protocol = protocol;
1456 SWRAP_DLIST_ADD(sockets, si);
1461 _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
1463 struct socket_info *parent_si, *child_si;
1465 struct sockaddr_un un_addr;
1466 socklen_t un_addrlen = sizeof(un_addr);
1467 struct sockaddr_un un_my_addr;
1468 socklen_t un_my_addrlen = sizeof(un_my_addr);
1469 struct sockaddr *my_addr;
1470 socklen_t my_addrlen, len;
1473 parent_si = find_socket_info(s);
1475 return real_accept(s, addr, addrlen);
1479 * assume out sockaddr have the same size as the in parent
1482 my_addrlen = socket_length(parent_si->family);
1483 if (my_addrlen <= 0) {
1488 my_addr = (struct sockaddr *)malloc(my_addrlen);
1489 if (my_addr == NULL) {
1493 memset(&un_addr, 0, sizeof(un_addr));
1494 memset(&un_my_addr, 0, sizeof(un_my_addr));
1496 ret = real_accept(s, (struct sockaddr *)&un_addr, &un_addrlen);
1505 ret = sockaddr_convert_from_un(parent_si, &un_addr, un_addrlen,
1506 parent_si->family, my_addr, &len);
1513 child_si = (struct socket_info *)malloc(sizeof(struct socket_info));
1514 memset(child_si, 0, sizeof(*child_si));
1517 child_si->family = parent_si->family;
1518 child_si->type = parent_si->type;
1519 child_si->protocol = parent_si->protocol;
1520 child_si->bound = 1;
1521 child_si->is_server = 1;
1522 child_si->connected = 1;
1524 child_si->peername_len = len;
1525 child_si->peername = sockaddr_dup(my_addr, len);
1527 if (addr != NULL && addrlen != NULL) {
1529 if (*addrlen >= len)
1530 memcpy(addr, my_addr, len);
1534 ret = real_getsockname(fd, (struct sockaddr *)&un_my_addr, &un_my_addrlen);
1542 ret = sockaddr_convert_from_un(child_si, &un_my_addr, un_my_addrlen,
1543 child_si->family, my_addr, &len);
1551 child_si->myname_len = len;
1552 child_si->myname = sockaddr_dup(my_addr, len);
1555 SWRAP_DLIST_ADD(sockets, child_si);
1557 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0);
1558 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_RECV, NULL, 0);
1559 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_ACK, NULL, 0);
1564 static int autobind_start_init;
1565 static int autobind_start;
1567 /* using sendto() or connect() on an unbound socket would give the
1568 recipient no way to reply, as unlike UDP and TCP, a unix domain
1569 socket can't auto-assign emphemeral port numbers, so we need to
1571 Note: this might change the family from ipv6 to ipv4
1573 static int swrap_auto_bind(struct socket_info *si, int family)
1575 struct sockaddr_un un_addr;
1582 if (autobind_start_init != 1) {
1583 autobind_start_init = 1;
1584 autobind_start = getpid();
1585 autobind_start %= 50000;
1586 autobind_start += 10000;
1589 un_addr.sun_family = AF_UNIX;
1593 struct sockaddr_in in;
1597 type = SOCKET_TYPE_CHAR_TCP;
1600 type = SOCKET_TYPE_CHAR_UDP;
1603 errno = ESOCKTNOSUPPORT;
1607 memset(&in, 0, sizeof(in));
1608 in.sin_family = AF_INET;
1609 in.sin_addr.s_addr = htonl(127<<24 |
1610 socket_wrapper_default_iface());
1612 si->myname_len = sizeof(in);
1613 si->myname = sockaddr_dup(&in, si->myname_len);
1618 struct sockaddr_in6 in6;
1620 if (si->family != family) {
1621 errno = ENETUNREACH;
1627 type = SOCKET_TYPE_CHAR_TCP_V6;
1630 type = SOCKET_TYPE_CHAR_UDP_V6;
1633 errno = ESOCKTNOSUPPORT;
1637 memset(&in6, 0, sizeof(in6));
1638 in6.sin6_family = AF_INET6;
1639 in6.sin6_addr = *swrap_ipv6();
1640 in6.sin6_addr.s6_addr[15] = socket_wrapper_default_iface();
1641 si->myname_len = sizeof(in6);
1642 si->myname = sockaddr_dup(&in6, si->myname_len);
1647 errno = ESOCKTNOSUPPORT;
1651 if (autobind_start > 60000) {
1652 autobind_start = 10000;
1655 for (i=0;i<1000;i++) {
1656 port = autobind_start + i;
1657 snprintf(un_addr.sun_path, sizeof(un_addr.sun_path),
1658 "%s/"SOCKET_FORMAT, socket_wrapper_dir(),
1659 type, socket_wrapper_default_iface(), port);
1660 if (stat(un_addr.sun_path, &st) == 0) continue;
1662 ret = real_bind(si->fd, (struct sockaddr *)&un_addr, sizeof(un_addr));
1663 if (ret == -1) return ret;
1665 si->tmp_path = strdup(un_addr.sun_path);
1667 autobind_start = port + 1;
1675 si->family = family;
1676 set_port(si->family, port, si->myname);
1682 _PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen)
1685 struct sockaddr_un un_addr;
1686 struct socket_info *si = find_socket_info(s);
1689 return real_connect(s, serv_addr, addrlen);
1692 if (si->bound == 0) {
1693 ret = swrap_auto_bind(si, serv_addr->sa_family);
1694 if (ret == -1) return -1;
1697 if (si->family != serv_addr->sa_family) {
1702 ret = sockaddr_convert_to_un(si, (const struct sockaddr *)serv_addr, addrlen, &un_addr, 0, NULL);
1703 if (ret == -1) return -1;
1705 if (si->type == SOCK_DGRAM) {
1706 si->defer_connect = 1;
1709 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0);
1711 ret = real_connect(s, (struct sockaddr *)&un_addr,
1712 sizeof(struct sockaddr_un));
1715 /* to give better errors */
1716 if (ret == -1 && errno == ENOENT) {
1717 errno = EHOSTUNREACH;
1721 si->peername_len = addrlen;
1722 si->peername = sockaddr_dup(serv_addr, addrlen);
1725 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0);
1726 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0);
1728 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0);
1734 _PUBLIC_ int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
1737 struct sockaddr_un un_addr;
1738 struct socket_info *si = find_socket_info(s);
1741 return real_bind(s, myaddr, addrlen);
1744 si->myname_len = addrlen;
1745 si->myname = sockaddr_dup(myaddr, addrlen);
1747 ret = sockaddr_convert_to_un(si, (const struct sockaddr *)myaddr, addrlen, &un_addr, 1, &si->bcast);
1748 if (ret == -1) return -1;
1750 unlink(un_addr.sun_path);
1752 ret = real_bind(s, (struct sockaddr *)&un_addr,
1753 sizeof(struct sockaddr_un));
1762 _PUBLIC_ int swrap_listen(int s, int backlog)
1765 struct socket_info *si = find_socket_info(s);
1768 return real_listen(s, backlog);
1771 ret = real_listen(s, backlog);
1776 _PUBLIC_ int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
1778 struct socket_info *si = find_socket_info(s);
1781 return real_getpeername(s, name, addrlen);
1790 memcpy(name, si->peername, si->peername_len);
1791 *addrlen = si->peername_len;
1796 _PUBLIC_ int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
1798 struct socket_info *si = find_socket_info(s);
1801 return real_getsockname(s, name, addrlen);
1804 memcpy(name, si->myname, si->myname_len);
1805 *addrlen = si->myname_len;
1810 _PUBLIC_ int swrap_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
1812 struct socket_info *si = find_socket_info(s);
1815 return real_getsockopt(s, level, optname, optval, optlen);
1818 if (level == SOL_SOCKET) {
1819 return real_getsockopt(s, level, optname, optval, optlen);
1822 errno = ENOPROTOOPT;
1826 _PUBLIC_ int swrap_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
1828 struct socket_info *si = find_socket_info(s);
1831 return real_setsockopt(s, level, optname, optval, optlen);
1834 if (level == SOL_SOCKET) {
1835 return real_setsockopt(s, level, optname, optval, optlen);
1838 switch (si->family) {
1842 errno = ENOPROTOOPT;
1847 _PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
1849 struct sockaddr_un un_addr;
1850 socklen_t un_addrlen = sizeof(un_addr);
1852 struct socket_info *si = find_socket_info(s);
1853 struct sockaddr_storage ss;
1854 socklen_t ss_len = sizeof(ss);
1857 return real_recvfrom(s, buf, len, flags, from, fromlen);
1861 from = (struct sockaddr *)&ss;
1865 len = MIN(len, 1500);
1867 /* irix 6.4 forgets to null terminate the sun_path string :-( */
1868 memset(&un_addr, 0, sizeof(un_addr));
1869 ret = real_recvfrom(s, buf, len, flags, (struct sockaddr *)&un_addr, &un_addrlen);
1873 if (sockaddr_convert_from_un(si, &un_addr, un_addrlen,
1874 si->family, from, fromlen) == -1) {
1878 swrap_dump_packet(si, from, SWRAP_RECVFROM, buf, ret);
1884 _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
1886 struct sockaddr_un un_addr;
1888 struct socket_info *si = find_socket_info(s);
1892 return real_sendto(s, buf, len, flags, to, tolen);
1895 if (si->connected) {
1902 tolen = si->peername_len;
1905 len = MIN(len, 1500);
1909 ret = real_send(s, buf, len, flags);
1912 if (si->bound == 0) {
1913 ret = swrap_auto_bind(si, si->family);
1914 if (ret == -1) return -1;
1917 ret = sockaddr_convert_to_un(si, to, tolen, &un_addr, 0, &bcast);
1918 if (ret == -1) return -1;
1923 unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port);
1926 type = SOCKET_TYPE_CHAR_UDP;
1928 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
1929 snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT,
1930 socket_wrapper_dir(), type, iface, prt);
1931 if (stat(un_addr.sun_path, &st) != 0) continue;
1933 /* ignore the any errors in broadcast sends */
1934 real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr));
1937 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
1942 if (si->defer_connect) {
1943 ret = real_connect(s, (struct sockaddr *)&un_addr,
1946 /* to give better errors */
1947 if (ret == -1 && errno == ENOENT) {
1948 errno = EHOSTUNREACH;
1954 si->defer_connect = 0;
1957 ret = real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr));
1961 errno = EHOSTUNREACH;
1965 /* to give better errors */
1966 if (ret == -1 && errno == ENOENT) {
1967 errno = EHOSTUNREACH;
1971 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
1972 swrap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);
1974 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, ret);
1980 _PUBLIC_ int swrap_ioctl(int s, int r, void *p)
1983 struct socket_info *si = find_socket_info(s);
1987 return real_ioctl(s, r, p);
1990 ret = real_ioctl(s, r, p);
1994 value = *((int *)p);
1995 if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
1996 swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
1997 } else if (value == 0) { /* END OF FILE */
1998 swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
2006 _PUBLIC_ ssize_t swrap_recv(int s, void *buf, size_t len, int flags)
2009 struct socket_info *si = find_socket_info(s);
2012 return real_recv(s, buf, len, flags);
2015 len = MIN(len, 1500);
2017 ret = real_recv(s, buf, len, flags);
2018 if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
2019 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
2020 } else if (ret == 0) { /* END OF FILE */
2021 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
2022 } else if (ret > 0) {
2023 swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
2030 _PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
2033 struct socket_info *si = find_socket_info(s);
2036 return real_send(s, buf, len, flags);
2039 len = MIN(len, 1500);
2041 if (si->defer_connect) {
2042 struct sockaddr_un un_addr;
2045 if (si->bound == 0) {
2046 ret = swrap_auto_bind(si, si->family);
2047 if (ret == -1) return -1;
2050 ret = sockaddr_convert_to_un(si, si->peername, si->peername_len,
2051 &un_addr, 0, &bcast);
2052 if (ret == -1) return -1;
2054 ret = real_connect(s, (struct sockaddr *)&un_addr,
2057 /* to give better errors */
2058 if (ret == -1 && errno == ENOENT) {
2059 errno = EHOSTUNREACH;
2065 si->defer_connect = 0;
2068 ret = real_send(s, buf, len, flags);
2071 swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
2072 swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
2074 swrap_dump_packet(si, NULL, SWRAP_SEND, buf, ret);
2080 _PUBLIC_ ssize_t swrap_sendmsg(int s, const struct msghdr *msg, int flags)
2088 struct socket_info *si = find_socket_info(s);
2091 return real_sendmsg(s, msg, flags);
2094 if (si->defer_connect) {
2095 struct sockaddr_un un_addr;
2098 if (si->bound == 0) {
2099 ret = swrap_auto_bind(si, si->family);
2100 if (ret == -1) return -1;
2103 ret = sockaddr_convert_to_un(si, si->peername, si->peername_len,
2104 &un_addr, 0, &bcast);
2105 if (ret == -1) return -1;
2107 ret = real_connect(s, (struct sockaddr *)&un_addr,
2110 /* to give better errors */
2111 if (ret == -1 && errno == ENOENT) {
2112 errno = EHOSTUNREACH;
2118 si->defer_connect = 0;
2121 ret = real_sendmsg(s, msg, flags);
2124 /* we capture it as one single packet */
2125 buf = (uint8_t *)malloc(ret);
2127 /* we just not capture the packet */
2132 for (i=0; i < msg->msg_iovlen; i++) {
2133 size_t this_time = MIN(remain, msg->msg_iov[i].iov_len);
2135 msg->msg_iov[i].iov_base,
2138 remain -= this_time;
2141 swrap_dump_packet(si, NULL, SWRAP_SEND, buf, ret);
2144 swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
2150 int swrap_readv(int s, const struct iovec *vector, size_t count)
2153 struct socket_info *si = find_socket_info(s);
2157 return real_readv(s, vector, count);
2160 /* we read 1500 bytes as maximum */
2164 for (i=0; i < count; i++) {
2166 nlen = len + vector[i].iov_len;
2174 v.iov_len = MIN(v.iov_len, 1500);
2180 ret = real_readv(s, vector, count);
2181 if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
2182 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
2183 } else if (ret == 0) { /* END OF FILE */
2184 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
2185 } else if (ret > 0) {
2189 size_t remain = ret;
2191 /* we capture it as one single packet */
2192 buf = (uint8_t *)malloc(ret);
2194 /* we just not capture the packet */
2199 for (i=0; i < count; i++) {
2200 size_t this_time = MIN(remain, vector[i].iov_len);
2205 remain -= this_time;
2208 swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
2215 int swrap_writev(int s, const struct iovec *vector, size_t count)
2218 struct socket_info *si = find_socket_info(s);
2222 return real_writev(s, vector, count);
2225 /* we write 1500 bytes as maximum */
2229 for (i=0; i < count; i++) {
2231 nlen = len + vector[i].iov_len;
2239 v.iov_len = MIN(v.iov_len, 1500);
2245 ret = real_writev(s, vector, count);
2247 swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
2252 size_t remain = ret;
2254 /* we capture it as one single packet */
2255 buf = (uint8_t *)malloc(ret);
2257 /* we just not capture the packet */
2262 for (i=0; i < count; i++) {
2263 size_t this_time = MIN(remain, vector[i].iov_len);
2268 remain -= this_time;
2271 swrap_dump_packet(si, NULL, SWRAP_SEND, buf, ret);
2278 _PUBLIC_ int swrap_close(int fd)
2280 struct socket_info *si = find_socket_info(fd);
2284 return real_close(fd);
2287 SWRAP_DLIST_REMOVE(sockets, si);
2289 if (si->myname && si->peername) {
2290 swrap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0);
2293 ret = real_close(fd);
2295 if (si->myname && si->peername) {
2296 swrap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0);
2297 swrap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0);
2300 if (si->path) free(si->path);
2301 if (si->myname) free(si->myname);
2302 if (si->peername) free(si->peername);
2304 unlink(si->tmp_path);