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) && (defined(HAVE_STRUCT_IN_PKTINFO) || defined(IP_RECVDSTADDR))
3412 struct sockaddr_in
*sin
;
3413 #if defined(HAVE_STRUCT_IN_PKTINFO)
3414 struct in_pktinfo pkt
;
3415 #elif defined(IP_RECVDSTADDR)
3419 if (si
->bindname_len
== sizeof(struct sockaddr_in
)) {
3420 sin
= (struct sockaddr_in
*)si
->bindname
;
3422 if (si
->myname_len
!= sizeof(struct sockaddr_in
)) {
3425 sin
= (struct sockaddr_in
*)si
->myname
;
3430 #if defined(HAVE_STRUCT_IN_PKTINFO)
3431 pkt
.ipi_ifindex
= socket_wrapper_default_iface();
3432 pkt
.ipi_addr
.s_addr
= sin
->sin_addr
.s_addr
;
3433 #elif defined(IP_RECVDSTADDR)
3434 pkt
= sin
->sin_addr
;
3437 swrap_msghdr_add_cmsghdr(msg
, IPPROTO_IP
, IP_PKTINFO
,
3442 #endif /* IP_PKTINFO */
3443 #if defined(HAVE_IPV6)
3445 #if defined(IPV6_PKTINFO) && defined(HAVE_STRUCT_IN6_PKTINFO)
3446 struct sockaddr_in6
*sin6
;
3447 struct in6_pktinfo pkt6
;
3449 if (si
->bindname_len
== sizeof(struct sockaddr_in6
)) {
3450 sin6
= (struct sockaddr_in6
*)si
->bindname
;
3452 if (si
->myname_len
!= sizeof(struct sockaddr_in6
)) {
3455 sin6
= (struct sockaddr_in6
*)si
->myname
;
3460 pkt6
.ipi6_ifindex
= socket_wrapper_default_iface();
3461 pkt6
.ipi6_addr
= sin6
->sin6_addr
;
3463 swrap_msghdr_add_cmsghdr(msg
, IPPROTO_IPV6
, IPV6_PKTINFO
,
3464 &pkt6
, sizeof(pkt6
));
3465 #endif /* HAVE_STRUCT_IN6_PKTINFO */
3469 #endif /* IPV6_PKTINFO */
3477 static int swrap_msghdr_add_socket_info(struct socket_info
*si
,
3478 struct msghdr
*omsg
)
3482 if (si
->pktinfo
> 0) {
3483 rc
= swrap_msghdr_add_pktinfo(si
, omsg
);
3489 static int swrap_sendmsg_copy_cmsg(struct cmsghdr
*cmsg
,
3491 size_t *cm_data_space
);
3492 static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr
*cmsg
,
3494 size_t *cm_data_space
);
3496 static int swrap_sendmsg_filter_cmsghdr(struct msghdr
*msg
,
3498 size_t *cm_data_space
) {
3499 struct cmsghdr
*cmsg
;
3503 if (msg
->msg_controllen
== 0 || msg
->msg_control
== NULL
) {
3507 for (cmsg
= CMSG_FIRSTHDR(msg
);
3509 cmsg
= CMSG_NXTHDR(msg
, cmsg
)) {
3510 switch (cmsg
->cmsg_level
) {
3512 rc
= swrap_sendmsg_filter_cmsg_socket(cmsg
,
3517 rc
= swrap_sendmsg_copy_cmsg(cmsg
,
3527 static int swrap_sendmsg_copy_cmsg(struct cmsghdr
*cmsg
,
3529 size_t *cm_data_space
)
3536 CMSG_SPACE(cmsg
->cmsg_len
- CMSG_ALIGN(sizeof(struct cmsghdr
)));
3538 p
= realloc((*cm_data
), cmspace
);
3544 p
= (*cm_data
) + (*cm_data_space
);
3545 *cm_data_space
= cmspace
;
3547 memcpy(p
, cmsg
, cmsg
->cmsg_len
);
3552 static int swrap_sendmsg_filter_cmsg_pktinfo(struct cmsghdr
*cmsg
,
3554 size_t *cm_data_space
);
3557 static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr
*cmsg
,
3559 size_t *cm_data_space
)
3563 switch(cmsg
->cmsg_type
) {
3566 rc
= swrap_sendmsg_filter_cmsg_pktinfo(cmsg
,
3573 rc
= swrap_sendmsg_filter_cmsg_pktinfo(cmsg
,
3585 static int swrap_sendmsg_filter_cmsg_pktinfo(struct cmsghdr
*cmsg
,
3587 size_t *cm_data_space
)
3589 (void)cmsg
; /* unused */
3590 (void)cm_data
; /* unused */
3591 (void)cm_data_space
; /* unused */
3594 * Passing a IP pktinfo to a unix socket might be rejected by the
3595 * Kernel, at least on FreeBSD. So skip this cmsg.
3599 #endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
3601 static ssize_t
swrap_sendmsg_before(int fd
,
3602 struct socket_info
*si
,
3604 struct iovec
*tmp_iov
,
3605 struct sockaddr_un
*tmp_un
,
3606 const struct sockaddr_un
**to_un
,
3607 const struct sockaddr
**to
,
3625 if (!si
->connected
) {
3630 if (msg
->msg_iovlen
== 0) {
3634 for (i
= 0; i
< (size_t)msg
->msg_iovlen
; i
++) {
3636 nlen
= len
+ msg
->msg_iov
[i
].iov_len
;
3637 if (nlen
> SOCKET_MAX_PACKET
) {
3641 msg
->msg_iovlen
= i
;
3642 if (msg
->msg_iovlen
== 0) {
3643 *tmp_iov
= msg
->msg_iov
[0];
3644 tmp_iov
->iov_len
= MIN(tmp_iov
->iov_len
, SOCKET_MAX_PACKET
);
3645 msg
->msg_iov
= tmp_iov
;
3646 msg
->msg_iovlen
= 1;
3651 if (si
->connected
) {
3652 if (msg
->msg_name
) {
3657 const struct sockaddr
*msg_name
;
3658 msg_name
= (const struct sockaddr
*)msg
->msg_name
;
3660 if (msg_name
== NULL
) {
3666 ret
= sockaddr_convert_to_un(si
, msg_name
, msg
->msg_namelen
,
3668 if (ret
== -1) return -1;
3676 msg
->msg_name
= tmp_un
;
3677 msg
->msg_namelen
= sizeof(*tmp_un
);
3680 if (si
->bound
== 0) {
3681 ret
= swrap_auto_bind(fd
, si
, si
->family
);
3683 if (errno
== ENOTSOCK
) {
3684 swrap_remove_stale(fd
);
3687 SWRAP_LOG(SWRAP_LOG_ERROR
, "swrap_sendmsg_before failed");
3693 if (!si
->defer_connect
) {
3697 ret
= sockaddr_convert_to_un(si
, si
->peername
, si
->peername_len
,
3699 if (ret
== -1) return -1;
3701 ret
= libc_connect(fd
,
3702 (struct sockaddr
*)(void *)tmp_un
,
3705 /* to give better errors */
3706 if (ret
== -1 && errno
== ENOENT
) {
3707 errno
= EHOSTUNREACH
;
3714 si
->defer_connect
= 0;
3717 errno
= EHOSTUNREACH
;
3721 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3722 if (msg
->msg_controllen
> 0 && msg
->msg_control
!= NULL
) {
3723 uint8_t *cmbuf
= NULL
;
3726 ret
= swrap_sendmsg_filter_cmsghdr(msg
, &cmbuf
, &cmlen
);
3733 msg
->msg_controllen
= 0;
3734 msg
->msg_control
= NULL
;
3735 } else if (cmlen
< msg
->msg_controllen
&& cmbuf
!= NULL
) {
3736 memcpy(msg
->msg_control
, cmbuf
, cmlen
);
3737 msg
->msg_controllen
= cmlen
;
3746 static void swrap_sendmsg_after(int fd
,
3747 struct socket_info
*si
,
3749 const struct sockaddr
*to
,
3752 int saved_errno
= errno
;
3759 /* to give better errors */
3761 if (saved_errno
== ENOENT
) {
3762 saved_errno
= EHOSTUNREACH
;
3763 } else if (saved_errno
== ENOTSOCK
) {
3764 /* If the fd is not a socket, remove it */
3765 swrap_remove_stale(fd
);
3769 for (i
= 0; i
< (size_t)msg
->msg_iovlen
; i
++) {
3770 avail
+= msg
->msg_iov
[i
].iov_len
;
3774 remain
= MIN(80, avail
);
3779 /* we capture it as one single packet */
3780 buf
= (uint8_t *)malloc(remain
);
3782 /* we just not capture the packet */
3783 errno
= saved_errno
;
3787 for (i
= 0; i
< (size_t)msg
->msg_iovlen
; i
++) {
3788 size_t this_time
= MIN(remain
, (size_t)msg
->msg_iov
[i
].iov_len
);
3790 msg
->msg_iov
[i
].iov_base
,
3793 remain
-= this_time
;
3800 swrap_dump_packet(si
, NULL
, SWRAP_SEND
, buf
, len
);
3801 swrap_dump_packet(si
, NULL
, SWRAP_SEND_RST
, NULL
, 0);
3803 swrap_dump_packet(si
, NULL
, SWRAP_SEND
, buf
, len
);
3808 if (si
->connected
) {
3812 swrap_dump_packet(si
, to
, SWRAP_SENDTO
, buf
, len
);
3813 swrap_dump_packet(si
, to
, SWRAP_SENDTO_UNREACH
, buf
, len
);
3815 swrap_dump_packet(si
, to
, SWRAP_SENDTO
, buf
, len
);
3821 errno
= saved_errno
;
3824 static int swrap_recvmsg_before(int fd
,
3825 struct socket_info
*si
,
3827 struct iovec
*tmp_iov
)
3832 (void)fd
; /* unused */
3836 if (!si
->connected
) {
3841 if (msg
->msg_iovlen
== 0) {
3845 for (i
= 0; i
< (size_t)msg
->msg_iovlen
; i
++) {
3847 nlen
= len
+ msg
->msg_iov
[i
].iov_len
;
3848 if (nlen
> SOCKET_MAX_PACKET
) {
3852 msg
->msg_iovlen
= i
;
3853 if (msg
->msg_iovlen
== 0) {
3854 *tmp_iov
= msg
->msg_iov
[0];
3855 tmp_iov
->iov_len
= MIN(tmp_iov
->iov_len
, SOCKET_MAX_PACKET
);
3856 msg
->msg_iov
= tmp_iov
;
3857 msg
->msg_iovlen
= 1;
3862 if (msg
->msg_name
== NULL
) {
3867 if (msg
->msg_iovlen
== 0) {
3871 if (si
->bound
== 0) {
3872 ret
= swrap_auto_bind(fd
, si
, si
->family
);
3875 * When attempting to read or write to a
3876 * descriptor, if an underlying autobind fails
3877 * because it's not a socket, stop intercepting
3878 * uses of that descriptor.
3880 if (errno
== ENOTSOCK
) {
3881 swrap_remove_stale(fd
);
3884 SWRAP_LOG(SWRAP_LOG_ERROR
,
3885 "swrap_recvmsg_before failed");
3892 errno
= EHOSTUNREACH
;
3899 static int swrap_recvmsg_after(int fd
,
3900 struct socket_info
*si
,
3902 const struct sockaddr_un
*un_addr
,
3903 socklen_t un_addrlen
,
3906 int saved_errno
= errno
;
3908 uint8_t *buf
= NULL
;
3914 /* to give better errors */
3916 if (saved_errno
== ENOENT
) {
3917 saved_errno
= EHOSTUNREACH
;
3918 } else if (saved_errno
== ENOTSOCK
) {
3919 /* If the fd is not a socket, remove it */
3920 swrap_remove_stale(fd
);
3924 for (i
= 0; i
< (size_t)msg
->msg_iovlen
; i
++) {
3925 avail
+= msg
->msg_iov
[i
].iov_len
;
3934 remain
= MIN(80, avail
);
3939 /* we capture it as one single packet */
3940 buf
= (uint8_t *)malloc(remain
);
3942 /* we just not capture the packet */
3943 errno
= saved_errno
;
3947 for (i
= 0; i
< (size_t)msg
->msg_iovlen
; i
++) {
3948 size_t this_time
= MIN(remain
, (size_t)msg
->msg_iov
[i
].iov_len
);
3950 msg
->msg_iov
[i
].iov_base
,
3953 remain
-= this_time
;
3958 if (ret
== -1 && saved_errno
!= EAGAIN
&& saved_errno
!= ENOBUFS
) {
3959 swrap_dump_packet(si
, NULL
, SWRAP_RECV_RST
, NULL
, 0);
3960 } else if (ret
== 0) { /* END OF FILE */
3961 swrap_dump_packet(si
, NULL
, SWRAP_RECV_RST
, NULL
, 0);
3962 } else if (ret
> 0) {
3963 swrap_dump_packet(si
, NULL
, SWRAP_RECV
, buf
, ret
);
3972 if (un_addr
!= NULL
) {
3973 rc
= sockaddr_convert_from_un(si
,
3983 swrap_dump_packet(si
,
3989 swrap_dump_packet(si
,
4002 errno
= saved_errno
;
4004 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4006 msg
->msg_controllen
> 0 &&
4007 msg
->msg_control
!= NULL
) {
4008 rc
= swrap_msghdr_add_socket_info(si
, msg
);
4018 /****************************************************************************
4020 ***************************************************************************/
4022 static ssize_t
swrap_recvfrom(int s
, void *buf
, size_t len
, int flags
,
4023 struct sockaddr
*from
, socklen_t
*fromlen
)
4025 struct sockaddr_un from_addr
;
4026 socklen_t from_addrlen
= sizeof(from_addr
);
4028 struct socket_info
*si
= find_socket_info(s
);
4029 struct sockaddr_storage ss
;
4030 socklen_t ss_len
= sizeof(ss
);
4036 return libc_recvfrom(s
,
4048 if (from
!= NULL
&& fromlen
!= NULL
) {
4049 msg
.msg_name
= from
; /* optional address */
4050 msg
.msg_namelen
= *fromlen
; /* size of address */
4052 msg
.msg_name
= (struct sockaddr
*)(void *)&ss
; /* optional address */
4053 msg
.msg_namelen
= ss_len
; /* size of address */
4055 msg
.msg_iov
= &tmp
; /* scatter/gather array */
4056 msg
.msg_iovlen
= 1; /* # elements in msg_iov */
4057 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4058 msg
.msg_control
= NULL
; /* ancillary data, see below */
4059 msg
.msg_controllen
= 0; /* ancillary data buffer len */
4060 msg
.msg_flags
= 0; /* flags on received message */
4063 tret
= swrap_recvmsg_before(s
, si
, &msg
, &tmp
);
4068 buf
= msg
.msg_iov
[0].iov_base
;
4069 len
= msg
.msg_iov
[0].iov_len
;
4071 /* irix 6.4 forgets to null terminate the sun_path string :-( */
4072 memset(&from_addr
, 0, sizeof(from_addr
));
4073 ret
= libc_recvfrom(s
,
4077 (struct sockaddr
*)(void *)&from_addr
,
4083 tret
= swrap_recvmsg_after(s
,
4093 if (from
!= NULL
&& fromlen
!= NULL
) {
4094 *fromlen
= msg
.msg_namelen
;
4100 #ifdef HAVE_ACCEPT_PSOCKLEN_T
4101 ssize_t
recvfrom(int s
, void *buf
, size_t len
, int flags
,
4102 struct sockaddr
*from
, Psocklen_t fromlen
)
4104 ssize_t
recvfrom(int s
, void *buf
, size_t len
, int flags
,
4105 struct sockaddr
*from
, socklen_t
*fromlen
)
4108 return swrap_recvfrom(s
, buf
, len
, flags
, from
, (socklen_t
*)fromlen
);
4111 /****************************************************************************
4113 ***************************************************************************/
4115 static ssize_t
swrap_sendto(int s
, const void *buf
, size_t len
, int flags
,
4116 const struct sockaddr
*to
, socklen_t tolen
)
4120 struct sockaddr_un un_addr
;
4121 const struct sockaddr_un
*to_un
= NULL
;
4124 struct socket_info
*si
= find_socket_info(s
);
4128 return libc_sendto(s
, buf
, len
, flags
, to
, tolen
);
4131 tmp
.iov_base
= discard_const_p(char, buf
);
4135 msg
.msg_name
= discard_const_p(struct sockaddr
, to
); /* optional address */
4136 msg
.msg_namelen
= tolen
; /* size of address */
4137 msg
.msg_iov
= &tmp
; /* scatter/gather array */
4138 msg
.msg_iovlen
= 1; /* # elements in msg_iov */
4139 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
4140 msg
.msg_control
= NULL
; /* ancillary data, see below */
4141 msg
.msg_controllen
= 0; /* ancillary data buffer len */
4142 msg
.msg_flags
= 0; /* flags on received message */
4145 rc
= swrap_sendmsg_before(s
, si
, &msg
, &tmp
, &un_addr
, &to_un
, &to
, &bcast
);
4150 buf
= msg
.msg_iov
[0].iov_base
;
4151 len
= msg
.msg_iov
[0].iov_len
;
4156 unsigned int prt
= ntohs(((const struct sockaddr_in
*)to
)->sin_port
);
4159 type
= SOCKET_TYPE_CHAR_UDP
;
4161 for(iface
=0; iface
<= MAX_WRAPPED_INTERFACES
; iface
++) {
4162 snprintf(un_addr
.sun_path
, sizeof(un_addr
.sun_path
), "%s/"SOCKET_FORMAT
,
4163 socket_wrapper_dir(), type
, iface
, prt
);
4164 if (stat(un_addr
.sun_path
, &st
) != 0) continue;
4166 /* ignore the any errors in broadcast sends */
4171 (struct sockaddr
*)(void *)&un_addr
,
4175 swrap_dump_packet(si
, to
, SWRAP_SENDTO
, buf
, len
);
4180 ret
= libc_sendto(s
,
4184 (struct sockaddr
*)msg
.msg_name
,
4187 swrap_sendmsg_after(s
, si
, &msg
, to
, ret
);
4192 ssize_t
sendto(int s
, const void *buf
, size_t len
, int flags
,
4193 const struct sockaddr
*to
, socklen_t tolen
)
4195 return swrap_sendto(s
, buf
, len
, flags
, to
, tolen
);
4198 /****************************************************************************
4200 ***************************************************************************/
4202 static ssize_t
swrap_recv(int s
, void *buf
, size_t len
, int flags
)
4204 struct socket_info
*si
;
4206 struct sockaddr_storage ss
;
4207 socklen_t ss_len
= sizeof(ss
);
4212 si
= find_socket_info(s
);
4214 return libc_recv(s
, buf
, len
, flags
);
4221 msg
.msg_name
= (struct sockaddr
*)(void *)&ss
; /* optional address */
4222 msg
.msg_namelen
= ss_len
; /* size of address */
4223 msg
.msg_iov
= &tmp
; /* scatter/gather array */
4224 msg
.msg_iovlen
= 1; /* # elements in msg_iov */
4225 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4226 msg
.msg_control
= NULL
; /* ancillary data, see below */
4227 msg
.msg_controllen
= 0; /* ancillary data buffer len */
4228 msg
.msg_flags
= 0; /* flags on received message */
4231 tret
= swrap_recvmsg_before(s
, si
, &msg
, &tmp
);
4236 buf
= msg
.msg_iov
[0].iov_base
;
4237 len
= msg
.msg_iov
[0].iov_len
;
4239 ret
= libc_recv(s
, buf
, len
, flags
);
4241 tret
= swrap_recvmsg_after(s
, si
, &msg
, NULL
, 0, ret
);
4249 ssize_t
recv(int s
, void *buf
, size_t len
, int flags
)
4251 return swrap_recv(s
, buf
, len
, flags
);
4254 /****************************************************************************
4256 ***************************************************************************/
4258 static ssize_t
swrap_read(int s
, void *buf
, size_t len
)
4260 struct socket_info
*si
;
4263 struct sockaddr_storage ss
;
4264 socklen_t ss_len
= sizeof(ss
);
4268 si
= find_socket_info(s
);
4270 return libc_read(s
, buf
, len
);
4277 msg
.msg_name
= (struct sockaddr
*)(void *)&ss
; /* optional address */
4278 msg
.msg_namelen
= ss_len
; /* size of address */
4279 msg
.msg_iov
= &tmp
; /* scatter/gather array */
4280 msg
.msg_iovlen
= 1; /* # elements in msg_iov */
4281 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4282 msg
.msg_control
= NULL
; /* ancillary data, see below */
4283 msg
.msg_controllen
= 0; /* ancillary data buffer len */
4284 msg
.msg_flags
= 0; /* flags on received message */
4287 tret
= swrap_recvmsg_before(s
, si
, &msg
, &tmp
);
4289 if (tret
== -ENOTSOCK
) {
4290 return libc_read(s
, buf
, len
);
4295 buf
= msg
.msg_iov
[0].iov_base
;
4296 len
= msg
.msg_iov
[0].iov_len
;
4298 ret
= libc_read(s
, buf
, len
);
4300 tret
= swrap_recvmsg_after(s
, si
, &msg
, NULL
, 0, ret
);
4308 ssize_t
read(int s
, void *buf
, size_t len
)
4310 return swrap_read(s
, buf
, len
);
4313 /****************************************************************************
4315 ***************************************************************************/
4317 static ssize_t
swrap_send(int s
, const void *buf
, size_t len
, int flags
)
4321 struct sockaddr_un un_addr
;
4324 struct socket_info
*si
= find_socket_info(s
);
4327 return libc_send(s
, buf
, len
, flags
);
4330 tmp
.iov_base
= discard_const_p(char, buf
);
4334 msg
.msg_name
= NULL
; /* optional address */
4335 msg
.msg_namelen
= 0; /* size of address */
4336 msg
.msg_iov
= &tmp
; /* scatter/gather array */
4337 msg
.msg_iovlen
= 1; /* # elements in msg_iov */
4338 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
4339 msg
.msg_control
= NULL
; /* ancillary data, see below */
4340 msg
.msg_controllen
= 0; /* ancillary data buffer len */
4341 msg
.msg_flags
= 0; /* flags on received message */
4344 rc
= swrap_sendmsg_before(s
, si
, &msg
, &tmp
, &un_addr
, NULL
, NULL
, NULL
);
4349 buf
= msg
.msg_iov
[0].iov_base
;
4350 len
= msg
.msg_iov
[0].iov_len
;
4352 ret
= libc_send(s
, buf
, len
, flags
);
4354 swrap_sendmsg_after(s
, si
, &msg
, NULL
, ret
);
4359 ssize_t
send(int s
, const void *buf
, size_t len
, int flags
)
4361 return swrap_send(s
, buf
, len
, flags
);
4364 /****************************************************************************
4366 ***************************************************************************/
4368 static ssize_t
swrap_recvmsg(int s
, struct msghdr
*omsg
, int flags
)
4370 struct sockaddr_un from_addr
;
4371 socklen_t from_addrlen
= sizeof(from_addr
);
4372 struct socket_info
*si
;
4375 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4376 size_t msg_ctrllen_filled
;
4377 size_t msg_ctrllen_left
;
4383 si
= find_socket_info(s
);
4385 return libc_recvmsg(s
, omsg
, flags
);
4388 tmp
.iov_base
= NULL
;
4392 msg
.msg_name
= (struct sockaddr
*)&from_addr
; /* optional address */
4393 msg
.msg_namelen
= from_addrlen
; /* size of address */
4394 msg
.msg_iov
= omsg
->msg_iov
; /* scatter/gather array */
4395 msg
.msg_iovlen
= omsg
->msg_iovlen
; /* # elements in msg_iov */
4396 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4397 msg_ctrllen_filled
= 0;
4398 msg_ctrllen_left
= omsg
->msg_controllen
;
4400 msg
.msg_control
= omsg
->msg_control
; /* ancillary data, see below */
4401 msg
.msg_controllen
= omsg
->msg_controllen
; /* ancillary data buffer len */
4402 msg
.msg_flags
= omsg
->msg_flags
; /* flags on received message */
4405 rc
= swrap_recvmsg_before(s
, si
, &msg
, &tmp
);
4410 ret
= libc_recvmsg(s
, &msg
, flags
);
4412 msg
.msg_name
= omsg
->msg_name
;
4413 msg
.msg_namelen
= omsg
->msg_namelen
;
4415 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4416 msg_ctrllen_filled
+= msg
.msg_controllen
;
4417 msg_ctrllen_left
-= msg
.msg_controllen
;
4419 if (omsg
->msg_control
!= NULL
) {
4422 p
= omsg
->msg_control
;
4423 p
+= msg_ctrllen_filled
;
4425 msg
.msg_control
= p
;
4426 msg
.msg_controllen
= msg_ctrllen_left
;
4428 msg
.msg_control
= NULL
;
4429 msg
.msg_controllen
= 0;
4433 rc
= swrap_recvmsg_after(s
, si
, &msg
, &from_addr
, from_addrlen
, ret
);
4438 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4439 if (omsg
->msg_control
!= NULL
) {
4440 /* msg.msg_controllen = space left */
4441 msg_ctrllen_left
= msg
.msg_controllen
;
4442 msg_ctrllen_filled
= omsg
->msg_controllen
- msg_ctrllen_left
;
4445 /* Update the original message length */
4446 omsg
->msg_controllen
= msg_ctrllen_filled
;
4447 omsg
->msg_flags
= msg
.msg_flags
;
4449 omsg
->msg_iovlen
= msg
.msg_iovlen
;
4454 ssize_t
recvmsg(int sockfd
, struct msghdr
*msg
, int flags
)
4456 return swrap_recvmsg(sockfd
, msg
, flags
);
4459 /****************************************************************************
4461 ***************************************************************************/
4463 static ssize_t
swrap_sendmsg(int s
, const struct msghdr
*omsg
, int flags
)
4467 struct sockaddr_un un_addr
;
4468 const struct sockaddr_un
*to_un
= NULL
;
4469 const struct sockaddr
*to
= NULL
;
4472 struct socket_info
*si
= find_socket_info(s
);
4476 return libc_sendmsg(s
, omsg
, flags
);
4479 ZERO_STRUCT(un_addr
);
4481 tmp
.iov_base
= NULL
;
4485 msg
.msg_name
= omsg
->msg_name
; /* optional address */
4486 msg
.msg_namelen
= omsg
->msg_namelen
; /* size of address */
4487 msg
.msg_iov
= omsg
->msg_iov
; /* scatter/gather array */
4488 msg
.msg_iovlen
= omsg
->msg_iovlen
; /* # elements in msg_iov */
4489 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4490 if (msg
.msg_controllen
> 0 && msg
.msg_control
!= NULL
) {
4491 /* omsg is a const so use a local buffer for modifications */
4492 uint8_t cmbuf
[omsg
->msg_controllen
];
4494 memcpy(cmbuf
, omsg
->msg_control
, omsg
->msg_controllen
);
4496 msg
.msg_control
= cmbuf
; /* ancillary data, see below */
4497 msg
.msg_controllen
= omsg
->msg_controllen
; /* ancillary data buffer len */
4499 msg
.msg_flags
= omsg
->msg_flags
; /* flags on received message */
4502 rc
= swrap_sendmsg_before(s
, si
, &msg
, &tmp
, &un_addr
, &to_un
, &to
, &bcast
);
4510 unsigned int prt
= ntohs(((const struct sockaddr_in
*)to
)->sin_port
);
4518 for (i
= 0; i
< (size_t)msg
.msg_iovlen
; i
++) {
4519 avail
+= msg
.msg_iov
[i
].iov_len
;
4525 /* we capture it as one single packet */
4526 buf
= (uint8_t *)malloc(remain
);
4531 for (i
= 0; i
< (size_t)msg
.msg_iovlen
; i
++) {
4532 size_t this_time
= MIN(remain
, (size_t)msg
.msg_iov
[i
].iov_len
);
4534 msg
.msg_iov
[i
].iov_base
,
4537 remain
-= this_time
;
4540 type
= SOCKET_TYPE_CHAR_UDP
;
4542 for(iface
=0; iface
<= MAX_WRAPPED_INTERFACES
; iface
++) {
4543 snprintf(un_addr
.sun_path
, sizeof(un_addr
.sun_path
), "%s/"SOCKET_FORMAT
,
4544 socket_wrapper_dir(), type
, iface
, prt
);
4545 if (stat(un_addr
.sun_path
, &st
) != 0) continue;
4547 msg
.msg_name
= &un_addr
; /* optional address */
4548 msg
.msg_namelen
= sizeof(un_addr
); /* size of address */
4550 /* ignore the any errors in broadcast sends */
4551 libc_sendmsg(s
, &msg
, flags
);
4554 swrap_dump_packet(si
, to
, SWRAP_SENDTO
, buf
, len
);
4560 ret
= libc_sendmsg(s
, &msg
, flags
);
4562 swrap_sendmsg_after(s
, si
, &msg
, to
, ret
);
4567 ssize_t
sendmsg(int s
, const struct msghdr
*omsg
, int flags
)
4569 return swrap_sendmsg(s
, omsg
, flags
);
4572 /****************************************************************************
4574 ***************************************************************************/
4576 static ssize_t
swrap_readv(int s
, const struct iovec
*vector
, int count
)
4578 struct socket_info
*si
;
4581 struct sockaddr_storage ss
;
4582 socklen_t ss_len
= sizeof(ss
);
4586 si
= find_socket_info(s
);
4588 return libc_readv(s
, vector
, count
);
4591 tmp
.iov_base
= NULL
;
4595 msg
.msg_name
= (struct sockaddr
*)(void *)&ss
; /* optional address */
4596 msg
.msg_namelen
= ss_len
; /* size of address */
4597 msg
.msg_iov
= discard_const_p(struct iovec
, vector
); /* scatter/gather array */
4598 msg
.msg_iovlen
= count
; /* # elements in msg_iov */
4599 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4600 msg
.msg_control
= NULL
; /* ancillary data, see below */
4601 msg
.msg_controllen
= 0; /* ancillary data buffer len */
4602 msg
.msg_flags
= 0; /* flags on received message */
4605 rc
= swrap_recvmsg_before(s
, si
, &msg
, &tmp
);
4607 if (rc
== -ENOTSOCK
) {
4608 return libc_readv(s
, vector
, count
);
4613 ret
= libc_readv(s
, msg
.msg_iov
, msg
.msg_iovlen
);
4615 rc
= swrap_recvmsg_after(s
, si
, &msg
, NULL
, 0, ret
);
4623 ssize_t
readv(int s
, const struct iovec
*vector
, int count
)
4625 return swrap_readv(s
, vector
, count
);
4628 /****************************************************************************
4630 ***************************************************************************/
4632 static ssize_t
swrap_writev(int s
, const struct iovec
*vector
, int count
)
4636 struct sockaddr_un un_addr
;
4639 struct socket_info
*si
= find_socket_info(s
);
4642 return libc_writev(s
, vector
, count
);
4645 tmp
.iov_base
= NULL
;
4649 msg
.msg_name
= NULL
; /* optional address */
4650 msg
.msg_namelen
= 0; /* size of address */
4651 msg
.msg_iov
= discard_const_p(struct iovec
, vector
); /* scatter/gather array */
4652 msg
.msg_iovlen
= count
; /* # elements in msg_iov */
4653 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
4654 msg
.msg_control
= NULL
; /* ancillary data, see below */
4655 msg
.msg_controllen
= 0; /* ancillary data buffer len */
4656 msg
.msg_flags
= 0; /* flags on received message */
4659 rc
= swrap_sendmsg_before(s
, si
, &msg
, &tmp
, &un_addr
, NULL
, NULL
, NULL
);
4661 if (rc
== -ENOTSOCK
) {
4662 return libc_readv(s
, vector
, count
);
4667 ret
= libc_writev(s
, msg
.msg_iov
, msg
.msg_iovlen
);
4669 swrap_sendmsg_after(s
, si
, &msg
, NULL
, ret
);
4674 ssize_t
writev(int s
, const struct iovec
*vector
, int count
)
4676 return swrap_writev(s
, vector
, count
);
4679 /****************************
4681 ***************************/
4683 static int swrap_close(int fd
)
4685 struct socket_info
*si
= find_socket_info(fd
);
4686 struct socket_info_fd
*fi
;
4690 return libc_close(fd
);
4693 for (fi
= si
->fds
; fi
; fi
= fi
->next
) {
4695 SWRAP_DLIST_REMOVE(si
->fds
, fi
);
4702 /* there are still references left */
4703 return libc_close(fd
);
4706 SWRAP_DLIST_REMOVE(sockets
, si
);
4708 if (si
->myname
&& si
->peername
) {
4709 swrap_dump_packet(si
, NULL
, SWRAP_CLOSE_SEND
, NULL
, 0);
4712 ret
= libc_close(fd
);
4714 if (si
->myname
&& si
->peername
) {
4715 swrap_dump_packet(si
, NULL
, SWRAP_CLOSE_RECV
, NULL
, 0);
4716 swrap_dump_packet(si
, NULL
, SWRAP_CLOSE_ACK
, NULL
, 0);
4719 if (si
->bindname
!= NULL
) {
4723 if (si
->myname
) free(si
->myname
);
4724 if (si
->peername
) free(si
->peername
);
4726 unlink(si
->tmp_path
);
4736 return swrap_close(fd
);
4739 /****************************
4741 ***************************/
4743 static int swrap_dup(int fd
)
4745 struct socket_info
*si
;
4746 struct socket_info_fd
*fi
;
4748 si
= find_socket_info(fd
);
4751 return libc_dup(fd
);
4754 fi
= (struct socket_info_fd
*)calloc(1, sizeof(struct socket_info_fd
));
4760 fi
->fd
= libc_dup(fd
);
4762 int saved_errno
= errno
;
4764 errno
= saved_errno
;
4768 /* Make sure we don't have an entry for the fd */
4769 swrap_remove_stale(fi
->fd
);
4771 SWRAP_DLIST_ADD(si
->fds
, fi
);
4777 return swrap_dup(fd
);
4780 /****************************
4782 ***************************/
4784 static int swrap_dup2(int fd
, int newfd
)
4786 struct socket_info
*si
;
4787 struct socket_info_fd
*fi
;
4789 si
= find_socket_info(fd
);
4792 return libc_dup2(fd
, newfd
);
4795 if (find_socket_info(newfd
)) {
4796 /* dup2() does an implicit close of newfd, which we
4797 * need to emulate */
4801 fi
= (struct socket_info_fd
*)calloc(1, sizeof(struct socket_info_fd
));
4807 fi
->fd
= libc_dup2(fd
, newfd
);
4809 int saved_errno
= errno
;
4811 errno
= saved_errno
;
4815 /* Make sure we don't have an entry for the fd */
4816 swrap_remove_stale(fi
->fd
);
4818 SWRAP_DLIST_ADD(si
->fds
, fi
);
4822 int dup2(int fd
, int newfd
)
4824 return swrap_dup2(fd
, newfd
);
4827 /****************************
4829 ***************************/
4832 static int swrap_eventfd(int count
, int flags
)
4836 fd
= libc_eventfd(count
, flags
);
4838 swrap_remove_stale(fd
);
4844 int eventfd(int count
, int flags
)
4846 return swrap_eventfd(count
, flags
);
4850 /****************************
4852 ***************************/
4855 * This function is called when the library is unloaded and makes sure that
4856 * sockets get closed and the unix file for the socket are unlinked.
4858 void swrap_destructor(void)
4860 struct socket_info
*s
= sockets
;
4863 struct socket_info_fd
*f
= s
->fds
;