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_read read
125 #define real_send send
126 #define real_readv readv
127 #define real_writev writev
128 #define real_socket socket
129 #define real_close close
132 #ifdef HAVE_GETTIMEOFDAY_TZ
133 #define swrapGetTimeOfDay(tval) gettimeofday(tval,NULL)
135 #define swrapGetTimeOfDay(tval) gettimeofday(tval)
138 /* we need to use a very terse format here as IRIX 6.4 silently
139 truncates names to 16 chars, so if we use a longer name then we
140 can't tell which port a packet came from with recvfrom()
142 with this format we have 8 chars left for the directory name
144 #define SOCKET_FORMAT "%c%02X%04X"
145 #define SOCKET_TYPE_CHAR_TCP 'T'
146 #define SOCKET_TYPE_CHAR_UDP 'U'
147 #define SOCKET_TYPE_CHAR_TCP_V6 'X'
148 #define SOCKET_TYPE_CHAR_UDP_V6 'Y'
150 #define MAX_WRAPPED_INTERFACES 16
156 static const struct in6_addr
*swrap_ipv6(void)
158 static struct in6_addr v
;
159 static int initialized
;
167 ret
= inet_pton(AF_INET6
, "FD00::5357:5F00", &v
);
176 static struct sockaddr
*sockaddr_dup(const void *data
, socklen_t len
)
178 struct sockaddr
*ret
= (struct sockaddr
*)malloc(len
);
179 memcpy(ret
, data
, len
);
183 static void set_port(int family
, int prt
, struct sockaddr
*addr
)
187 ((struct sockaddr_in
*)addr
)->sin_port
= htons(prt
);
191 ((struct sockaddr_in6
*)addr
)->sin6_port
= htons(prt
);
197 static size_t socket_length(int family
)
201 return sizeof(struct sockaddr_in
);
204 return sizeof(struct sockaddr_in6
);
228 struct sockaddr
*myname
;
229 socklen_t myname_len
;
231 struct sockaddr
*peername
;
232 socklen_t peername_len
;
235 unsigned long pck_snd
;
236 unsigned long pck_rcv
;
239 struct socket_info
*prev
, *next
;
242 static struct socket_info
*sockets
;
244 const char *socket_wrapper_dir(void)
246 const char *s
= getenv("SOCKET_WRAPPER_DIR");
250 if (strncmp(s
, "./", 2) == 0) {
256 unsigned int socket_wrapper_default_iface(void)
258 const char *s
= getenv("SOCKET_WRAPPER_DEFAULT_IFACE");
261 if (sscanf(s
, "%u", &iface
) == 1) {
262 if (iface
>= 1 && iface
<= MAX_WRAPPED_INTERFACES
) {
268 return 1;/* 127.0.0.1 */
271 static int convert_un_in(const struct sockaddr_un
*un
, struct sockaddr
*in
, socklen_t
*len
)
278 p
= strrchr(un
->sun_path
, '/');
279 if (p
) p
++; else p
= un
->sun_path
;
281 if (sscanf(p
, SOCKET_FORMAT
, &type
, &iface
, &prt
) != 3) {
286 if (iface
== 0 || iface
> MAX_WRAPPED_INTERFACES
) {
297 case SOCKET_TYPE_CHAR_TCP
:
298 case SOCKET_TYPE_CHAR_UDP
: {
299 struct sockaddr_in
*in2
= (struct sockaddr_in
*)in
;
301 if ((*len
) < sizeof(*in2
)) {
306 memset(in2
, 0, sizeof(*in2
));
307 in2
->sin_family
= AF_INET
;
308 in2
->sin_addr
.s_addr
= htonl((127<<24) | iface
);
309 in2
->sin_port
= htons(prt
);
315 case SOCKET_TYPE_CHAR_TCP_V6
:
316 case SOCKET_TYPE_CHAR_UDP_V6
: {
317 struct sockaddr_in6
*in2
= (struct sockaddr_in6
*)in
;
319 if ((*len
) < sizeof(*in2
)) {
324 memset(in2
, 0, sizeof(*in2
));
325 in2
->sin6_family
= AF_INET6
;
326 in2
->sin6_addr
= *swrap_ipv6();
327 in2
->sin6_addr
.s6_addr
[15] = iface
;
328 in2
->sin6_port
= htons(prt
);
342 static int convert_in_un_remote(struct socket_info
*si
, const struct sockaddr
*inaddr
, struct sockaddr_un
*un
,
350 if (bcast
) *bcast
= 0;
352 switch (inaddr
->sa_family
) {
354 const struct sockaddr_in
*in
=
355 (const struct sockaddr_in
*)inaddr
;
356 unsigned int addr
= ntohl(in
->sin_addr
.s_addr
);
363 u_type
= SOCKET_TYPE_CHAR_TCP
;
366 u_type
= SOCKET_TYPE_CHAR_UDP
;
367 a_type
= SOCKET_TYPE_CHAR_UDP
;
368 b_type
= SOCKET_TYPE_CHAR_UDP
;
372 prt
= ntohs(in
->sin_port
);
373 if (a_type
&& addr
== 0xFFFFFFFF) {
374 /* 255.255.255.255 only udp */
377 iface
= socket_wrapper_default_iface();
378 } else if (b_type
&& addr
== 0x7FFFFFFF) {
379 /* 127.255.255.255 only udp */
382 iface
= socket_wrapper_default_iface();
383 } else if ((addr
& 0xFFFFFF00) == 0x7F000000) {
387 iface
= (addr
& 0x000000FF);
392 if (bcast
) *bcast
= is_bcast
;
397 const struct sockaddr_in6
*in
=
398 (const struct sockaddr_in6
*)inaddr
;
403 type
= SOCKET_TYPE_CHAR_TCP_V6
;
406 type
= SOCKET_TYPE_CHAR_UDP_V6
;
410 /* XXX no multicast/broadcast */
412 prt
= ntohs(in
->sin6_port
);
416 if (IN6_ARE_ADDR_EQUAL(swrap_ipv6(), &cmp
)) {
417 iface
= in
->sin6_addr
.s6_addr
[15];
437 snprintf(un
->sun_path
, sizeof(un
->sun_path
), "%s/EINVAL",
438 socket_wrapper_dir());
439 /* the caller need to do more processing */
443 snprintf(un
->sun_path
, sizeof(un
->sun_path
), "%s/"SOCKET_FORMAT
,
444 socket_wrapper_dir(), type
, iface
, prt
);
449 static int convert_in_un_alloc(struct socket_info
*si
, const struct sockaddr
*inaddr
, struct sockaddr_un
*un
,
458 if (bcast
) *bcast
= 0;
460 switch (si
->family
) {
462 const struct sockaddr_in
*in
=
463 (const struct sockaddr_in
*)inaddr
;
464 unsigned int addr
= ntohl(in
->sin_addr
.s_addr
);
470 prt
= ntohs(in
->sin_port
);
474 u_type
= SOCKET_TYPE_CHAR_TCP
;
475 d_type
= SOCKET_TYPE_CHAR_TCP
;
478 u_type
= SOCKET_TYPE_CHAR_UDP
;
479 d_type
= SOCKET_TYPE_CHAR_UDP
;
480 a_type
= SOCKET_TYPE_CHAR_UDP
;
481 b_type
= SOCKET_TYPE_CHAR_UDP
;
489 iface
= socket_wrapper_default_iface();
490 } else if (a_type
&& addr
== 0xFFFFFFFF) {
491 /* 255.255.255.255 only udp */
494 iface
= socket_wrapper_default_iface();
495 } else if (b_type
&& addr
== 0x7FFFFFFF) {
496 /* 127.255.255.255 only udp */
499 iface
= socket_wrapper_default_iface();
500 } else if ((addr
& 0xFFFFFF00) == 0x7F000000) {
504 iface
= (addr
& 0x000000FF);
506 errno
= EADDRNOTAVAIL
;
513 const struct sockaddr_in6
*in
=
514 (const struct sockaddr_in6
*)inaddr
;
519 type
= SOCKET_TYPE_CHAR_TCP_V6
;
522 type
= SOCKET_TYPE_CHAR_UDP_V6
;
526 /* XXX no multicast/broadcast */
528 prt
= ntohs(in
->sin6_port
);
532 if (IN6_IS_ADDR_UNSPECIFIED(&in
->sin6_addr
)) {
533 iface
= socket_wrapper_default_iface();
534 } else if (IN6_ARE_ADDR_EQUAL(swrap_ipv6(), &cmp
)) {
535 iface
= in
->sin6_addr
.s6_addr
[15];
537 errno
= EADDRNOTAVAIL
;
545 errno
= EADDRNOTAVAIL
;
550 if (bcast
) *bcast
= is_bcast
;
553 /* handle auto-allocation of ephemeral ports */
554 for (prt
= 5001; prt
< 10000; prt
++) {
555 snprintf(un
->sun_path
, sizeof(un
->sun_path
), "%s/"SOCKET_FORMAT
,
556 socket_wrapper_dir(), type
, iface
, prt
);
557 if (stat(un
->sun_path
, &st
) == 0) continue;
559 set_port(si
->family
, prt
, si
->myname
);
568 snprintf(un
->sun_path
, sizeof(un
->sun_path
), "%s/"SOCKET_FORMAT
,
569 socket_wrapper_dir(), type
, iface
, prt
);
573 static struct socket_info
*find_socket_info(int fd
)
575 struct socket_info
*i
;
576 for (i
= sockets
; i
; i
= i
->next
) {
584 static int sockaddr_convert_to_un(struct socket_info
*si
, const struct sockaddr
*in_addr
, socklen_t in_len
,
585 struct sockaddr_un
*out_addr
, int alloc_sock
, int *bcast
)
587 struct sockaddr
*out
= (struct sockaddr
*)(void *)out_addr
;
591 out
->sa_family
= AF_UNIX
;
592 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
593 out
->sa_len
= sizeof(*out_addr
);
596 switch (in_addr
->sa_family
) {
606 errno
= ESOCKTNOSUPPORT
;
610 return convert_in_un_alloc(si
, in_addr
, out_addr
, bcast
);
612 return convert_in_un_remote(si
, in_addr
, out_addr
, bcast
);
618 errno
= EAFNOSUPPORT
;
622 static int sockaddr_convert_from_un(const struct socket_info
*si
,
623 const struct sockaddr_un
*in_addr
,
624 socklen_t un_addrlen
,
626 struct sockaddr
*out_addr
,
627 socklen_t
*out_addrlen
)
631 if (out_addr
== NULL
|| out_addrlen
== NULL
)
634 if (un_addrlen
== 0) {
649 errno
= ESOCKTNOSUPPORT
;
652 ret
= convert_un_in(in_addr
, out_addr
, out_addrlen
);
653 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
654 out_addr
->sa_len
= *out_addrlen
;
661 errno
= EAFNOSUPPORT
;
665 enum swrap_packet_type
{
667 SWRAP_CONNECT_UNREACH
,
675 SWRAP_SENDTO_UNREACH
,
686 struct swrap_file_hdr
{
688 uint16_t version_major
;
689 uint16_t version_minor
;
692 uint32_t frame_max_len
;
693 #define SWRAP_FRAME_LENGTH_MAX 0xFFFF
696 #define SWRAP_FILE_HDR_SIZE 24
698 struct swrap_packet_frame
{
700 uint32_t micro_seconds
;
701 uint32_t recorded_length
;
702 uint32_t full_length
;
704 #define SWRAP_PACKET_FRAME_SIZE 16
706 union swrap_packet_ip
{
710 uint16_t packet_length
;
711 uint16_t identification
;
716 uint16_t hdr_checksum
;
720 #define SWRAP_PACKET_IP_V4_SIZE 20
723 uint8_t flow_label_high
;
724 uint16_t flow_label_low
;
725 uint16_t payload_length
;
728 uint8_t src_addr
[16];
729 uint8_t dest_addr
[16];
731 #define SWRAP_PACKET_IP_V6_SIZE 40
733 #define SWRAP_PACKET_IP_SIZE 40
735 union swrap_packet_payload
{
737 uint16_t source_port
;
747 #define SWRAP_PACKET_PAYLOAD_TCP_SIZE 20
749 uint16_t source_port
;
754 #define SWRAP_PACKET_PAYLOAD_UDP_SIZE 8
761 #define SWRAP_PACKET_PAYLOAD_ICMP4_SIZE 8
768 #define SWRAP_PACKET_PAYLOAD_ICMP6_SIZE 8
770 #define SWRAP_PACKET_PAYLOAD_SIZE 20
772 #define SWRAP_PACKET_MIN_ALLOC \
773 (SWRAP_PACKET_FRAME_SIZE + \
774 SWRAP_PACKET_IP_SIZE + \
775 SWRAP_PACKET_PAYLOAD_SIZE)
777 static const char *socket_wrapper_pcap_file(void)
779 static int initialized
= 0;
780 static const char *s
= NULL
;
781 static const struct swrap_file_hdr h
;
782 static const struct swrap_packet_frame f
;
783 static const union swrap_packet_ip i
;
784 static const union swrap_packet_payload p
;
786 if (initialized
== 1) {
792 * TODO: don't use the structs use plain buffer offsets
793 * and PUSH_U8(), PUSH_U16() and PUSH_U32()
795 * for now make sure we disable PCAP support
796 * if the struct has alignment!
798 if (sizeof(h
) != SWRAP_FILE_HDR_SIZE
) {
801 if (sizeof(f
) != SWRAP_PACKET_FRAME_SIZE
) {
804 if (sizeof(i
) != SWRAP_PACKET_IP_SIZE
) {
807 if (sizeof(i
.v4
) != SWRAP_PACKET_IP_V4_SIZE
) {
810 if (sizeof(i
.v6
) != SWRAP_PACKET_IP_V6_SIZE
) {
813 if (sizeof(p
) != SWRAP_PACKET_PAYLOAD_SIZE
) {
816 if (sizeof(p
.tcp
) != SWRAP_PACKET_PAYLOAD_TCP_SIZE
) {
819 if (sizeof(p
.udp
) != SWRAP_PACKET_PAYLOAD_UDP_SIZE
) {
822 if (sizeof(p
.icmp4
) != SWRAP_PACKET_PAYLOAD_ICMP4_SIZE
) {
825 if (sizeof(p
.icmp6
) != SWRAP_PACKET_PAYLOAD_ICMP6_SIZE
) {
829 s
= getenv("SOCKET_WRAPPER_PCAP_FILE");
833 if (strncmp(s
, "./", 2) == 0) {
839 static uint8_t *swrap_packet_init(struct timeval
*tval
,
840 const struct sockaddr
*src
,
841 const struct sockaddr
*dest
,
843 const uint8_t *payload
,
845 unsigned long tcp_seqno
,
846 unsigned long tcp_ack
,
847 unsigned char tcp_ctl
,
853 struct swrap_packet_frame
*frame
;
854 union swrap_packet_ip
*ip
;
855 union swrap_packet_payload
*pay
;
858 size_t nonwire_len
= sizeof(*frame
);
859 size_t wire_hdr_len
= 0;
861 size_t ip_hdr_len
= 0;
862 size_t icmp_hdr_len
= 0;
863 size_t icmp_truncate_len
= 0;
864 uint8_t protocol
= 0, icmp_protocol
= 0;
865 const struct sockaddr_in
*src_in
= NULL
;
866 const struct sockaddr_in
*dest_in
= NULL
;
868 const struct sockaddr_in6
*src_in6
= NULL
;
869 const struct sockaddr_in6
*dest_in6
= NULL
;
874 switch (src
->sa_family
) {
876 src_in
= (const struct sockaddr_in
*)src
;
877 dest_in
= (const struct sockaddr_in
*)dest
;
878 src_port
= src_in
->sin_port
;
879 dest_port
= dest_in
->sin_port
;
880 ip_hdr_len
= sizeof(ip
->v4
);
884 src_in6
= (const struct sockaddr_in6
*)src
;
885 dest_in6
= (const struct sockaddr_in6
*)dest
;
886 src_port
= src_in6
->sin6_port
;
887 dest_port
= dest_in6
->sin6_port
;
888 ip_hdr_len
= sizeof(ip
->v6
);
895 switch (socket_type
) {
897 protocol
= 0x06; /* TCP */
898 wire_hdr_len
= ip_hdr_len
+ sizeof(pay
->tcp
);
899 wire_len
= wire_hdr_len
+ payload_len
;
903 protocol
= 0x11; /* UDP */
904 wire_hdr_len
= ip_hdr_len
+ sizeof(pay
->udp
);
905 wire_len
= wire_hdr_len
+ payload_len
;
913 icmp_protocol
= protocol
;
914 switch (src
->sa_family
) {
916 protocol
= 0x01; /* ICMPv4 */
917 icmp_hdr_len
= ip_hdr_len
+ sizeof(pay
->icmp4
);
921 protocol
= 0x3A; /* ICMPv6 */
922 icmp_hdr_len
= ip_hdr_len
+ sizeof(pay
->icmp6
);
926 if (wire_len
> 64 ) {
927 icmp_truncate_len
= wire_len
- 64;
929 wire_hdr_len
+= icmp_hdr_len
;
930 wire_len
+= icmp_hdr_len
;
933 packet_len
= nonwire_len
+ wire_len
;
934 alloc_len
= packet_len
;
935 if (alloc_len
< SWRAP_PACKET_MIN_ALLOC
) {
936 alloc_len
= SWRAP_PACKET_MIN_ALLOC
;
939 base
= (uint8_t *)malloc(alloc_len
);
940 if (!base
) return NULL
;
944 frame
= (struct swrap_packet_frame
*)buf
;
945 frame
->seconds
= tval
->tv_sec
;
946 frame
->micro_seconds
= tval
->tv_usec
;
947 frame
->recorded_length
= wire_len
- icmp_truncate_len
;
948 frame
->full_length
= wire_len
- icmp_truncate_len
;
949 buf
+= SWRAP_PACKET_FRAME_SIZE
;
951 ip
= (union swrap_packet_ip
*)buf
;
952 switch (src
->sa_family
) {
954 ip
->v4
.ver_hdrlen
= 0x45; /* version 4 and 5 * 32 bit words */
956 ip
->v4
.packet_length
= htons(wire_len
- icmp_truncate_len
);
957 ip
->v4
.identification
= htons(0xFFFF);
958 ip
->v4
.flags
= 0x40; /* BIT 1 set - means don't fraqment */
959 ip
->v4
.fragment
= htons(0x0000);
961 ip
->v4
.protocol
= protocol
;
962 ip
->v4
.hdr_checksum
= htons(0x0000);
963 ip
->v4
.src_addr
= src_in
->sin_addr
.s_addr
;
964 ip
->v4
.dest_addr
= dest_in
->sin_addr
.s_addr
;
965 buf
+= SWRAP_PACKET_IP_V4_SIZE
;
969 ip
->v6
.ver_prio
= 0x60; /* version 4 and 5 * 32 bit words */
970 ip
->v6
.flow_label_high
= 0x00;
971 ip
->v6
.flow_label_low
= 0x0000;
972 ip
->v6
.payload_length
= htons(wire_len
- icmp_truncate_len
);//TODO
973 ip
->v6
.next_header
= protocol
;
974 memcpy(ip
->v6
.src_addr
, src_in6
->sin6_addr
.s6_addr
, 16);
975 memcpy(ip
->v6
.dest_addr
, dest_in6
->sin6_addr
.s6_addr
, 16);
976 buf
+= SWRAP_PACKET_IP_V6_SIZE
;
982 pay
= (union swrap_packet_payload
*)buf
;
983 switch (src
->sa_family
) {
985 pay
->icmp4
.type
= 0x03; /* destination unreachable */
986 pay
->icmp4
.code
= 0x01; /* host unreachable */
987 pay
->icmp4
.checksum
= htons(0x0000);
988 pay
->icmp4
.unused
= htonl(0x00000000);
989 buf
+= SWRAP_PACKET_PAYLOAD_ICMP4_SIZE
;
991 /* set the ip header in the ICMP payload */
992 ip
= (union swrap_packet_ip
*)buf
;
993 ip
->v4
.ver_hdrlen
= 0x45; /* version 4 and 5 * 32 bit words */
995 ip
->v4
.packet_length
= htons(wire_len
- icmp_hdr_len
);
996 ip
->v4
.identification
= htons(0xFFFF);
997 ip
->v4
.flags
= 0x40; /* BIT 1 set - means don't fraqment */
998 ip
->v4
.fragment
= htons(0x0000);
1000 ip
->v4
.protocol
= icmp_protocol
;
1001 ip
->v4
.hdr_checksum
= htons(0x0000);
1002 ip
->v4
.src_addr
= dest_in
->sin_addr
.s_addr
;
1003 ip
->v4
.dest_addr
= src_in
->sin_addr
.s_addr
;
1004 buf
+= SWRAP_PACKET_IP_V4_SIZE
;
1006 src_port
= dest_in
->sin_port
;
1007 dest_port
= src_in
->sin_port
;
1011 pay
->icmp6
.type
= 0x01; /* destination unreachable */
1012 pay
->icmp6
.code
= 0x03; /* address unreachable */
1013 pay
->icmp6
.checksum
= htons(0x0000);
1014 pay
->icmp6
.unused
= htonl(0x00000000);
1015 buf
+= SWRAP_PACKET_PAYLOAD_ICMP6_SIZE
;
1017 /* set the ip header in the ICMP payload */
1018 ip
= (union swrap_packet_ip
*)buf
;
1019 ip
->v6
.ver_prio
= 0x60; /* version 4 and 5 * 32 bit words */
1020 ip
->v6
.flow_label_high
= 0x00;
1021 ip
->v6
.flow_label_low
= 0x0000;
1022 ip
->v6
.payload_length
= htons(wire_len
- icmp_truncate_len
);//TODO
1023 ip
->v6
.next_header
= protocol
;
1024 memcpy(ip
->v6
.src_addr
, dest_in6
->sin6_addr
.s6_addr
, 16);
1025 memcpy(ip
->v6
.dest_addr
, src_in6
->sin6_addr
.s6_addr
, 16);
1026 buf
+= SWRAP_PACKET_IP_V6_SIZE
;
1028 src_port
= dest_in6
->sin6_port
;
1029 dest_port
= src_in6
->sin6_port
;
1035 pay
= (union swrap_packet_payload
*)buf
;
1037 switch (socket_type
) {
1039 pay
->tcp
.source_port
= src_port
;
1040 pay
->tcp
.dest_port
= dest_port
;
1041 pay
->tcp
.seq_num
= htonl(tcp_seqno
);
1042 pay
->tcp
.ack_num
= htonl(tcp_ack
);
1043 pay
->tcp
.hdr_length
= 0x50; /* 5 * 32 bit words */
1044 pay
->tcp
.control
= tcp_ctl
;
1045 pay
->tcp
.window
= htons(0x7FFF);
1046 pay
->tcp
.checksum
= htons(0x0000);
1047 pay
->tcp
.urg
= htons(0x0000);
1048 buf
+= SWRAP_PACKET_PAYLOAD_TCP_SIZE
;
1053 pay
->udp
.source_port
= src_port
;
1054 pay
->udp
.dest_port
= dest_port
;
1055 pay
->udp
.length
= htons(8 + payload_len
);
1056 pay
->udp
.checksum
= htons(0x0000);
1057 buf
+= SWRAP_PACKET_PAYLOAD_UDP_SIZE
;
1062 if (payload
&& payload_len
> 0) {
1063 memcpy(buf
, payload
, payload_len
);
1066 *_packet_len
= packet_len
- icmp_truncate_len
;
1070 static int swrap_get_pcap_fd(const char *fname
)
1074 if (fd
!= -1) return fd
;
1076 fd
= open(fname
, O_WRONLY
|O_CREAT
|O_EXCL
|O_APPEND
, 0644);
1078 struct swrap_file_hdr file_hdr
;
1079 file_hdr
.magic
= 0xA1B2C3D4;
1080 file_hdr
.version_major
= 0x0002;
1081 file_hdr
.version_minor
= 0x0004;
1082 file_hdr
.timezone
= 0x00000000;
1083 file_hdr
.sigfigs
= 0x00000000;
1084 file_hdr
.frame_max_len
= SWRAP_FRAME_LENGTH_MAX
;
1085 file_hdr
.link_type
= 0x0065; /* 101 RAW IP */
1087 if (write(fd
, &file_hdr
, sizeof(file_hdr
)) != sizeof(file_hdr
)) {
1094 fd
= open(fname
, O_WRONLY
|O_APPEND
, 0644);
1099 static uint8_t *swrap_marshall_packet(struct socket_info
*si
,
1100 const struct sockaddr
*addr
,
1101 enum swrap_packet_type type
,
1102 const void *buf
, size_t len
,
1105 const struct sockaddr
*src_addr
;
1106 const struct sockaddr
*dest_addr
;
1107 unsigned long tcp_seqno
= 0;
1108 unsigned long tcp_ack
= 0;
1109 unsigned char tcp_ctl
= 0;
1110 int unreachable
= 0;
1114 switch (si
->family
) {
1126 case SWRAP_CONNECT_SEND
:
1127 if (si
->type
!= SOCK_STREAM
) return NULL
;
1129 src_addr
= si
->myname
;
1132 tcp_seqno
= si
->io
.pck_snd
;
1133 tcp_ack
= si
->io
.pck_rcv
;
1134 tcp_ctl
= 0x02; /* SYN */
1136 si
->io
.pck_snd
+= 1;
1140 case SWRAP_CONNECT_RECV
:
1141 if (si
->type
!= SOCK_STREAM
) return NULL
;
1143 dest_addr
= si
->myname
;
1146 tcp_seqno
= si
->io
.pck_rcv
;
1147 tcp_ack
= si
->io
.pck_snd
;
1148 tcp_ctl
= 0x12; /** SYN,ACK */
1150 si
->io
.pck_rcv
+= 1;
1154 case SWRAP_CONNECT_UNREACH
:
1155 if (si
->type
!= SOCK_STREAM
) return NULL
;
1157 dest_addr
= si
->myname
;
1160 /* Unreachable: resend the data of SWRAP_CONNECT_SEND */
1161 tcp_seqno
= si
->io
.pck_snd
- 1;
1162 tcp_ack
= si
->io
.pck_rcv
;
1163 tcp_ctl
= 0x02; /* SYN */
1168 case SWRAP_CONNECT_ACK
:
1169 if (si
->type
!= SOCK_STREAM
) return NULL
;
1171 src_addr
= si
->myname
;
1174 tcp_seqno
= si
->io
.pck_snd
;
1175 tcp_ack
= si
->io
.pck_rcv
;
1176 tcp_ctl
= 0x10; /* ACK */
1180 case SWRAP_ACCEPT_SEND
:
1181 if (si
->type
!= SOCK_STREAM
) return NULL
;
1183 dest_addr
= si
->myname
;
1186 tcp_seqno
= si
->io
.pck_rcv
;
1187 tcp_ack
= si
->io
.pck_snd
;
1188 tcp_ctl
= 0x02; /* SYN */
1190 si
->io
.pck_rcv
+= 1;
1194 case SWRAP_ACCEPT_RECV
:
1195 if (si
->type
!= SOCK_STREAM
) return NULL
;
1197 src_addr
= si
->myname
;
1200 tcp_seqno
= si
->io
.pck_snd
;
1201 tcp_ack
= si
->io
.pck_rcv
;
1202 tcp_ctl
= 0x12; /* SYN,ACK */
1204 si
->io
.pck_snd
+= 1;
1208 case SWRAP_ACCEPT_ACK
:
1209 if (si
->type
!= SOCK_STREAM
) return NULL
;
1211 dest_addr
= si
->myname
;
1214 tcp_seqno
= si
->io
.pck_rcv
;
1215 tcp_ack
= si
->io
.pck_snd
;
1216 tcp_ctl
= 0x10; /* ACK */
1221 src_addr
= si
->myname
;
1222 dest_addr
= si
->peername
;
1224 tcp_seqno
= si
->io
.pck_snd
;
1225 tcp_ack
= si
->io
.pck_rcv
;
1226 tcp_ctl
= 0x18; /* PSH,ACK */
1228 si
->io
.pck_snd
+= len
;
1232 case SWRAP_SEND_RST
:
1233 dest_addr
= si
->myname
;
1234 src_addr
= si
->peername
;
1236 if (si
->type
== SOCK_DGRAM
) {
1237 return swrap_marshall_packet(si
, si
->peername
,
1238 SWRAP_SENDTO_UNREACH
,
1239 buf
, len
, packet_len
);
1242 tcp_seqno
= si
->io
.pck_rcv
;
1243 tcp_ack
= si
->io
.pck_snd
;
1244 tcp_ctl
= 0x14; /** RST,ACK */
1248 case SWRAP_PENDING_RST
:
1249 dest_addr
= si
->myname
;
1250 src_addr
= si
->peername
;
1252 if (si
->type
== SOCK_DGRAM
) {
1256 tcp_seqno
= si
->io
.pck_rcv
;
1257 tcp_ack
= si
->io
.pck_snd
;
1258 tcp_ctl
= 0x14; /* RST,ACK */
1263 dest_addr
= si
->myname
;
1264 src_addr
= si
->peername
;
1266 tcp_seqno
= si
->io
.pck_rcv
;
1267 tcp_ack
= si
->io
.pck_snd
;
1268 tcp_ctl
= 0x18; /* PSH,ACK */
1270 si
->io
.pck_rcv
+= len
;
1274 case SWRAP_RECV_RST
:
1275 dest_addr
= si
->myname
;
1276 src_addr
= si
->peername
;
1278 if (si
->type
== SOCK_DGRAM
) {
1282 tcp_seqno
= si
->io
.pck_rcv
;
1283 tcp_ack
= si
->io
.pck_snd
;
1284 tcp_ctl
= 0x14; /* RST,ACK */
1289 src_addr
= si
->myname
;
1292 si
->io
.pck_snd
+= len
;
1296 case SWRAP_SENDTO_UNREACH
:
1297 dest_addr
= si
->myname
;
1304 case SWRAP_RECVFROM
:
1305 dest_addr
= si
->myname
;
1308 si
->io
.pck_rcv
+= len
;
1312 case SWRAP_CLOSE_SEND
:
1313 if (si
->type
!= SOCK_STREAM
) return NULL
;
1315 src_addr
= si
->myname
;
1316 dest_addr
= si
->peername
;
1318 tcp_seqno
= si
->io
.pck_snd
;
1319 tcp_ack
= si
->io
.pck_rcv
;
1320 tcp_ctl
= 0x11; /* FIN, ACK */
1322 si
->io
.pck_snd
+= 1;
1326 case SWRAP_CLOSE_RECV
:
1327 if (si
->type
!= SOCK_STREAM
) return NULL
;
1329 dest_addr
= si
->myname
;
1330 src_addr
= si
->peername
;
1332 tcp_seqno
= si
->io
.pck_rcv
;
1333 tcp_ack
= si
->io
.pck_snd
;
1334 tcp_ctl
= 0x11; /* FIN,ACK */
1336 si
->io
.pck_rcv
+= 1;
1340 case SWRAP_CLOSE_ACK
:
1341 if (si
->type
!= SOCK_STREAM
) return NULL
;
1343 src_addr
= si
->myname
;
1344 dest_addr
= si
->peername
;
1346 tcp_seqno
= si
->io
.pck_snd
;
1347 tcp_ack
= si
->io
.pck_rcv
;
1348 tcp_ctl
= 0x10; /* ACK */
1355 swrapGetTimeOfDay(&tv
);
1357 return swrap_packet_init(&tv
, src_addr
, dest_addr
, si
->type
,
1358 (const uint8_t *)buf
, len
,
1359 tcp_seqno
, tcp_ack
, tcp_ctl
, unreachable
,
1363 static void swrap_dump_packet(struct socket_info
*si
,
1364 const struct sockaddr
*addr
,
1365 enum swrap_packet_type type
,
1366 const void *buf
, size_t len
)
1368 const char *file_name
;
1370 size_t packet_len
= 0;
1373 file_name
= socket_wrapper_pcap_file();
1378 packet
= swrap_marshall_packet(si
, addr
, type
, buf
, len
, &packet_len
);
1383 fd
= swrap_get_pcap_fd(file_name
);
1385 if (write(fd
, packet
, packet_len
) != packet_len
) {
1394 _PUBLIC_
int swrap_socket(int family
, int type
, int protocol
)
1396 struct socket_info
*si
;
1398 int real_type
= type
;
1400 real_type
&= ~SOCK_CLOEXEC
;
1402 #ifdef SOCK_NONBLOCK
1403 real_type
&= ~SOCK_NONBLOCK
;
1406 if (!socket_wrapper_dir()) {
1407 return real_socket(family
, type
, protocol
);
1417 return real_socket(family
, type
, protocol
);
1419 errno
= EAFNOSUPPORT
;
1423 switch (real_type
) {
1429 errno
= EPROTONOSUPPORT
;
1437 if (real_type
== SOCK_STREAM
) {
1442 if (real_type
== SOCK_DGRAM
) {
1447 errno
= EPROTONOSUPPORT
;
1451 /* We must call real_socket with type, from the caller, not the version we removed
1452 SOCK_CLOEXEC and SOCK_NONBLOCK from */
1453 fd
= real_socket(AF_UNIX
, type
, 0);
1455 if (fd
== -1) return -1;
1457 si
= (struct socket_info
*)calloc(1, sizeof(struct socket_info
));
1459 si
->family
= family
;
1461 /* however, the rest of the socket_wrapper code expects just
1462 * the type, not the flags */
1463 si
->type
= real_type
;
1464 si
->protocol
= protocol
;
1467 SWRAP_DLIST_ADD(sockets
, si
);
1472 _PUBLIC_
int swrap_accept(int s
, struct sockaddr
*addr
, socklen_t
*addrlen
)
1474 struct socket_info
*parent_si
, *child_si
;
1476 struct sockaddr_un un_addr
;
1477 socklen_t un_addrlen
= sizeof(un_addr
);
1478 struct sockaddr_un un_my_addr
;
1479 socklen_t un_my_addrlen
= sizeof(un_my_addr
);
1480 struct sockaddr
*my_addr
;
1481 socklen_t my_addrlen
, len
;
1484 parent_si
= find_socket_info(s
);
1486 return real_accept(s
, addr
, addrlen
);
1490 * assume out sockaddr have the same size as the in parent
1493 my_addrlen
= socket_length(parent_si
->family
);
1494 if (my_addrlen
<= 0) {
1499 my_addr
= (struct sockaddr
*)malloc(my_addrlen
);
1500 if (my_addr
== NULL
) {
1504 memset(&un_addr
, 0, sizeof(un_addr
));
1505 memset(&un_my_addr
, 0, sizeof(un_my_addr
));
1507 ret
= real_accept(s
, (struct sockaddr
*)&un_addr
, &un_addrlen
);
1516 ret
= sockaddr_convert_from_un(parent_si
, &un_addr
, un_addrlen
,
1517 parent_si
->family
, my_addr
, &len
);
1524 child_si
= (struct socket_info
*)malloc(sizeof(struct socket_info
));
1525 memset(child_si
, 0, sizeof(*child_si
));
1528 child_si
->family
= parent_si
->family
;
1529 child_si
->type
= parent_si
->type
;
1530 child_si
->protocol
= parent_si
->protocol
;
1531 child_si
->bound
= 1;
1532 child_si
->is_server
= 1;
1533 child_si
->connected
= 1;
1535 child_si
->peername_len
= len
;
1536 child_si
->peername
= sockaddr_dup(my_addr
, len
);
1538 if (addr
!= NULL
&& addrlen
!= NULL
) {
1540 if (*addrlen
>= len
)
1541 memcpy(addr
, my_addr
, len
);
1545 ret
= real_getsockname(fd
, (struct sockaddr
*)&un_my_addr
, &un_my_addrlen
);
1553 ret
= sockaddr_convert_from_un(child_si
, &un_my_addr
, un_my_addrlen
,
1554 child_si
->family
, my_addr
, &len
);
1562 child_si
->myname_len
= len
;
1563 child_si
->myname
= sockaddr_dup(my_addr
, len
);
1566 SWRAP_DLIST_ADD(sockets
, child_si
);
1568 swrap_dump_packet(child_si
, addr
, SWRAP_ACCEPT_SEND
, NULL
, 0);
1569 swrap_dump_packet(child_si
, addr
, SWRAP_ACCEPT_RECV
, NULL
, 0);
1570 swrap_dump_packet(child_si
, addr
, SWRAP_ACCEPT_ACK
, NULL
, 0);
1575 static int autobind_start_init
;
1576 static int autobind_start
;
1578 /* using sendto() or connect() on an unbound socket would give the
1579 recipient no way to reply, as unlike UDP and TCP, a unix domain
1580 socket can't auto-assign emphemeral port numbers, so we need to
1582 Note: this might change the family from ipv6 to ipv4
1584 static int swrap_auto_bind(struct socket_info
*si
, int family
)
1586 struct sockaddr_un un_addr
;
1593 if (autobind_start_init
!= 1) {
1594 autobind_start_init
= 1;
1595 autobind_start
= getpid();
1596 autobind_start
%= 50000;
1597 autobind_start
+= 10000;
1600 un_addr
.sun_family
= AF_UNIX
;
1604 struct sockaddr_in in
;
1608 type
= SOCKET_TYPE_CHAR_TCP
;
1611 type
= SOCKET_TYPE_CHAR_UDP
;
1614 errno
= ESOCKTNOSUPPORT
;
1618 memset(&in
, 0, sizeof(in
));
1619 in
.sin_family
= AF_INET
;
1620 in
.sin_addr
.s_addr
= htonl(127<<24 |
1621 socket_wrapper_default_iface());
1623 si
->myname_len
= sizeof(in
);
1624 si
->myname
= sockaddr_dup(&in
, si
->myname_len
);
1629 struct sockaddr_in6 in6
;
1631 if (si
->family
!= family
) {
1632 errno
= ENETUNREACH
;
1638 type
= SOCKET_TYPE_CHAR_TCP_V6
;
1641 type
= SOCKET_TYPE_CHAR_UDP_V6
;
1644 errno
= ESOCKTNOSUPPORT
;
1648 memset(&in6
, 0, sizeof(in6
));
1649 in6
.sin6_family
= AF_INET6
;
1650 in6
.sin6_addr
= *swrap_ipv6();
1651 in6
.sin6_addr
.s6_addr
[15] = socket_wrapper_default_iface();
1652 si
->myname_len
= sizeof(in6
);
1653 si
->myname
= sockaddr_dup(&in6
, si
->myname_len
);
1658 errno
= ESOCKTNOSUPPORT
;
1662 if (autobind_start
> 60000) {
1663 autobind_start
= 10000;
1666 for (i
=0;i
<1000;i
++) {
1667 port
= autobind_start
+ i
;
1668 snprintf(un_addr
.sun_path
, sizeof(un_addr
.sun_path
),
1669 "%s/"SOCKET_FORMAT
, socket_wrapper_dir(),
1670 type
, socket_wrapper_default_iface(), port
);
1671 if (stat(un_addr
.sun_path
, &st
) == 0) continue;
1673 ret
= real_bind(si
->fd
, (struct sockaddr
*)&un_addr
, sizeof(un_addr
));
1674 if (ret
== -1) return ret
;
1676 si
->tmp_path
= strdup(un_addr
.sun_path
);
1678 autobind_start
= port
+ 1;
1686 si
->family
= family
;
1687 set_port(si
->family
, port
, si
->myname
);
1693 _PUBLIC_
int swrap_connect(int s
, const struct sockaddr
*serv_addr
, socklen_t addrlen
)
1696 struct sockaddr_un un_addr
;
1697 struct socket_info
*si
= find_socket_info(s
);
1700 return real_connect(s
, serv_addr
, addrlen
);
1703 if (si
->bound
== 0) {
1704 ret
= swrap_auto_bind(si
, serv_addr
->sa_family
);
1705 if (ret
== -1) return -1;
1708 if (si
->family
!= serv_addr
->sa_family
) {
1713 ret
= sockaddr_convert_to_un(si
, (const struct sockaddr
*)serv_addr
, addrlen
, &un_addr
, 0, NULL
);
1714 if (ret
== -1) return -1;
1716 if (si
->type
== SOCK_DGRAM
) {
1717 si
->defer_connect
= 1;
1720 swrap_dump_packet(si
, serv_addr
, SWRAP_CONNECT_SEND
, NULL
, 0);
1722 ret
= real_connect(s
, (struct sockaddr
*)&un_addr
,
1723 sizeof(struct sockaddr_un
));
1726 /* to give better errors */
1727 if (ret
== -1 && errno
== ENOENT
) {
1728 errno
= EHOSTUNREACH
;
1732 si
->peername_len
= addrlen
;
1733 si
->peername
= sockaddr_dup(serv_addr
, addrlen
);
1736 swrap_dump_packet(si
, serv_addr
, SWRAP_CONNECT_RECV
, NULL
, 0);
1737 swrap_dump_packet(si
, serv_addr
, SWRAP_CONNECT_ACK
, NULL
, 0);
1739 swrap_dump_packet(si
, serv_addr
, SWRAP_CONNECT_UNREACH
, NULL
, 0);
1745 _PUBLIC_
int swrap_bind(int s
, const struct sockaddr
*myaddr
, socklen_t addrlen
)
1748 struct sockaddr_un un_addr
;
1749 struct socket_info
*si
= find_socket_info(s
);
1752 return real_bind(s
, myaddr
, addrlen
);
1755 si
->myname_len
= addrlen
;
1756 si
->myname
= sockaddr_dup(myaddr
, addrlen
);
1758 ret
= sockaddr_convert_to_un(si
, (const struct sockaddr
*)myaddr
, addrlen
, &un_addr
, 1, &si
->bcast
);
1759 if (ret
== -1) return -1;
1761 unlink(un_addr
.sun_path
);
1763 ret
= real_bind(s
, (struct sockaddr
*)&un_addr
,
1764 sizeof(struct sockaddr_un
));
1773 _PUBLIC_
int swrap_listen(int s
, int backlog
)
1776 struct socket_info
*si
= find_socket_info(s
);
1779 return real_listen(s
, backlog
);
1782 ret
= real_listen(s
, backlog
);
1787 _PUBLIC_
int swrap_getpeername(int s
, struct sockaddr
*name
, socklen_t
*addrlen
)
1789 struct socket_info
*si
= find_socket_info(s
);
1792 return real_getpeername(s
, name
, addrlen
);
1801 memcpy(name
, si
->peername
, si
->peername_len
);
1802 *addrlen
= si
->peername_len
;
1807 _PUBLIC_
int swrap_getsockname(int s
, struct sockaddr
*name
, socklen_t
*addrlen
)
1809 struct socket_info
*si
= find_socket_info(s
);
1812 return real_getsockname(s
, name
, addrlen
);
1815 memcpy(name
, si
->myname
, si
->myname_len
);
1816 *addrlen
= si
->myname_len
;
1821 _PUBLIC_
int swrap_getsockopt(int s
, int level
, int optname
, void *optval
, socklen_t
*optlen
)
1823 struct socket_info
*si
= find_socket_info(s
);
1826 return real_getsockopt(s
, level
, optname
, optval
, optlen
);
1829 if (level
== SOL_SOCKET
) {
1830 return real_getsockopt(s
, level
, optname
, optval
, optlen
);
1833 errno
= ENOPROTOOPT
;
1837 _PUBLIC_
int swrap_setsockopt(int s
, int level
, int optname
, const void *optval
, socklen_t optlen
)
1839 struct socket_info
*si
= find_socket_info(s
);
1842 return real_setsockopt(s
, level
, optname
, optval
, optlen
);
1845 if (level
== SOL_SOCKET
) {
1846 return real_setsockopt(s
, level
, optname
, optval
, optlen
);
1849 switch (si
->family
) {
1857 errno
= ENOPROTOOPT
;
1862 _PUBLIC_ ssize_t
swrap_recvfrom(int s
, void *buf
, size_t len
, int flags
, struct sockaddr
*from
, socklen_t
*fromlen
)
1864 struct sockaddr_un un_addr
;
1865 socklen_t un_addrlen
= sizeof(un_addr
);
1867 struct socket_info
*si
= find_socket_info(s
);
1868 struct sockaddr_storage ss
;
1869 socklen_t ss_len
= sizeof(ss
);
1872 return real_recvfrom(s
, buf
, len
, flags
, from
, fromlen
);
1876 from
= (struct sockaddr
*)&ss
;
1880 if (si
->type
== SOCK_STREAM
) {
1881 /* cut down to 1500 byte packets for stream sockets,
1882 * which makes it easier to format PCAP capture files
1883 * (as the caller will simply continue from here) */
1884 len
= MIN(len
, 1500);
1887 /* irix 6.4 forgets to null terminate the sun_path string :-( */
1888 memset(&un_addr
, 0, sizeof(un_addr
));
1889 ret
= real_recvfrom(s
, buf
, len
, flags
, (struct sockaddr
*)&un_addr
, &un_addrlen
);
1893 if (sockaddr_convert_from_un(si
, &un_addr
, un_addrlen
,
1894 si
->family
, from
, fromlen
) == -1) {
1898 swrap_dump_packet(si
, from
, SWRAP_RECVFROM
, buf
, ret
);
1904 _PUBLIC_ ssize_t
swrap_sendto(int s
, const void *buf
, size_t len
, int flags
, const struct sockaddr
*to
, socklen_t tolen
)
1906 struct sockaddr_un un_addr
;
1908 struct socket_info
*si
= find_socket_info(s
);
1912 return real_sendto(s
, buf
, len
, flags
, to
, tolen
);
1915 if (si
->connected
) {
1922 tolen
= si
->peername_len
;
1927 /* cut down to 1500 byte packets for stream sockets,
1928 * which makes it easier to format PCAP capture files
1929 * (as the caller will simply continue from here) */
1930 len
= MIN(len
, 1500);
1932 ret
= real_send(s
, buf
, len
, flags
);
1935 if (si
->bound
== 0) {
1936 ret
= swrap_auto_bind(si
, si
->family
);
1937 if (ret
== -1) return -1;
1940 ret
= sockaddr_convert_to_un(si
, to
, tolen
, &un_addr
, 0, &bcast
);
1941 if (ret
== -1) return -1;
1946 unsigned int prt
= ntohs(((const struct sockaddr_in
*)to
)->sin_port
);
1949 type
= SOCKET_TYPE_CHAR_UDP
;
1951 for(iface
=0; iface
<= MAX_WRAPPED_INTERFACES
; iface
++) {
1952 snprintf(un_addr
.sun_path
, sizeof(un_addr
.sun_path
), "%s/"SOCKET_FORMAT
,
1953 socket_wrapper_dir(), type
, iface
, prt
);
1954 if (stat(un_addr
.sun_path
, &st
) != 0) continue;
1956 /* ignore the any errors in broadcast sends */
1957 real_sendto(s
, buf
, len
, flags
, (struct sockaddr
*)&un_addr
, sizeof(un_addr
));
1960 swrap_dump_packet(si
, to
, SWRAP_SENDTO
, buf
, len
);
1965 if (si
->defer_connect
) {
1966 ret
= real_connect(s
, (struct sockaddr
*)&un_addr
,
1969 /* to give better errors */
1970 if (ret
== -1 && errno
== ENOENT
) {
1971 errno
= EHOSTUNREACH
;
1977 si
->defer_connect
= 0;
1980 /* Man page for Linux says:
1981 * "the error EISONN may be returned when they are not NULL and 0"
1982 * But in practice it's not on x86/amd64, but on other unix it is
1984 * So if we are already connected we send NULL/0
1986 if (si
->connected
) {
1987 ret
= real_sendto(s
, buf
, len
, flags
, NULL
, 0);
1989 ret
= real_sendto(s
, buf
, len
, flags
, (struct sockaddr
*)&un_addr
, sizeof(un_addr
));
1994 errno
= EHOSTUNREACH
;
1998 /* to give better errors */
1999 if (ret
== -1 && errno
== ENOENT
) {
2000 errno
= EHOSTUNREACH
;
2004 swrap_dump_packet(si
, to
, SWRAP_SENDTO
, buf
, len
);
2005 swrap_dump_packet(si
, to
, SWRAP_SENDTO_UNREACH
, buf
, len
);
2007 swrap_dump_packet(si
, to
, SWRAP_SENDTO
, buf
, ret
);
2013 _PUBLIC_
int swrap_ioctl(int s
, int r
, void *p
)
2016 struct socket_info
*si
= find_socket_info(s
);
2020 return real_ioctl(s
, r
, p
);
2023 ret
= real_ioctl(s
, r
, p
);
2027 value
= *((int *)p
);
2028 if (ret
== -1 && errno
!= EAGAIN
&& errno
!= ENOBUFS
) {
2029 swrap_dump_packet(si
, NULL
, SWRAP_PENDING_RST
, NULL
, 0);
2030 } else if (value
== 0) { /* END OF FILE */
2031 swrap_dump_packet(si
, NULL
, SWRAP_PENDING_RST
, NULL
, 0);
2039 _PUBLIC_ ssize_t
swrap_recv(int s
, void *buf
, size_t len
, int flags
)
2042 struct socket_info
*si
= find_socket_info(s
);
2045 return real_recv(s
, buf
, len
, flags
);
2048 if (si
->type
== SOCK_STREAM
) {
2049 /* cut down to 1500 byte packets for stream sockets,
2050 * which makes it easier to format PCAP capture files
2051 * (as the caller will simply continue from here) */
2052 len
= MIN(len
, 1500);
2055 ret
= real_recv(s
, buf
, len
, flags
);
2056 if (ret
== -1 && errno
!= EAGAIN
&& errno
!= ENOBUFS
) {
2057 swrap_dump_packet(si
, NULL
, SWRAP_RECV_RST
, NULL
, 0);
2058 } else if (ret
== 0) { /* END OF FILE */
2059 swrap_dump_packet(si
, NULL
, SWRAP_RECV_RST
, NULL
, 0);
2060 } else if (ret
> 0) {
2061 swrap_dump_packet(si
, NULL
, SWRAP_RECV
, buf
, ret
);
2067 _PUBLIC_ ssize_t
swrap_read(int s
, void *buf
, size_t len
)
2070 struct socket_info
*si
= find_socket_info(s
);
2073 return real_read(s
, buf
, len
);
2076 if (si
->type
== SOCK_STREAM
) {
2077 /* cut down to 1500 byte packets for stream sockets,
2078 * which makes it easier to format PCAP capture files
2079 * (as the caller will simply continue from here) */
2080 len
= MIN(len
, 1500);
2083 ret
= real_read(s
, buf
, len
);
2084 if (ret
== -1 && errno
!= EAGAIN
&& errno
!= ENOBUFS
) {
2085 swrap_dump_packet(si
, NULL
, SWRAP_RECV_RST
, NULL
, 0);
2086 } else if (ret
== 0) { /* END OF FILE */
2087 swrap_dump_packet(si
, NULL
, SWRAP_RECV_RST
, NULL
, 0);
2088 } else if (ret
> 0) {
2089 swrap_dump_packet(si
, NULL
, SWRAP_RECV
, buf
, ret
);
2096 _PUBLIC_ ssize_t
swrap_send(int s
, const void *buf
, size_t len
, int flags
)
2099 struct socket_info
*si
= find_socket_info(s
);
2102 return real_send(s
, buf
, len
, flags
);
2105 if (si
->type
== SOCK_STREAM
) {
2106 /* cut down to 1500 byte packets for stream sockets,
2107 * which makes it easier to format PCAP capture files
2108 * (as the caller will simply continue from here) */
2109 len
= MIN(len
, 1500);
2112 if (si
->defer_connect
) {
2113 struct sockaddr_un un_addr
;
2116 if (si
->bound
== 0) {
2117 ret
= swrap_auto_bind(si
, si
->family
);
2118 if (ret
== -1) return -1;
2121 ret
= sockaddr_convert_to_un(si
, si
->peername
, si
->peername_len
,
2122 &un_addr
, 0, &bcast
);
2123 if (ret
== -1) return -1;
2125 ret
= real_connect(s
, (struct sockaddr
*)&un_addr
,
2128 /* to give better errors */
2129 if (ret
== -1 && errno
== ENOENT
) {
2130 errno
= EHOSTUNREACH
;
2136 si
->defer_connect
= 0;
2139 ret
= real_send(s
, buf
, len
, flags
);
2142 swrap_dump_packet(si
, NULL
, SWRAP_SEND
, buf
, len
);
2143 swrap_dump_packet(si
, NULL
, SWRAP_SEND_RST
, NULL
, 0);
2145 swrap_dump_packet(si
, NULL
, SWRAP_SEND
, buf
, ret
);
2151 _PUBLIC_ ssize_t
swrap_sendmsg(int s
, const struct msghdr
*msg
, int flags
)
2159 struct socket_info
*si
= find_socket_info(s
);
2162 return real_sendmsg(s
, msg
, flags
);
2165 if (si
->defer_connect
) {
2166 struct sockaddr_un un_addr
;
2169 if (si
->bound
== 0) {
2170 ret
= swrap_auto_bind(si
, si
->family
);
2171 if (ret
== -1) return -1;
2174 ret
= sockaddr_convert_to_un(si
, si
->peername
, si
->peername_len
,
2175 &un_addr
, 0, &bcast
);
2176 if (ret
== -1) return -1;
2178 ret
= real_connect(s
, (struct sockaddr
*)&un_addr
,
2181 /* to give better errors */
2182 if (ret
== -1 && errno
== ENOENT
) {
2183 errno
= EHOSTUNREACH
;
2189 si
->defer_connect
= 0;
2192 ret
= real_sendmsg(s
, msg
, flags
);
2195 /* we capture it as one single packet */
2196 buf
= (uint8_t *)malloc(ret
);
2198 /* we just not capture the packet */
2203 for (i
=0; i
< msg
->msg_iovlen
; i
++) {
2204 size_t this_time
= MIN(remain
, msg
->msg_iov
[i
].iov_len
);
2206 msg
->msg_iov
[i
].iov_base
,
2209 remain
-= this_time
;
2212 swrap_dump_packet(si
, NULL
, SWRAP_SEND
, buf
, ret
);
2215 swrap_dump_packet(si
, NULL
, SWRAP_SEND_RST
, NULL
, 0);
2221 int swrap_readv(int s
, const struct iovec
*vector
, size_t count
)
2224 struct socket_info
*si
= find_socket_info(s
);
2228 return real_readv(s
, vector
, count
);
2231 if (si
->type
== SOCK_STREAM
&& count
> 0) {
2232 /* cut down to 1500 byte packets for stream sockets,
2233 * which makes it easier to format PCAP capture files
2234 * (as the caller will simply continue from here) */
2237 for (i
=0; i
< count
; i
++) {
2239 nlen
= len
+ vector
[i
].iov_len
;
2247 v
.iov_len
= MIN(v
.iov_len
, 1500);
2253 ret
= real_readv(s
, vector
, count
);
2254 if (ret
== -1 && errno
!= EAGAIN
&& errno
!= ENOBUFS
) {
2255 swrap_dump_packet(si
, NULL
, SWRAP_RECV_RST
, NULL
, 0);
2256 } else if (ret
== 0) { /* END OF FILE */
2257 swrap_dump_packet(si
, NULL
, SWRAP_RECV_RST
, NULL
, 0);
2258 } else if (ret
> 0) {
2262 size_t remain
= ret
;
2264 /* we capture it as one single packet */
2265 buf
= (uint8_t *)malloc(ret
);
2267 /* we just not capture the packet */
2272 for (i
=0; i
< count
; i
++) {
2273 size_t this_time
= MIN(remain
, vector
[i
].iov_len
);
2278 remain
-= this_time
;
2281 swrap_dump_packet(si
, NULL
, SWRAP_RECV
, buf
, ret
);
2288 int swrap_writev(int s
, const struct iovec
*vector
, size_t count
)
2291 struct socket_info
*si
= find_socket_info(s
);
2295 return real_writev(s
, vector
, count
);
2298 if (si
->type
== SOCK_STREAM
&& count
> 0) {
2299 /* cut down to 1500 byte packets for stream sockets,
2300 * which makes it easier to format PCAP capture files
2301 * (as the caller will simply continue from here) */
2304 for (i
=0; i
< count
; i
++) {
2306 nlen
= len
+ vector
[i
].iov_len
;
2314 v
.iov_len
= MIN(v
.iov_len
, 1500);
2320 ret
= real_writev(s
, vector
, count
);
2322 swrap_dump_packet(si
, NULL
, SWRAP_SEND_RST
, NULL
, 0);
2327 size_t remain
= ret
;
2329 /* we capture it as one single packet */
2330 buf
= (uint8_t *)malloc(ret
);
2332 /* we just not capture the packet */
2337 for (i
=0; i
< count
; i
++) {
2338 size_t this_time
= MIN(remain
, vector
[i
].iov_len
);
2343 remain
-= this_time
;
2346 swrap_dump_packet(si
, NULL
, SWRAP_SEND
, buf
, ret
);
2353 _PUBLIC_
int swrap_close(int fd
)
2355 struct socket_info
*si
= find_socket_info(fd
);
2359 return real_close(fd
);
2362 SWRAP_DLIST_REMOVE(sockets
, si
);
2364 if (si
->myname
&& si
->peername
) {
2365 swrap_dump_packet(si
, NULL
, SWRAP_CLOSE_SEND
, NULL
, 0);
2368 ret
= real_close(fd
);
2370 if (si
->myname
&& si
->peername
) {
2371 swrap_dump_packet(si
, NULL
, SWRAP_CLOSE_RECV
, NULL
, 0);
2372 swrap_dump_packet(si
, NULL
, SWRAP_CLOSE_ACK
, NULL
, 0);
2375 if (si
->path
) free(si
->path
);
2376 if (si
->myname
) free(si
->myname
);
2377 if (si
->peername
) free(si
->peername
);
2379 unlink(si
->tmp_path
);