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 #ifdef HAVE_LIBREPLACE
46 #define SOCKET_WRAPPER_NOT_REPLACE
48 #include "system/network.h"
49 #include "system/filesys.h"
50 #include "system/time.h"
52 #else /* HAVE_LIBREPLACE */
54 #include <sys/types.h>
57 #include <sys/socket.h>
58 #include <sys/ioctl.h>
59 #include <sys/filio.h>
62 #include <netinet/in.h>
63 #include <netinet/tcp.h>
71 #endif /* HAVE_LIBREPLACE */
77 #define SWRAP_DLIST_ADD(list,item) do { \
79 (item)->prev = NULL; \
80 (item)->next = NULL; \
83 (item)->prev = NULL; \
84 (item)->next = (list); \
85 (list)->prev = (item); \
90 #define SWRAP_DLIST_REMOVE(list,item) do { \
91 if ((list) == (item)) { \
92 (list) = (item)->next; \
94 (list)->prev = NULL; \
98 (item)->prev->next = (item)->next; \
100 if ((item)->next) { \
101 (item)->next->prev = (item)->prev; \
104 (item)->prev = NULL; \
105 (item)->next = NULL; \
108 /* LD_PRELOAD doesn't work yet, so REWRITE_CALLS is all we support
110 #define REWRITE_CALLS
113 #define real_accept accept
114 #define real_connect connect
115 #define real_bind bind
116 #define real_listen listen
117 #define real_getpeername getpeername
118 #define real_getsockname getsockname
119 #define real_getsockopt getsockopt
120 #define real_setsockopt setsockopt
121 #define real_recvfrom recvfrom
122 #define real_sendto sendto
123 #define real_sendmsg sendmsg
124 #define real_ioctl ioctl
125 #define real_recv recv
126 #define real_read read
127 #define real_send send
128 #define real_readv readv
129 #define real_writev writev
130 #define real_socket socket
131 #define real_close close
133 #define real_dup2 dup2
136 #ifdef HAVE_GETTIMEOFDAY_TZ
137 #define swrapGetTimeOfDay(tval) gettimeofday(tval,NULL)
139 #define swrapGetTimeOfDay(tval) gettimeofday(tval)
142 /* we need to use a very terse format here as IRIX 6.4 silently
143 truncates names to 16 chars, so if we use a longer name then we
144 can't tell which port a packet came from with recvfrom()
146 with this format we have 8 chars left for the directory name
148 #define SOCKET_FORMAT "%c%02X%04X"
149 #define SOCKET_TYPE_CHAR_TCP 'T'
150 #define SOCKET_TYPE_CHAR_UDP 'U'
151 #define SOCKET_TYPE_CHAR_TCP_V6 'X'
152 #define SOCKET_TYPE_CHAR_UDP_V6 'Y'
154 /* This limit is to avoid broadcast sendto() needing to stat too many
155 * files. It may be raised (with a performance cost) to up to 254
156 * without changing the format above */
157 #define MAX_WRAPPED_INTERFACES 40
163 static const struct in6_addr
*swrap_ipv6(void)
165 static struct in6_addr v
;
166 static int initialized
;
174 ret
= inet_pton(AF_INET6
, "FD00::5357:5F00", &v
);
183 static struct sockaddr
*sockaddr_dup(const void *data
, socklen_t len
)
185 struct sockaddr
*ret
= (struct sockaddr
*)malloc(len
);
186 memcpy(ret
, data
, len
);
190 static void set_port(int family
, int prt
, struct sockaddr
*addr
)
194 ((struct sockaddr_in
*)addr
)->sin_port
= htons(prt
);
198 ((struct sockaddr_in6
*)addr
)->sin6_port
= htons(prt
);
204 static size_t socket_length(int family
)
208 return sizeof(struct sockaddr_in
);
211 return sizeof(struct sockaddr_in6
);
217 struct socket_info_fd
{
218 struct socket_info_fd
*prev
, *next
;
224 struct socket_info_fd
*fds
;
237 struct sockaddr
*myname
;
238 socklen_t myname_len
;
240 struct sockaddr
*peername
;
241 socklen_t peername_len
;
244 unsigned long pck_snd
;
245 unsigned long pck_rcv
;
248 struct socket_info
*prev
, *next
;
251 static struct socket_info
*sockets
;
253 const char *socket_wrapper_dir(void)
255 const char *s
= getenv("SOCKET_WRAPPER_DIR");
259 if (strncmp(s
, "./", 2) == 0) {
265 unsigned int socket_wrapper_default_iface(void)
267 const char *s
= getenv("SOCKET_WRAPPER_DEFAULT_IFACE");
270 if (sscanf(s
, "%u", &iface
) == 1) {
271 if (iface
>= 1 && iface
<= MAX_WRAPPED_INTERFACES
) {
277 return 1;/* 127.0.0.1 */
280 static int convert_un_in(const struct sockaddr_un
*un
, struct sockaddr
*in
, socklen_t
*len
)
287 p
= strrchr(un
->sun_path
, '/');
288 if (p
) p
++; else p
= un
->sun_path
;
290 if (sscanf(p
, SOCKET_FORMAT
, &type
, &iface
, &prt
) != 3) {
295 if (iface
== 0 || iface
> MAX_WRAPPED_INTERFACES
) {
306 case SOCKET_TYPE_CHAR_TCP
:
307 case SOCKET_TYPE_CHAR_UDP
: {
308 struct sockaddr_in
*in2
= (struct sockaddr_in
*)(void *)in
;
310 if ((*len
) < sizeof(*in2
)) {
315 memset(in2
, 0, sizeof(*in2
));
316 in2
->sin_family
= AF_INET
;
317 in2
->sin_addr
.s_addr
= htonl((127<<24) | iface
);
318 in2
->sin_port
= htons(prt
);
324 case SOCKET_TYPE_CHAR_TCP_V6
:
325 case SOCKET_TYPE_CHAR_UDP_V6
: {
326 struct sockaddr_in6
*in2
= (struct sockaddr_in6
*)(void *)in
;
328 if ((*len
) < sizeof(*in2
)) {
333 memset(in2
, 0, sizeof(*in2
));
334 in2
->sin6_family
= AF_INET6
;
335 in2
->sin6_addr
= *swrap_ipv6();
336 in2
->sin6_addr
.s6_addr
[15] = iface
;
337 in2
->sin6_port
= htons(prt
);
351 static int convert_in_un_remote(struct socket_info
*si
, const struct sockaddr
*inaddr
, struct sockaddr_un
*un
,
359 if (bcast
) *bcast
= 0;
361 switch (inaddr
->sa_family
) {
363 const struct sockaddr_in
*in
=
364 (const struct sockaddr_in
*)(const void *)inaddr
;
365 unsigned int addr
= ntohl(in
->sin_addr
.s_addr
);
372 u_type
= SOCKET_TYPE_CHAR_TCP
;
375 u_type
= SOCKET_TYPE_CHAR_UDP
;
376 a_type
= SOCKET_TYPE_CHAR_UDP
;
377 b_type
= SOCKET_TYPE_CHAR_UDP
;
381 prt
= ntohs(in
->sin_port
);
382 if (a_type
&& addr
== 0xFFFFFFFF) {
383 /* 255.255.255.255 only udp */
386 iface
= socket_wrapper_default_iface();
387 } else if (b_type
&& addr
== 0x7FFFFFFF) {
388 /* 127.255.255.255 only udp */
391 iface
= socket_wrapper_default_iface();
392 } else if ((addr
& 0xFFFFFF00) == 0x7F000000) {
396 iface
= (addr
& 0x000000FF);
401 if (bcast
) *bcast
= is_bcast
;
406 const struct sockaddr_in6
*in
=
407 (const struct sockaddr_in6
*)(const void *)inaddr
;
408 struct in6_addr cmp1
, cmp2
;
412 type
= SOCKET_TYPE_CHAR_TCP_V6
;
415 type
= SOCKET_TYPE_CHAR_UDP_V6
;
419 /* XXX no multicast/broadcast */
421 prt
= ntohs(in
->sin6_port
);
423 cmp1
= *swrap_ipv6();
424 cmp2
= in
->sin6_addr
;
425 cmp2
.s6_addr
[15] = 0;
426 if (IN6_ARE_ADDR_EQUAL(&cmp1
, &cmp2
)) {
427 iface
= in
->sin6_addr
.s6_addr
[15];
447 snprintf(un
->sun_path
, sizeof(un
->sun_path
), "%s/EINVAL",
448 socket_wrapper_dir());
449 /* the caller need to do more processing */
453 snprintf(un
->sun_path
, sizeof(un
->sun_path
), "%s/"SOCKET_FORMAT
,
454 socket_wrapper_dir(), type
, iface
, prt
);
459 static int convert_in_un_alloc(struct socket_info
*si
, const struct sockaddr
*inaddr
, struct sockaddr_un
*un
,
468 if (bcast
) *bcast
= 0;
470 switch (si
->family
) {
472 const struct sockaddr_in
*in
=
473 (const struct sockaddr_in
*)(const void *)inaddr
;
474 unsigned int addr
= ntohl(in
->sin_addr
.s_addr
);
480 prt
= ntohs(in
->sin_port
);
484 u_type
= SOCKET_TYPE_CHAR_TCP
;
485 d_type
= SOCKET_TYPE_CHAR_TCP
;
488 u_type
= SOCKET_TYPE_CHAR_UDP
;
489 d_type
= SOCKET_TYPE_CHAR_UDP
;
490 a_type
= SOCKET_TYPE_CHAR_UDP
;
491 b_type
= SOCKET_TYPE_CHAR_UDP
;
499 iface
= socket_wrapper_default_iface();
500 } else if (a_type
&& addr
== 0xFFFFFFFF) {
501 /* 255.255.255.255 only udp */
504 iface
= socket_wrapper_default_iface();
505 } else if (b_type
&& addr
== 0x7FFFFFFF) {
506 /* 127.255.255.255 only udp */
509 iface
= socket_wrapper_default_iface();
510 } else if ((addr
& 0xFFFFFF00) == 0x7F000000) {
514 iface
= (addr
& 0x000000FF);
516 errno
= EADDRNOTAVAIL
;
523 const struct sockaddr_in6
*in
=
524 (const struct sockaddr_in6
*)(const void *)inaddr
;
525 struct in6_addr cmp1
, cmp2
;
529 type
= SOCKET_TYPE_CHAR_TCP_V6
;
532 type
= SOCKET_TYPE_CHAR_UDP_V6
;
536 /* XXX no multicast/broadcast */
538 prt
= ntohs(in
->sin6_port
);
540 cmp1
= *swrap_ipv6();
541 cmp2
= in
->sin6_addr
;
542 cmp2
.s6_addr
[15] = 0;
543 if (IN6_IS_ADDR_UNSPECIFIED(&in
->sin6_addr
)) {
544 iface
= socket_wrapper_default_iface();
545 } else if (IN6_ARE_ADDR_EQUAL(&cmp1
, &cmp2
)) {
546 iface
= in
->sin6_addr
.s6_addr
[15];
548 errno
= EADDRNOTAVAIL
;
556 errno
= EADDRNOTAVAIL
;
561 if (bcast
) *bcast
= is_bcast
;
563 if (iface
== 0 || iface
> MAX_WRAPPED_INTERFACES
) {
569 /* handle auto-allocation of ephemeral ports */
570 for (prt
= 5001; prt
< 10000; prt
++) {
571 snprintf(un
->sun_path
, sizeof(un
->sun_path
), "%s/"SOCKET_FORMAT
,
572 socket_wrapper_dir(), type
, iface
, prt
);
573 if (stat(un
->sun_path
, &st
) == 0) continue;
575 set_port(si
->family
, prt
, si
->myname
);
584 snprintf(un
->sun_path
, sizeof(un
->sun_path
), "%s/"SOCKET_FORMAT
,
585 socket_wrapper_dir(), type
, iface
, prt
);
589 static struct socket_info
*find_socket_info(int fd
)
591 struct socket_info
*i
;
592 for (i
= sockets
; i
; i
= i
->next
) {
593 struct socket_info_fd
*f
;
594 for (f
= i
->fds
; f
; f
= f
->next
) {
604 static int sockaddr_convert_to_un(struct socket_info
*si
, const struct sockaddr
*in_addr
, socklen_t in_len
,
605 struct sockaddr_un
*out_addr
, int alloc_sock
, int *bcast
)
607 struct sockaddr
*out
= (struct sockaddr
*)(void *)out_addr
;
611 out
->sa_family
= AF_UNIX
;
612 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
613 out
->sa_len
= sizeof(*out_addr
);
616 switch (in_addr
->sa_family
) {
626 errno
= ESOCKTNOSUPPORT
;
630 return convert_in_un_alloc(si
, in_addr
, out_addr
, bcast
);
632 return convert_in_un_remote(si
, in_addr
, out_addr
, bcast
);
638 errno
= EAFNOSUPPORT
;
642 static int sockaddr_convert_from_un(const struct socket_info
*si
,
643 const struct sockaddr_un
*in_addr
,
644 socklen_t un_addrlen
,
646 struct sockaddr
*out_addr
,
647 socklen_t
*out_addrlen
)
651 if (out_addr
== NULL
|| out_addrlen
== NULL
)
654 if (un_addrlen
== 0) {
669 errno
= ESOCKTNOSUPPORT
;
672 ret
= convert_un_in(in_addr
, out_addr
, out_addrlen
);
673 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
674 out_addr
->sa_len
= *out_addrlen
;
681 errno
= EAFNOSUPPORT
;
685 enum swrap_packet_type
{
687 SWRAP_CONNECT_UNREACH
,
695 SWRAP_SENDTO_UNREACH
,
706 struct swrap_file_hdr
{
708 uint16_t version_major
;
709 uint16_t version_minor
;
712 uint32_t frame_max_len
;
713 #define SWRAP_FRAME_LENGTH_MAX 0xFFFF
716 #define SWRAP_FILE_HDR_SIZE 24
718 struct swrap_packet_frame
{
720 uint32_t micro_seconds
;
721 uint32_t recorded_length
;
722 uint32_t full_length
;
724 #define SWRAP_PACKET_FRAME_SIZE 16
726 union swrap_packet_ip
{
730 uint16_t packet_length
;
731 uint16_t identification
;
736 uint16_t hdr_checksum
;
740 #define SWRAP_PACKET_IP_V4_SIZE 20
743 uint8_t flow_label_high
;
744 uint16_t flow_label_low
;
745 uint16_t payload_length
;
748 uint8_t src_addr
[16];
749 uint8_t dest_addr
[16];
751 #define SWRAP_PACKET_IP_V6_SIZE 40
753 #define SWRAP_PACKET_IP_SIZE 40
755 union swrap_packet_payload
{
757 uint16_t source_port
;
767 #define SWRAP_PACKET_PAYLOAD_TCP_SIZE 20
769 uint16_t source_port
;
774 #define SWRAP_PACKET_PAYLOAD_UDP_SIZE 8
781 #define SWRAP_PACKET_PAYLOAD_ICMP4_SIZE 8
788 #define SWRAP_PACKET_PAYLOAD_ICMP6_SIZE 8
790 #define SWRAP_PACKET_PAYLOAD_SIZE 20
792 #define SWRAP_PACKET_MIN_ALLOC \
793 (SWRAP_PACKET_FRAME_SIZE + \
794 SWRAP_PACKET_IP_SIZE + \
795 SWRAP_PACKET_PAYLOAD_SIZE)
797 static const char *socket_wrapper_pcap_file(void)
799 static int initialized
= 0;
800 static const char *s
= NULL
;
801 static const struct swrap_file_hdr h
;
802 static const struct swrap_packet_frame f
;
803 static const union swrap_packet_ip i
;
804 static const union swrap_packet_payload p
;
806 if (initialized
== 1) {
812 * TODO: don't use the structs use plain buffer offsets
813 * and PUSH_U8(), PUSH_U16() and PUSH_U32()
815 * for now make sure we disable PCAP support
816 * if the struct has alignment!
818 if (sizeof(h
) != SWRAP_FILE_HDR_SIZE
) {
821 if (sizeof(f
) != SWRAP_PACKET_FRAME_SIZE
) {
824 if (sizeof(i
) != SWRAP_PACKET_IP_SIZE
) {
827 if (sizeof(i
.v4
) != SWRAP_PACKET_IP_V4_SIZE
) {
830 if (sizeof(i
.v6
) != SWRAP_PACKET_IP_V6_SIZE
) {
833 if (sizeof(p
) != SWRAP_PACKET_PAYLOAD_SIZE
) {
836 if (sizeof(p
.tcp
) != SWRAP_PACKET_PAYLOAD_TCP_SIZE
) {
839 if (sizeof(p
.udp
) != SWRAP_PACKET_PAYLOAD_UDP_SIZE
) {
842 if (sizeof(p
.icmp4
) != SWRAP_PACKET_PAYLOAD_ICMP4_SIZE
) {
845 if (sizeof(p
.icmp6
) != SWRAP_PACKET_PAYLOAD_ICMP6_SIZE
) {
849 s
= getenv("SOCKET_WRAPPER_PCAP_FILE");
853 if (strncmp(s
, "./", 2) == 0) {
859 static uint8_t *swrap_packet_init(struct timeval
*tval
,
860 const struct sockaddr
*src
,
861 const struct sockaddr
*dest
,
863 const uint8_t *payload
,
865 unsigned long tcp_seqno
,
866 unsigned long tcp_ack
,
867 unsigned char tcp_ctl
,
873 struct swrap_packet_frame
*frame
;
874 union swrap_packet_ip
*ip
;
875 union swrap_packet_payload
*pay
;
878 size_t nonwire_len
= sizeof(*frame
);
879 size_t wire_hdr_len
= 0;
881 size_t ip_hdr_len
= 0;
882 size_t icmp_hdr_len
= 0;
883 size_t icmp_truncate_len
= 0;
884 uint8_t protocol
= 0, icmp_protocol
= 0;
885 const struct sockaddr_in
*src_in
= NULL
;
886 const struct sockaddr_in
*dest_in
= NULL
;
888 const struct sockaddr_in6
*src_in6
= NULL
;
889 const struct sockaddr_in6
*dest_in6
= NULL
;
894 switch (src
->sa_family
) {
896 src_in
= (const struct sockaddr_in
*)src
;
897 dest_in
= (const struct sockaddr_in
*)dest
;
898 src_port
= src_in
->sin_port
;
899 dest_port
= dest_in
->sin_port
;
900 ip_hdr_len
= sizeof(ip
->v4
);
904 src_in6
= (const struct sockaddr_in6
*)src
;
905 dest_in6
= (const struct sockaddr_in6
*)dest
;
906 src_port
= src_in6
->sin6_port
;
907 dest_port
= dest_in6
->sin6_port
;
908 ip_hdr_len
= sizeof(ip
->v6
);
915 switch (socket_type
) {
917 protocol
= 0x06; /* TCP */
918 wire_hdr_len
= ip_hdr_len
+ sizeof(pay
->tcp
);
919 wire_len
= wire_hdr_len
+ payload_len
;
923 protocol
= 0x11; /* UDP */
924 wire_hdr_len
= ip_hdr_len
+ sizeof(pay
->udp
);
925 wire_len
= wire_hdr_len
+ payload_len
;
933 icmp_protocol
= protocol
;
934 switch (src
->sa_family
) {
936 protocol
= 0x01; /* ICMPv4 */
937 icmp_hdr_len
= ip_hdr_len
+ sizeof(pay
->icmp4
);
941 protocol
= 0x3A; /* ICMPv6 */
942 icmp_hdr_len
= ip_hdr_len
+ sizeof(pay
->icmp6
);
946 if (wire_len
> 64 ) {
947 icmp_truncate_len
= wire_len
- 64;
949 wire_hdr_len
+= icmp_hdr_len
;
950 wire_len
+= icmp_hdr_len
;
953 packet_len
= nonwire_len
+ wire_len
;
954 alloc_len
= packet_len
;
955 if (alloc_len
< SWRAP_PACKET_MIN_ALLOC
) {
956 alloc_len
= SWRAP_PACKET_MIN_ALLOC
;
959 base
= (uint8_t *)malloc(alloc_len
);
960 if (!base
) return NULL
;
964 frame
= (struct swrap_packet_frame
*)buf
;
965 frame
->seconds
= tval
->tv_sec
;
966 frame
->micro_seconds
= tval
->tv_usec
;
967 frame
->recorded_length
= wire_len
- icmp_truncate_len
;
968 frame
->full_length
= wire_len
- icmp_truncate_len
;
969 buf
+= SWRAP_PACKET_FRAME_SIZE
;
971 ip
= (union swrap_packet_ip
*)buf
;
972 switch (src
->sa_family
) {
974 ip
->v4
.ver_hdrlen
= 0x45; /* version 4 and 5 * 32 bit words */
976 ip
->v4
.packet_length
= htons(wire_len
- icmp_truncate_len
);
977 ip
->v4
.identification
= htons(0xFFFF);
978 ip
->v4
.flags
= 0x40; /* BIT 1 set - means don't fraqment */
979 ip
->v4
.fragment
= htons(0x0000);
981 ip
->v4
.protocol
= protocol
;
982 ip
->v4
.hdr_checksum
= htons(0x0000);
983 ip
->v4
.src_addr
= src_in
->sin_addr
.s_addr
;
984 ip
->v4
.dest_addr
= dest_in
->sin_addr
.s_addr
;
985 buf
+= SWRAP_PACKET_IP_V4_SIZE
;
989 ip
->v6
.ver_prio
= 0x60; /* version 4 and 5 * 32 bit words */
990 ip
->v6
.flow_label_high
= 0x00;
991 ip
->v6
.flow_label_low
= 0x0000;
992 ip
->v6
.payload_length
= htons(wire_len
- icmp_truncate_len
); /* TODO */
993 ip
->v6
.next_header
= protocol
;
994 memcpy(ip
->v6
.src_addr
, src_in6
->sin6_addr
.s6_addr
, 16);
995 memcpy(ip
->v6
.dest_addr
, dest_in6
->sin6_addr
.s6_addr
, 16);
996 buf
+= SWRAP_PACKET_IP_V6_SIZE
;
1002 pay
= (union swrap_packet_payload
*)buf
;
1003 switch (src
->sa_family
) {
1005 pay
->icmp4
.type
= 0x03; /* destination unreachable */
1006 pay
->icmp4
.code
= 0x01; /* host unreachable */
1007 pay
->icmp4
.checksum
= htons(0x0000);
1008 pay
->icmp4
.unused
= htonl(0x00000000);
1009 buf
+= SWRAP_PACKET_PAYLOAD_ICMP4_SIZE
;
1011 /* set the ip header in the ICMP payload */
1012 ip
= (union swrap_packet_ip
*)buf
;
1013 ip
->v4
.ver_hdrlen
= 0x45; /* version 4 and 5 * 32 bit words */
1015 ip
->v4
.packet_length
= htons(wire_len
- icmp_hdr_len
);
1016 ip
->v4
.identification
= htons(0xFFFF);
1017 ip
->v4
.flags
= 0x40; /* BIT 1 set - means don't fraqment */
1018 ip
->v4
.fragment
= htons(0x0000);
1020 ip
->v4
.protocol
= icmp_protocol
;
1021 ip
->v4
.hdr_checksum
= htons(0x0000);
1022 ip
->v4
.src_addr
= dest_in
->sin_addr
.s_addr
;
1023 ip
->v4
.dest_addr
= src_in
->sin_addr
.s_addr
;
1024 buf
+= SWRAP_PACKET_IP_V4_SIZE
;
1026 src_port
= dest_in
->sin_port
;
1027 dest_port
= src_in
->sin_port
;
1031 pay
->icmp6
.type
= 0x01; /* destination unreachable */
1032 pay
->icmp6
.code
= 0x03; /* address unreachable */
1033 pay
->icmp6
.checksum
= htons(0x0000);
1034 pay
->icmp6
.unused
= htonl(0x00000000);
1035 buf
+= SWRAP_PACKET_PAYLOAD_ICMP6_SIZE
;
1037 /* set the ip header in the ICMP payload */
1038 ip
= (union swrap_packet_ip
*)buf
;
1039 ip
->v6
.ver_prio
= 0x60; /* version 4 and 5 * 32 bit words */
1040 ip
->v6
.flow_label_high
= 0x00;
1041 ip
->v6
.flow_label_low
= 0x0000;
1042 ip
->v6
.payload_length
= htons(wire_len
- icmp_truncate_len
); /* TODO */
1043 ip
->v6
.next_header
= protocol
;
1044 memcpy(ip
->v6
.src_addr
, dest_in6
->sin6_addr
.s6_addr
, 16);
1045 memcpy(ip
->v6
.dest_addr
, src_in6
->sin6_addr
.s6_addr
, 16);
1046 buf
+= SWRAP_PACKET_IP_V6_SIZE
;
1048 src_port
= dest_in6
->sin6_port
;
1049 dest_port
= src_in6
->sin6_port
;
1055 pay
= (union swrap_packet_payload
*)buf
;
1057 switch (socket_type
) {
1059 pay
->tcp
.source_port
= src_port
;
1060 pay
->tcp
.dest_port
= dest_port
;
1061 pay
->tcp
.seq_num
= htonl(tcp_seqno
);
1062 pay
->tcp
.ack_num
= htonl(tcp_ack
);
1063 pay
->tcp
.hdr_length
= 0x50; /* 5 * 32 bit words */
1064 pay
->tcp
.control
= tcp_ctl
;
1065 pay
->tcp
.window
= htons(0x7FFF);
1066 pay
->tcp
.checksum
= htons(0x0000);
1067 pay
->tcp
.urg
= htons(0x0000);
1068 buf
+= SWRAP_PACKET_PAYLOAD_TCP_SIZE
;
1073 pay
->udp
.source_port
= src_port
;
1074 pay
->udp
.dest_port
= dest_port
;
1075 pay
->udp
.length
= htons(8 + payload_len
);
1076 pay
->udp
.checksum
= htons(0x0000);
1077 buf
+= SWRAP_PACKET_PAYLOAD_UDP_SIZE
;
1082 if (payload
&& payload_len
> 0) {
1083 memcpy(buf
, payload
, payload_len
);
1086 *_packet_len
= packet_len
- icmp_truncate_len
;
1090 static int swrap_get_pcap_fd(const char *fname
)
1094 if (fd
!= -1) return fd
;
1096 fd
= open(fname
, O_WRONLY
|O_CREAT
|O_EXCL
|O_APPEND
, 0644);
1098 struct swrap_file_hdr file_hdr
;
1099 file_hdr
.magic
= 0xA1B2C3D4;
1100 file_hdr
.version_major
= 0x0002;
1101 file_hdr
.version_minor
= 0x0004;
1102 file_hdr
.timezone
= 0x00000000;
1103 file_hdr
.sigfigs
= 0x00000000;
1104 file_hdr
.frame_max_len
= SWRAP_FRAME_LENGTH_MAX
;
1105 file_hdr
.link_type
= 0x0065; /* 101 RAW IP */
1107 if (write(fd
, &file_hdr
, sizeof(file_hdr
)) != sizeof(file_hdr
)) {
1114 fd
= open(fname
, O_WRONLY
|O_APPEND
, 0644);
1119 static uint8_t *swrap_marshall_packet(struct socket_info
*si
,
1120 const struct sockaddr
*addr
,
1121 enum swrap_packet_type type
,
1122 const void *buf
, size_t len
,
1125 const struct sockaddr
*src_addr
;
1126 const struct sockaddr
*dest_addr
;
1127 unsigned long tcp_seqno
= 0;
1128 unsigned long tcp_ack
= 0;
1129 unsigned char tcp_ctl
= 0;
1130 int unreachable
= 0;
1134 switch (si
->family
) {
1146 case SWRAP_CONNECT_SEND
:
1147 if (si
->type
!= SOCK_STREAM
) return NULL
;
1149 src_addr
= si
->myname
;
1152 tcp_seqno
= si
->io
.pck_snd
;
1153 tcp_ack
= si
->io
.pck_rcv
;
1154 tcp_ctl
= 0x02; /* SYN */
1156 si
->io
.pck_snd
+= 1;
1160 case SWRAP_CONNECT_RECV
:
1161 if (si
->type
!= SOCK_STREAM
) return NULL
;
1163 dest_addr
= si
->myname
;
1166 tcp_seqno
= si
->io
.pck_rcv
;
1167 tcp_ack
= si
->io
.pck_snd
;
1168 tcp_ctl
= 0x12; /** SYN,ACK */
1170 si
->io
.pck_rcv
+= 1;
1174 case SWRAP_CONNECT_UNREACH
:
1175 if (si
->type
!= SOCK_STREAM
) return NULL
;
1177 dest_addr
= si
->myname
;
1180 /* Unreachable: resend the data of SWRAP_CONNECT_SEND */
1181 tcp_seqno
= si
->io
.pck_snd
- 1;
1182 tcp_ack
= si
->io
.pck_rcv
;
1183 tcp_ctl
= 0x02; /* SYN */
1188 case SWRAP_CONNECT_ACK
:
1189 if (si
->type
!= SOCK_STREAM
) return NULL
;
1191 src_addr
= si
->myname
;
1194 tcp_seqno
= si
->io
.pck_snd
;
1195 tcp_ack
= si
->io
.pck_rcv
;
1196 tcp_ctl
= 0x10; /* ACK */
1200 case SWRAP_ACCEPT_SEND
:
1201 if (si
->type
!= SOCK_STREAM
) return NULL
;
1203 dest_addr
= si
->myname
;
1206 tcp_seqno
= si
->io
.pck_rcv
;
1207 tcp_ack
= si
->io
.pck_snd
;
1208 tcp_ctl
= 0x02; /* SYN */
1210 si
->io
.pck_rcv
+= 1;
1214 case SWRAP_ACCEPT_RECV
:
1215 if (si
->type
!= SOCK_STREAM
) return NULL
;
1217 src_addr
= si
->myname
;
1220 tcp_seqno
= si
->io
.pck_snd
;
1221 tcp_ack
= si
->io
.pck_rcv
;
1222 tcp_ctl
= 0x12; /* SYN,ACK */
1224 si
->io
.pck_snd
+= 1;
1228 case SWRAP_ACCEPT_ACK
:
1229 if (si
->type
!= SOCK_STREAM
) return NULL
;
1231 dest_addr
= si
->myname
;
1234 tcp_seqno
= si
->io
.pck_rcv
;
1235 tcp_ack
= si
->io
.pck_snd
;
1236 tcp_ctl
= 0x10; /* ACK */
1241 src_addr
= si
->myname
;
1242 dest_addr
= si
->peername
;
1244 tcp_seqno
= si
->io
.pck_snd
;
1245 tcp_ack
= si
->io
.pck_rcv
;
1246 tcp_ctl
= 0x18; /* PSH,ACK */
1248 si
->io
.pck_snd
+= len
;
1252 case SWRAP_SEND_RST
:
1253 dest_addr
= si
->myname
;
1254 src_addr
= si
->peername
;
1256 if (si
->type
== SOCK_DGRAM
) {
1257 return swrap_marshall_packet(si
, si
->peername
,
1258 SWRAP_SENDTO_UNREACH
,
1259 buf
, len
, packet_len
);
1262 tcp_seqno
= si
->io
.pck_rcv
;
1263 tcp_ack
= si
->io
.pck_snd
;
1264 tcp_ctl
= 0x14; /** RST,ACK */
1268 case SWRAP_PENDING_RST
:
1269 dest_addr
= si
->myname
;
1270 src_addr
= si
->peername
;
1272 if (si
->type
== SOCK_DGRAM
) {
1276 tcp_seqno
= si
->io
.pck_rcv
;
1277 tcp_ack
= si
->io
.pck_snd
;
1278 tcp_ctl
= 0x14; /* RST,ACK */
1283 dest_addr
= si
->myname
;
1284 src_addr
= si
->peername
;
1286 tcp_seqno
= si
->io
.pck_rcv
;
1287 tcp_ack
= si
->io
.pck_snd
;
1288 tcp_ctl
= 0x18; /* PSH,ACK */
1290 si
->io
.pck_rcv
+= len
;
1294 case SWRAP_RECV_RST
:
1295 dest_addr
= si
->myname
;
1296 src_addr
= si
->peername
;
1298 if (si
->type
== SOCK_DGRAM
) {
1302 tcp_seqno
= si
->io
.pck_rcv
;
1303 tcp_ack
= si
->io
.pck_snd
;
1304 tcp_ctl
= 0x14; /* RST,ACK */
1309 src_addr
= si
->myname
;
1312 si
->io
.pck_snd
+= len
;
1316 case SWRAP_SENDTO_UNREACH
:
1317 dest_addr
= si
->myname
;
1324 case SWRAP_RECVFROM
:
1325 dest_addr
= si
->myname
;
1328 si
->io
.pck_rcv
+= len
;
1332 case SWRAP_CLOSE_SEND
:
1333 if (si
->type
!= SOCK_STREAM
) return NULL
;
1335 src_addr
= si
->myname
;
1336 dest_addr
= si
->peername
;
1338 tcp_seqno
= si
->io
.pck_snd
;
1339 tcp_ack
= si
->io
.pck_rcv
;
1340 tcp_ctl
= 0x11; /* FIN, ACK */
1342 si
->io
.pck_snd
+= 1;
1346 case SWRAP_CLOSE_RECV
:
1347 if (si
->type
!= SOCK_STREAM
) return NULL
;
1349 dest_addr
= si
->myname
;
1350 src_addr
= si
->peername
;
1352 tcp_seqno
= si
->io
.pck_rcv
;
1353 tcp_ack
= si
->io
.pck_snd
;
1354 tcp_ctl
= 0x11; /* FIN,ACK */
1356 si
->io
.pck_rcv
+= 1;
1360 case SWRAP_CLOSE_ACK
:
1361 if (si
->type
!= SOCK_STREAM
) return NULL
;
1363 src_addr
= si
->myname
;
1364 dest_addr
= si
->peername
;
1366 tcp_seqno
= si
->io
.pck_snd
;
1367 tcp_ack
= si
->io
.pck_rcv
;
1368 tcp_ctl
= 0x10; /* ACK */
1375 swrapGetTimeOfDay(&tv
);
1377 return swrap_packet_init(&tv
, src_addr
, dest_addr
, si
->type
,
1378 (const uint8_t *)buf
, len
,
1379 tcp_seqno
, tcp_ack
, tcp_ctl
, unreachable
,
1383 static void swrap_dump_packet(struct socket_info
*si
,
1384 const struct sockaddr
*addr
,
1385 enum swrap_packet_type type
,
1386 const void *buf
, size_t len
)
1388 const char *file_name
;
1390 size_t packet_len
= 0;
1393 file_name
= socket_wrapper_pcap_file();
1398 packet
= swrap_marshall_packet(si
, addr
, type
, buf
, len
, &packet_len
);
1403 fd
= swrap_get_pcap_fd(file_name
);
1405 if (write(fd
, packet
, packet_len
) != packet_len
) {
1414 _PUBLIC_
int swrap_socket(int family
, int type
, int protocol
)
1416 struct socket_info
*si
;
1417 struct socket_info_fd
*fi
;
1419 int real_type
= type
;
1421 real_type
&= ~SOCK_CLOEXEC
;
1423 #ifdef SOCK_NONBLOCK
1424 real_type
&= ~SOCK_NONBLOCK
;
1427 if (!socket_wrapper_dir()) {
1428 return real_socket(family
, type
, protocol
);
1438 return real_socket(family
, type
, protocol
);
1440 errno
= EAFNOSUPPORT
;
1444 switch (real_type
) {
1450 errno
= EPROTONOSUPPORT
;
1458 if (real_type
== SOCK_STREAM
) {
1463 if (real_type
== SOCK_DGRAM
) {
1468 errno
= EPROTONOSUPPORT
;
1472 /* We must call real_socket with type, from the caller, not the version we removed
1473 SOCK_CLOEXEC and SOCK_NONBLOCK from */
1474 fd
= real_socket(AF_UNIX
, type
, 0);
1476 if (fd
== -1) return -1;
1478 si
= (struct socket_info
*)calloc(1, sizeof(struct socket_info
));
1484 si
->family
= family
;
1486 /* however, the rest of the socket_wrapper code expects just
1487 * the type, not the flags */
1488 si
->type
= real_type
;
1489 si
->protocol
= protocol
;
1491 fi
= (struct socket_info_fd
*)calloc(1, sizeof(struct socket_info_fd
));
1500 SWRAP_DLIST_ADD(si
->fds
, fi
);
1501 SWRAP_DLIST_ADD(sockets
, si
);
1506 _PUBLIC_
int swrap_accept(int s
, struct sockaddr
*addr
, socklen_t
*addrlen
)
1508 struct socket_info
*parent_si
, *child_si
;
1509 struct socket_info_fd
*child_fi
;
1511 struct sockaddr_un un_addr
;
1512 socklen_t un_addrlen
= sizeof(un_addr
);
1513 struct sockaddr_un un_my_addr
;
1514 socklen_t un_my_addrlen
= sizeof(un_my_addr
);
1515 struct sockaddr
*my_addr
;
1516 socklen_t my_addrlen
, len
;
1519 parent_si
= find_socket_info(s
);
1521 return real_accept(s
, addr
, addrlen
);
1525 * assume out sockaddr have the same size as the in parent
1528 my_addrlen
= socket_length(parent_si
->family
);
1529 if (my_addrlen
<= 0) {
1534 my_addr
= (struct sockaddr
*)malloc(my_addrlen
);
1535 if (my_addr
== NULL
) {
1539 memset(&un_addr
, 0, sizeof(un_addr
));
1540 memset(&un_my_addr
, 0, sizeof(un_my_addr
));
1542 ret
= real_accept(s
, (struct sockaddr
*)(void *)&un_addr
, &un_addrlen
);
1551 ret
= sockaddr_convert_from_un(parent_si
, &un_addr
, un_addrlen
,
1552 parent_si
->family
, my_addr
, &len
);
1559 child_si
= (struct socket_info
*)malloc(sizeof(struct socket_info
));
1560 memset(child_si
, 0, sizeof(*child_si
));
1562 child_fi
= (struct socket_info_fd
*)calloc(1, sizeof(struct socket_info_fd
));
1563 if (child_fi
== NULL
) {
1573 SWRAP_DLIST_ADD(child_si
->fds
, child_fi
);
1575 child_si
->family
= parent_si
->family
;
1576 child_si
->type
= parent_si
->type
;
1577 child_si
->protocol
= parent_si
->protocol
;
1578 child_si
->bound
= 1;
1579 child_si
->is_server
= 1;
1580 child_si
->connected
= 1;
1582 child_si
->peername_len
= len
;
1583 child_si
->peername
= sockaddr_dup(my_addr
, len
);
1585 if (addr
!= NULL
&& addrlen
!= NULL
) {
1586 size_t copy_len
= MIN(*addrlen
, len
);
1588 memcpy(addr
, my_addr
, copy_len
);
1593 ret
= real_getsockname(fd
, (struct sockaddr
*)(void *)&un_my_addr
,
1603 ret
= sockaddr_convert_from_un(child_si
, &un_my_addr
, un_my_addrlen
,
1604 child_si
->family
, my_addr
, &len
);
1613 child_si
->myname_len
= len
;
1614 child_si
->myname
= sockaddr_dup(my_addr
, len
);
1617 SWRAP_DLIST_ADD(sockets
, child_si
);
1619 swrap_dump_packet(child_si
, addr
, SWRAP_ACCEPT_SEND
, NULL
, 0);
1620 swrap_dump_packet(child_si
, addr
, SWRAP_ACCEPT_RECV
, NULL
, 0);
1621 swrap_dump_packet(child_si
, addr
, SWRAP_ACCEPT_ACK
, NULL
, 0);
1626 static int autobind_start_init
;
1627 static int autobind_start
;
1629 /* using sendto() or connect() on an unbound socket would give the
1630 recipient no way to reply, as unlike UDP and TCP, a unix domain
1631 socket can't auto-assign emphemeral port numbers, so we need to
1633 Note: this might change the family from ipv6 to ipv4
1635 static int swrap_auto_bind(int fd
, struct socket_info
*si
, int family
)
1637 struct sockaddr_un un_addr
;
1644 if (autobind_start_init
!= 1) {
1645 autobind_start_init
= 1;
1646 autobind_start
= getpid();
1647 autobind_start
%= 50000;
1648 autobind_start
+= 10000;
1651 un_addr
.sun_family
= AF_UNIX
;
1655 struct sockaddr_in in
;
1659 type
= SOCKET_TYPE_CHAR_TCP
;
1662 type
= SOCKET_TYPE_CHAR_UDP
;
1665 errno
= ESOCKTNOSUPPORT
;
1669 memset(&in
, 0, sizeof(in
));
1670 in
.sin_family
= AF_INET
;
1671 in
.sin_addr
.s_addr
= htonl(127<<24 |
1672 socket_wrapper_default_iface());
1674 si
->myname_len
= sizeof(in
);
1675 si
->myname
= sockaddr_dup(&in
, si
->myname_len
);
1680 struct sockaddr_in6 in6
;
1682 if (si
->family
!= family
) {
1683 errno
= ENETUNREACH
;
1689 type
= SOCKET_TYPE_CHAR_TCP_V6
;
1692 type
= SOCKET_TYPE_CHAR_UDP_V6
;
1695 errno
= ESOCKTNOSUPPORT
;
1699 memset(&in6
, 0, sizeof(in6
));
1700 in6
.sin6_family
= AF_INET6
;
1701 in6
.sin6_addr
= *swrap_ipv6();
1702 in6
.sin6_addr
.s6_addr
[15] = socket_wrapper_default_iface();
1703 si
->myname_len
= sizeof(in6
);
1704 si
->myname
= sockaddr_dup(&in6
, si
->myname_len
);
1709 errno
= ESOCKTNOSUPPORT
;
1713 if (autobind_start
> 60000) {
1714 autobind_start
= 10000;
1717 for (i
=0;i
<1000;i
++) {
1718 port
= autobind_start
+ i
;
1719 snprintf(un_addr
.sun_path
, sizeof(un_addr
.sun_path
),
1720 "%s/"SOCKET_FORMAT
, socket_wrapper_dir(),
1721 type
, socket_wrapper_default_iface(), port
);
1722 if (stat(un_addr
.sun_path
, &st
) == 0) continue;
1724 ret
= real_bind(fd
, (struct sockaddr
*)(void *)&un_addr
,
1726 if (ret
== -1) return ret
;
1728 si
->tmp_path
= strdup(un_addr
.sun_path
);
1730 autobind_start
= port
+ 1;
1738 si
->family
= family
;
1739 set_port(si
->family
, port
, si
->myname
);
1745 _PUBLIC_
int swrap_connect(int s
, const struct sockaddr
*serv_addr
, socklen_t addrlen
)
1748 struct sockaddr_un un_addr
;
1749 struct socket_info
*si
= find_socket_info(s
);
1753 return real_connect(s
, serv_addr
, addrlen
);
1756 if (si
->bound
== 0) {
1757 ret
= swrap_auto_bind(s
, si
, serv_addr
->sa_family
);
1758 if (ret
== -1) return -1;
1761 if (si
->family
!= serv_addr
->sa_family
) {
1766 ret
= sockaddr_convert_to_un(si
, serv_addr
,
1767 addrlen
, &un_addr
, 0, &bcast
);
1768 if (ret
== -1) return -1;
1771 errno
= ENETUNREACH
;
1775 if (si
->type
== SOCK_DGRAM
) {
1776 si
->defer_connect
= 1;
1779 swrap_dump_packet(si
, serv_addr
, SWRAP_CONNECT_SEND
, NULL
, 0);
1781 ret
= real_connect(s
, (struct sockaddr
*)(void *)&un_addr
,
1782 sizeof(struct sockaddr_un
));
1785 /* to give better errors */
1786 if (ret
== -1 && errno
== ENOENT
) {
1787 errno
= EHOSTUNREACH
;
1791 si
->peername_len
= addrlen
;
1792 si
->peername
= sockaddr_dup(serv_addr
, addrlen
);
1795 swrap_dump_packet(si
, serv_addr
, SWRAP_CONNECT_RECV
, NULL
, 0);
1796 swrap_dump_packet(si
, serv_addr
, SWRAP_CONNECT_ACK
, NULL
, 0);
1798 swrap_dump_packet(si
, serv_addr
, SWRAP_CONNECT_UNREACH
, NULL
, 0);
1804 _PUBLIC_
int swrap_bind(int s
, const struct sockaddr
*myaddr
, socklen_t addrlen
)
1807 struct sockaddr_un un_addr
;
1808 struct socket_info
*si
= find_socket_info(s
);
1811 return real_bind(s
, myaddr
, addrlen
);
1814 si
->myname_len
= addrlen
;
1815 si
->myname
= sockaddr_dup(myaddr
, addrlen
);
1817 ret
= sockaddr_convert_to_un(si
, myaddr
, addrlen
, &un_addr
, 1, &si
->bcast
);
1818 if (ret
== -1) return -1;
1820 unlink(un_addr
.sun_path
);
1822 ret
= real_bind(s
, (struct sockaddr
*)(void *)&un_addr
,
1823 sizeof(struct sockaddr_un
));
1832 _PUBLIC_
int swrap_listen(int s
, int backlog
)
1835 struct socket_info
*si
= find_socket_info(s
);
1838 return real_listen(s
, backlog
);
1841 ret
= real_listen(s
, backlog
);
1846 _PUBLIC_
int swrap_getpeername(int s
, struct sockaddr
*name
, socklen_t
*addrlen
)
1848 struct socket_info
*si
= find_socket_info(s
);
1851 return real_getpeername(s
, name
, addrlen
);
1860 memcpy(name
, si
->peername
, si
->peername_len
);
1861 *addrlen
= si
->peername_len
;
1866 _PUBLIC_
int swrap_getsockname(int s
, struct sockaddr
*name
, socklen_t
*addrlen
)
1868 struct socket_info
*si
= find_socket_info(s
);
1871 return real_getsockname(s
, name
, addrlen
);
1874 memcpy(name
, si
->myname
, si
->myname_len
);
1875 *addrlen
= si
->myname_len
;
1880 _PUBLIC_
int swrap_getsockopt(int s
, int level
, int optname
, void *optval
, socklen_t
*optlen
)
1882 struct socket_info
*si
= find_socket_info(s
);
1885 return real_getsockopt(s
, level
, optname
, optval
, optlen
);
1888 if (level
== SOL_SOCKET
) {
1889 return real_getsockopt(s
, level
, optname
, optval
, optlen
);
1892 errno
= ENOPROTOOPT
;
1896 _PUBLIC_
int swrap_setsockopt(int s
, int level
, int optname
, const void *optval
, socklen_t optlen
)
1898 struct socket_info
*si
= find_socket_info(s
);
1901 return real_setsockopt(s
, level
, optname
, optval
, optlen
);
1904 if (level
== SOL_SOCKET
) {
1905 return real_setsockopt(s
, level
, optname
, optval
, optlen
);
1908 switch (si
->family
) {
1916 errno
= ENOPROTOOPT
;
1921 _PUBLIC_
int swrap_ioctl(int s
, int r
, void *p
)
1924 struct socket_info
*si
= find_socket_info(s
);
1928 return real_ioctl(s
, r
, p
);
1931 ret
= real_ioctl(s
, r
, p
);
1935 value
= *((int *)p
);
1936 if (ret
== -1 && errno
!= EAGAIN
&& errno
!= ENOBUFS
) {
1937 swrap_dump_packet(si
, NULL
, SWRAP_PENDING_RST
, NULL
, 0);
1938 } else if (value
== 0) { /* END OF FILE */
1939 swrap_dump_packet(si
, NULL
, SWRAP_PENDING_RST
, NULL
, 0);
1947 static ssize_t
swrap_sendmsg_before(int fd
,
1948 struct socket_info
*si
,
1950 struct iovec
*tmp_iov
,
1951 struct sockaddr_un
*tmp_un
,
1952 const struct sockaddr_un
**to_un
,
1953 const struct sockaddr
**to
,
1971 if (!si
->connected
) {
1976 if (msg
->msg_iovlen
== 0) {
1981 * cut down to 1500 byte packets for stream sockets,
1982 * which makes it easier to format PCAP capture files
1983 * (as the caller will simply continue from here)
1986 for (i
=0; i
< msg
->msg_iovlen
; i
++) {
1988 nlen
= len
+ msg
->msg_iov
[i
].iov_len
;
1993 msg
->msg_iovlen
= i
;
1994 if (msg
->msg_iovlen
== 0) {
1995 *tmp_iov
= msg
->msg_iov
[0];
1996 tmp_iov
->iov_len
= MIN(tmp_iov
->iov_len
, 1500);
1997 msg
->msg_iov
= tmp_iov
;
1998 msg
->msg_iovlen
= 1;
2003 if (si
->connected
) {
2004 if (msg
->msg_name
) {
2009 const struct sockaddr
*msg_name
;
2010 msg_name
= (const struct sockaddr
*)msg
->msg_name
;
2012 if (msg_name
== NULL
) {
2018 ret
= sockaddr_convert_to_un(si
, msg_name
, msg
->msg_namelen
,
2020 if (ret
== -1) return -1;
2028 msg
->msg_name
= tmp_un
;
2029 msg
->msg_namelen
= sizeof(*tmp_un
);
2032 if (si
->bound
== 0) {
2033 ret
= swrap_auto_bind(fd
, si
, si
->family
);
2034 if (ret
== -1) return -1;
2037 if (!si
->defer_connect
) {
2041 ret
= sockaddr_convert_to_un(si
, si
->peername
, si
->peername_len
,
2043 if (ret
== -1) return -1;
2045 ret
= real_connect(fd
, (struct sockaddr
*)(void *)tmp_un
,
2048 /* to give better errors */
2049 if (ret
== -1 && errno
== ENOENT
) {
2050 errno
= EHOSTUNREACH
;
2057 si
->defer_connect
= 0;
2060 errno
= EHOSTUNREACH
;
2067 static void swrap_sendmsg_after(struct socket_info
*si
,
2069 const struct sockaddr
*to
,
2072 int saved_errno
= errno
;
2079 /* to give better errors */
2080 if (ret
== -1 && saved_errno
== ENOENT
) {
2081 saved_errno
= EHOSTUNREACH
;
2084 for (i
=0; i
< msg
->msg_iovlen
; i
++) {
2085 avail
+= msg
->msg_iov
[i
].iov_len
;
2089 remain
= MIN(80, avail
);
2094 /* we capture it as one single packet */
2095 buf
= (uint8_t *)malloc(remain
);
2097 /* we just not capture the packet */
2098 errno
= saved_errno
;
2102 for (i
=0; i
< msg
->msg_iovlen
; i
++) {
2103 size_t this_time
= MIN(remain
, msg
->msg_iov
[i
].iov_len
);
2105 msg
->msg_iov
[i
].iov_base
,
2108 remain
-= this_time
;
2115 swrap_dump_packet(si
, NULL
, SWRAP_SEND
, buf
, len
);
2116 swrap_dump_packet(si
, NULL
, SWRAP_SEND_RST
, NULL
, 0);
2118 swrap_dump_packet(si
, NULL
, SWRAP_SEND
, buf
, len
);
2123 if (si
->connected
) {
2127 swrap_dump_packet(si
, to
, SWRAP_SENDTO
, buf
, len
);
2128 swrap_dump_packet(si
, to
, SWRAP_SENDTO_UNREACH
, buf
, len
);
2130 swrap_dump_packet(si
, to
, SWRAP_SENDTO
, buf
, len
);
2136 errno
= saved_errno
;
2139 _PUBLIC_ ssize_t
swrap_recvfrom(int s
, void *buf
, size_t len
, int flags
, struct sockaddr
*from
, socklen_t
*fromlen
)
2141 struct sockaddr_un un_addr
;
2142 socklen_t un_addrlen
= sizeof(un_addr
);
2144 struct socket_info
*si
= find_socket_info(s
);
2145 struct sockaddr_storage ss
;
2146 socklen_t ss_len
= sizeof(ss
);
2149 return real_recvfrom(s
, buf
, len
, flags
, from
, fromlen
);
2153 from
= (struct sockaddr
*)(void *)&ss
;
2157 if (si
->type
== SOCK_STREAM
) {
2158 /* cut down to 1500 byte packets for stream sockets,
2159 * which makes it easier to format PCAP capture files
2160 * (as the caller will simply continue from here) */
2161 len
= MIN(len
, 1500);
2164 /* irix 6.4 forgets to null terminate the sun_path string :-( */
2165 memset(&un_addr
, 0, sizeof(un_addr
));
2166 ret
= real_recvfrom(s
, buf
, len
, flags
,
2167 (struct sockaddr
*)(void *)&un_addr
, &un_addrlen
);
2171 if (sockaddr_convert_from_un(si
, &un_addr
, un_addrlen
,
2172 si
->family
, from
, fromlen
) == -1) {
2176 swrap_dump_packet(si
, from
, SWRAP_RECVFROM
, buf
, ret
);
2182 _PUBLIC_ ssize_t
swrap_sendto(int s
, const void *buf
, size_t len
, int flags
, const struct sockaddr
*to
, socklen_t tolen
)
2186 struct sockaddr_un un_addr
;
2187 const struct sockaddr_un
*to_un
= NULL
;
2189 struct socket_info
*si
= find_socket_info(s
);
2193 return real_sendto(s
, buf
, len
, flags
, to
, tolen
);
2196 tmp
.iov_base
= discard_const_p(char, buf
);
2200 msg
.msg_name
= discard_const_p(struct sockaddr
, to
); /* optional address */
2201 msg
.msg_namelen
= tolen
; /* size of address */
2202 msg
.msg_iov
= &tmp
; /* scatter/gather array */
2203 msg
.msg_iovlen
= 1; /* # elements in msg_iov */
2204 #if 0 /* not available on solaris */
2205 msg
.msg_control
= NULL
; /* ancillary data, see below */
2206 msg
.msg_controllen
= 0; /* ancillary data buffer len */
2207 msg
.msg_flags
= 0; /* flags on received message */
2210 ret
= swrap_sendmsg_before(s
, si
, &msg
, &tmp
, &un_addr
, &to_un
, &to
, &bcast
);
2211 if (ret
== -1) return -1;
2213 buf
= msg
.msg_iov
[0].iov_base
;
2214 len
= msg
.msg_iov
[0].iov_len
;
2219 unsigned int prt
= ntohs(((const struct sockaddr_in
*)to
)->sin_port
);
2222 type
= SOCKET_TYPE_CHAR_UDP
;
2224 for(iface
=0; iface
<= MAX_WRAPPED_INTERFACES
; iface
++) {
2225 snprintf(un_addr
.sun_path
, sizeof(un_addr
.sun_path
), "%s/"SOCKET_FORMAT
,
2226 socket_wrapper_dir(), type
, iface
, prt
);
2227 if (stat(un_addr
.sun_path
, &st
) != 0) continue;
2229 /* ignore the any errors in broadcast sends */
2230 real_sendto(s
, buf
, len
, flags
,
2231 (struct sockaddr
*)(void *)&un_addr
,
2235 swrap_dump_packet(si
, to
, SWRAP_SENDTO
, buf
, len
);
2240 ret
= real_sendto(s
, buf
, len
, flags
, (struct sockaddr
*)msg
.msg_name
,
2243 swrap_sendmsg_after(si
, &msg
, to
, ret
);
2248 _PUBLIC_ ssize_t
swrap_recv(int s
, void *buf
, size_t len
, int flags
)
2251 struct socket_info
*si
= find_socket_info(s
);
2254 return real_recv(s
, buf
, len
, flags
);
2257 if (si
->type
== SOCK_STREAM
) {
2258 /* cut down to 1500 byte packets for stream sockets,
2259 * which makes it easier to format PCAP capture files
2260 * (as the caller will simply continue from here) */
2261 len
= MIN(len
, 1500);
2264 ret
= real_recv(s
, buf
, len
, flags
);
2265 if (ret
== -1 && errno
!= EAGAIN
&& errno
!= ENOBUFS
) {
2266 swrap_dump_packet(si
, NULL
, SWRAP_RECV_RST
, NULL
, 0);
2267 } else if (ret
== 0) { /* END OF FILE */
2268 swrap_dump_packet(si
, NULL
, SWRAP_RECV_RST
, NULL
, 0);
2269 } else if (ret
> 0) {
2270 swrap_dump_packet(si
, NULL
, SWRAP_RECV
, buf
, ret
);
2276 _PUBLIC_ ssize_t
swrap_read(int s
, void *buf
, size_t len
)
2279 struct socket_info
*si
= find_socket_info(s
);
2282 return real_read(s
, buf
, len
);
2285 if (si
->type
== SOCK_STREAM
) {
2286 /* cut down to 1500 byte packets for stream sockets,
2287 * which makes it easier to format PCAP capture files
2288 * (as the caller will simply continue from here) */
2289 len
= MIN(len
, 1500);
2292 ret
= real_read(s
, buf
, len
);
2293 if (ret
== -1 && errno
!= EAGAIN
&& errno
!= ENOBUFS
) {
2294 swrap_dump_packet(si
, NULL
, SWRAP_RECV_RST
, NULL
, 0);
2295 } else if (ret
== 0) { /* END OF FILE */
2296 swrap_dump_packet(si
, NULL
, SWRAP_RECV_RST
, NULL
, 0);
2297 } else if (ret
> 0) {
2298 swrap_dump_packet(si
, NULL
, SWRAP_RECV
, buf
, ret
);
2305 _PUBLIC_ ssize_t
swrap_send(int s
, const void *buf
, size_t len
, int flags
)
2309 struct sockaddr_un un_addr
;
2311 struct socket_info
*si
= find_socket_info(s
);
2314 return real_send(s
, buf
, len
, flags
);
2317 tmp
.iov_base
= discard_const_p(char, buf
);
2321 msg
.msg_name
= NULL
; /* optional address */
2322 msg
.msg_namelen
= 0; /* size of address */
2323 msg
.msg_iov
= &tmp
; /* scatter/gather array */
2324 msg
.msg_iovlen
= 1; /* # elements in msg_iov */
2325 #if 0 /* not available on solaris */
2326 msg
.msg_control
= NULL
; /* ancillary data, see below */
2327 msg
.msg_controllen
= 0; /* ancillary data buffer len */
2328 msg
.msg_flags
= 0; /* flags on received message */
2331 ret
= swrap_sendmsg_before(s
, si
, &msg
, &tmp
, &un_addr
, NULL
, NULL
, NULL
);
2332 if (ret
== -1) return -1;
2334 buf
= msg
.msg_iov
[0].iov_base
;
2335 len
= msg
.msg_iov
[0].iov_len
;
2337 ret
= real_send(s
, buf
, len
, flags
);
2339 swrap_sendmsg_after(si
, &msg
, NULL
, ret
);
2344 _PUBLIC_ ssize_t
swrap_sendmsg(int s
, const struct msghdr
*omsg
, int flags
)
2348 struct sockaddr_un un_addr
;
2349 const struct sockaddr_un
*to_un
= NULL
;
2350 const struct sockaddr
*to
= NULL
;
2352 struct socket_info
*si
= find_socket_info(s
);
2356 return real_sendmsg(s
, omsg
, flags
);
2359 tmp
.iov_base
= NULL
;
2364 msg
.msg_name
= omsg
->msg_name
; /* optional address */
2365 msg
.msg_namelen
= omsg
->msg_namelen
; /* size of address */
2366 msg
.msg_iov
= omsg
->msg_iov
; /* scatter/gather array */
2367 msg
.msg_iovlen
= omsg
->msg_iovlen
; /* # elements in msg_iov */
2368 /* the following is not available on solaris */
2369 msg
.msg_control
= omsg
->msg_control
; /* ancillary data, see below */
2370 msg
.msg_controllen
= omsg
->msg_controllen
; /* ancillary data buffer len */
2371 msg
.msg_flags
= omsg
->msg_flags
; /* flags on received message */
2374 ret
= swrap_sendmsg_before(s
, si
, &msg
, &tmp
, &un_addr
, &to_un
, &to
, &bcast
);
2375 if (ret
== -1) return -1;
2380 unsigned int prt
= ntohs(((const struct sockaddr_in
*)to
)->sin_port
);
2388 for (i
=0; i
< msg
.msg_iovlen
; i
++) {
2389 avail
+= msg
.msg_iov
[i
].iov_len
;
2395 /* we capture it as one single packet */
2396 buf
= (uint8_t *)malloc(remain
);
2401 for (i
=0; i
< msg
.msg_iovlen
; i
++) {
2402 size_t this_time
= MIN(remain
, msg
.msg_iov
[i
].iov_len
);
2404 msg
.msg_iov
[i
].iov_base
,
2407 remain
-= this_time
;
2410 type
= SOCKET_TYPE_CHAR_UDP
;
2412 for(iface
=0; iface
<= MAX_WRAPPED_INTERFACES
; iface
++) {
2413 snprintf(un_addr
.sun_path
, sizeof(un_addr
.sun_path
), "%s/"SOCKET_FORMAT
,
2414 socket_wrapper_dir(), type
, iface
, prt
);
2415 if (stat(un_addr
.sun_path
, &st
) != 0) continue;
2417 msg
.msg_name
= &un_addr
; /* optional address */
2418 msg
.msg_namelen
= sizeof(un_addr
); /* size of address */
2420 /* ignore the any errors in broadcast sends */
2421 real_sendmsg(s
, &msg
, flags
);
2424 swrap_dump_packet(si
, to
, SWRAP_SENDTO
, buf
, len
);
2430 ret
= real_sendmsg(s
, &msg
, flags
);
2432 swrap_sendmsg_after(si
, &msg
, to
, ret
);
2437 int swrap_readv(int s
, const struct iovec
*vector
, size_t count
)
2440 struct socket_info
*si
= find_socket_info(s
);
2444 return real_readv(s
, vector
, count
);
2447 if (!si
->connected
) {
2452 if (si
->type
== SOCK_STREAM
&& count
> 0) {
2453 /* cut down to 1500 byte packets for stream sockets,
2454 * which makes it easier to format PCAP capture files
2455 * (as the caller will simply continue from here) */
2458 for (i
=0; i
< count
; i
++) {
2460 nlen
= len
+ vector
[i
].iov_len
;
2468 v
.iov_len
= MIN(v
.iov_len
, 1500);
2474 ret
= real_readv(s
, vector
, count
);
2475 if (ret
== -1 && errno
!= EAGAIN
&& errno
!= ENOBUFS
) {
2476 swrap_dump_packet(si
, NULL
, SWRAP_RECV_RST
, NULL
, 0);
2477 } else if (ret
== 0) { /* END OF FILE */
2478 swrap_dump_packet(si
, NULL
, SWRAP_RECV_RST
, NULL
, 0);
2479 } else if (ret
> 0) {
2483 size_t remain
= ret
;
2485 /* we capture it as one single packet */
2486 buf
= (uint8_t *)malloc(ret
);
2488 /* we just not capture the packet */
2493 for (i
=0; i
< count
; i
++) {
2494 size_t this_time
= MIN(remain
, vector
[i
].iov_len
);
2499 remain
-= this_time
;
2502 swrap_dump_packet(si
, NULL
, SWRAP_RECV
, buf
, ret
);
2509 ssize_t
swrap_writev(int s
, const struct iovec
*vector
, size_t count
)
2513 struct sockaddr_un un_addr
;
2515 struct socket_info
*si
= find_socket_info(s
);
2518 return real_writev(s
, vector
, count
);
2521 tmp
.iov_base
= NULL
;
2525 msg
.msg_name
= NULL
; /* optional address */
2526 msg
.msg_namelen
= 0; /* size of address */
2527 msg
.msg_iov
= discard_const_p(struct iovec
, vector
); /* scatter/gather array */
2528 msg
.msg_iovlen
= count
; /* # elements in msg_iov */
2529 #if 0 /* not available on solaris */
2530 msg
.msg_control
= NULL
; /* ancillary data, see below */
2531 msg
.msg_controllen
= 0; /* ancillary data buffer len */
2532 msg
.msg_flags
= 0; /* flags on received message */
2535 ret
= swrap_sendmsg_before(s
, si
, &msg
, &tmp
, &un_addr
, NULL
, NULL
, NULL
);
2536 if (ret
== -1) return -1;
2538 ret
= real_writev(s
, msg
.msg_iov
, msg
.msg_iovlen
);
2540 swrap_sendmsg_after(si
, &msg
, NULL
, ret
);
2545 _PUBLIC_
int swrap_close(int fd
)
2547 struct socket_info
*si
= find_socket_info(fd
);
2548 struct socket_info_fd
*fi
;
2552 return real_close(fd
);
2555 for (fi
= si
->fds
; fi
; fi
= fi
->next
) {
2557 SWRAP_DLIST_REMOVE(si
->fds
, fi
);
2564 /* there are still references left */
2565 return real_close(fd
);
2568 SWRAP_DLIST_REMOVE(sockets
, si
);
2570 if (si
->myname
&& si
->peername
) {
2571 swrap_dump_packet(si
, NULL
, SWRAP_CLOSE_SEND
, NULL
, 0);
2574 ret
= real_close(fd
);
2576 if (si
->myname
&& si
->peername
) {
2577 swrap_dump_packet(si
, NULL
, SWRAP_CLOSE_RECV
, NULL
, 0);
2578 swrap_dump_packet(si
, NULL
, SWRAP_CLOSE_ACK
, NULL
, 0);
2581 if (si
->myname
) free(si
->myname
);
2582 if (si
->peername
) free(si
->peername
);
2584 unlink(si
->tmp_path
);
2592 _PUBLIC_
int swrap_dup(int fd
)
2594 struct socket_info
*si
;
2595 struct socket_info_fd
*fi
;
2597 si
= find_socket_info(fd
);
2600 return real_dup(fd
);
2603 fi
= (struct socket_info_fd
*)calloc(1, sizeof(struct socket_info_fd
));
2609 fi
->fd
= real_dup(fd
);
2611 int saved_errno
= errno
;
2613 errno
= saved_errno
;
2617 SWRAP_DLIST_ADD(si
->fds
, fi
);
2621 _PUBLIC_
int swrap_dup2(int fd
, int newfd
)
2623 struct socket_info
*si
;
2624 struct socket_info_fd
*fi
;
2626 si
= find_socket_info(fd
);
2629 return real_dup2(fd
, newfd
);
2632 if (find_socket_info(newfd
)) {
2633 /* dup2() does an implicit close of newfd, which we
2634 * need to emulate */
2638 fi
= (struct socket_info_fd
*)calloc(1, sizeof(struct socket_info_fd
));
2644 fi
->fd
= real_dup2(fd
, newfd
);
2646 int saved_errno
= errno
;
2648 errno
= saved_errno
;
2652 SWRAP_DLIST_ADD(si
->fds
, fi
);