2 * Copyright (C) Jelmer Vernooij 2005,2008 <jelmer@samba.org>
3 * Copyright (C) Stefan Metzmacher 2006-2009 <metze@samba.org>
4 * Copyright (C) Andreas Schneider 2013 <asn@samba.org>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the author nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 Socket wrapper library. Passes all socket communication over
39 unix domain sockets if the environment variable SOCKET_WRAPPER_DIR
45 #include <sys/types.h>
48 #include <sys/socket.h>
49 #include <sys/ioctl.h>
50 #ifdef HAVE_SYS_FILIO_H
51 #include <sys/filio.h>
53 #ifdef HAVE_SYS_SIGNALFD_H
54 #include <sys/signalfd.h>
56 #ifdef HAVE_SYS_EVENTFD_H
57 #include <sys/eventfd.h>
59 #ifdef HAVE_SYS_TIMERFD_H
60 #include <sys/timerfd.h>
65 #include <netinet/in.h>
66 #include <netinet/tcp.h>
67 #include <arpa/inet.h>
76 #ifdef HAVE_GNU_LIB_NAMES_H
77 #include <gnu/lib-names.h>
90 /* GCC have printf type attribute check. */
91 #ifdef HAVE_FUNCTION_ATTRIBUTE_FORMAT
92 #define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
94 #define PRINTF_ATTRIBUTE(a,b)
95 #endif /* HAVE_FUNCTION_ATTRIBUTE_FORMAT */
97 #ifdef HAVE_DESTRUCTOR_ATTRIBUTE
98 #define DESTRUCTOR_ATTRIBUTE __attribute__ ((destructor))
100 #define DESTRUCTOR_ATTRIBUTE
103 #ifdef HAVE_GCC_THREAD_LOCAL_STORAGE
104 # define SWRAP_THREAD __thread
106 # define SWRAP_THREAD
110 #define MIN(a,b) ((a)<(b)?(a):(b))
114 #define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
118 #define ZERO_STRUCTP(x) do { \
120 memset((char *)(x), 0, sizeof(*(x))); \
124 #ifndef discard_const
125 #define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
128 #ifndef discard_const_p
129 #define discard_const_p(type, ptr) ((type *)discard_const(ptr))
133 # ifndef IPV6_RECVPKTINFO
134 # define IPV6_RECVPKTINFO IPV6_PKTINFO
135 # endif /* IPV6_RECVPKTINFO */
136 #endif /* IPV6_PKTINFO */
139 * On BSD IP_PKTINFO has a different name because during
140 * the time when they implemented it, there was no RFC.
141 * The name for IPv6 is the same as on Linux.
144 # ifdef IP_RECVDSTADDR
145 # define IP_PKTINFO IP_RECVDSTADDR
150 #define SWRAP_DLIST_ADD(list,item) do { \
152 (item)->prev = NULL; \
153 (item)->next = NULL; \
156 (item)->prev = NULL; \
157 (item)->next = (list); \
158 (list)->prev = (item); \
163 #define SWRAP_DLIST_REMOVE(list,item) do { \
164 if ((list) == (item)) { \
165 (list) = (item)->next; \
167 (list)->prev = NULL; \
170 if ((item)->prev) { \
171 (item)->prev->next = (item)->next; \
173 if ((item)->next) { \
174 (item)->next->prev = (item)->prev; \
177 (item)->prev = NULL; \
178 (item)->next = NULL; \
181 #if defined(HAVE_GETTIMEOFDAY_TZ) || defined(HAVE_GETTIMEOFDAY_TZ_VOID)
182 #define swrapGetTimeOfDay(tval) gettimeofday(tval,NULL)
184 #define swrapGetTimeOfDay(tval) gettimeofday(tval)
187 /* we need to use a very terse format here as IRIX 6.4 silently
188 truncates names to 16 chars, so if we use a longer name then we
189 can't tell which port a packet came from with recvfrom()
191 with this format we have 8 chars left for the directory name
193 #define SOCKET_FORMAT "%c%02X%04X"
194 #define SOCKET_TYPE_CHAR_TCP 'T'
195 #define SOCKET_TYPE_CHAR_UDP 'U'
196 #define SOCKET_TYPE_CHAR_TCP_V6 'X'
197 #define SOCKET_TYPE_CHAR_UDP_V6 'Y'
200 * Cut down to 1500 byte packets for stream sockets,
201 * which makes it easier to format PCAP capture files
202 * (as the caller will simply continue from here)
204 #define SOCKET_MAX_PACKET 1500
206 #define SOCKET_MAX_SOCKETS 1024
208 /* This limit is to avoid broadcast sendto() needing to stat too many
209 * files. It may be raised (with a performance cost) to up to 254
210 * without changing the format above */
211 #define MAX_WRAPPED_INTERFACES 40
213 struct socket_info_fd
{
214 struct socket_info_fd
*prev
, *next
;
220 struct socket_info_fd
*fds
;
234 struct sockaddr
*bindname
;
235 socklen_t bindname_len
;
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
;
252 * File descriptors are shared between threads so we should share socket
255 struct socket_info
*sockets
;
257 /* Function prototypes */
259 bool socket_wrapper_enabled(void);
260 void swrap_destructor(void) DESTRUCTOR_ATTRIBUTE
;
263 # define SWRAP_LOG(...)
266 static void swrap_log(enum swrap_dbglvl_e dbglvl
, const char *format
, ...) PRINTF_ATTRIBUTE(2, 3);
267 # define SWRAP_LOG(dbglvl, ...) swrap_log((dbglvl), __VA_ARGS__)
269 static void swrap_log(enum swrap_dbglvl_e dbglvl
, const char *format
, ...)
274 unsigned int lvl
= 0;
276 d
= getenv("SOCKET_WRAPPER_DEBUGLEVEL");
281 va_start(va
, format
);
282 vsnprintf(buffer
, sizeof(buffer
), format
, va
);
287 case SWRAP_LOG_ERROR
:
289 "SWRAP_ERROR(%d): %s\n",
290 (int)getpid(), buffer
);
294 "SWRAP_WARN(%d): %s\n",
295 (int)getpid(), buffer
);
297 case SWRAP_LOG_DEBUG
:
299 "SWRAP_DEBUG(%d): %s\n",
300 (int)getpid(), buffer
);
302 case SWRAP_LOG_TRACE
:
304 "SWRAP_TRACE(%d): %s\n",
305 (int)getpid(), buffer
);
312 /*********************************************************
313 * SWRAP LOADING LIBC FUNCTIONS
314 *********************************************************/
318 struct swrap_libc_fns
{
319 int (*libc_accept
)(int sockfd
,
320 struct sockaddr
*addr
,
322 int (*libc_bind
)(int sockfd
,
323 const struct sockaddr
*addr
,
325 int (*libc_close
)(int fd
);
326 int (*libc_connect
)(int sockfd
,
327 const struct sockaddr
*addr
,
329 int (*libc_dup
)(int fd
);
330 int (*libc_dup2
)(int oldfd
, int newfd
);
332 int (*libc_eventfd
)(int count
, int flags
);
334 int (*libc_getpeername
)(int sockfd
,
335 struct sockaddr
*addr
,
337 int (*libc_getsockname
)(int sockfd
,
338 struct sockaddr
*addr
,
340 int (*libc_getsockopt
)(int sockfd
,
345 int (*libc_ioctl
)(int d
, unsigned long int request
, ...);
346 int (*libc_listen
)(int sockfd
, int backlog
);
347 int (*libc_open
)(const char *pathname
, int flags
, mode_t mode
);
348 int (*libc_pipe
)(int pipefd
[2]);
349 int (*libc_read
)(int fd
, void *buf
, size_t count
);
350 ssize_t (*libc_readv
)(int fd
, const struct iovec
*iov
, int iovcnt
);
351 int (*libc_recv
)(int sockfd
, void *buf
, size_t len
, int flags
);
352 int (*libc_recvfrom
)(int sockfd
,
356 struct sockaddr
*src_addr
,
358 int (*libc_recvmsg
)(int sockfd
, const struct msghdr
*msg
, int flags
);
359 int (*libc_send
)(int sockfd
, const void *buf
, size_t len
, int flags
);
360 int (*libc_sendmsg
)(int sockfd
, const struct msghdr
*msg
, int flags
);
361 int (*libc_sendto
)(int sockfd
,
365 const struct sockaddr
*dst_addr
,
367 int (*libc_setsockopt
)(int sockfd
,
373 int (*libc_signalfd
)(int fd
, const sigset_t
*mask
, int flags
);
375 int (*libc_socket
)(int domain
, int type
, int protocol
);
376 int (*libc_socketpair
)(int domain
, int type
, int protocol
, int sv
[2]);
377 #ifdef HAVE_TIMERFD_CREATE
378 int (*libc_timerfd_create
)(int clockid
, int flags
);
380 ssize_t (*libc_writev
)(int fd
, const struct iovec
*iov
, int iovcnt
);
385 void *libsocket_handle
;
392 struct swrap_libc_fns fns
;
395 static struct swrap swrap
;
398 static const char *socket_wrapper_dir(void);
400 #define LIBC_NAME "libc.so"
409 static const char *swrap_str_lib(enum swrap_lib lib
)
416 case SWRAP_LIBSOCKET
:
420 /* Compiler would warn us about unhandled enum value if we get here */
425 static void *swrap_load_lib_handle(enum swrap_lib lib
)
427 int flags
= RTLD_LAZY
;
432 flags
|= RTLD_DEEPBIND
;
438 case SWRAP_LIBSOCKET
:
439 #ifdef HAVE_LIBSOCKET
440 handle
= swrap
.libsocket_handle
;
441 if (handle
== NULL
) {
442 for (handle
= NULL
, i
= 10; handle
== NULL
&& i
>= 0; i
--) {
443 char soname
[256] = {0};
445 snprintf(soname
, sizeof(soname
), "libsocket.so.%d", i
);
446 handle
= dlopen(soname
, flags
);
449 swrap
.libsocket_handle
= handle
;
455 handle
= swrap
.libc_handle
;
457 if (handle
== NULL
) {
458 handle
= dlopen(LIBC_SO
, flags
);
460 swrap
.libc_handle
= handle
;
463 if (handle
== NULL
) {
464 for (handle
= NULL
, i
= 10; handle
== NULL
&& i
>= 0; i
--) {
465 char soname
[256] = {0};
467 snprintf(soname
, sizeof(soname
), "libc.so.%d", i
);
468 handle
= dlopen(soname
, flags
);
471 swrap
.libc_handle
= handle
;
476 if (handle
== NULL
) {
478 handle
= swrap
.libc_handle
= swrap
.libsocket_handle
= RTLD_NEXT
;
480 SWRAP_LOG(SWRAP_LOG_ERROR
,
481 "Failed to dlopen library: %s\n",
490 static void *_swrap_load_lib_function(enum swrap_lib lib
, const char *fn_name
)
495 handle
= swrap_load_lib_handle(lib
);
497 func
= dlsym(handle
, fn_name
);
499 SWRAP_LOG(SWRAP_LOG_ERROR
,
500 "Failed to find %s: %s\n",
505 SWRAP_LOG(SWRAP_LOG_TRACE
,
507 fn_name
, swrap_str_lib(lib
));
511 #define swrap_load_lib_function(lib, fn_name) \
512 if (swrap.fns.libc_##fn_name == NULL) { \
513 *(void **) (&swrap.fns.libc_##fn_name) = \
514 _swrap_load_lib_function(lib, #fn_name); \
521 * Functions especially from libc need to be loaded individually, you can't load
522 * all at once or gdb will segfault at startup. The same applies to valgrind and
523 * has probably something todo with with the linker.
524 * So we need load each function at the point it is called the first time.
526 static int libc_accept(int sockfd
, struct sockaddr
*addr
, socklen_t
*addrlen
)
528 swrap_load_lib_function(SWRAP_LIBSOCKET
, accept
);
530 return swrap
.fns
.libc_accept(sockfd
, addr
, addrlen
);
533 static int libc_bind(int sockfd
,
534 const struct sockaddr
*addr
,
537 swrap_load_lib_function(SWRAP_LIBSOCKET
, bind
);
539 return swrap
.fns
.libc_bind(sockfd
, addr
, addrlen
);
542 static int libc_close(int fd
)
544 swrap_load_lib_function(SWRAP_LIBC
, close
);
546 return swrap
.fns
.libc_close(fd
);
549 static int libc_connect(int sockfd
,
550 const struct sockaddr
*addr
,
553 swrap_load_lib_function(SWRAP_LIBSOCKET
, connect
);
555 return swrap
.fns
.libc_connect(sockfd
, addr
, addrlen
);
558 static int libc_dup(int fd
)
560 swrap_load_lib_function(SWRAP_LIBC
, dup
);
562 return swrap
.fns
.libc_dup(fd
);
565 static int libc_dup2(int oldfd
, int newfd
)
567 swrap_load_lib_function(SWRAP_LIBC
, dup2
);
569 return swrap
.fns
.libc_dup2(oldfd
, newfd
);
573 static int libc_eventfd(int count
, int flags
)
575 swrap_load_lib_function(SWRAP_LIBC
, eventfd
);
577 return swrap
.fns
.libc_eventfd(count
, flags
);
581 static int libc_getpeername(int sockfd
,
582 struct sockaddr
*addr
,
585 swrap_load_lib_function(SWRAP_LIBSOCKET
, getpeername
);
587 return swrap
.fns
.libc_getpeername(sockfd
, addr
, addrlen
);
590 static int libc_getsockname(int sockfd
,
591 struct sockaddr
*addr
,
594 swrap_load_lib_function(SWRAP_LIBSOCKET
, getsockname
);
596 return swrap
.fns
.libc_getsockname(sockfd
, addr
, addrlen
);
599 static int libc_getsockopt(int sockfd
,
605 swrap_load_lib_function(SWRAP_LIBSOCKET
, getsockopt
);
607 return swrap
.fns
.libc_getsockopt(sockfd
, level
, optname
, optval
, optlen
);
610 static int libc_vioctl(int d
, unsigned long int request
, va_list ap
)
616 swrap_load_lib_function(SWRAP_LIBC
, ioctl
);
618 for (i
= 0; i
< 4; i
++) {
619 args
[i
] = va_arg(ap
, long int);
622 rc
= swrap
.fns
.libc_ioctl(d
,
632 static int libc_listen(int sockfd
, int backlog
)
634 swrap_load_lib_function(SWRAP_LIBSOCKET
, listen
);
636 return swrap
.fns
.libc_listen(sockfd
, backlog
);
639 static int libc_vopen(const char *pathname
, int flags
, va_list ap
)
644 swrap_load_lib_function(SWRAP_LIBC
, open
);
646 mode
= va_arg(ap
, long int);
648 fd
= swrap
.fns
.libc_open(pathname
, flags
, (mode_t
)mode
);
653 static int libc_open(const char *pathname
, int flags
, ...)
659 fd
= libc_vopen(pathname
, flags
, ap
);
665 static int libc_pipe(int pipefd
[2])
667 swrap_load_lib_function(SWRAP_LIBSOCKET
, pipe
);
669 return swrap
.fns
.libc_pipe(pipefd
);
672 static int libc_read(int fd
, void *buf
, size_t count
)
674 swrap_load_lib_function(SWRAP_LIBC
, read
);
676 return swrap
.fns
.libc_read(fd
, buf
, count
);
679 static ssize_t
libc_readv(int fd
, const struct iovec
*iov
, int iovcnt
)
681 swrap_load_lib_function(SWRAP_LIBSOCKET
, readv
);
683 return swrap
.fns
.libc_readv(fd
, iov
, iovcnt
);
686 static int libc_recv(int sockfd
, void *buf
, size_t len
, int flags
)
688 swrap_load_lib_function(SWRAP_LIBSOCKET
, recv
);
690 return swrap
.fns
.libc_recv(sockfd
, buf
, len
, flags
);
693 static int libc_recvfrom(int sockfd
,
697 struct sockaddr
*src_addr
,
700 swrap_load_lib_function(SWRAP_LIBSOCKET
, recvfrom
);
702 return swrap
.fns
.libc_recvfrom(sockfd
, buf
, len
, flags
, src_addr
, addrlen
);
705 static int libc_recvmsg(int sockfd
, struct msghdr
*msg
, int flags
)
707 swrap_load_lib_function(SWRAP_LIBSOCKET
, recvmsg
);
709 return swrap
.fns
.libc_recvmsg(sockfd
, msg
, flags
);
712 static int libc_send(int sockfd
, const void *buf
, size_t len
, int flags
)
714 swrap_load_lib_function(SWRAP_LIBSOCKET
, send
);
716 return swrap
.fns
.libc_send(sockfd
, buf
, len
, flags
);
719 static int libc_sendmsg(int sockfd
, const struct msghdr
*msg
, int flags
)
721 swrap_load_lib_function(SWRAP_LIBSOCKET
, sendmsg
);
723 return swrap
.fns
.libc_sendmsg(sockfd
, msg
, flags
);
726 static int libc_sendto(int sockfd
,
730 const struct sockaddr
*dst_addr
,
733 swrap_load_lib_function(SWRAP_LIBSOCKET
, sendto
);
735 return swrap
.fns
.libc_sendto(sockfd
, buf
, len
, flags
, dst_addr
, addrlen
);
738 static int libc_setsockopt(int sockfd
,
744 swrap_load_lib_function(SWRAP_LIBSOCKET
, setsockopt
);
746 return swrap
.fns
.libc_setsockopt(sockfd
, level
, optname
, optval
, optlen
);
750 static int libc_signalfd(int fd
, const sigset_t
*mask
, int flags
)
752 swrap_load_lib_function(SWRAP_LIBSOCKET
, signalfd
);
754 return swrap
.fns
.libc_signalfd(fd
, mask
, flags
);
758 static int libc_socket(int domain
, int type
, int protocol
)
760 swrap_load_lib_function(SWRAP_LIBSOCKET
, socket
);
762 return swrap
.fns
.libc_socket(domain
, type
, protocol
);
765 static int libc_socketpair(int domain
, int type
, int protocol
, int sv
[2])
767 swrap_load_lib_function(SWRAP_LIBSOCKET
, socketpair
);
769 return swrap
.fns
.libc_socketpair(domain
, type
, protocol
, sv
);
772 #ifdef HAVE_TIMERFD_CREATE
773 static int libc_timerfd_create(int clockid
, int flags
)
775 swrap_load_lib_function(SWRAP_LIBC
, timerfd_create
);
777 return swrap
.fns
.libc_timerfd_create(clockid
, flags
);
781 static ssize_t
libc_writev(int fd
, const struct iovec
*iov
, int iovcnt
)
783 swrap_load_lib_function(SWRAP_LIBSOCKET
, writev
);
785 return swrap
.fns
.libc_writev(fd
, iov
, iovcnt
);
788 /*********************************************************
789 * SWRAP HELPER FUNCTIONS
790 *********************************************************/
796 static const struct in6_addr
*swrap_ipv6(void)
798 static struct in6_addr v
;
799 static int initialized
;
807 ret
= inet_pton(AF_INET6
, "FD00::5357:5F00", &v
);
816 static struct sockaddr
*sockaddr_dup(const void *data
, socklen_t len
)
818 struct sockaddr
*ret
= (struct sockaddr
*)malloc(len
);
819 memcpy(ret
, data
, len
);
823 static void set_port(int family
, int prt
, struct sockaddr
*addr
)
827 ((struct sockaddr_in
*)addr
)->sin_port
= htons(prt
);
831 ((struct sockaddr_in6
*)addr
)->sin6_port
= htons(prt
);
837 static size_t socket_length(int family
)
841 return sizeof(struct sockaddr_in
);
844 return sizeof(struct sockaddr_in6
);
850 static const char *socket_wrapper_dir(void)
852 const char *s
= getenv("SOCKET_WRAPPER_DIR");
856 /* TODO use realpath(3) here, when we add support for threads */
857 if (strncmp(s
, "./", 2) == 0) {
861 SWRAP_LOG(SWRAP_LOG_TRACE
, "socket_wrapper_dir: %s", s
);
865 bool socket_wrapper_enabled(void)
867 const char *s
= socket_wrapper_dir();
869 return s
!= NULL
? true : false;
872 static unsigned int socket_wrapper_default_iface(void)
874 const char *s
= getenv("SOCKET_WRAPPER_DEFAULT_IFACE");
877 if (sscanf(s
, "%u", &iface
) == 1) {
878 if (iface
>= 1 && iface
<= MAX_WRAPPED_INTERFACES
) {
884 return 1;/* 127.0.0.1 */
887 static int convert_un_in(const struct sockaddr_un
*un
, struct sockaddr
*in
, socklen_t
*len
)
894 p
= strrchr(un
->sun_path
, '/');
895 if (p
) p
++; else p
= un
->sun_path
;
897 if (sscanf(p
, SOCKET_FORMAT
, &type
, &iface
, &prt
) != 3) {
902 SWRAP_LOG(SWRAP_LOG_TRACE
, "type %c iface %u port %u",
905 if (iface
== 0 || iface
> MAX_WRAPPED_INTERFACES
) {
916 case SOCKET_TYPE_CHAR_TCP
:
917 case SOCKET_TYPE_CHAR_UDP
: {
918 struct sockaddr_in
*in2
= (struct sockaddr_in
*)(void *)in
;
920 if ((*len
) < sizeof(*in2
)) {
925 memset(in2
, 0, sizeof(*in2
));
926 in2
->sin_family
= AF_INET
;
927 in2
->sin_addr
.s_addr
= htonl((127<<24) | iface
);
928 in2
->sin_port
= htons(prt
);
934 case SOCKET_TYPE_CHAR_TCP_V6
:
935 case SOCKET_TYPE_CHAR_UDP_V6
: {
936 struct sockaddr_in6
*in2
= (struct sockaddr_in6
*)(void *)in
;
938 if ((*len
) < sizeof(*in2
)) {
943 memset(in2
, 0, sizeof(*in2
));
944 in2
->sin6_family
= AF_INET6
;
945 in2
->sin6_addr
= *swrap_ipv6();
946 in2
->sin6_addr
.s6_addr
[15] = iface
;
947 in2
->sin6_port
= htons(prt
);
961 static int convert_in_un_remote(struct socket_info
*si
, const struct sockaddr
*inaddr
, struct sockaddr_un
*un
,
969 if (bcast
) *bcast
= 0;
971 switch (inaddr
->sa_family
) {
973 const struct sockaddr_in
*in
=
974 (const struct sockaddr_in
*)(const void *)inaddr
;
975 unsigned int addr
= ntohl(in
->sin_addr
.s_addr
);
982 u_type
= SOCKET_TYPE_CHAR_TCP
;
985 u_type
= SOCKET_TYPE_CHAR_UDP
;
986 a_type
= SOCKET_TYPE_CHAR_UDP
;
987 b_type
= SOCKET_TYPE_CHAR_UDP
;
990 SWRAP_LOG(SWRAP_LOG_ERROR
, "Unknown socket type!\n");
991 errno
= ESOCKTNOSUPPORT
;
995 prt
= ntohs(in
->sin_port
);
996 if (a_type
&& addr
== 0xFFFFFFFF) {
997 /* 255.255.255.255 only udp */
1000 iface
= socket_wrapper_default_iface();
1001 } else if (b_type
&& addr
== 0x7FFFFFFF) {
1002 /* 127.255.255.255 only udp */
1005 iface
= socket_wrapper_default_iface();
1006 } else if ((addr
& 0xFFFFFF00) == 0x7F000000) {
1010 iface
= (addr
& 0x000000FF);
1012 errno
= ENETUNREACH
;
1015 if (bcast
) *bcast
= is_bcast
;
1020 const struct sockaddr_in6
*in
=
1021 (const struct sockaddr_in6
*)(const void *)inaddr
;
1022 struct in6_addr cmp1
, cmp2
;
1026 type
= SOCKET_TYPE_CHAR_TCP_V6
;
1029 type
= SOCKET_TYPE_CHAR_UDP_V6
;
1032 SWRAP_LOG(SWRAP_LOG_ERROR
, "Unknown socket type!\n");
1033 errno
= ESOCKTNOSUPPORT
;
1037 /* XXX no multicast/broadcast */
1039 prt
= ntohs(in
->sin6_port
);
1041 cmp1
= *swrap_ipv6();
1042 cmp2
= in
->sin6_addr
;
1043 cmp2
.s6_addr
[15] = 0;
1044 if (IN6_ARE_ADDR_EQUAL(&cmp1
, &cmp2
)) {
1045 iface
= in
->sin6_addr
.s6_addr
[15];
1047 errno
= ENETUNREACH
;
1055 SWRAP_LOG(SWRAP_LOG_ERROR
, "Unknown address family!\n");
1056 errno
= ENETUNREACH
;
1061 SWRAP_LOG(SWRAP_LOG_WARN
, "Port not set\n");
1067 snprintf(un
->sun_path
, sizeof(un
->sun_path
), "%s/EINVAL",
1068 socket_wrapper_dir());
1069 SWRAP_LOG(SWRAP_LOG_DEBUG
, "un path [%s]", un
->sun_path
);
1070 /* the caller need to do more processing */
1074 snprintf(un
->sun_path
, sizeof(un
->sun_path
), "%s/"SOCKET_FORMAT
,
1075 socket_wrapper_dir(), type
, iface
, prt
);
1076 SWRAP_LOG(SWRAP_LOG_DEBUG
, "un path [%s]", un
->sun_path
);
1081 static int convert_in_un_alloc(struct socket_info
*si
, const struct sockaddr
*inaddr
, struct sockaddr_un
*un
,
1090 if (bcast
) *bcast
= 0;
1092 switch (si
->family
) {
1094 const struct sockaddr_in
*in
=
1095 (const struct sockaddr_in
*)(const void *)inaddr
;
1096 unsigned int addr
= ntohl(in
->sin_addr
.s_addr
);
1102 prt
= ntohs(in
->sin_port
);
1106 u_type
= SOCKET_TYPE_CHAR_TCP
;
1107 d_type
= SOCKET_TYPE_CHAR_TCP
;
1110 u_type
= SOCKET_TYPE_CHAR_UDP
;
1111 d_type
= SOCKET_TYPE_CHAR_UDP
;
1112 a_type
= SOCKET_TYPE_CHAR_UDP
;
1113 b_type
= SOCKET_TYPE_CHAR_UDP
;
1116 SWRAP_LOG(SWRAP_LOG_ERROR
, "Unknown socket type!\n");
1117 errno
= ESOCKTNOSUPPORT
;
1125 iface
= socket_wrapper_default_iface();
1126 } else if (a_type
&& addr
== 0xFFFFFFFF) {
1127 /* 255.255.255.255 only udp */
1130 iface
= socket_wrapper_default_iface();
1131 } else if (b_type
&& addr
== 0x7FFFFFFF) {
1132 /* 127.255.255.255 only udp */
1135 iface
= socket_wrapper_default_iface();
1136 } else if ((addr
& 0xFFFFFF00) == 0x7F000000) {
1140 iface
= (addr
& 0x000000FF);
1142 errno
= EADDRNOTAVAIL
;
1146 /* Store the bind address for connect() */
1147 if (si
->bindname
== NULL
) {
1148 struct sockaddr_in bind_in
;
1149 socklen_t blen
= sizeof(struct sockaddr_in
);
1151 ZERO_STRUCT(bind_in
);
1152 bind_in
.sin_family
= in
->sin_family
;
1153 bind_in
.sin_port
= in
->sin_port
;
1154 bind_in
.sin_addr
.s_addr
= htonl(0x7F000000 | iface
);
1156 si
->bindname
= sockaddr_dup(&bind_in
, blen
);
1157 si
->bindname_len
= blen
;
1164 const struct sockaddr_in6
*in
=
1165 (const struct sockaddr_in6
*)(const void *)inaddr
;
1166 struct in6_addr cmp1
, cmp2
;
1170 type
= SOCKET_TYPE_CHAR_TCP_V6
;
1173 type
= SOCKET_TYPE_CHAR_UDP_V6
;
1176 SWRAP_LOG(SWRAP_LOG_ERROR
, "Unknown socket type!\n");
1177 errno
= ESOCKTNOSUPPORT
;
1181 /* XXX no multicast/broadcast */
1183 prt
= ntohs(in
->sin6_port
);
1185 cmp1
= *swrap_ipv6();
1186 cmp2
= in
->sin6_addr
;
1187 cmp2
.s6_addr
[15] = 0;
1188 if (IN6_IS_ADDR_UNSPECIFIED(&in
->sin6_addr
)) {
1189 iface
= socket_wrapper_default_iface();
1190 } else if (IN6_ARE_ADDR_EQUAL(&cmp1
, &cmp2
)) {
1191 iface
= in
->sin6_addr
.s6_addr
[15];
1193 errno
= EADDRNOTAVAIL
;
1197 /* Store the bind address for connect() */
1198 if (si
->bindname
== NULL
) {
1199 struct sockaddr_in6 bind_in
;
1200 socklen_t blen
= sizeof(struct sockaddr_in6
);
1202 ZERO_STRUCT(bind_in
);
1203 bind_in
.sin6_family
= in
->sin6_family
;
1204 bind_in
.sin6_port
= in
->sin6_port
;
1206 bind_in
.sin6_addr
= *swrap_ipv6();
1207 bind_in
.sin6_addr
.s6_addr
[15] = iface
;
1209 si
->bindname
= sockaddr_dup(&bind_in
, blen
);
1210 si
->bindname_len
= blen
;
1217 SWRAP_LOG(SWRAP_LOG_ERROR
, "Unknown address family\n");
1218 errno
= EADDRNOTAVAIL
;
1223 if (bcast
) *bcast
= is_bcast
;
1225 if (iface
== 0 || iface
> MAX_WRAPPED_INTERFACES
) {
1231 /* handle auto-allocation of ephemeral ports */
1232 for (prt
= 5001; prt
< 10000; prt
++) {
1233 snprintf(un
->sun_path
, sizeof(un
->sun_path
), "%s/"SOCKET_FORMAT
,
1234 socket_wrapper_dir(), type
, iface
, prt
);
1235 if (stat(un
->sun_path
, &st
) == 0) continue;
1237 set_port(si
->family
, prt
, si
->myname
);
1238 set_port(si
->family
, prt
, si
->bindname
);
1248 snprintf(un
->sun_path
, sizeof(un
->sun_path
), "%s/"SOCKET_FORMAT
,
1249 socket_wrapper_dir(), type
, iface
, prt
);
1250 SWRAP_LOG(SWRAP_LOG_DEBUG
, "un path [%s]", un
->sun_path
);
1254 static struct socket_info
*find_socket_info(int fd
)
1256 struct socket_info
*i
;
1258 for (i
= sockets
; i
; i
= i
->next
) {
1259 struct socket_info_fd
*f
;
1260 for (f
= i
->fds
; f
; f
= f
->next
) {
1271 static bool check_addr_port_in_use(const struct sockaddr
*sa
, socklen_t len
)
1273 struct socket_info
*s
;
1275 /* first catch invalid input */
1276 switch (sa
->sa_family
) {
1278 if (len
< sizeof(struct sockaddr_in
)) {
1284 if (len
< sizeof(struct sockaddr_in6
)) {
1294 for (s
= sockets
; s
!= NULL
; s
= s
->next
) {
1295 if (s
->myname
== NULL
) {
1298 if (s
->myname
->sa_family
!= sa
->sa_family
) {
1301 switch (s
->myname
->sa_family
) {
1303 struct sockaddr_in
*sin1
, *sin2
;
1305 sin1
= (struct sockaddr_in
*)s
->myname
;
1306 sin2
= (struct sockaddr_in
*)sa
;
1308 if (sin1
->sin_addr
.s_addr
== htonl(INADDR_ANY
)) {
1311 if (sin1
->sin_port
!= sin2
->sin_port
) {
1314 if (sin1
->sin_addr
.s_addr
!= sin2
->sin_addr
.s_addr
) {
1324 struct sockaddr_in6
*sin1
, *sin2
;
1326 sin1
= (struct sockaddr_in6
*)s
->myname
;
1327 sin2
= (struct sockaddr_in6
*)sa
;
1329 if (sin1
->sin6_port
!= sin2
->sin6_port
) {
1332 if (!IN6_ARE_ADDR_EQUAL(&sin1
->sin6_addr
,
1354 static void swrap_remove_stale(int fd
)
1356 struct socket_info
*si
= find_socket_info(fd
);
1357 struct socket_info_fd
*fi
;
1360 for (fi
= si
->fds
; fi
; fi
= fi
->next
) {
1362 SWRAP_LOG(SWRAP_LOG_TRACE
, "remove stale wrapper for %d", fd
);
1363 SWRAP_DLIST_REMOVE(si
->fds
, fi
);
1369 if (si
->fds
== NULL
) {
1370 SWRAP_DLIST_REMOVE(sockets
, si
);
1375 static int sockaddr_convert_to_un(struct socket_info
*si
,
1376 const struct sockaddr
*in_addr
,
1378 struct sockaddr_un
*out_addr
,
1382 struct sockaddr
*out
= (struct sockaddr
*)(void *)out_addr
;
1384 (void) in_len
; /* unused */
1386 if (out_addr
== NULL
) {
1390 out
->sa_family
= AF_UNIX
;
1391 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
1392 out
->sa_len
= sizeof(*out_addr
);
1395 switch (in_addr
->sa_family
) {
1397 struct sockaddr_in
*sin
;
1398 if (si
->family
!= AF_INET
) {
1401 if (in_len
< sizeof(struct sockaddr_in
)) {
1404 sin
= (struct sockaddr_in
*)in_addr
;
1405 if(sin
->sin_addr
.s_addr
!= htonl(INADDR_ANY
)) {
1410 * Note: in the special case of AF_UNSPEC and INADDR_ANY,
1411 * AF_UNSPEC is mapped to AF_INET and must be treated here.
1425 SWRAP_LOG(SWRAP_LOG_ERROR
, "Unknown socket type!\n");
1426 errno
= ESOCKTNOSUPPORT
;
1430 return convert_in_un_alloc(si
, in_addr
, out_addr
, bcast
);
1432 return convert_in_un_remote(si
, in_addr
, out_addr
, bcast
);
1438 errno
= EAFNOSUPPORT
;
1439 SWRAP_LOG(SWRAP_LOG_ERROR
, "Unknown address family\n");
1443 static int sockaddr_convert_from_un(const struct socket_info
*si
,
1444 const struct sockaddr_un
*in_addr
,
1445 socklen_t un_addrlen
,
1447 struct sockaddr
*out_addr
,
1448 socklen_t
*out_addrlen
)
1452 if (out_addr
== NULL
|| out_addrlen
== NULL
)
1455 if (un_addrlen
== 0) {
1470 SWRAP_LOG(SWRAP_LOG_ERROR
, "Unknown socket type!\n");
1471 errno
= ESOCKTNOSUPPORT
;
1474 ret
= convert_un_in(in_addr
, out_addr
, out_addrlen
);
1475 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
1476 out_addr
->sa_len
= *out_addrlen
;
1483 SWRAP_LOG(SWRAP_LOG_ERROR
, "Unknown address family\n");
1484 errno
= EAFNOSUPPORT
;
1488 enum swrap_packet_type
{
1490 SWRAP_CONNECT_UNREACH
,
1498 SWRAP_SENDTO_UNREACH
,
1509 struct swrap_file_hdr
{
1511 uint16_t version_major
;
1512 uint16_t version_minor
;
1515 uint32_t frame_max_len
;
1516 #define SWRAP_FRAME_LENGTH_MAX 0xFFFF
1519 #define SWRAP_FILE_HDR_SIZE 24
1521 struct swrap_packet_frame
{
1523 uint32_t micro_seconds
;
1524 uint32_t recorded_length
;
1525 uint32_t full_length
;
1527 #define SWRAP_PACKET_FRAME_SIZE 16
1529 union swrap_packet_ip
{
1533 uint16_t packet_length
;
1534 uint16_t identification
;
1539 uint16_t hdr_checksum
;
1543 #define SWRAP_PACKET_IP_V4_SIZE 20
1546 uint8_t flow_label_high
;
1547 uint16_t flow_label_low
;
1548 uint16_t payload_length
;
1549 uint8_t next_header
;
1551 uint8_t src_addr
[16];
1552 uint8_t dest_addr
[16];
1554 #define SWRAP_PACKET_IP_V6_SIZE 40
1556 #define SWRAP_PACKET_IP_SIZE 40
1558 union swrap_packet_payload
{
1560 uint16_t source_port
;
1570 #define SWRAP_PACKET_PAYLOAD_TCP_SIZE 20
1572 uint16_t source_port
;
1577 #define SWRAP_PACKET_PAYLOAD_UDP_SIZE 8
1584 #define SWRAP_PACKET_PAYLOAD_ICMP4_SIZE 8
1591 #define SWRAP_PACKET_PAYLOAD_ICMP6_SIZE 8
1593 #define SWRAP_PACKET_PAYLOAD_SIZE 20
1595 #define SWRAP_PACKET_MIN_ALLOC \
1596 (SWRAP_PACKET_FRAME_SIZE + \
1597 SWRAP_PACKET_IP_SIZE + \
1598 SWRAP_PACKET_PAYLOAD_SIZE)
1600 static const char *socket_wrapper_pcap_file(void)
1602 static int initialized
= 0;
1603 static const char *s
= NULL
;
1604 static const struct swrap_file_hdr h
;
1605 static const struct swrap_packet_frame f
;
1606 static const union swrap_packet_ip i
;
1607 static const union swrap_packet_payload p
;
1609 if (initialized
== 1) {
1615 * TODO: don't use the structs use plain buffer offsets
1616 * and PUSH_U8(), PUSH_U16() and PUSH_U32()
1618 * for now make sure we disable PCAP support
1619 * if the struct has alignment!
1621 if (sizeof(h
) != SWRAP_FILE_HDR_SIZE
) {
1624 if (sizeof(f
) != SWRAP_PACKET_FRAME_SIZE
) {
1627 if (sizeof(i
) != SWRAP_PACKET_IP_SIZE
) {
1630 if (sizeof(i
.v4
) != SWRAP_PACKET_IP_V4_SIZE
) {
1633 if (sizeof(i
.v6
) != SWRAP_PACKET_IP_V6_SIZE
) {
1636 if (sizeof(p
) != SWRAP_PACKET_PAYLOAD_SIZE
) {
1639 if (sizeof(p
.tcp
) != SWRAP_PACKET_PAYLOAD_TCP_SIZE
) {
1642 if (sizeof(p
.udp
) != SWRAP_PACKET_PAYLOAD_UDP_SIZE
) {
1645 if (sizeof(p
.icmp4
) != SWRAP_PACKET_PAYLOAD_ICMP4_SIZE
) {
1648 if (sizeof(p
.icmp6
) != SWRAP_PACKET_PAYLOAD_ICMP6_SIZE
) {
1652 s
= getenv("SOCKET_WRAPPER_PCAP_FILE");
1656 if (strncmp(s
, "./", 2) == 0) {
1662 static uint8_t *swrap_packet_init(struct timeval
*tval
,
1663 const struct sockaddr
*src
,
1664 const struct sockaddr
*dest
,
1666 const uint8_t *payload
,
1668 unsigned long tcp_seqno
,
1669 unsigned long tcp_ack
,
1670 unsigned char tcp_ctl
,
1672 size_t *_packet_len
)
1676 struct swrap_packet_frame
*frame
;
1677 union swrap_packet_ip
*ip
;
1678 union swrap_packet_payload
*pay
;
1681 size_t nonwire_len
= sizeof(*frame
);
1682 size_t wire_hdr_len
= 0;
1683 size_t wire_len
= 0;
1684 size_t ip_hdr_len
= 0;
1685 size_t icmp_hdr_len
= 0;
1686 size_t icmp_truncate_len
= 0;
1687 uint8_t protocol
= 0, icmp_protocol
= 0;
1688 const struct sockaddr_in
*src_in
= NULL
;
1689 const struct sockaddr_in
*dest_in
= NULL
;
1691 const struct sockaddr_in6
*src_in6
= NULL
;
1692 const struct sockaddr_in6
*dest_in6
= NULL
;
1697 switch (src
->sa_family
) {
1699 src_in
= (const struct sockaddr_in
*)src
;
1700 dest_in
= (const struct sockaddr_in
*)dest
;
1701 src_port
= src_in
->sin_port
;
1702 dest_port
= dest_in
->sin_port
;
1703 ip_hdr_len
= sizeof(ip
->v4
);
1707 src_in6
= (const struct sockaddr_in6
*)src
;
1708 dest_in6
= (const struct sockaddr_in6
*)dest
;
1709 src_port
= src_in6
->sin6_port
;
1710 dest_port
= dest_in6
->sin6_port
;
1711 ip_hdr_len
= sizeof(ip
->v6
);
1718 switch (socket_type
) {
1720 protocol
= 0x06; /* TCP */
1721 wire_hdr_len
= ip_hdr_len
+ sizeof(pay
->tcp
);
1722 wire_len
= wire_hdr_len
+ payload_len
;
1726 protocol
= 0x11; /* UDP */
1727 wire_hdr_len
= ip_hdr_len
+ sizeof(pay
->udp
);
1728 wire_len
= wire_hdr_len
+ payload_len
;
1736 icmp_protocol
= protocol
;
1737 switch (src
->sa_family
) {
1739 protocol
= 0x01; /* ICMPv4 */
1740 icmp_hdr_len
= ip_hdr_len
+ sizeof(pay
->icmp4
);
1744 protocol
= 0x3A; /* ICMPv6 */
1745 icmp_hdr_len
= ip_hdr_len
+ sizeof(pay
->icmp6
);
1749 if (wire_len
> 64 ) {
1750 icmp_truncate_len
= wire_len
- 64;
1752 wire_hdr_len
+= icmp_hdr_len
;
1753 wire_len
+= icmp_hdr_len
;
1756 packet_len
= nonwire_len
+ wire_len
;
1757 alloc_len
= packet_len
;
1758 if (alloc_len
< SWRAP_PACKET_MIN_ALLOC
) {
1759 alloc_len
= SWRAP_PACKET_MIN_ALLOC
;
1762 base
= (uint8_t *)malloc(alloc_len
);
1766 memset(base
, 0x0, alloc_len
);
1770 frame
= (struct swrap_packet_frame
*)buf
;
1771 frame
->seconds
= tval
->tv_sec
;
1772 frame
->micro_seconds
= tval
->tv_usec
;
1773 frame
->recorded_length
= wire_len
- icmp_truncate_len
;
1774 frame
->full_length
= wire_len
- icmp_truncate_len
;
1775 buf
+= SWRAP_PACKET_FRAME_SIZE
;
1777 ip
= (union swrap_packet_ip
*)buf
;
1778 switch (src
->sa_family
) {
1780 ip
->v4
.ver_hdrlen
= 0x45; /* version 4 and 5 * 32 bit words */
1782 ip
->v4
.packet_length
= htons(wire_len
- icmp_truncate_len
);
1783 ip
->v4
.identification
= htons(0xFFFF);
1784 ip
->v4
.flags
= 0x40; /* BIT 1 set - means don't fragment */
1785 ip
->v4
.fragment
= htons(0x0000);
1787 ip
->v4
.protocol
= protocol
;
1788 ip
->v4
.hdr_checksum
= htons(0x0000);
1789 ip
->v4
.src_addr
= src_in
->sin_addr
.s_addr
;
1790 ip
->v4
.dest_addr
= dest_in
->sin_addr
.s_addr
;
1791 buf
+= SWRAP_PACKET_IP_V4_SIZE
;
1795 ip
->v6
.ver_prio
= 0x60; /* version 4 and 5 * 32 bit words */
1796 ip
->v6
.flow_label_high
= 0x00;
1797 ip
->v6
.flow_label_low
= 0x0000;
1798 ip
->v6
.payload_length
= htons(wire_len
- icmp_truncate_len
); /* TODO */
1799 ip
->v6
.next_header
= protocol
;
1800 memcpy(ip
->v6
.src_addr
, src_in6
->sin6_addr
.s6_addr
, 16);
1801 memcpy(ip
->v6
.dest_addr
, dest_in6
->sin6_addr
.s6_addr
, 16);
1802 buf
+= SWRAP_PACKET_IP_V6_SIZE
;
1808 pay
= (union swrap_packet_payload
*)buf
;
1809 switch (src
->sa_family
) {
1811 pay
->icmp4
.type
= 0x03; /* destination unreachable */
1812 pay
->icmp4
.code
= 0x01; /* host unreachable */
1813 pay
->icmp4
.checksum
= htons(0x0000);
1814 pay
->icmp4
.unused
= htonl(0x00000000);
1815 buf
+= SWRAP_PACKET_PAYLOAD_ICMP4_SIZE
;
1817 /* set the ip header in the ICMP payload */
1818 ip
= (union swrap_packet_ip
*)buf
;
1819 ip
->v4
.ver_hdrlen
= 0x45; /* version 4 and 5 * 32 bit words */
1821 ip
->v4
.packet_length
= htons(wire_len
- icmp_hdr_len
);
1822 ip
->v4
.identification
= htons(0xFFFF);
1823 ip
->v4
.flags
= 0x40; /* BIT 1 set - means don't fragment */
1824 ip
->v4
.fragment
= htons(0x0000);
1826 ip
->v4
.protocol
= icmp_protocol
;
1827 ip
->v4
.hdr_checksum
= htons(0x0000);
1828 ip
->v4
.src_addr
= dest_in
->sin_addr
.s_addr
;
1829 ip
->v4
.dest_addr
= src_in
->sin_addr
.s_addr
;
1830 buf
+= SWRAP_PACKET_IP_V4_SIZE
;
1832 src_port
= dest_in
->sin_port
;
1833 dest_port
= src_in
->sin_port
;
1837 pay
->icmp6
.type
= 0x01; /* destination unreachable */
1838 pay
->icmp6
.code
= 0x03; /* address unreachable */
1839 pay
->icmp6
.checksum
= htons(0x0000);
1840 pay
->icmp6
.unused
= htonl(0x00000000);
1841 buf
+= SWRAP_PACKET_PAYLOAD_ICMP6_SIZE
;
1843 /* set the ip header in the ICMP payload */
1844 ip
= (union swrap_packet_ip
*)buf
;
1845 ip
->v6
.ver_prio
= 0x60; /* version 4 and 5 * 32 bit words */
1846 ip
->v6
.flow_label_high
= 0x00;
1847 ip
->v6
.flow_label_low
= 0x0000;
1848 ip
->v6
.payload_length
= htons(wire_len
- icmp_truncate_len
); /* TODO */
1849 ip
->v6
.next_header
= protocol
;
1850 memcpy(ip
->v6
.src_addr
, dest_in6
->sin6_addr
.s6_addr
, 16);
1851 memcpy(ip
->v6
.dest_addr
, src_in6
->sin6_addr
.s6_addr
, 16);
1852 buf
+= SWRAP_PACKET_IP_V6_SIZE
;
1854 src_port
= dest_in6
->sin6_port
;
1855 dest_port
= src_in6
->sin6_port
;
1861 pay
= (union swrap_packet_payload
*)buf
;
1863 switch (socket_type
) {
1865 pay
->tcp
.source_port
= src_port
;
1866 pay
->tcp
.dest_port
= dest_port
;
1867 pay
->tcp
.seq_num
= htonl(tcp_seqno
);
1868 pay
->tcp
.ack_num
= htonl(tcp_ack
);
1869 pay
->tcp
.hdr_length
= 0x50; /* 5 * 32 bit words */
1870 pay
->tcp
.control
= tcp_ctl
;
1871 pay
->tcp
.window
= htons(0x7FFF);
1872 pay
->tcp
.checksum
= htons(0x0000);
1873 pay
->tcp
.urg
= htons(0x0000);
1874 buf
+= SWRAP_PACKET_PAYLOAD_TCP_SIZE
;
1879 pay
->udp
.source_port
= src_port
;
1880 pay
->udp
.dest_port
= dest_port
;
1881 pay
->udp
.length
= htons(8 + payload_len
);
1882 pay
->udp
.checksum
= htons(0x0000);
1883 buf
+= SWRAP_PACKET_PAYLOAD_UDP_SIZE
;
1888 if (payload
&& payload_len
> 0) {
1889 memcpy(buf
, payload
, payload_len
);
1892 *_packet_len
= packet_len
- icmp_truncate_len
;
1896 static int swrap_get_pcap_fd(const char *fname
)
1900 if (fd
!= -1) return fd
;
1902 fd
= libc_open(fname
, O_WRONLY
|O_CREAT
|O_EXCL
|O_APPEND
, 0644);
1904 struct swrap_file_hdr file_hdr
;
1905 file_hdr
.magic
= 0xA1B2C3D4;
1906 file_hdr
.version_major
= 0x0002;
1907 file_hdr
.version_minor
= 0x0004;
1908 file_hdr
.timezone
= 0x00000000;
1909 file_hdr
.sigfigs
= 0x00000000;
1910 file_hdr
.frame_max_len
= SWRAP_FRAME_LENGTH_MAX
;
1911 file_hdr
.link_type
= 0x0065; /* 101 RAW IP */
1913 if (write(fd
, &file_hdr
, sizeof(file_hdr
)) != sizeof(file_hdr
)) {
1920 fd
= libc_open(fname
, O_WRONLY
|O_APPEND
, 0644);
1925 static uint8_t *swrap_marshall_packet(struct socket_info
*si
,
1926 const struct sockaddr
*addr
,
1927 enum swrap_packet_type type
,
1928 const void *buf
, size_t len
,
1931 const struct sockaddr
*src_addr
;
1932 const struct sockaddr
*dest_addr
;
1933 unsigned long tcp_seqno
= 0;
1934 unsigned long tcp_ack
= 0;
1935 unsigned char tcp_ctl
= 0;
1936 int unreachable
= 0;
1940 switch (si
->family
) {
1952 case SWRAP_CONNECT_SEND
:
1953 if (si
->type
!= SOCK_STREAM
) return NULL
;
1955 src_addr
= si
->myname
;
1958 tcp_seqno
= si
->io
.pck_snd
;
1959 tcp_ack
= si
->io
.pck_rcv
;
1960 tcp_ctl
= 0x02; /* SYN */
1962 si
->io
.pck_snd
+= 1;
1966 case SWRAP_CONNECT_RECV
:
1967 if (si
->type
!= SOCK_STREAM
) return NULL
;
1969 dest_addr
= si
->myname
;
1972 tcp_seqno
= si
->io
.pck_rcv
;
1973 tcp_ack
= si
->io
.pck_snd
;
1974 tcp_ctl
= 0x12; /** SYN,ACK */
1976 si
->io
.pck_rcv
+= 1;
1980 case SWRAP_CONNECT_UNREACH
:
1981 if (si
->type
!= SOCK_STREAM
) return NULL
;
1983 dest_addr
= si
->myname
;
1986 /* Unreachable: resend the data of SWRAP_CONNECT_SEND */
1987 tcp_seqno
= si
->io
.pck_snd
- 1;
1988 tcp_ack
= si
->io
.pck_rcv
;
1989 tcp_ctl
= 0x02; /* SYN */
1994 case SWRAP_CONNECT_ACK
:
1995 if (si
->type
!= SOCK_STREAM
) return NULL
;
1997 src_addr
= si
->myname
;
2000 tcp_seqno
= si
->io
.pck_snd
;
2001 tcp_ack
= si
->io
.pck_rcv
;
2002 tcp_ctl
= 0x10; /* ACK */
2006 case SWRAP_ACCEPT_SEND
:
2007 if (si
->type
!= SOCK_STREAM
) return NULL
;
2009 dest_addr
= si
->myname
;
2012 tcp_seqno
= si
->io
.pck_rcv
;
2013 tcp_ack
= si
->io
.pck_snd
;
2014 tcp_ctl
= 0x02; /* SYN */
2016 si
->io
.pck_rcv
+= 1;
2020 case SWRAP_ACCEPT_RECV
:
2021 if (si
->type
!= SOCK_STREAM
) return NULL
;
2023 src_addr
= si
->myname
;
2026 tcp_seqno
= si
->io
.pck_snd
;
2027 tcp_ack
= si
->io
.pck_rcv
;
2028 tcp_ctl
= 0x12; /* SYN,ACK */
2030 si
->io
.pck_snd
+= 1;
2034 case SWRAP_ACCEPT_ACK
:
2035 if (si
->type
!= SOCK_STREAM
) return NULL
;
2037 dest_addr
= si
->myname
;
2040 tcp_seqno
= si
->io
.pck_rcv
;
2041 tcp_ack
= si
->io
.pck_snd
;
2042 tcp_ctl
= 0x10; /* ACK */
2047 src_addr
= si
->myname
;
2048 dest_addr
= si
->peername
;
2050 tcp_seqno
= si
->io
.pck_snd
;
2051 tcp_ack
= si
->io
.pck_rcv
;
2052 tcp_ctl
= 0x18; /* PSH,ACK */
2054 si
->io
.pck_snd
+= len
;
2058 case SWRAP_SEND_RST
:
2059 dest_addr
= si
->myname
;
2060 src_addr
= si
->peername
;
2062 if (si
->type
== SOCK_DGRAM
) {
2063 return swrap_marshall_packet(si
, si
->peername
,
2064 SWRAP_SENDTO_UNREACH
,
2065 buf
, len
, packet_len
);
2068 tcp_seqno
= si
->io
.pck_rcv
;
2069 tcp_ack
= si
->io
.pck_snd
;
2070 tcp_ctl
= 0x14; /** RST,ACK */
2074 case SWRAP_PENDING_RST
:
2075 dest_addr
= si
->myname
;
2076 src_addr
= si
->peername
;
2078 if (si
->type
== SOCK_DGRAM
) {
2082 tcp_seqno
= si
->io
.pck_rcv
;
2083 tcp_ack
= si
->io
.pck_snd
;
2084 tcp_ctl
= 0x14; /* RST,ACK */
2089 dest_addr
= si
->myname
;
2090 src_addr
= si
->peername
;
2092 tcp_seqno
= si
->io
.pck_rcv
;
2093 tcp_ack
= si
->io
.pck_snd
;
2094 tcp_ctl
= 0x18; /* PSH,ACK */
2096 si
->io
.pck_rcv
+= len
;
2100 case SWRAP_RECV_RST
:
2101 dest_addr
= si
->myname
;
2102 src_addr
= si
->peername
;
2104 if (si
->type
== SOCK_DGRAM
) {
2108 tcp_seqno
= si
->io
.pck_rcv
;
2109 tcp_ack
= si
->io
.pck_snd
;
2110 tcp_ctl
= 0x14; /* RST,ACK */
2115 src_addr
= si
->myname
;
2118 si
->io
.pck_snd
+= len
;
2122 case SWRAP_SENDTO_UNREACH
:
2123 dest_addr
= si
->myname
;
2130 case SWRAP_RECVFROM
:
2131 dest_addr
= si
->myname
;
2134 si
->io
.pck_rcv
+= len
;
2138 case SWRAP_CLOSE_SEND
:
2139 if (si
->type
!= SOCK_STREAM
) return NULL
;
2141 src_addr
= si
->myname
;
2142 dest_addr
= si
->peername
;
2144 tcp_seqno
= si
->io
.pck_snd
;
2145 tcp_ack
= si
->io
.pck_rcv
;
2146 tcp_ctl
= 0x11; /* FIN, ACK */
2148 si
->io
.pck_snd
+= 1;
2152 case SWRAP_CLOSE_RECV
:
2153 if (si
->type
!= SOCK_STREAM
) return NULL
;
2155 dest_addr
= si
->myname
;
2156 src_addr
= si
->peername
;
2158 tcp_seqno
= si
->io
.pck_rcv
;
2159 tcp_ack
= si
->io
.pck_snd
;
2160 tcp_ctl
= 0x11; /* FIN,ACK */
2162 si
->io
.pck_rcv
+= 1;
2166 case SWRAP_CLOSE_ACK
:
2167 if (si
->type
!= SOCK_STREAM
) return NULL
;
2169 src_addr
= si
->myname
;
2170 dest_addr
= si
->peername
;
2172 tcp_seqno
= si
->io
.pck_snd
;
2173 tcp_ack
= si
->io
.pck_rcv
;
2174 tcp_ctl
= 0x10; /* ACK */
2181 swrapGetTimeOfDay(&tv
);
2183 return swrap_packet_init(&tv
, src_addr
, dest_addr
, si
->type
,
2184 (const uint8_t *)buf
, len
,
2185 tcp_seqno
, tcp_ack
, tcp_ctl
, unreachable
,
2189 static void swrap_dump_packet(struct socket_info
*si
,
2190 const struct sockaddr
*addr
,
2191 enum swrap_packet_type type
,
2192 const void *buf
, size_t len
)
2194 const char *file_name
;
2196 size_t packet_len
= 0;
2199 file_name
= socket_wrapper_pcap_file();
2204 packet
= swrap_marshall_packet(si
, addr
, type
, buf
, len
, &packet_len
);
2209 fd
= swrap_get_pcap_fd(file_name
);
2211 if (write(fd
, packet
, packet_len
) != (ssize_t
)packet_len
) {
2220 /****************************************************************************
2222 ***************************************************************************/
2224 #ifdef HAVE_SIGNALFD
2225 static int swrap_signalfd(int fd
, const sigset_t
*mask
, int flags
)
2229 rc
= libc_signalfd(fd
, mask
, flags
);
2231 swrap_remove_stale(fd
);
2237 int signalfd(int fd
, const sigset_t
*mask
, int flags
)
2239 return swrap_signalfd(fd
, mask
, flags
);
2243 /****************************************************************************
2245 ***************************************************************************/
2247 static int swrap_socket(int family
, int type
, int protocol
)
2249 struct socket_info
*si
;
2250 struct socket_info_fd
*fi
;
2252 int real_type
= type
;
2255 * Remove possible addition flags passed to socket() so
2256 * do not fail checking the type.
2257 * See https://lwn.net/Articles/281965/
2260 real_type
&= ~SOCK_CLOEXEC
;
2262 #ifdef SOCK_NONBLOCK
2263 real_type
&= ~SOCK_NONBLOCK
;
2266 if (!socket_wrapper_enabled()) {
2267 return libc_socket(family
, type
, protocol
);
2277 return libc_socket(family
, type
, protocol
);
2279 errno
= EAFNOSUPPORT
;
2283 switch (real_type
) {
2289 errno
= EPROTONOSUPPORT
;
2297 if (real_type
== SOCK_STREAM
) {
2302 if (real_type
== SOCK_DGRAM
) {
2307 errno
= EPROTONOSUPPORT
;
2312 * We must call libc_socket with type, from the caller, not the version
2313 * we removed SOCK_CLOEXEC and SOCK_NONBLOCK from
2315 fd
= libc_socket(AF_UNIX
, type
, 0);
2321 /* Check if we have a stale fd and remove it */
2322 si
= find_socket_info(fd
);
2324 swrap_remove_stale(fd
);
2327 si
= (struct socket_info
*)malloc(sizeof(struct socket_info
));
2328 memset(si
, 0, sizeof(struct socket_info
));
2334 si
->family
= family
;
2336 /* however, the rest of the socket_wrapper code expects just
2337 * the type, not the flags */
2338 si
->type
= real_type
;
2339 si
->protocol
= protocol
;
2342 * Setup myname so getsockname() can succeed to find out the socket
2345 switch(si
->family
) {
2347 struct sockaddr_in sin
= {
2348 .sin_family
= AF_INET
,
2351 si
->myname_len
= sizeof(struct sockaddr_in
);
2352 si
->myname
= sockaddr_dup(&sin
, si
->myname_len
);
2356 struct sockaddr_in6 sin6
= {
2357 .sin6_family
= AF_INET6
,
2360 si
->myname_len
= sizeof(struct sockaddr_in6
);
2361 si
->myname
= sockaddr_dup(&sin6
, si
->myname_len
);
2370 fi
= (struct socket_info_fd
*)calloc(1, sizeof(struct socket_info_fd
));
2372 if (si
->myname
!= NULL
) {
2382 SWRAP_DLIST_ADD(si
->fds
, fi
);
2383 SWRAP_DLIST_ADD(sockets
, si
);
2388 int socket(int family
, int type
, int protocol
)
2390 return swrap_socket(family
, type
, protocol
);
2393 /****************************************************************************
2395 ***************************************************************************/
2397 static int swrap_socketpair(int family
, int type
, int protocol
, int sv
[2])
2401 rc
= libc_socketpair(family
, type
, protocol
, sv
);
2403 swrap_remove_stale(sv
[0]);
2404 swrap_remove_stale(sv
[1]);
2410 int socketpair(int family
, int type
, int protocol
, int sv
[2])
2412 return swrap_socketpair(family
, type
, protocol
, sv
);
2415 /****************************************************************************
2417 ***************************************************************************/
2419 #ifdef HAVE_TIMERFD_CREATE
2420 static int swrap_timerfd_create(int clockid
, int flags
)
2424 fd
= libc_timerfd_create(clockid
, flags
);
2426 swrap_remove_stale(fd
);
2432 int timerfd_create(int clockid
, int flags
)
2434 return swrap_timerfd_create(clockid
, flags
);
2438 /****************************************************************************
2440 ***************************************************************************/
2442 static int swrap_pipe(int pipefd
[2])
2446 rc
= libc_pipe(pipefd
);
2448 swrap_remove_stale(pipefd
[0]);
2449 swrap_remove_stale(pipefd
[1]);
2455 int pipe(int pipefd
[2])
2457 return swrap_pipe(pipefd
);
2460 /****************************************************************************
2462 ***************************************************************************/
2464 static int swrap_accept(int s
, struct sockaddr
*addr
, socklen_t
*addrlen
)
2466 struct socket_info
*parent_si
, *child_si
;
2467 struct socket_info_fd
*child_fi
;
2469 struct sockaddr_un un_addr
;
2470 socklen_t un_addrlen
= sizeof(un_addr
);
2471 struct sockaddr_un un_my_addr
;
2472 socklen_t un_my_addrlen
= sizeof(un_my_addr
);
2473 struct sockaddr
*my_addr
;
2474 socklen_t my_addrlen
, len
;
2477 parent_si
= find_socket_info(s
);
2479 return libc_accept(s
, addr
, addrlen
);
2483 * assume out sockaddr have the same size as the in parent
2486 my_addrlen
= socket_length(parent_si
->family
);
2487 if (my_addrlen
<= 0) {
2492 my_addr
= (struct sockaddr
*)malloc(my_addrlen
);
2493 if (my_addr
== NULL
) {
2497 memset(&un_addr
, 0, sizeof(un_addr
));
2498 memset(&un_my_addr
, 0, sizeof(un_my_addr
));
2500 ret
= libc_accept(s
, (struct sockaddr
*)(void *)&un_addr
, &un_addrlen
);
2502 if (errno
== ENOTSOCK
) {
2503 /* Remove stale fds */
2504 swrap_remove_stale(s
);
2513 ret
= sockaddr_convert_from_un(parent_si
, &un_addr
, un_addrlen
,
2514 parent_si
->family
, my_addr
, &len
);
2521 child_si
= (struct socket_info
*)malloc(sizeof(struct socket_info
));
2522 memset(child_si
, 0, sizeof(struct socket_info
));
2524 child_fi
= (struct socket_info_fd
*)calloc(1, sizeof(struct socket_info_fd
));
2525 if (child_fi
== NULL
) {
2535 SWRAP_DLIST_ADD(child_si
->fds
, child_fi
);
2537 child_si
->family
= parent_si
->family
;
2538 child_si
->type
= parent_si
->type
;
2539 child_si
->protocol
= parent_si
->protocol
;
2540 child_si
->bound
= 1;
2541 child_si
->is_server
= 1;
2542 child_si
->connected
= 1;
2544 child_si
->peername_len
= len
;
2545 child_si
->peername
= sockaddr_dup(my_addr
, len
);
2547 if (addr
!= NULL
&& addrlen
!= NULL
) {
2548 size_t copy_len
= MIN(*addrlen
, len
);
2550 memcpy(addr
, my_addr
, copy_len
);
2555 ret
= libc_getsockname(fd
,
2556 (struct sockaddr
*)(void *)&un_my_addr
,
2567 ret
= sockaddr_convert_from_un(child_si
, &un_my_addr
, un_my_addrlen
,
2568 child_si
->family
, my_addr
, &len
);
2577 SWRAP_LOG(SWRAP_LOG_TRACE
,
2578 "accept() path=%s, fd=%d",
2579 un_my_addr
.sun_path
, s
);
2581 child_si
->myname_len
= len
;
2582 child_si
->myname
= sockaddr_dup(my_addr
, len
);
2585 SWRAP_DLIST_ADD(sockets
, child_si
);
2588 swrap_dump_packet(child_si
, addr
, SWRAP_ACCEPT_SEND
, NULL
, 0);
2589 swrap_dump_packet(child_si
, addr
, SWRAP_ACCEPT_RECV
, NULL
, 0);
2590 swrap_dump_packet(child_si
, addr
, SWRAP_ACCEPT_ACK
, NULL
, 0);
2596 #ifdef HAVE_ACCEPT_PSOCKLEN_T
2597 int accept(int s
, struct sockaddr
*addr
, Psocklen_t addrlen
)
2599 int accept(int s
, struct sockaddr
*addr
, socklen_t
*addrlen
)
2602 return swrap_accept(s
, addr
, (socklen_t
*)addrlen
);
2605 static int autobind_start_init
;
2606 static int autobind_start
;
2608 /* using sendto() or connect() on an unbound socket would give the
2609 recipient no way to reply, as unlike UDP and TCP, a unix domain
2610 socket can't auto-assign ephemeral port numbers, so we need to
2612 Note: this might change the family from ipv6 to ipv4
2614 static int swrap_auto_bind(int fd
, struct socket_info
*si
, int family
)
2616 struct sockaddr_un un_addr
;
2623 if (autobind_start_init
!= 1) {
2624 autobind_start_init
= 1;
2625 autobind_start
= getpid();
2626 autobind_start
%= 50000;
2627 autobind_start
+= 10000;
2630 un_addr
.sun_family
= AF_UNIX
;
2634 struct sockaddr_in in
;
2638 type
= SOCKET_TYPE_CHAR_TCP
;
2641 type
= SOCKET_TYPE_CHAR_UDP
;
2644 errno
= ESOCKTNOSUPPORT
;
2648 memset(&in
, 0, sizeof(in
));
2649 in
.sin_family
= AF_INET
;
2650 in
.sin_addr
.s_addr
= htonl(127<<24 |
2651 socket_wrapper_default_iface());
2654 si
->myname_len
= sizeof(in
);
2655 si
->myname
= sockaddr_dup(&in
, si
->myname_len
);
2660 struct sockaddr_in6 in6
;
2662 if (si
->family
!= family
) {
2663 errno
= ENETUNREACH
;
2669 type
= SOCKET_TYPE_CHAR_TCP_V6
;
2672 type
= SOCKET_TYPE_CHAR_UDP_V6
;
2675 errno
= ESOCKTNOSUPPORT
;
2679 memset(&in6
, 0, sizeof(in6
));
2680 in6
.sin6_family
= AF_INET6
;
2681 in6
.sin6_addr
= *swrap_ipv6();
2682 in6
.sin6_addr
.s6_addr
[15] = socket_wrapper_default_iface();
2684 si
->myname_len
= sizeof(in6
);
2685 si
->myname
= sockaddr_dup(&in6
, si
->myname_len
);
2690 errno
= ESOCKTNOSUPPORT
;
2694 if (autobind_start
> 60000) {
2695 autobind_start
= 10000;
2698 for (i
= 0; i
< SOCKET_MAX_SOCKETS
; i
++) {
2699 port
= autobind_start
+ i
;
2700 snprintf(un_addr
.sun_path
, sizeof(un_addr
.sun_path
),
2701 "%s/"SOCKET_FORMAT
, socket_wrapper_dir(),
2702 type
, socket_wrapper_default_iface(), port
);
2703 if (stat(un_addr
.sun_path
, &st
) == 0) continue;
2705 ret
= libc_bind(fd
, (struct sockaddr
*)(void *)&un_addr
,
2707 if (ret
== -1) return ret
;
2709 si
->tmp_path
= strdup(un_addr
.sun_path
);
2711 autobind_start
= port
+ 1;
2714 if (i
== SOCKET_MAX_SOCKETS
) {
2715 SWRAP_LOG(SWRAP_LOG_ERROR
, "Too many open unix sockets (%u) for "
2716 "interface "SOCKET_FORMAT
,
2719 socket_wrapper_default_iface(),
2725 si
->family
= family
;
2726 set_port(si
->family
, port
, si
->myname
);
2731 /****************************************************************************
2733 ***************************************************************************/
2735 static int swrap_connect(int s
, const struct sockaddr
*serv_addr
,
2739 struct sockaddr_un un_addr
;
2740 struct socket_info
*si
= find_socket_info(s
);
2744 return libc_connect(s
, serv_addr
, addrlen
);
2747 if (si
->bound
== 0) {
2748 ret
= swrap_auto_bind(s
, si
, serv_addr
->sa_family
);
2749 if (ret
== -1) return -1;
2752 if (si
->family
!= serv_addr
->sa_family
) {
2757 ret
= sockaddr_convert_to_un(si
, serv_addr
,
2758 addrlen
, &un_addr
, 0, &bcast
);
2759 if (ret
== -1) return -1;
2762 errno
= ENETUNREACH
;
2766 if (si
->type
== SOCK_DGRAM
) {
2767 si
->defer_connect
= 1;
2770 swrap_dump_packet(si
, serv_addr
, SWRAP_CONNECT_SEND
, NULL
, 0);
2772 ret
= libc_connect(s
,
2773 (struct sockaddr
*)(void *)&un_addr
,
2774 sizeof(struct sockaddr_un
));
2777 SWRAP_LOG(SWRAP_LOG_TRACE
,
2778 "connect() path=%s, fd=%d",
2779 un_addr
.sun_path
, s
);
2782 /* to give better errors */
2783 if (ret
== -1 && errno
== ENOENT
) {
2784 errno
= EHOSTUNREACH
;
2788 si
->peername_len
= addrlen
;
2789 si
->peername
= sockaddr_dup(serv_addr
, addrlen
);
2793 * When we connect() on a socket than we have to bind the
2794 * outgoing connection on the interface we use for the
2795 * transport. We already bound it on the right interface
2796 * but here we have to update the name so getsockname()
2797 * returns correct information.
2799 if (si
->bindname
!= NULL
) {
2802 si
->myname
= si
->bindname
;
2803 si
->myname_len
= si
->bindname_len
;
2805 si
->bindname
= NULL
;
2806 si
->bindname_len
= 0;
2809 swrap_dump_packet(si
, serv_addr
, SWRAP_CONNECT_RECV
, NULL
, 0);
2810 swrap_dump_packet(si
, serv_addr
, SWRAP_CONNECT_ACK
, NULL
, 0);
2812 swrap_dump_packet(si
, serv_addr
, SWRAP_CONNECT_UNREACH
, NULL
, 0);
2818 int connect(int s
, const struct sockaddr
*serv_addr
, socklen_t addrlen
)
2820 return swrap_connect(s
, serv_addr
, addrlen
);
2823 /****************************************************************************
2825 ***************************************************************************/
2827 static int swrap_bind(int s
, const struct sockaddr
*myaddr
, socklen_t addrlen
)
2830 struct sockaddr_un un_addr
;
2831 struct socket_info
*si
= find_socket_info(s
);
2838 return libc_bind(s
, myaddr
, addrlen
);
2841 switch (si
->family
) {
2843 const struct sockaddr_in
*sin
;
2844 if (addrlen
< sizeof(struct sockaddr_in
)) {
2845 bind_error
= EINVAL
;
2849 sin
= (struct sockaddr_in
*)myaddr
;
2851 if (sin
->sin_family
!= AF_INET
) {
2852 bind_error
= EAFNOSUPPORT
;
2855 /* special case for AF_UNSPEC */
2856 if (sin
->sin_family
== AF_UNSPEC
&&
2857 (sin
->sin_addr
.s_addr
== htonl(INADDR_ANY
)))
2866 const struct sockaddr_in6
*sin6
;
2867 if (addrlen
< sizeof(struct sockaddr_in6
)) {
2868 bind_error
= EINVAL
;
2872 sin6
= (struct sockaddr_in6
*)myaddr
;
2874 if (sin6
->sin6_family
!= AF_INET6
) {
2875 bind_error
= EAFNOSUPPORT
;
2882 bind_error
= EINVAL
;
2886 if (bind_error
!= 0) {
2892 in_use
= check_addr_port_in_use(myaddr
, addrlen
);
2900 si
->myname_len
= addrlen
;
2901 si
->myname
= sockaddr_dup(myaddr
, addrlen
);
2903 ret
= sockaddr_convert_to_un(si
, myaddr
, addrlen
, &un_addr
, 1, &si
->bcast
);
2904 if (ret
== -1) return -1;
2906 unlink(un_addr
.sun_path
);
2908 ret
= libc_bind(s
, (struct sockaddr
*)(void *)&un_addr
,
2909 sizeof(struct sockaddr_un
));
2911 SWRAP_LOG(SWRAP_LOG_TRACE
,
2912 "bind() path=%s, fd=%d",
2913 un_addr
.sun_path
, s
);
2922 int bind(int s
, const struct sockaddr
*myaddr
, socklen_t addrlen
)
2924 return swrap_bind(s
, myaddr
, addrlen
);
2927 /****************************************************************************
2929 ***************************************************************************/
2931 #ifdef HAVE_BINDRESVPORT
2932 static int swrap_getsockname(int s
, struct sockaddr
*name
, socklen_t
*addrlen
);
2934 static int swrap_bindresvport_sa(int sd
, struct sockaddr
*sa
)
2936 struct sockaddr_storage myaddr
;
2938 static uint16_t port
;
2943 #define SWRAP_STARTPORT 600
2944 #define SWRAP_ENDPORT (IPPORT_RESERVED - 1)
2945 #define SWRAP_NPORTS (SWRAP_ENDPORT - SWRAP_STARTPORT + 1)
2948 port
= (getpid() % SWRAP_NPORTS
) + SWRAP_STARTPORT
;
2952 salen
= sizeof(struct sockaddr
);
2953 sa
= (struct sockaddr
*)&myaddr
;
2955 rc
= swrap_getsockname(sd
, (struct sockaddr
*)&myaddr
, &salen
);
2961 memset(&myaddr
, 0, salen
);
2966 for (i
= 0; i
< SWRAP_NPORTS
; i
++, port
++) {
2969 struct sockaddr_in
*sinp
= (struct sockaddr_in
*)sa
;
2971 salen
= sizeof(struct sockaddr_in
);
2972 sinp
->sin_port
= htons(port
);
2976 struct sockaddr_in6
*sin6p
= (struct sockaddr_in6
*)sa
;
2978 salen
= sizeof(struct sockaddr_in6
);
2979 sin6p
->sin6_port
= htons(port
);
2983 errno
= EAFNOSUPPORT
;
2988 if (port
> SWRAP_ENDPORT
) {
2989 port
= SWRAP_STARTPORT
;
2992 rc
= swrap_bind(sd
, (struct sockaddr
*)sa
, salen
);
2993 if (rc
== 0 || errno
!= EADDRINUSE
) {
3001 int bindresvport(int sockfd
, struct sockaddr_in
*sinp
)
3003 return swrap_bindresvport_sa(sockfd
, (struct sockaddr
*)sinp
);
3007 /****************************************************************************
3009 ***************************************************************************/
3011 static int swrap_listen(int s
, int backlog
)
3014 struct socket_info
*si
= find_socket_info(s
);
3017 return libc_listen(s
, backlog
);
3020 ret
= libc_listen(s
, backlog
);
3025 int listen(int s
, int backlog
)
3027 return swrap_listen(s
, backlog
);
3030 /****************************************************************************
3032 ***************************************************************************/
3034 static int swrap_vopen(const char *pathname
, int flags
, va_list ap
)
3038 ret
= libc_vopen(pathname
, flags
, ap
);
3041 * There are methods for closing descriptors (libc-internal code
3042 * paths, direct syscalls) which close descriptors in ways that
3043 * we can't intercept, so try to recover when we notice that
3046 swrap_remove_stale(ret
);
3051 int open(const char *pathname
, int flags
, ...)
3056 va_start(ap
, flags
);
3057 fd
= swrap_vopen(pathname
, flags
, ap
);
3063 /****************************************************************************
3065 ***************************************************************************/
3067 static int swrap_getpeername(int s
, struct sockaddr
*name
, socklen_t
*addrlen
)
3069 struct socket_info
*si
= find_socket_info(s
);
3073 return libc_getpeername(s
, name
, addrlen
);
3082 len
= MIN(*addrlen
, si
->peername_len
);
3087 memcpy(name
, si
->peername
, len
);
3088 *addrlen
= si
->peername_len
;
3093 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3094 int getpeername(int s
, struct sockaddr
*name
, Psocklen_t addrlen
)
3096 int getpeername(int s
, struct sockaddr
*name
, socklen_t
*addrlen
)
3099 return swrap_getpeername(s
, name
, (socklen_t
*)addrlen
);
3102 /****************************************************************************
3104 ***************************************************************************/
3106 static int swrap_getsockname(int s
, struct sockaddr
*name
, socklen_t
*addrlen
)
3108 struct socket_info
*si
= find_socket_info(s
);
3112 return libc_getsockname(s
, name
, addrlen
);
3115 len
= MIN(*addrlen
, si
->myname_len
);
3120 memcpy(name
, si
->myname
, len
);
3121 *addrlen
= si
->myname_len
;
3126 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3127 int getsockname(int s
, struct sockaddr
*name
, Psocklen_t addrlen
)
3129 int getsockname(int s
, struct sockaddr
*name
, socklen_t
*addrlen
)
3132 return swrap_getsockname(s
, name
, (socklen_t
*)addrlen
);
3135 /****************************************************************************
3137 ***************************************************************************/
3140 # ifdef SO_PROTOTYPE /* The Solaris name */
3141 # define SO_PROTOCOL SO_PROTOTYPE
3142 # endif /* SO_PROTOTYPE */
3143 #endif /* SO_PROTOCOL */
3145 static int swrap_getsockopt(int s
, int level
, int optname
,
3146 void *optval
, socklen_t
*optlen
)
3148 struct socket_info
*si
= find_socket_info(s
);
3151 return libc_getsockopt(s
,
3158 if (level
== SOL_SOCKET
) {
3162 if (optval
== NULL
|| optlen
== NULL
||
3163 *optlen
< (socklen_t
)sizeof(int)) {
3168 *optlen
= sizeof(int);
3169 *(int *)optval
= si
->family
;
3171 #endif /* SO_DOMAIN */
3173 if (optval
== NULL
|| optlen
== NULL
||
3174 *optlen
< (socklen_t
)sizeof(int)) {
3179 *optlen
= sizeof(int);
3180 *(int *)optval
= si
->protocol
;
3183 if (optval
== NULL
|| optlen
== NULL
||
3184 *optlen
< (socklen_t
)sizeof(int)) {
3189 *optlen
= sizeof(int);
3190 *(int *)optval
= si
->type
;
3193 return libc_getsockopt(s
,
3201 errno
= ENOPROTOOPT
;
3205 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3206 int getsockopt(int s
, int level
, int optname
, void *optval
, Psocklen_t optlen
)
3208 int getsockopt(int s
, int level
, int optname
, void *optval
, socklen_t
*optlen
)
3211 return swrap_getsockopt(s
, level
, optname
, optval
, (socklen_t
*)optlen
);
3214 /****************************************************************************
3216 ***************************************************************************/
3218 static int swrap_setsockopt(int s
, int level
, int optname
,
3219 const void *optval
, socklen_t optlen
)
3221 struct socket_info
*si
= find_socket_info(s
);
3224 return libc_setsockopt(s
,
3231 if (level
== SOL_SOCKET
) {
3232 return libc_setsockopt(s
,
3239 switch (si
->family
) {
3241 if (level
== IPPROTO_IP
) {
3243 if (optname
== IP_PKTINFO
) {
3244 si
->pktinfo
= AF_INET
;
3246 #endif /* IP_PKTINFO */
3251 if (level
== IPPROTO_IPV6
) {
3252 #ifdef IPV6_RECVPKTINFO
3253 if (optname
== IPV6_RECVPKTINFO
) {
3254 si
->pktinfo
= AF_INET6
;
3256 #endif /* IPV6_PKTINFO */
3261 errno
= ENOPROTOOPT
;
3266 int setsockopt(int s
, int level
, int optname
,
3267 const void *optval
, socklen_t optlen
)
3269 return swrap_setsockopt(s
, level
, optname
, optval
, optlen
);
3272 /****************************************************************************
3274 ***************************************************************************/
3276 static int swrap_vioctl(int s
, unsigned long int r
, va_list va
)
3278 struct socket_info
*si
= find_socket_info(s
);
3284 return libc_vioctl(s
, r
, va
);
3289 rc
= libc_vioctl(s
, r
, va
);
3293 value
= *((int *)va_arg(ap
, int *));
3295 if (rc
== -1 && errno
!= EAGAIN
&& errno
!= ENOBUFS
) {
3296 swrap_dump_packet(si
, NULL
, SWRAP_PENDING_RST
, NULL
, 0);
3297 } else if (value
== 0) { /* END OF FILE */
3298 swrap_dump_packet(si
, NULL
, SWRAP_PENDING_RST
, NULL
, 0);
3308 #ifdef HAVE_IOCTL_INT
3309 int ioctl(int s
, int r
, ...)
3311 int ioctl(int s
, unsigned long int r
, ...)
3319 rc
= swrap_vioctl(s
, (unsigned long int) r
, va
);
3330 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3333 # ifdef _ALIGN /* BSD */
3334 #define CMSG_ALIGN _ALIGN
3336 #error NO_CMSG_ALIGN
3337 # endif /* _ALIGN */
3338 #endif /* CMSG_ALIGN */
3341 * @brief Add a cmsghdr to a msghdr.
3343 * This is an function to add any type of cmsghdr. It will operate on the
3344 * msg->msg_control and msg->msg_controllen you pass in by adapting them to
3345 * the buffer position after the added cmsg element. Hence, this function is
3346 * intended to be used with an intermediate msghdr and not on the original
3347 * one handed in by the client.
3349 * @param[in] msg The msghdr to which to add the cmsg.
3351 * @param[in] level The cmsg level to set.
3353 * @param[in] type The cmsg type to set.
3355 * @param[in] data The cmsg data to set.
3357 * @param[in] len the length of the data to set.
3359 static void swrap_msghdr_add_cmsghdr(struct msghdr
*msg
,
3365 size_t cmlen
= CMSG_LEN(len
);
3366 size_t cmspace
= CMSG_SPACE(len
);
3367 uint8_t cmbuf
[cmspace
];
3368 struct cmsghdr
*cm
= (struct cmsghdr
*)cmbuf
;
3371 memset(cmbuf
, 0, cmspace
);
3373 if (msg
->msg_controllen
< cmlen
) {
3374 cmlen
= msg
->msg_controllen
;
3375 msg
->msg_flags
|= MSG_CTRUNC
;
3378 if (msg
->msg_controllen
< cmspace
) {
3379 cmspace
= msg
->msg_controllen
;
3383 * We copy the full input data into an intermediate cmsghdr first
3384 * in order to more easily cope with truncation.
3386 cm
->cmsg_len
= cmlen
;
3387 cm
->cmsg_level
= level
;
3388 cm
->cmsg_type
= type
;
3389 memcpy(CMSG_DATA(cm
), data
, len
);
3392 * We now copy the possibly truncated buffer.
3393 * We copy cmlen bytes, but consume cmspace bytes,
3394 * leaving the possible padding uninitialiazed.
3396 p
= (uint8_t *)msg
->msg_control
;
3397 memcpy(p
, cm
, cmlen
);
3399 msg
->msg_control
= p
;
3400 msg
->msg_controllen
-= cmspace
;
3405 static int swrap_msghdr_add_pktinfo(struct socket_info
*si
,
3408 /* Add packet info */
3409 switch (si
->pktinfo
) {
3410 #if defined(IP_PKTINFO)
3411 /* && (defined(HAVE_STRUCT_IN_PKTINFO) || defined(IP_RECVDSTADDR)) */
3413 struct sockaddr_in
*sin
;
3414 #if defined(HAVE_STRUCT_IN_PKTINFO)
3415 struct in_pktinfo pkt
;
3416 #elif defined(IP_RECVDSTADDR)
3420 if (si
->bindname_len
== sizeof(struct sockaddr_in
)) {
3421 sin
= (struct sockaddr_in
*)si
->bindname
;
3423 if (si
->myname_len
!= sizeof(struct sockaddr_in
)) {
3426 sin
= (struct sockaddr_in
*)si
->myname
;
3431 #if defined(HAVE_STRUCT_IN_PKTINFO)
3432 pkt
.ipi_ifindex
= socket_wrapper_default_iface();
3433 pkt
.ipi_addr
.s_addr
= sin
->sin_addr
.s_addr
;
3434 #elif defined(IP_RECVDSTADDR)
3435 pkt
= sin
->sin_addr
;
3438 swrap_msghdr_add_cmsghdr(msg
, IPPROTO_IP
, IP_PKTINFO
,
3443 #endif /* IP_PKTINFO */
3444 #if defined(HAVE_IPV6)
3446 #if defined(IPV6_PKTINFO) && defined(HAVE_STRUCT_IN6_PKTINFO)
3447 struct sockaddr_in6
*sin6
;
3448 struct in6_pktinfo pkt6
;
3450 if (si
->bindname_len
== sizeof(struct sockaddr_in6
)) {
3451 sin6
= (struct sockaddr_in6
*)si
->bindname
;
3453 if (si
->myname_len
!= sizeof(struct sockaddr_in6
)) {
3456 sin6
= (struct sockaddr_in6
*)si
->myname
;
3461 pkt6
.ipi6_ifindex
= socket_wrapper_default_iface();
3462 pkt6
.ipi6_addr
= sin6
->sin6_addr
;
3464 swrap_msghdr_add_cmsghdr(msg
, IPPROTO_IPV6
, IPV6_PKTINFO
,
3465 &pkt6
, sizeof(pkt6
));
3466 #endif /* HAVE_STRUCT_IN6_PKTINFO */
3470 #endif /* IPV6_PKTINFO */
3478 static int swrap_msghdr_add_socket_info(struct socket_info
*si
,
3479 struct msghdr
*omsg
)
3483 if (si
->pktinfo
> 0) {
3484 rc
= swrap_msghdr_add_pktinfo(si
, omsg
);
3490 static int swrap_sendmsg_copy_cmsg(struct cmsghdr
*cmsg
,
3492 size_t *cm_data_space
);
3493 static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr
*cmsg
,
3495 size_t *cm_data_space
);
3497 static int swrap_sendmsg_filter_cmsghdr(struct msghdr
*msg
,
3499 size_t *cm_data_space
) {
3500 struct cmsghdr
*cmsg
;
3504 if (msg
->msg_controllen
== 0 || msg
->msg_control
== NULL
) {
3508 for (cmsg
= CMSG_FIRSTHDR(msg
);
3510 cmsg
= CMSG_NXTHDR(msg
, cmsg
)) {
3511 switch (cmsg
->cmsg_level
) {
3513 rc
= swrap_sendmsg_filter_cmsg_socket(cmsg
,
3518 rc
= swrap_sendmsg_copy_cmsg(cmsg
,
3528 static int swrap_sendmsg_copy_cmsg(struct cmsghdr
*cmsg
,
3530 size_t *cm_data_space
)
3537 CMSG_SPACE(cmsg
->cmsg_len
- CMSG_ALIGN(sizeof(struct cmsghdr
)));
3539 p
= realloc((*cm_data
), cmspace
);
3545 p
= (*cm_data
) + (*cm_data_space
);
3546 *cm_data_space
= cmspace
;
3548 memcpy(p
, cmsg
, cmsg
->cmsg_len
);
3553 static int swrap_sendmsg_filter_cmsg_pktinfo(struct cmsghdr
*cmsg
,
3555 size_t *cm_data_space
);
3558 static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr
*cmsg
,
3560 size_t *cm_data_space
)
3564 switch(cmsg
->cmsg_type
) {
3567 rc
= swrap_sendmsg_filter_cmsg_pktinfo(cmsg
,
3574 rc
= swrap_sendmsg_filter_cmsg_pktinfo(cmsg
,
3586 static int swrap_sendmsg_filter_cmsg_pktinfo(struct cmsghdr
*cmsg
,
3588 size_t *cm_data_space
)
3590 (void)cmsg
; /* unused */
3591 (void)cm_data
; /* unused */
3592 (void)cm_data_space
; /* unused */
3595 * Passing a IP pktinfo to a unix socket might be rejected by the
3596 * Kernel, at least on FreeBSD. So skip this cmsg.
3600 #endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
3602 static ssize_t
swrap_sendmsg_before(int fd
,
3603 struct socket_info
*si
,
3605 struct iovec
*tmp_iov
,
3606 struct sockaddr_un
*tmp_un
,
3607 const struct sockaddr_un
**to_un
,
3608 const struct sockaddr
**to
,
3626 if (!si
->connected
) {
3631 if (msg
->msg_iovlen
== 0) {
3635 for (i
= 0; i
< (size_t)msg
->msg_iovlen
; i
++) {
3637 nlen
= len
+ msg
->msg_iov
[i
].iov_len
;
3638 if (nlen
> SOCKET_MAX_PACKET
) {
3642 msg
->msg_iovlen
= i
;
3643 if (msg
->msg_iovlen
== 0) {
3644 *tmp_iov
= msg
->msg_iov
[0];
3645 tmp_iov
->iov_len
= MIN(tmp_iov
->iov_len
, SOCKET_MAX_PACKET
);
3646 msg
->msg_iov
= tmp_iov
;
3647 msg
->msg_iovlen
= 1;
3652 if (si
->connected
) {
3653 if (msg
->msg_name
) {
3658 const struct sockaddr
*msg_name
;
3659 msg_name
= (const struct sockaddr
*)msg
->msg_name
;
3661 if (msg_name
== NULL
) {
3667 ret
= sockaddr_convert_to_un(si
, msg_name
, msg
->msg_namelen
,
3669 if (ret
== -1) return -1;
3677 msg
->msg_name
= tmp_un
;
3678 msg
->msg_namelen
= sizeof(*tmp_un
);
3681 if (si
->bound
== 0) {
3682 ret
= swrap_auto_bind(fd
, si
, si
->family
);
3684 if (errno
== ENOTSOCK
) {
3685 swrap_remove_stale(fd
);
3688 SWRAP_LOG(SWRAP_LOG_ERROR
, "swrap_sendmsg_before failed");
3694 if (!si
->defer_connect
) {
3698 ret
= sockaddr_convert_to_un(si
, si
->peername
, si
->peername_len
,
3700 if (ret
== -1) return -1;
3702 ret
= libc_connect(fd
,
3703 (struct sockaddr
*)(void *)tmp_un
,
3706 /* to give better errors */
3707 if (ret
== -1 && errno
== ENOENT
) {
3708 errno
= EHOSTUNREACH
;
3715 si
->defer_connect
= 0;
3718 errno
= EHOSTUNREACH
;
3722 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3723 if (msg
->msg_controllen
> 0 && msg
->msg_control
!= NULL
) {
3724 uint8_t *cmbuf
= NULL
;
3727 ret
= swrap_sendmsg_filter_cmsghdr(msg
, &cmbuf
, &cmlen
);
3734 msg
->msg_controllen
= 0;
3735 msg
->msg_control
= NULL
;
3736 } else if (cmlen
< msg
->msg_controllen
&& cmbuf
!= NULL
) {
3737 memcpy(msg
->msg_control
, cmbuf
, cmlen
);
3738 msg
->msg_controllen
= cmlen
;
3747 static void swrap_sendmsg_after(int fd
,
3748 struct socket_info
*si
,
3750 const struct sockaddr
*to
,
3753 int saved_errno
= errno
;
3760 /* to give better errors */
3762 if (saved_errno
== ENOENT
) {
3763 saved_errno
= EHOSTUNREACH
;
3764 } else if (saved_errno
== ENOTSOCK
) {
3765 /* If the fd is not a socket, remove it */
3766 swrap_remove_stale(fd
);
3770 for (i
= 0; i
< (size_t)msg
->msg_iovlen
; i
++) {
3771 avail
+= msg
->msg_iov
[i
].iov_len
;
3775 remain
= MIN(80, avail
);
3780 /* we capture it as one single packet */
3781 buf
= (uint8_t *)malloc(remain
);
3783 /* we just not capture the packet */
3784 errno
= saved_errno
;
3788 for (i
= 0; i
< (size_t)msg
->msg_iovlen
; i
++) {
3789 size_t this_time
= MIN(remain
, (size_t)msg
->msg_iov
[i
].iov_len
);
3791 msg
->msg_iov
[i
].iov_base
,
3794 remain
-= this_time
;
3801 swrap_dump_packet(si
, NULL
, SWRAP_SEND
, buf
, len
);
3802 swrap_dump_packet(si
, NULL
, SWRAP_SEND_RST
, NULL
, 0);
3804 swrap_dump_packet(si
, NULL
, SWRAP_SEND
, buf
, len
);
3809 if (si
->connected
) {
3813 swrap_dump_packet(si
, to
, SWRAP_SENDTO
, buf
, len
);
3814 swrap_dump_packet(si
, to
, SWRAP_SENDTO_UNREACH
, buf
, len
);
3816 swrap_dump_packet(si
, to
, SWRAP_SENDTO
, buf
, len
);
3822 errno
= saved_errno
;
3825 static int swrap_recvmsg_before(int fd
,
3826 struct socket_info
*si
,
3828 struct iovec
*tmp_iov
)
3833 (void)fd
; /* unused */
3837 if (!si
->connected
) {
3842 if (msg
->msg_iovlen
== 0) {
3846 for (i
= 0; i
< (size_t)msg
->msg_iovlen
; i
++) {
3848 nlen
= len
+ msg
->msg_iov
[i
].iov_len
;
3849 if (nlen
> SOCKET_MAX_PACKET
) {
3853 msg
->msg_iovlen
= i
;
3854 if (msg
->msg_iovlen
== 0) {
3855 *tmp_iov
= msg
->msg_iov
[0];
3856 tmp_iov
->iov_len
= MIN(tmp_iov
->iov_len
, SOCKET_MAX_PACKET
);
3857 msg
->msg_iov
= tmp_iov
;
3858 msg
->msg_iovlen
= 1;
3863 if (msg
->msg_name
== NULL
) {
3868 if (msg
->msg_iovlen
== 0) {
3872 if (si
->bound
== 0) {
3873 ret
= swrap_auto_bind(fd
, si
, si
->family
);
3876 * When attempting to read or write to a
3877 * descriptor, if an underlying autobind fails
3878 * because it's not a socket, stop intercepting
3879 * uses of that descriptor.
3881 if (errno
== ENOTSOCK
) {
3882 swrap_remove_stale(fd
);
3885 SWRAP_LOG(SWRAP_LOG_ERROR
,
3886 "swrap_recvmsg_before failed");
3893 errno
= EHOSTUNREACH
;
3900 static int swrap_recvmsg_after(int fd
,
3901 struct socket_info
*si
,
3903 const struct sockaddr_un
*un_addr
,
3904 socklen_t un_addrlen
,
3907 int saved_errno
= errno
;
3909 uint8_t *buf
= NULL
;
3915 /* to give better errors */
3917 if (saved_errno
== ENOENT
) {
3918 saved_errno
= EHOSTUNREACH
;
3919 } else if (saved_errno
== ENOTSOCK
) {
3920 /* If the fd is not a socket, remove it */
3921 swrap_remove_stale(fd
);
3925 for (i
= 0; i
< (size_t)msg
->msg_iovlen
; i
++) {
3926 avail
+= msg
->msg_iov
[i
].iov_len
;
3935 remain
= MIN(80, avail
);
3940 /* we capture it as one single packet */
3941 buf
= (uint8_t *)malloc(remain
);
3943 /* we just not capture the packet */
3944 errno
= saved_errno
;
3948 for (i
= 0; i
< (size_t)msg
->msg_iovlen
; i
++) {
3949 size_t this_time
= MIN(remain
, (size_t)msg
->msg_iov
[i
].iov_len
);
3951 msg
->msg_iov
[i
].iov_base
,
3954 remain
-= this_time
;
3959 if (ret
== -1 && saved_errno
!= EAGAIN
&& saved_errno
!= ENOBUFS
) {
3960 swrap_dump_packet(si
, NULL
, SWRAP_RECV_RST
, NULL
, 0);
3961 } else if (ret
== 0) { /* END OF FILE */
3962 swrap_dump_packet(si
, NULL
, SWRAP_RECV_RST
, NULL
, 0);
3963 } else if (ret
> 0) {
3964 swrap_dump_packet(si
, NULL
, SWRAP_RECV
, buf
, ret
);
3973 if (un_addr
!= NULL
) {
3974 rc
= sockaddr_convert_from_un(si
,
3984 swrap_dump_packet(si
,
3990 swrap_dump_packet(si
,
4003 errno
= saved_errno
;
4005 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4007 msg
->msg_controllen
> 0 &&
4008 msg
->msg_control
!= NULL
) {
4009 rc
= swrap_msghdr_add_socket_info(si
, msg
);
4019 /****************************************************************************
4021 ***************************************************************************/
4023 static ssize_t
swrap_recvfrom(int s
, void *buf
, size_t len
, int flags
,
4024 struct sockaddr
*from
, socklen_t
*fromlen
)
4026 struct sockaddr_un from_addr
;
4027 socklen_t from_addrlen
= sizeof(from_addr
);
4029 struct socket_info
*si
= find_socket_info(s
);
4030 struct sockaddr_storage ss
;
4031 socklen_t ss_len
= sizeof(ss
);
4037 return libc_recvfrom(s
,
4049 if (from
!= NULL
&& fromlen
!= NULL
) {
4050 msg
.msg_name
= from
; /* optional address */
4051 msg
.msg_namelen
= *fromlen
; /* size of address */
4053 msg
.msg_name
= (struct sockaddr
*)(void *)&ss
; /* optional address */
4054 msg
.msg_namelen
= ss_len
; /* size of address */
4056 msg
.msg_iov
= &tmp
; /* scatter/gather array */
4057 msg
.msg_iovlen
= 1; /* # elements in msg_iov */
4058 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4059 msg
.msg_control
= NULL
; /* ancillary data, see below */
4060 msg
.msg_controllen
= 0; /* ancillary data buffer len */
4061 msg
.msg_flags
= 0; /* flags on received message */
4064 tret
= swrap_recvmsg_before(s
, si
, &msg
, &tmp
);
4069 buf
= msg
.msg_iov
[0].iov_base
;
4070 len
= msg
.msg_iov
[0].iov_len
;
4072 /* irix 6.4 forgets to null terminate the sun_path string :-( */
4073 memset(&from_addr
, 0, sizeof(from_addr
));
4074 ret
= libc_recvfrom(s
,
4078 (struct sockaddr
*)(void *)&from_addr
,
4084 tret
= swrap_recvmsg_after(s
,
4094 if (from
!= NULL
&& fromlen
!= NULL
) {
4095 *fromlen
= msg
.msg_namelen
;
4101 #ifdef HAVE_ACCEPT_PSOCKLEN_T
4102 ssize_t
recvfrom(int s
, void *buf
, size_t len
, int flags
,
4103 struct sockaddr
*from
, Psocklen_t fromlen
)
4105 ssize_t
recvfrom(int s
, void *buf
, size_t len
, int flags
,
4106 struct sockaddr
*from
, socklen_t
*fromlen
)
4109 return swrap_recvfrom(s
, buf
, len
, flags
, from
, (socklen_t
*)fromlen
);
4112 /****************************************************************************
4114 ***************************************************************************/
4116 static ssize_t
swrap_sendto(int s
, const void *buf
, size_t len
, int flags
,
4117 const struct sockaddr
*to
, socklen_t tolen
)
4121 struct sockaddr_un un_addr
;
4122 const struct sockaddr_un
*to_un
= NULL
;
4125 struct socket_info
*si
= find_socket_info(s
);
4129 return libc_sendto(s
, buf
, len
, flags
, to
, tolen
);
4132 tmp
.iov_base
= discard_const_p(char, buf
);
4136 msg
.msg_name
= discard_const_p(struct sockaddr
, to
); /* optional address */
4137 msg
.msg_namelen
= tolen
; /* size of address */
4138 msg
.msg_iov
= &tmp
; /* scatter/gather array */
4139 msg
.msg_iovlen
= 1; /* # elements in msg_iov */
4140 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
4141 msg
.msg_control
= NULL
; /* ancillary data, see below */
4142 msg
.msg_controllen
= 0; /* ancillary data buffer len */
4143 msg
.msg_flags
= 0; /* flags on received message */
4146 rc
= swrap_sendmsg_before(s
, si
, &msg
, &tmp
, &un_addr
, &to_un
, &to
, &bcast
);
4151 buf
= msg
.msg_iov
[0].iov_base
;
4152 len
= msg
.msg_iov
[0].iov_len
;
4157 unsigned int prt
= ntohs(((const struct sockaddr_in
*)to
)->sin_port
);
4160 type
= SOCKET_TYPE_CHAR_UDP
;
4162 for(iface
=0; iface
<= MAX_WRAPPED_INTERFACES
; iface
++) {
4163 snprintf(un_addr
.sun_path
, sizeof(un_addr
.sun_path
), "%s/"SOCKET_FORMAT
,
4164 socket_wrapper_dir(), type
, iface
, prt
);
4165 if (stat(un_addr
.sun_path
, &st
) != 0) continue;
4167 /* ignore the any errors in broadcast sends */
4172 (struct sockaddr
*)(void *)&un_addr
,
4176 swrap_dump_packet(si
, to
, SWRAP_SENDTO
, buf
, len
);
4181 ret
= libc_sendto(s
,
4185 (struct sockaddr
*)msg
.msg_name
,
4188 swrap_sendmsg_after(s
, si
, &msg
, to
, ret
);
4193 ssize_t
sendto(int s
, const void *buf
, size_t len
, int flags
,
4194 const struct sockaddr
*to
, socklen_t tolen
)
4196 return swrap_sendto(s
, buf
, len
, flags
, to
, tolen
);
4199 /****************************************************************************
4201 ***************************************************************************/
4203 static ssize_t
swrap_recv(int s
, void *buf
, size_t len
, int flags
)
4205 struct socket_info
*si
;
4207 struct sockaddr_storage ss
;
4208 socklen_t ss_len
= sizeof(ss
);
4213 si
= find_socket_info(s
);
4215 return libc_recv(s
, buf
, len
, flags
);
4222 msg
.msg_name
= (struct sockaddr
*)(void *)&ss
; /* optional address */
4223 msg
.msg_namelen
= ss_len
; /* size of address */
4224 msg
.msg_iov
= &tmp
; /* scatter/gather array */
4225 msg
.msg_iovlen
= 1; /* # elements in msg_iov */
4226 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4227 msg
.msg_control
= NULL
; /* ancillary data, see below */
4228 msg
.msg_controllen
= 0; /* ancillary data buffer len */
4229 msg
.msg_flags
= 0; /* flags on received message */
4232 tret
= swrap_recvmsg_before(s
, si
, &msg
, &tmp
);
4237 buf
= msg
.msg_iov
[0].iov_base
;
4238 len
= msg
.msg_iov
[0].iov_len
;
4240 ret
= libc_recv(s
, buf
, len
, flags
);
4242 tret
= swrap_recvmsg_after(s
, si
, &msg
, NULL
, 0, ret
);
4250 ssize_t
recv(int s
, void *buf
, size_t len
, int flags
)
4252 return swrap_recv(s
, buf
, len
, flags
);
4255 /****************************************************************************
4257 ***************************************************************************/
4259 static ssize_t
swrap_read(int s
, void *buf
, size_t len
)
4261 struct socket_info
*si
;
4264 struct sockaddr_storage ss
;
4265 socklen_t ss_len
= sizeof(ss
);
4269 si
= find_socket_info(s
);
4271 return libc_read(s
, buf
, len
);
4278 msg
.msg_name
= (struct sockaddr
*)(void *)&ss
; /* optional address */
4279 msg
.msg_namelen
= ss_len
; /* size of address */
4280 msg
.msg_iov
= &tmp
; /* scatter/gather array */
4281 msg
.msg_iovlen
= 1; /* # elements in msg_iov */
4282 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4283 msg
.msg_control
= NULL
; /* ancillary data, see below */
4284 msg
.msg_controllen
= 0; /* ancillary data buffer len */
4285 msg
.msg_flags
= 0; /* flags on received message */
4288 tret
= swrap_recvmsg_before(s
, si
, &msg
, &tmp
);
4290 if (tret
== -ENOTSOCK
) {
4291 return libc_read(s
, buf
, len
);
4296 buf
= msg
.msg_iov
[0].iov_base
;
4297 len
= msg
.msg_iov
[0].iov_len
;
4299 ret
= libc_read(s
, buf
, len
);
4301 tret
= swrap_recvmsg_after(s
, si
, &msg
, NULL
, 0, ret
);
4309 ssize_t
read(int s
, void *buf
, size_t len
)
4311 return swrap_read(s
, buf
, len
);
4314 /****************************************************************************
4316 ***************************************************************************/
4318 static ssize_t
swrap_send(int s
, const void *buf
, size_t len
, int flags
)
4322 struct sockaddr_un un_addr
;
4325 struct socket_info
*si
= find_socket_info(s
);
4328 return libc_send(s
, buf
, len
, flags
);
4331 tmp
.iov_base
= discard_const_p(char, buf
);
4335 msg
.msg_name
= NULL
; /* optional address */
4336 msg
.msg_namelen
= 0; /* size of address */
4337 msg
.msg_iov
= &tmp
; /* scatter/gather array */
4338 msg
.msg_iovlen
= 1; /* # elements in msg_iov */
4339 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
4340 msg
.msg_control
= NULL
; /* ancillary data, see below */
4341 msg
.msg_controllen
= 0; /* ancillary data buffer len */
4342 msg
.msg_flags
= 0; /* flags on received message */
4345 rc
= swrap_sendmsg_before(s
, si
, &msg
, &tmp
, &un_addr
, NULL
, NULL
, NULL
);
4350 buf
= msg
.msg_iov
[0].iov_base
;
4351 len
= msg
.msg_iov
[0].iov_len
;
4353 ret
= libc_send(s
, buf
, len
, flags
);
4355 swrap_sendmsg_after(s
, si
, &msg
, NULL
, ret
);
4360 ssize_t
send(int s
, const void *buf
, size_t len
, int flags
)
4362 return swrap_send(s
, buf
, len
, flags
);
4365 /****************************************************************************
4367 ***************************************************************************/
4369 static ssize_t
swrap_recvmsg(int s
, struct msghdr
*omsg
, int flags
)
4371 struct sockaddr_un from_addr
;
4372 socklen_t from_addrlen
= sizeof(from_addr
);
4373 struct socket_info
*si
;
4376 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4377 size_t msg_ctrllen_filled
;
4378 size_t msg_ctrllen_left
;
4384 si
= find_socket_info(s
);
4386 return libc_recvmsg(s
, omsg
, flags
);
4389 tmp
.iov_base
= NULL
;
4393 msg
.msg_name
= (struct sockaddr
*)&from_addr
; /* optional address */
4394 msg
.msg_namelen
= from_addrlen
; /* size of address */
4395 msg
.msg_iov
= omsg
->msg_iov
; /* scatter/gather array */
4396 msg
.msg_iovlen
= omsg
->msg_iovlen
; /* # elements in msg_iov */
4397 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4398 msg_ctrllen_filled
= 0;
4399 msg_ctrllen_left
= omsg
->msg_controllen
;
4401 msg
.msg_control
= omsg
->msg_control
; /* ancillary data, see below */
4402 msg
.msg_controllen
= omsg
->msg_controllen
; /* ancillary data buffer len */
4403 msg
.msg_flags
= omsg
->msg_flags
; /* flags on received message */
4406 rc
= swrap_recvmsg_before(s
, si
, &msg
, &tmp
);
4411 ret
= libc_recvmsg(s
, &msg
, flags
);
4413 msg
.msg_name
= omsg
->msg_name
;
4414 msg
.msg_namelen
= omsg
->msg_namelen
;
4416 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4417 msg_ctrllen_filled
+= msg
.msg_controllen
;
4418 msg_ctrllen_left
-= msg
.msg_controllen
;
4420 if (omsg
->msg_control
!= NULL
) {
4423 p
= omsg
->msg_control
;
4424 p
+= msg_ctrllen_filled
;
4426 msg
.msg_control
= p
;
4427 msg
.msg_controllen
= msg_ctrllen_left
;
4429 msg
.msg_control
= NULL
;
4430 msg
.msg_controllen
= 0;
4434 rc
= swrap_recvmsg_after(s
, si
, &msg
, &from_addr
, from_addrlen
, ret
);
4439 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4440 if (omsg
->msg_control
!= NULL
) {
4441 /* msg.msg_controllen = space left */
4442 msg_ctrllen_left
= msg
.msg_controllen
;
4443 msg_ctrllen_filled
= omsg
->msg_controllen
- msg_ctrllen_left
;
4446 /* Update the original message length */
4447 omsg
->msg_controllen
= msg_ctrllen_filled
;
4448 omsg
->msg_flags
= msg
.msg_flags
;
4450 omsg
->msg_iovlen
= msg
.msg_iovlen
;
4455 ssize_t
recvmsg(int sockfd
, struct msghdr
*msg
, int flags
)
4457 return swrap_recvmsg(sockfd
, msg
, flags
);
4460 /****************************************************************************
4462 ***************************************************************************/
4464 static ssize_t
swrap_sendmsg(int s
, const struct msghdr
*omsg
, int flags
)
4468 struct sockaddr_un un_addr
;
4469 const struct sockaddr_un
*to_un
= NULL
;
4470 const struct sockaddr
*to
= NULL
;
4473 struct socket_info
*si
= find_socket_info(s
);
4477 return libc_sendmsg(s
, omsg
, flags
);
4480 ZERO_STRUCT(un_addr
);
4482 tmp
.iov_base
= NULL
;
4486 msg
.msg_name
= omsg
->msg_name
; /* optional address */
4487 msg
.msg_namelen
= omsg
->msg_namelen
; /* size of address */
4488 msg
.msg_iov
= omsg
->msg_iov
; /* scatter/gather array */
4489 msg
.msg_iovlen
= omsg
->msg_iovlen
; /* # elements in msg_iov */
4490 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4491 if (msg
.msg_controllen
> 0 && msg
.msg_control
!= NULL
) {
4492 /* omsg is a const so use a local buffer for modifications */
4493 uint8_t cmbuf
[omsg
->msg_controllen
];
4495 memcpy(cmbuf
, omsg
->msg_control
, omsg
->msg_controllen
);
4497 msg
.msg_control
= cmbuf
; /* ancillary data, see below */
4498 msg
.msg_controllen
= omsg
->msg_controllen
; /* ancillary data buffer len */
4500 msg
.msg_flags
= omsg
->msg_flags
; /* flags on received message */
4503 rc
= swrap_sendmsg_before(s
, si
, &msg
, &tmp
, &un_addr
, &to_un
, &to
, &bcast
);
4511 unsigned int prt
= ntohs(((const struct sockaddr_in
*)to
)->sin_port
);
4519 for (i
= 0; i
< (size_t)msg
.msg_iovlen
; i
++) {
4520 avail
+= msg
.msg_iov
[i
].iov_len
;
4526 /* we capture it as one single packet */
4527 buf
= (uint8_t *)malloc(remain
);
4532 for (i
= 0; i
< (size_t)msg
.msg_iovlen
; i
++) {
4533 size_t this_time
= MIN(remain
, (size_t)msg
.msg_iov
[i
].iov_len
);
4535 msg
.msg_iov
[i
].iov_base
,
4538 remain
-= this_time
;
4541 type
= SOCKET_TYPE_CHAR_UDP
;
4543 for(iface
=0; iface
<= MAX_WRAPPED_INTERFACES
; iface
++) {
4544 snprintf(un_addr
.sun_path
, sizeof(un_addr
.sun_path
), "%s/"SOCKET_FORMAT
,
4545 socket_wrapper_dir(), type
, iface
, prt
);
4546 if (stat(un_addr
.sun_path
, &st
) != 0) continue;
4548 msg
.msg_name
= &un_addr
; /* optional address */
4549 msg
.msg_namelen
= sizeof(un_addr
); /* size of address */
4551 /* ignore the any errors in broadcast sends */
4552 libc_sendmsg(s
, &msg
, flags
);
4555 swrap_dump_packet(si
, to
, SWRAP_SENDTO
, buf
, len
);
4561 ret
= libc_sendmsg(s
, &msg
, flags
);
4563 swrap_sendmsg_after(s
, si
, &msg
, to
, ret
);
4568 ssize_t
sendmsg(int s
, const struct msghdr
*omsg
, int flags
)
4570 return swrap_sendmsg(s
, omsg
, flags
);
4573 /****************************************************************************
4575 ***************************************************************************/
4577 static ssize_t
swrap_readv(int s
, const struct iovec
*vector
, int count
)
4579 struct socket_info
*si
;
4582 struct sockaddr_storage ss
;
4583 socklen_t ss_len
= sizeof(ss
);
4587 si
= find_socket_info(s
);
4589 return libc_readv(s
, vector
, count
);
4592 tmp
.iov_base
= NULL
;
4596 msg
.msg_name
= (struct sockaddr
*)(void *)&ss
; /* optional address */
4597 msg
.msg_namelen
= ss_len
; /* size of address */
4598 msg
.msg_iov
= discard_const_p(struct iovec
, vector
); /* scatter/gather array */
4599 msg
.msg_iovlen
= count
; /* # elements in msg_iov */
4600 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4601 msg
.msg_control
= NULL
; /* ancillary data, see below */
4602 msg
.msg_controllen
= 0; /* ancillary data buffer len */
4603 msg
.msg_flags
= 0; /* flags on received message */
4606 rc
= swrap_recvmsg_before(s
, si
, &msg
, &tmp
);
4608 if (rc
== -ENOTSOCK
) {
4609 return libc_readv(s
, vector
, count
);
4614 ret
= libc_readv(s
, msg
.msg_iov
, msg
.msg_iovlen
);
4616 rc
= swrap_recvmsg_after(s
, si
, &msg
, NULL
, 0, ret
);
4624 ssize_t
readv(int s
, const struct iovec
*vector
, int count
)
4626 return swrap_readv(s
, vector
, count
);
4629 /****************************************************************************
4631 ***************************************************************************/
4633 static ssize_t
swrap_writev(int s
, const struct iovec
*vector
, int count
)
4637 struct sockaddr_un un_addr
;
4640 struct socket_info
*si
= find_socket_info(s
);
4643 return libc_writev(s
, vector
, count
);
4646 tmp
.iov_base
= NULL
;
4650 msg
.msg_name
= NULL
; /* optional address */
4651 msg
.msg_namelen
= 0; /* size of address */
4652 msg
.msg_iov
= discard_const_p(struct iovec
, vector
); /* scatter/gather array */
4653 msg
.msg_iovlen
= count
; /* # elements in msg_iov */
4654 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
4655 msg
.msg_control
= NULL
; /* ancillary data, see below */
4656 msg
.msg_controllen
= 0; /* ancillary data buffer len */
4657 msg
.msg_flags
= 0; /* flags on received message */
4660 rc
= swrap_sendmsg_before(s
, si
, &msg
, &tmp
, &un_addr
, NULL
, NULL
, NULL
);
4662 if (rc
== -ENOTSOCK
) {
4663 return libc_readv(s
, vector
, count
);
4668 ret
= libc_writev(s
, msg
.msg_iov
, msg
.msg_iovlen
);
4670 swrap_sendmsg_after(s
, si
, &msg
, NULL
, ret
);
4675 ssize_t
writev(int s
, const struct iovec
*vector
, int count
)
4677 return swrap_writev(s
, vector
, count
);
4680 /****************************
4682 ***************************/
4684 static int swrap_close(int fd
)
4686 struct socket_info
*si
= find_socket_info(fd
);
4687 struct socket_info_fd
*fi
;
4691 return libc_close(fd
);
4694 for (fi
= si
->fds
; fi
; fi
= fi
->next
) {
4696 SWRAP_DLIST_REMOVE(si
->fds
, fi
);
4703 /* there are still references left */
4704 return libc_close(fd
);
4707 SWRAP_DLIST_REMOVE(sockets
, si
);
4709 if (si
->myname
&& si
->peername
) {
4710 swrap_dump_packet(si
, NULL
, SWRAP_CLOSE_SEND
, NULL
, 0);
4713 ret
= libc_close(fd
);
4715 if (si
->myname
&& si
->peername
) {
4716 swrap_dump_packet(si
, NULL
, SWRAP_CLOSE_RECV
, NULL
, 0);
4717 swrap_dump_packet(si
, NULL
, SWRAP_CLOSE_ACK
, NULL
, 0);
4720 if (si
->bindname
!= NULL
) {
4724 if (si
->myname
) free(si
->myname
);
4725 if (si
->peername
) free(si
->peername
);
4727 unlink(si
->tmp_path
);
4737 return swrap_close(fd
);
4740 /****************************
4742 ***************************/
4744 static int swrap_dup(int fd
)
4746 struct socket_info
*si
;
4747 struct socket_info_fd
*fi
;
4749 si
= find_socket_info(fd
);
4752 return libc_dup(fd
);
4755 fi
= (struct socket_info_fd
*)calloc(1, sizeof(struct socket_info_fd
));
4761 fi
->fd
= libc_dup(fd
);
4763 int saved_errno
= errno
;
4765 errno
= saved_errno
;
4769 /* Make sure we don't have an entry for the fd */
4770 swrap_remove_stale(fi
->fd
);
4772 SWRAP_DLIST_ADD(si
->fds
, fi
);
4778 return swrap_dup(fd
);
4781 /****************************
4783 ***************************/
4785 static int swrap_dup2(int fd
, int newfd
)
4787 struct socket_info
*si
;
4788 struct socket_info_fd
*fi
;
4790 si
= find_socket_info(fd
);
4793 return libc_dup2(fd
, newfd
);
4796 if (find_socket_info(newfd
)) {
4797 /* dup2() does an implicit close of newfd, which we
4798 * need to emulate */
4802 fi
= (struct socket_info_fd
*)calloc(1, sizeof(struct socket_info_fd
));
4808 fi
->fd
= libc_dup2(fd
, newfd
);
4810 int saved_errno
= errno
;
4812 errno
= saved_errno
;
4816 /* Make sure we don't have an entry for the fd */
4817 swrap_remove_stale(fi
->fd
);
4819 SWRAP_DLIST_ADD(si
->fds
, fi
);
4823 int dup2(int fd
, int newfd
)
4825 return swrap_dup2(fd
, newfd
);
4828 /****************************
4830 ***************************/
4833 static int swrap_eventfd(int count
, int flags
)
4837 fd
= libc_eventfd(count
, flags
);
4839 swrap_remove_stale(fd
);
4845 int eventfd(int count
, int flags
)
4847 return swrap_eventfd(count
, flags
);
4851 /****************************
4853 ***************************/
4856 * This function is called when the library is unloaded and makes sure that
4857 * sockets get closed and the unix file for the socket are unlinked.
4859 void swrap_destructor(void)
4861 struct socket_info
*s
= sockets
;
4864 struct socket_info_fd
*f
= s
->fds
;