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 const struct sockaddr_in
*sin
;
1398 if (si
->family
!= AF_INET
) {
1401 if (in_len
< sizeof(struct sockaddr_in
)) {
1404 sin
= (const 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
= (const 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
= (const 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 */
3175 if (optval
== NULL
|| optlen
== NULL
||
3176 *optlen
< (socklen_t
)sizeof(int)) {
3181 *optlen
= sizeof(int);
3182 *(int *)optval
= si
->protocol
;
3184 #endif /* SO_PROTOCOL */
3186 if (optval
== NULL
|| optlen
== NULL
||
3187 *optlen
< (socklen_t
)sizeof(int)) {
3192 *optlen
= sizeof(int);
3193 *(int *)optval
= si
->type
;
3196 return libc_getsockopt(s
,
3204 errno
= ENOPROTOOPT
;
3208 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3209 int getsockopt(int s
, int level
, int optname
, void *optval
, Psocklen_t optlen
)
3211 int getsockopt(int s
, int level
, int optname
, void *optval
, socklen_t
*optlen
)
3214 return swrap_getsockopt(s
, level
, optname
, optval
, (socklen_t
*)optlen
);
3217 /****************************************************************************
3219 ***************************************************************************/
3221 static int swrap_setsockopt(int s
, int level
, int optname
,
3222 const void *optval
, socklen_t optlen
)
3224 struct socket_info
*si
= find_socket_info(s
);
3227 return libc_setsockopt(s
,
3234 if (level
== SOL_SOCKET
) {
3235 return libc_setsockopt(s
,
3242 switch (si
->family
) {
3244 if (level
== IPPROTO_IP
) {
3246 if (optname
== IP_PKTINFO
) {
3247 si
->pktinfo
= AF_INET
;
3249 #endif /* IP_PKTINFO */
3254 if (level
== IPPROTO_IPV6
) {
3255 #ifdef IPV6_RECVPKTINFO
3256 if (optname
== IPV6_RECVPKTINFO
) {
3257 si
->pktinfo
= AF_INET6
;
3259 #endif /* IPV6_PKTINFO */
3264 errno
= ENOPROTOOPT
;
3269 int setsockopt(int s
, int level
, int optname
,
3270 const void *optval
, socklen_t optlen
)
3272 return swrap_setsockopt(s
, level
, optname
, optval
, optlen
);
3275 /****************************************************************************
3277 ***************************************************************************/
3279 static int swrap_vioctl(int s
, unsigned long int r
, va_list va
)
3281 struct socket_info
*si
= find_socket_info(s
);
3287 return libc_vioctl(s
, r
, va
);
3292 rc
= libc_vioctl(s
, r
, va
);
3296 value
= *((int *)va_arg(ap
, int *));
3298 if (rc
== -1 && errno
!= EAGAIN
&& errno
!= ENOBUFS
) {
3299 swrap_dump_packet(si
, NULL
, SWRAP_PENDING_RST
, NULL
, 0);
3300 } else if (value
== 0) { /* END OF FILE */
3301 swrap_dump_packet(si
, NULL
, SWRAP_PENDING_RST
, NULL
, 0);
3311 #ifdef HAVE_IOCTL_INT
3312 int ioctl(int s
, int r
, ...)
3314 int ioctl(int s
, unsigned long int r
, ...)
3322 rc
= swrap_vioctl(s
, (unsigned long int) r
, va
);
3333 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3336 # ifdef _ALIGN /* BSD */
3337 #define CMSG_ALIGN _ALIGN
3339 #error NO_CMSG_ALIGN
3340 # endif /* _ALIGN */
3341 #endif /* CMSG_ALIGN */
3344 * @brief Add a cmsghdr to a msghdr.
3346 * This is an function to add any type of cmsghdr. It will operate on the
3347 * msg->msg_control and msg->msg_controllen you pass in by adapting them to
3348 * the buffer position after the added cmsg element. Hence, this function is
3349 * intended to be used with an intermediate msghdr and not on the original
3350 * one handed in by the client.
3352 * @param[in] msg The msghdr to which to add the cmsg.
3354 * @param[in] level The cmsg level to set.
3356 * @param[in] type The cmsg type to set.
3358 * @param[in] data The cmsg data to set.
3360 * @param[in] len the length of the data to set.
3362 static void swrap_msghdr_add_cmsghdr(struct msghdr
*msg
,
3368 size_t cmlen
= CMSG_LEN(len
);
3369 size_t cmspace
= CMSG_SPACE(len
);
3370 uint8_t cmbuf
[cmspace
];
3371 struct cmsghdr
*cm
= (struct cmsghdr
*)cmbuf
;
3374 memset(cmbuf
, 0, cmspace
);
3376 if (msg
->msg_controllen
< cmlen
) {
3377 cmlen
= msg
->msg_controllen
;
3378 msg
->msg_flags
|= MSG_CTRUNC
;
3381 if (msg
->msg_controllen
< cmspace
) {
3382 cmspace
= msg
->msg_controllen
;
3386 * We copy the full input data into an intermediate cmsghdr first
3387 * in order to more easily cope with truncation.
3389 cm
->cmsg_len
= cmlen
;
3390 cm
->cmsg_level
= level
;
3391 cm
->cmsg_type
= type
;
3392 memcpy(CMSG_DATA(cm
), data
, len
);
3395 * We now copy the possibly truncated buffer.
3396 * We copy cmlen bytes, but consume cmspace bytes,
3397 * leaving the possible padding uninitialiazed.
3399 p
= (uint8_t *)msg
->msg_control
;
3400 memcpy(p
, cm
, cmlen
);
3402 msg
->msg_control
= p
;
3403 msg
->msg_controllen
-= cmspace
;
3408 static int swrap_msghdr_add_pktinfo(struct socket_info
*si
,
3411 /* Add packet info */
3412 switch (si
->pktinfo
) {
3413 #if defined(IP_PKTINFO) && (defined(HAVE_STRUCT_IN_PKTINFO) || defined(IP_RECVDSTADDR))
3415 struct sockaddr_in
*sin
;
3416 #if defined(HAVE_STRUCT_IN_PKTINFO)
3417 struct in_pktinfo pkt
;
3418 #elif defined(IP_RECVDSTADDR)
3422 if (si
->bindname_len
== sizeof(struct sockaddr_in
)) {
3423 sin
= (struct sockaddr_in
*)si
->bindname
;
3425 if (si
->myname_len
!= sizeof(struct sockaddr_in
)) {
3428 sin
= (struct sockaddr_in
*)si
->myname
;
3433 #if defined(HAVE_STRUCT_IN_PKTINFO)
3434 pkt
.ipi_ifindex
= socket_wrapper_default_iface();
3435 pkt
.ipi_addr
.s_addr
= sin
->sin_addr
.s_addr
;
3436 #elif defined(IP_RECVDSTADDR)
3437 pkt
= sin
->sin_addr
;
3440 swrap_msghdr_add_cmsghdr(msg
, IPPROTO_IP
, IP_PKTINFO
,
3445 #endif /* IP_PKTINFO */
3446 #if defined(HAVE_IPV6)
3448 #if defined(IPV6_PKTINFO) && defined(HAVE_STRUCT_IN6_PKTINFO)
3449 struct sockaddr_in6
*sin6
;
3450 struct in6_pktinfo pkt6
;
3452 if (si
->bindname_len
== sizeof(struct sockaddr_in6
)) {
3453 sin6
= (struct sockaddr_in6
*)si
->bindname
;
3455 if (si
->myname_len
!= sizeof(struct sockaddr_in6
)) {
3458 sin6
= (struct sockaddr_in6
*)si
->myname
;
3463 pkt6
.ipi6_ifindex
= socket_wrapper_default_iface();
3464 pkt6
.ipi6_addr
= sin6
->sin6_addr
;
3466 swrap_msghdr_add_cmsghdr(msg
, IPPROTO_IPV6
, IPV6_PKTINFO
,
3467 &pkt6
, sizeof(pkt6
));
3468 #endif /* HAVE_STRUCT_IN6_PKTINFO */
3472 #endif /* IPV6_PKTINFO */
3480 static int swrap_msghdr_add_socket_info(struct socket_info
*si
,
3481 struct msghdr
*omsg
)
3485 if (si
->pktinfo
> 0) {
3486 rc
= swrap_msghdr_add_pktinfo(si
, omsg
);
3492 static int swrap_sendmsg_copy_cmsg(struct cmsghdr
*cmsg
,
3494 size_t *cm_data_space
);
3495 static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr
*cmsg
,
3497 size_t *cm_data_space
);
3499 static int swrap_sendmsg_filter_cmsghdr(struct msghdr
*msg
,
3501 size_t *cm_data_space
) {
3502 struct cmsghdr
*cmsg
;
3506 if (msg
->msg_controllen
== 0 || msg
->msg_control
== NULL
) {
3510 for (cmsg
= CMSG_FIRSTHDR(msg
);
3512 cmsg
= CMSG_NXTHDR(msg
, cmsg
)) {
3513 switch (cmsg
->cmsg_level
) {
3515 rc
= swrap_sendmsg_filter_cmsg_socket(cmsg
,
3520 rc
= swrap_sendmsg_copy_cmsg(cmsg
,
3530 static int swrap_sendmsg_copy_cmsg(struct cmsghdr
*cmsg
,
3532 size_t *cm_data_space
)
3539 CMSG_SPACE(cmsg
->cmsg_len
- CMSG_ALIGN(sizeof(struct cmsghdr
)));
3541 p
= realloc((*cm_data
), cmspace
);
3547 p
= (*cm_data
) + (*cm_data_space
);
3548 *cm_data_space
= cmspace
;
3550 memcpy(p
, cmsg
, cmsg
->cmsg_len
);
3555 static int swrap_sendmsg_filter_cmsg_pktinfo(struct cmsghdr
*cmsg
,
3557 size_t *cm_data_space
);
3560 static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr
*cmsg
,
3562 size_t *cm_data_space
)
3566 switch(cmsg
->cmsg_type
) {
3569 rc
= swrap_sendmsg_filter_cmsg_pktinfo(cmsg
,
3576 rc
= swrap_sendmsg_filter_cmsg_pktinfo(cmsg
,
3588 static int swrap_sendmsg_filter_cmsg_pktinfo(struct cmsghdr
*cmsg
,
3590 size_t *cm_data_space
)
3592 (void)cmsg
; /* unused */
3593 (void)cm_data
; /* unused */
3594 (void)cm_data_space
; /* unused */
3597 * Passing a IP pktinfo to a unix socket might be rejected by the
3598 * Kernel, at least on FreeBSD. So skip this cmsg.
3602 #endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
3604 static ssize_t
swrap_sendmsg_before(int fd
,
3605 struct socket_info
*si
,
3607 struct iovec
*tmp_iov
,
3608 struct sockaddr_un
*tmp_un
,
3609 const struct sockaddr_un
**to_un
,
3610 const struct sockaddr
**to
,
3628 if (!si
->connected
) {
3633 if (msg
->msg_iovlen
== 0) {
3637 for (i
= 0; i
< (size_t)msg
->msg_iovlen
; i
++) {
3639 nlen
= len
+ msg
->msg_iov
[i
].iov_len
;
3640 if (nlen
> SOCKET_MAX_PACKET
) {
3644 msg
->msg_iovlen
= i
;
3645 if (msg
->msg_iovlen
== 0) {
3646 *tmp_iov
= msg
->msg_iov
[0];
3647 tmp_iov
->iov_len
= MIN(tmp_iov
->iov_len
, SOCKET_MAX_PACKET
);
3648 msg
->msg_iov
= tmp_iov
;
3649 msg
->msg_iovlen
= 1;
3654 if (si
->connected
) {
3655 if (msg
->msg_name
) {
3660 const struct sockaddr
*msg_name
;
3661 msg_name
= (const struct sockaddr
*)msg
->msg_name
;
3663 if (msg_name
== NULL
) {
3669 ret
= sockaddr_convert_to_un(si
, msg_name
, msg
->msg_namelen
,
3671 if (ret
== -1) return -1;
3679 msg
->msg_name
= tmp_un
;
3680 msg
->msg_namelen
= sizeof(*tmp_un
);
3683 if (si
->bound
== 0) {
3684 ret
= swrap_auto_bind(fd
, si
, si
->family
);
3686 if (errno
== ENOTSOCK
) {
3687 swrap_remove_stale(fd
);
3690 SWRAP_LOG(SWRAP_LOG_ERROR
, "swrap_sendmsg_before failed");
3696 if (!si
->defer_connect
) {
3700 ret
= sockaddr_convert_to_un(si
, si
->peername
, si
->peername_len
,
3702 if (ret
== -1) return -1;
3704 ret
= libc_connect(fd
,
3705 (struct sockaddr
*)(void *)tmp_un
,
3708 /* to give better errors */
3709 if (ret
== -1 && errno
== ENOENT
) {
3710 errno
= EHOSTUNREACH
;
3717 si
->defer_connect
= 0;
3720 errno
= EHOSTUNREACH
;
3724 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3725 if (msg
->msg_controllen
> 0 && msg
->msg_control
!= NULL
) {
3726 uint8_t *cmbuf
= NULL
;
3729 ret
= swrap_sendmsg_filter_cmsghdr(msg
, &cmbuf
, &cmlen
);
3736 msg
->msg_controllen
= 0;
3737 msg
->msg_control
= NULL
;
3738 } else if (cmlen
< msg
->msg_controllen
&& cmbuf
!= NULL
) {
3739 memcpy(msg
->msg_control
, cmbuf
, cmlen
);
3740 msg
->msg_controllen
= cmlen
;
3749 static void swrap_sendmsg_after(int fd
,
3750 struct socket_info
*si
,
3752 const struct sockaddr
*to
,
3755 int saved_errno
= errno
;
3762 /* to give better errors */
3764 if (saved_errno
== ENOENT
) {
3765 saved_errno
= EHOSTUNREACH
;
3766 } else if (saved_errno
== ENOTSOCK
) {
3767 /* If the fd is not a socket, remove it */
3768 swrap_remove_stale(fd
);
3772 for (i
= 0; i
< (size_t)msg
->msg_iovlen
; i
++) {
3773 avail
+= msg
->msg_iov
[i
].iov_len
;
3777 remain
= MIN(80, avail
);
3782 /* we capture it as one single packet */
3783 buf
= (uint8_t *)malloc(remain
);
3785 /* we just not capture the packet */
3786 errno
= saved_errno
;
3790 for (i
= 0; i
< (size_t)msg
->msg_iovlen
; i
++) {
3791 size_t this_time
= MIN(remain
, (size_t)msg
->msg_iov
[i
].iov_len
);
3793 msg
->msg_iov
[i
].iov_base
,
3796 remain
-= this_time
;
3803 swrap_dump_packet(si
, NULL
, SWRAP_SEND
, buf
, len
);
3804 swrap_dump_packet(si
, NULL
, SWRAP_SEND_RST
, NULL
, 0);
3806 swrap_dump_packet(si
, NULL
, SWRAP_SEND
, buf
, len
);
3811 if (si
->connected
) {
3815 swrap_dump_packet(si
, to
, SWRAP_SENDTO
, buf
, len
);
3816 swrap_dump_packet(si
, to
, SWRAP_SENDTO_UNREACH
, buf
, len
);
3818 swrap_dump_packet(si
, to
, SWRAP_SENDTO
, buf
, len
);
3824 errno
= saved_errno
;
3827 static int swrap_recvmsg_before(int fd
,
3828 struct socket_info
*si
,
3830 struct iovec
*tmp_iov
)
3835 (void)fd
; /* unused */
3839 if (!si
->connected
) {
3844 if (msg
->msg_iovlen
== 0) {
3848 for (i
= 0; i
< (size_t)msg
->msg_iovlen
; i
++) {
3850 nlen
= len
+ msg
->msg_iov
[i
].iov_len
;
3851 if (nlen
> SOCKET_MAX_PACKET
) {
3855 msg
->msg_iovlen
= i
;
3856 if (msg
->msg_iovlen
== 0) {
3857 *tmp_iov
= msg
->msg_iov
[0];
3858 tmp_iov
->iov_len
= MIN(tmp_iov
->iov_len
, SOCKET_MAX_PACKET
);
3859 msg
->msg_iov
= tmp_iov
;
3860 msg
->msg_iovlen
= 1;
3865 if (msg
->msg_name
== NULL
) {
3870 if (msg
->msg_iovlen
== 0) {
3874 if (si
->bound
== 0) {
3875 ret
= swrap_auto_bind(fd
, si
, si
->family
);
3878 * When attempting to read or write to a
3879 * descriptor, if an underlying autobind fails
3880 * because it's not a socket, stop intercepting
3881 * uses of that descriptor.
3883 if (errno
== ENOTSOCK
) {
3884 swrap_remove_stale(fd
);
3887 SWRAP_LOG(SWRAP_LOG_ERROR
,
3888 "swrap_recvmsg_before failed");
3895 errno
= EHOSTUNREACH
;
3902 static int swrap_recvmsg_after(int fd
,
3903 struct socket_info
*si
,
3905 const struct sockaddr_un
*un_addr
,
3906 socklen_t un_addrlen
,
3909 int saved_errno
= errno
;
3911 uint8_t *buf
= NULL
;
3917 /* to give better errors */
3919 if (saved_errno
== ENOENT
) {
3920 saved_errno
= EHOSTUNREACH
;
3921 } else if (saved_errno
== ENOTSOCK
) {
3922 /* If the fd is not a socket, remove it */
3923 swrap_remove_stale(fd
);
3927 for (i
= 0; i
< (size_t)msg
->msg_iovlen
; i
++) {
3928 avail
+= msg
->msg_iov
[i
].iov_len
;
3937 remain
= MIN(80, avail
);
3942 /* we capture it as one single packet */
3943 buf
= (uint8_t *)malloc(remain
);
3945 /* we just not capture the packet */
3946 errno
= saved_errno
;
3950 for (i
= 0; i
< (size_t)msg
->msg_iovlen
; i
++) {
3951 size_t this_time
= MIN(remain
, (size_t)msg
->msg_iov
[i
].iov_len
);
3953 msg
->msg_iov
[i
].iov_base
,
3956 remain
-= this_time
;
3961 if (ret
== -1 && saved_errno
!= EAGAIN
&& saved_errno
!= ENOBUFS
) {
3962 swrap_dump_packet(si
, NULL
, SWRAP_RECV_RST
, NULL
, 0);
3963 } else if (ret
== 0) { /* END OF FILE */
3964 swrap_dump_packet(si
, NULL
, SWRAP_RECV_RST
, NULL
, 0);
3965 } else if (ret
> 0) {
3966 swrap_dump_packet(si
, NULL
, SWRAP_RECV
, buf
, ret
);
3975 if (un_addr
!= NULL
) {
3976 rc
= sockaddr_convert_from_un(si
,
3986 swrap_dump_packet(si
,
3992 swrap_dump_packet(si
,
4005 errno
= saved_errno
;
4007 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4009 msg
->msg_controllen
> 0 &&
4010 msg
->msg_control
!= NULL
) {
4011 rc
= swrap_msghdr_add_socket_info(si
, msg
);
4021 /****************************************************************************
4023 ***************************************************************************/
4025 static ssize_t
swrap_recvfrom(int s
, void *buf
, size_t len
, int flags
,
4026 struct sockaddr
*from
, socklen_t
*fromlen
)
4028 struct sockaddr_un from_addr
;
4029 socklen_t from_addrlen
= sizeof(from_addr
);
4031 struct socket_info
*si
= find_socket_info(s
);
4032 struct sockaddr_storage ss
;
4033 socklen_t ss_len
= sizeof(ss
);
4039 return libc_recvfrom(s
,
4051 if (from
!= NULL
&& fromlen
!= NULL
) {
4052 msg
.msg_name
= from
; /* optional address */
4053 msg
.msg_namelen
= *fromlen
; /* size of address */
4055 msg
.msg_name
= (struct sockaddr
*)(void *)&ss
; /* optional address */
4056 msg
.msg_namelen
= ss_len
; /* size of address */
4058 msg
.msg_iov
= &tmp
; /* scatter/gather array */
4059 msg
.msg_iovlen
= 1; /* # elements in msg_iov */
4060 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4061 msg
.msg_control
= NULL
; /* ancillary data, see below */
4062 msg
.msg_controllen
= 0; /* ancillary data buffer len */
4063 msg
.msg_flags
= 0; /* flags on received message */
4066 tret
= swrap_recvmsg_before(s
, si
, &msg
, &tmp
);
4071 buf
= msg
.msg_iov
[0].iov_base
;
4072 len
= msg
.msg_iov
[0].iov_len
;
4074 /* irix 6.4 forgets to null terminate the sun_path string :-( */
4075 memset(&from_addr
, 0, sizeof(from_addr
));
4076 ret
= libc_recvfrom(s
,
4080 (struct sockaddr
*)(void *)&from_addr
,
4086 tret
= swrap_recvmsg_after(s
,
4096 if (from
!= NULL
&& fromlen
!= NULL
) {
4097 *fromlen
= msg
.msg_namelen
;
4103 #ifdef HAVE_ACCEPT_PSOCKLEN_T
4104 ssize_t
recvfrom(int s
, void *buf
, size_t len
, int flags
,
4105 struct sockaddr
*from
, Psocklen_t fromlen
)
4107 ssize_t
recvfrom(int s
, void *buf
, size_t len
, int flags
,
4108 struct sockaddr
*from
, socklen_t
*fromlen
)
4111 return swrap_recvfrom(s
, buf
, len
, flags
, from
, (socklen_t
*)fromlen
);
4114 /****************************************************************************
4116 ***************************************************************************/
4118 static ssize_t
swrap_sendto(int s
, const void *buf
, size_t len
, int flags
,
4119 const struct sockaddr
*to
, socklen_t tolen
)
4123 struct sockaddr_un un_addr
;
4124 const struct sockaddr_un
*to_un
= NULL
;
4127 struct socket_info
*si
= find_socket_info(s
);
4131 return libc_sendto(s
, buf
, len
, flags
, to
, tolen
);
4134 tmp
.iov_base
= discard_const_p(char, buf
);
4138 msg
.msg_name
= discard_const_p(struct sockaddr
, to
); /* optional address */
4139 msg
.msg_namelen
= tolen
; /* size of address */
4140 msg
.msg_iov
= &tmp
; /* scatter/gather array */
4141 msg
.msg_iovlen
= 1; /* # elements in msg_iov */
4142 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
4143 msg
.msg_control
= NULL
; /* ancillary data, see below */
4144 msg
.msg_controllen
= 0; /* ancillary data buffer len */
4145 msg
.msg_flags
= 0; /* flags on received message */
4148 rc
= swrap_sendmsg_before(s
, si
, &msg
, &tmp
, &un_addr
, &to_un
, &to
, &bcast
);
4153 buf
= msg
.msg_iov
[0].iov_base
;
4154 len
= msg
.msg_iov
[0].iov_len
;
4159 unsigned int prt
= ntohs(((const struct sockaddr_in
*)to
)->sin_port
);
4162 type
= SOCKET_TYPE_CHAR_UDP
;
4164 for(iface
=0; iface
<= MAX_WRAPPED_INTERFACES
; iface
++) {
4165 snprintf(un_addr
.sun_path
, sizeof(un_addr
.sun_path
), "%s/"SOCKET_FORMAT
,
4166 socket_wrapper_dir(), type
, iface
, prt
);
4167 if (stat(un_addr
.sun_path
, &st
) != 0) continue;
4169 /* ignore the any errors in broadcast sends */
4174 (struct sockaddr
*)(void *)&un_addr
,
4178 swrap_dump_packet(si
, to
, SWRAP_SENDTO
, buf
, len
);
4183 ret
= libc_sendto(s
,
4187 (struct sockaddr
*)msg
.msg_name
,
4190 swrap_sendmsg_after(s
, si
, &msg
, to
, ret
);
4195 ssize_t
sendto(int s
, const void *buf
, size_t len
, int flags
,
4196 const struct sockaddr
*to
, socklen_t tolen
)
4198 return swrap_sendto(s
, buf
, len
, flags
, to
, tolen
);
4201 /****************************************************************************
4203 ***************************************************************************/
4205 static ssize_t
swrap_recv(int s
, void *buf
, size_t len
, int flags
)
4207 struct socket_info
*si
;
4209 struct sockaddr_storage ss
;
4210 socklen_t ss_len
= sizeof(ss
);
4215 si
= find_socket_info(s
);
4217 return libc_recv(s
, buf
, len
, flags
);
4224 msg
.msg_name
= (struct sockaddr
*)(void *)&ss
; /* optional address */
4225 msg
.msg_namelen
= ss_len
; /* size of address */
4226 msg
.msg_iov
= &tmp
; /* scatter/gather array */
4227 msg
.msg_iovlen
= 1; /* # elements in msg_iov */
4228 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4229 msg
.msg_control
= NULL
; /* ancillary data, see below */
4230 msg
.msg_controllen
= 0; /* ancillary data buffer len */
4231 msg
.msg_flags
= 0; /* flags on received message */
4234 tret
= swrap_recvmsg_before(s
, si
, &msg
, &tmp
);
4239 buf
= msg
.msg_iov
[0].iov_base
;
4240 len
= msg
.msg_iov
[0].iov_len
;
4242 ret
= libc_recv(s
, buf
, len
, flags
);
4244 tret
= swrap_recvmsg_after(s
, si
, &msg
, NULL
, 0, ret
);
4252 ssize_t
recv(int s
, void *buf
, size_t len
, int flags
)
4254 return swrap_recv(s
, buf
, len
, flags
);
4257 /****************************************************************************
4259 ***************************************************************************/
4261 static ssize_t
swrap_read(int s
, void *buf
, size_t len
)
4263 struct socket_info
*si
;
4266 struct sockaddr_storage ss
;
4267 socklen_t ss_len
= sizeof(ss
);
4271 si
= find_socket_info(s
);
4273 return libc_read(s
, buf
, len
);
4280 msg
.msg_name
= (struct sockaddr
*)(void *)&ss
; /* optional address */
4281 msg
.msg_namelen
= ss_len
; /* size of address */
4282 msg
.msg_iov
= &tmp
; /* scatter/gather array */
4283 msg
.msg_iovlen
= 1; /* # elements in msg_iov */
4284 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4285 msg
.msg_control
= NULL
; /* ancillary data, see below */
4286 msg
.msg_controllen
= 0; /* ancillary data buffer len */
4287 msg
.msg_flags
= 0; /* flags on received message */
4290 tret
= swrap_recvmsg_before(s
, si
, &msg
, &tmp
);
4292 if (tret
== -ENOTSOCK
) {
4293 return libc_read(s
, buf
, len
);
4298 buf
= msg
.msg_iov
[0].iov_base
;
4299 len
= msg
.msg_iov
[0].iov_len
;
4301 ret
= libc_read(s
, buf
, len
);
4303 tret
= swrap_recvmsg_after(s
, si
, &msg
, NULL
, 0, ret
);
4311 ssize_t
read(int s
, void *buf
, size_t len
)
4313 return swrap_read(s
, buf
, len
);
4316 /****************************************************************************
4318 ***************************************************************************/
4320 static ssize_t
swrap_send(int s
, const void *buf
, size_t len
, int flags
)
4324 struct sockaddr_un un_addr
;
4327 struct socket_info
*si
= find_socket_info(s
);
4330 return libc_send(s
, buf
, len
, flags
);
4333 tmp
.iov_base
= discard_const_p(char, buf
);
4337 msg
.msg_name
= NULL
; /* optional address */
4338 msg
.msg_namelen
= 0; /* size of address */
4339 msg
.msg_iov
= &tmp
; /* scatter/gather array */
4340 msg
.msg_iovlen
= 1; /* # elements in msg_iov */
4341 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
4342 msg
.msg_control
= NULL
; /* ancillary data, see below */
4343 msg
.msg_controllen
= 0; /* ancillary data buffer len */
4344 msg
.msg_flags
= 0; /* flags on received message */
4347 rc
= swrap_sendmsg_before(s
, si
, &msg
, &tmp
, &un_addr
, NULL
, NULL
, NULL
);
4352 buf
= msg
.msg_iov
[0].iov_base
;
4353 len
= msg
.msg_iov
[0].iov_len
;
4355 ret
= libc_send(s
, buf
, len
, flags
);
4357 swrap_sendmsg_after(s
, si
, &msg
, NULL
, ret
);
4362 ssize_t
send(int s
, const void *buf
, size_t len
, int flags
)
4364 return swrap_send(s
, buf
, len
, flags
);
4367 /****************************************************************************
4369 ***************************************************************************/
4371 static ssize_t
swrap_recvmsg(int s
, struct msghdr
*omsg
, int flags
)
4373 struct sockaddr_un from_addr
;
4374 socklen_t from_addrlen
= sizeof(from_addr
);
4375 struct socket_info
*si
;
4378 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4379 size_t msg_ctrllen_filled
;
4380 size_t msg_ctrllen_left
;
4386 si
= find_socket_info(s
);
4388 return libc_recvmsg(s
, omsg
, flags
);
4391 tmp
.iov_base
= NULL
;
4395 msg
.msg_name
= (struct sockaddr
*)&from_addr
; /* optional address */
4396 msg
.msg_namelen
= from_addrlen
; /* size of address */
4397 msg
.msg_iov
= omsg
->msg_iov
; /* scatter/gather array */
4398 msg
.msg_iovlen
= omsg
->msg_iovlen
; /* # elements in msg_iov */
4399 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4400 msg_ctrllen_filled
= 0;
4401 msg_ctrllen_left
= omsg
->msg_controllen
;
4403 msg
.msg_control
= omsg
->msg_control
; /* ancillary data, see below */
4404 msg
.msg_controllen
= omsg
->msg_controllen
; /* ancillary data buffer len */
4405 msg
.msg_flags
= omsg
->msg_flags
; /* flags on received message */
4408 rc
= swrap_recvmsg_before(s
, si
, &msg
, &tmp
);
4413 ret
= libc_recvmsg(s
, &msg
, flags
);
4415 msg
.msg_name
= omsg
->msg_name
;
4416 msg
.msg_namelen
= omsg
->msg_namelen
;
4418 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4419 msg_ctrllen_filled
+= msg
.msg_controllen
;
4420 msg_ctrllen_left
-= msg
.msg_controllen
;
4422 if (omsg
->msg_control
!= NULL
) {
4425 p
= omsg
->msg_control
;
4426 p
+= msg_ctrllen_filled
;
4428 msg
.msg_control
= p
;
4429 msg
.msg_controllen
= msg_ctrllen_left
;
4431 msg
.msg_control
= NULL
;
4432 msg
.msg_controllen
= 0;
4436 rc
= swrap_recvmsg_after(s
, si
, &msg
, &from_addr
, from_addrlen
, ret
);
4441 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4442 if (omsg
->msg_control
!= NULL
) {
4443 /* msg.msg_controllen = space left */
4444 msg_ctrllen_left
= msg
.msg_controllen
;
4445 msg_ctrllen_filled
= omsg
->msg_controllen
- msg_ctrllen_left
;
4448 /* Update the original message length */
4449 omsg
->msg_controllen
= msg_ctrllen_filled
;
4450 omsg
->msg_flags
= msg
.msg_flags
;
4452 omsg
->msg_iovlen
= msg
.msg_iovlen
;
4457 ssize_t
recvmsg(int sockfd
, struct msghdr
*msg
, int flags
)
4459 return swrap_recvmsg(sockfd
, msg
, flags
);
4462 /****************************************************************************
4464 ***************************************************************************/
4466 static ssize_t
swrap_sendmsg(int s
, const struct msghdr
*omsg
, int flags
)
4470 struct sockaddr_un un_addr
;
4471 const struct sockaddr_un
*to_un
= NULL
;
4472 const struct sockaddr
*to
= NULL
;
4475 struct socket_info
*si
= find_socket_info(s
);
4479 return libc_sendmsg(s
, omsg
, flags
);
4482 ZERO_STRUCT(un_addr
);
4484 tmp
.iov_base
= NULL
;
4488 msg
.msg_name
= omsg
->msg_name
; /* optional address */
4489 msg
.msg_namelen
= omsg
->msg_namelen
; /* size of address */
4490 msg
.msg_iov
= omsg
->msg_iov
; /* scatter/gather array */
4491 msg
.msg_iovlen
= omsg
->msg_iovlen
; /* # elements in msg_iov */
4492 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4493 if (msg
.msg_controllen
> 0 && msg
.msg_control
!= NULL
) {
4494 /* omsg is a const so use a local buffer for modifications */
4495 uint8_t cmbuf
[omsg
->msg_controllen
];
4497 memcpy(cmbuf
, omsg
->msg_control
, omsg
->msg_controllen
);
4499 msg
.msg_control
= cmbuf
; /* ancillary data, see below */
4500 msg
.msg_controllen
= omsg
->msg_controllen
; /* ancillary data buffer len */
4502 msg
.msg_flags
= omsg
->msg_flags
; /* flags on received message */
4505 rc
= swrap_sendmsg_before(s
, si
, &msg
, &tmp
, &un_addr
, &to_un
, &to
, &bcast
);
4513 unsigned int prt
= ntohs(((const struct sockaddr_in
*)to
)->sin_port
);
4521 for (i
= 0; i
< (size_t)msg
.msg_iovlen
; i
++) {
4522 avail
+= msg
.msg_iov
[i
].iov_len
;
4528 /* we capture it as one single packet */
4529 buf
= (uint8_t *)malloc(remain
);
4534 for (i
= 0; i
< (size_t)msg
.msg_iovlen
; i
++) {
4535 size_t this_time
= MIN(remain
, (size_t)msg
.msg_iov
[i
].iov_len
);
4537 msg
.msg_iov
[i
].iov_base
,
4540 remain
-= this_time
;
4543 type
= SOCKET_TYPE_CHAR_UDP
;
4545 for(iface
=0; iface
<= MAX_WRAPPED_INTERFACES
; iface
++) {
4546 snprintf(un_addr
.sun_path
, sizeof(un_addr
.sun_path
), "%s/"SOCKET_FORMAT
,
4547 socket_wrapper_dir(), type
, iface
, prt
);
4548 if (stat(un_addr
.sun_path
, &st
) != 0) continue;
4550 msg
.msg_name
= &un_addr
; /* optional address */
4551 msg
.msg_namelen
= sizeof(un_addr
); /* size of address */
4553 /* ignore the any errors in broadcast sends */
4554 libc_sendmsg(s
, &msg
, flags
);
4557 swrap_dump_packet(si
, to
, SWRAP_SENDTO
, buf
, len
);
4563 ret
= libc_sendmsg(s
, &msg
, flags
);
4565 swrap_sendmsg_after(s
, si
, &msg
, to
, ret
);
4570 ssize_t
sendmsg(int s
, const struct msghdr
*omsg
, int flags
)
4572 return swrap_sendmsg(s
, omsg
, flags
);
4575 /****************************************************************************
4577 ***************************************************************************/
4579 static ssize_t
swrap_readv(int s
, const struct iovec
*vector
, int count
)
4581 struct socket_info
*si
;
4584 struct sockaddr_storage ss
;
4585 socklen_t ss_len
= sizeof(ss
);
4589 si
= find_socket_info(s
);
4591 return libc_readv(s
, vector
, count
);
4594 tmp
.iov_base
= NULL
;
4598 msg
.msg_name
= (struct sockaddr
*)(void *)&ss
; /* optional address */
4599 msg
.msg_namelen
= ss_len
; /* size of address */
4600 msg
.msg_iov
= discard_const_p(struct iovec
, vector
); /* scatter/gather array */
4601 msg
.msg_iovlen
= count
; /* # elements in msg_iov */
4602 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4603 msg
.msg_control
= NULL
; /* ancillary data, see below */
4604 msg
.msg_controllen
= 0; /* ancillary data buffer len */
4605 msg
.msg_flags
= 0; /* flags on received message */
4608 rc
= swrap_recvmsg_before(s
, si
, &msg
, &tmp
);
4610 if (rc
== -ENOTSOCK
) {
4611 return libc_readv(s
, vector
, count
);
4616 ret
= libc_readv(s
, msg
.msg_iov
, msg
.msg_iovlen
);
4618 rc
= swrap_recvmsg_after(s
, si
, &msg
, NULL
, 0, ret
);
4626 ssize_t
readv(int s
, const struct iovec
*vector
, int count
)
4628 return swrap_readv(s
, vector
, count
);
4631 /****************************************************************************
4633 ***************************************************************************/
4635 static ssize_t
swrap_writev(int s
, const struct iovec
*vector
, int count
)
4639 struct sockaddr_un un_addr
;
4642 struct socket_info
*si
= find_socket_info(s
);
4645 return libc_writev(s
, vector
, count
);
4648 tmp
.iov_base
= NULL
;
4652 msg
.msg_name
= NULL
; /* optional address */
4653 msg
.msg_namelen
= 0; /* size of address */
4654 msg
.msg_iov
= discard_const_p(struct iovec
, vector
); /* scatter/gather array */
4655 msg
.msg_iovlen
= count
; /* # elements in msg_iov */
4656 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
4657 msg
.msg_control
= NULL
; /* ancillary data, see below */
4658 msg
.msg_controllen
= 0; /* ancillary data buffer len */
4659 msg
.msg_flags
= 0; /* flags on received message */
4662 rc
= swrap_sendmsg_before(s
, si
, &msg
, &tmp
, &un_addr
, NULL
, NULL
, NULL
);
4664 if (rc
== -ENOTSOCK
) {
4665 return libc_readv(s
, vector
, count
);
4670 ret
= libc_writev(s
, msg
.msg_iov
, msg
.msg_iovlen
);
4672 swrap_sendmsg_after(s
, si
, &msg
, NULL
, ret
);
4677 ssize_t
writev(int s
, const struct iovec
*vector
, int count
)
4679 return swrap_writev(s
, vector
, count
);
4682 /****************************
4684 ***************************/
4686 static int swrap_close(int fd
)
4688 struct socket_info
*si
= find_socket_info(fd
);
4689 struct socket_info_fd
*fi
;
4693 return libc_close(fd
);
4696 for (fi
= si
->fds
; fi
; fi
= fi
->next
) {
4698 SWRAP_DLIST_REMOVE(si
->fds
, fi
);
4705 /* there are still references left */
4706 return libc_close(fd
);
4709 SWRAP_DLIST_REMOVE(sockets
, si
);
4711 if (si
->myname
&& si
->peername
) {
4712 swrap_dump_packet(si
, NULL
, SWRAP_CLOSE_SEND
, NULL
, 0);
4715 ret
= libc_close(fd
);
4717 if (si
->myname
&& si
->peername
) {
4718 swrap_dump_packet(si
, NULL
, SWRAP_CLOSE_RECV
, NULL
, 0);
4719 swrap_dump_packet(si
, NULL
, SWRAP_CLOSE_ACK
, NULL
, 0);
4722 if (si
->bindname
!= NULL
) {
4726 if (si
->myname
) free(si
->myname
);
4727 if (si
->peername
) free(si
->peername
);
4729 unlink(si
->tmp_path
);
4739 return swrap_close(fd
);
4742 /****************************
4744 ***************************/
4746 static int swrap_dup(int fd
)
4748 struct socket_info
*si
;
4749 struct socket_info_fd
*fi
;
4751 si
= find_socket_info(fd
);
4754 return libc_dup(fd
);
4757 fi
= (struct socket_info_fd
*)calloc(1, sizeof(struct socket_info_fd
));
4763 fi
->fd
= libc_dup(fd
);
4765 int saved_errno
= errno
;
4767 errno
= saved_errno
;
4771 /* Make sure we don't have an entry for the fd */
4772 swrap_remove_stale(fi
->fd
);
4774 SWRAP_DLIST_ADD(si
->fds
, fi
);
4780 return swrap_dup(fd
);
4783 /****************************
4785 ***************************/
4787 static int swrap_dup2(int fd
, int newfd
)
4789 struct socket_info
*si
;
4790 struct socket_info_fd
*fi
;
4792 si
= find_socket_info(fd
);
4795 return libc_dup2(fd
, newfd
);
4798 if (find_socket_info(newfd
)) {
4799 /* dup2() does an implicit close of newfd, which we
4800 * need to emulate */
4804 fi
= (struct socket_info_fd
*)calloc(1, sizeof(struct socket_info_fd
));
4810 fi
->fd
= libc_dup2(fd
, newfd
);
4812 int saved_errno
= errno
;
4814 errno
= saved_errno
;
4818 /* Make sure we don't have an entry for the fd */
4819 swrap_remove_stale(fi
->fd
);
4821 SWRAP_DLIST_ADD(si
->fds
, fi
);
4825 int dup2(int fd
, int newfd
)
4827 return swrap_dup2(fd
, newfd
);
4830 /****************************
4832 ***************************/
4835 static int swrap_eventfd(int count
, int flags
)
4839 fd
= libc_eventfd(count
, flags
);
4841 swrap_remove_stale(fd
);
4847 int eventfd(int count
, int flags
)
4849 return swrap_eventfd(count
, flags
);
4853 /****************************
4855 ***************************/
4858 * This function is called when the library is unloaded and makes sure that
4859 * sockets get closed and the unix file for the socket are unlinked.
4861 void swrap_destructor(void)
4863 struct socket_info
*s
= sockets
;
4866 struct socket_info_fd
*f
= s
->fds
;