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>
87 /* GCC have printf type attribute check. */
88 #ifdef HAVE_FUNCTION_ATTRIBUTE_FORMAT
89 #define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
91 #define PRINTF_ATTRIBUTE(a,b)
92 #endif /* HAVE_FUNCTION_ATTRIBUTE_FORMAT */
94 #ifdef HAVE_DESTRUCTOR_ATTRIBUTE
95 #define DESTRUCTOR_ATTRIBUTE __attribute__ ((destructor))
97 #define DESTRUCTOR_ATTRIBUTE
100 #ifdef HAVE_GCC_THREAD_LOCAL_STORAGE
101 # define SWRAP_THREAD __thread
103 # define SWRAP_THREAD
107 #define MIN(a,b) ((a)<(b)?(a):(b))
111 #define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
114 #ifndef discard_const
115 #define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
118 #ifndef discard_const_p
119 #define discard_const_p(type, ptr) ((type *)discard_const(ptr))
123 # ifndef IPV6_RECVPKTINFO
124 # define IPV6_RECVPKTINFO IPV6_PKTINFO
125 # endif /* IPV6_RECVPKTINFO */
126 #endif /* IPV6_PKTINFO */
128 #define SWRAP_DLIST_ADD(list,item) do { \
130 (item)->prev = NULL; \
131 (item)->next = NULL; \
134 (item)->prev = NULL; \
135 (item)->next = (list); \
136 (list)->prev = (item); \
141 #define SWRAP_DLIST_REMOVE(list,item) do { \
142 if ((list) == (item)) { \
143 (list) = (item)->next; \
145 (list)->prev = NULL; \
148 if ((item)->prev) { \
149 (item)->prev->next = (item)->next; \
151 if ((item)->next) { \
152 (item)->next->prev = (item)->prev; \
155 (item)->prev = NULL; \
156 (item)->next = NULL; \
159 #if defined(HAVE_GETTIMEOFDAY_TZ) || defined(HAVE_GETTIMEOFDAY_TZ_VOID)
160 #define swrapGetTimeOfDay(tval) gettimeofday(tval,NULL)
162 #define swrapGetTimeOfDay(tval) gettimeofday(tval)
165 /* we need to use a very terse format here as IRIX 6.4 silently
166 truncates names to 16 chars, so if we use a longer name then we
167 can't tell which port a packet came from with recvfrom()
169 with this format we have 8 chars left for the directory name
171 #define SOCKET_FORMAT "%c%02X%04X"
172 #define SOCKET_TYPE_CHAR_TCP 'T'
173 #define SOCKET_TYPE_CHAR_UDP 'U'
174 #define SOCKET_TYPE_CHAR_TCP_V6 'X'
175 #define SOCKET_TYPE_CHAR_UDP_V6 'Y'
178 * Cut down to 1500 byte packets for stream sockets,
179 * which makes it easier to format PCAP capture files
180 * (as the caller will simply continue from here)
182 #define SOCKET_MAX_PACKET 1500
184 #define SOCKET_MAX_SOCKETS 1024
186 /* This limit is to avoid broadcast sendto() needing to stat too many
187 * files. It may be raised (with a performance cost) to up to 254
188 * without changing the format above */
189 #define MAX_WRAPPED_INTERFACES 40
191 struct socket_info_fd {
192 struct socket_info_fd *prev, *next;
198 struct socket_info_fd *fds;
212 struct sockaddr *bindname;
213 socklen_t bindname_len;
215 struct sockaddr *myname;
216 socklen_t myname_len;
218 struct sockaddr *peername;
219 socklen_t peername_len;
222 unsigned long pck_snd;
223 unsigned long pck_rcv;
226 struct socket_info *prev, *next;
230 * File descriptors are shared between threads so we should share socket
233 struct socket_info *sockets;
235 /* Function prototypes */
237 bool socket_wrapper_enabled(void);
238 void swrap_destructor(void) DESTRUCTOR_ATTRIBUTE;
241 # define SWRAP_LOG(...)
244 static void swrap_log(enum swrap_dbglvl_e dbglvl, const char *format, ...) PRINTF_ATTRIBUTE(2, 3);
245 # define SWRAP_LOG(dbglvl, ...) swrap_log((dbglvl), __VA_ARGS__)
247 static void swrap_log(enum swrap_dbglvl_e dbglvl, const char *format, ...)
252 unsigned int lvl = 0;
254 d = getenv("SOCKET_WRAPPER_DEBUGLEVEL");
259 va_start(va, format);
260 vsnprintf(buffer, sizeof(buffer), format, va);
265 case SWRAP_LOG_ERROR:
267 "SWRAP_ERROR(%d): %s\n",
268 (int)getpid(), buffer);
272 "SWRAP_WARN(%d): %s\n",
273 (int)getpid(), buffer);
275 case SWRAP_LOG_DEBUG:
277 "SWRAP_DEBUG(%d): %s\n",
278 (int)getpid(), buffer);
280 case SWRAP_LOG_TRACE:
282 "SWRAP_TRACE(%d): %s\n",
283 (int)getpid(), buffer);
290 /*********************************************************
291 * SWRAP LOADING LIBC FUNCTIONS
292 *********************************************************/
296 struct swrap_libc_fns {
297 int (*libc_accept)(int sockfd,
298 struct sockaddr *addr,
300 int (*libc_bind)(int sockfd,
301 const struct sockaddr *addr,
303 int (*libc_close)(int fd);
304 int (*libc_connect)(int sockfd,
305 const struct sockaddr *addr,
307 int (*libc_dup)(int fd);
308 int (*libc_dup2)(int oldfd, int newfd);
310 int (*libc_eventfd)(int count, int flags);
312 int (*libc_getpeername)(int sockfd,
313 struct sockaddr *addr,
315 int (*libc_getsockname)(int sockfd,
316 struct sockaddr *addr,
318 int (*libc_getsockopt)(int sockfd,
323 int (*libc_ioctl)(int d, unsigned long int request, ...);
324 int (*libc_listen)(int sockfd, int backlog);
325 int (*libc_open)(const char *pathname, int flags, mode_t mode);
326 int (*libc_pipe)(int pipefd[2]);
327 int (*libc_read)(int fd, void *buf, size_t count);
328 ssize_t (*libc_readv)(int fd, const struct iovec *iov, int iovcnt);
329 int (*libc_recv)(int sockfd, void *buf, size_t len, int flags);
330 int (*libc_recvfrom)(int sockfd,
334 struct sockaddr *src_addr,
336 int (*libc_recvmsg)(int sockfd, const struct msghdr *msg, int flags);
337 int (*libc_send)(int sockfd, const void *buf, size_t len, int flags);
338 int (*libc_sendmsg)(int sockfd, const struct msghdr *msg, int flags);
339 int (*libc_sendto)(int sockfd,
343 const struct sockaddr *dst_addr,
345 int (*libc_setsockopt)(int sockfd,
351 int (*libc_signalfd)(int fd, const sigset_t *mask, int flags);
353 int (*libc_socket)(int domain, int type, int protocol);
354 int (*libc_socketpair)(int domain, int type, int protocol, int sv[2]);
355 #ifdef HAVE_TIMERFD_CREATE
356 int (*libc_timerfd_create)(int clockid, int flags);
358 ssize_t (*libc_writev)(int fd, const struct iovec *iov, int iovcnt);
363 void *libsocket_handle;
370 struct swrap_libc_fns fns;
373 static struct swrap swrap;
376 static const char *socket_wrapper_dir(void);
378 #define LIBC_NAME "libc.so"
387 static const char *swrap_str_lib(enum swrap_lib lib)
394 case SWRAP_LIBSOCKET:
398 /* Compiler would warn us about unhandled enum value if we get here */
403 static void *swrap_load_lib_handle(enum swrap_lib lib)
405 int flags = RTLD_LAZY;
410 flags |= RTLD_DEEPBIND;
416 case SWRAP_LIBSOCKET:
417 #ifdef HAVE_LIBSOCKET
418 handle = swrap.libsocket_handle;
419 if (handle == NULL) {
420 for (handle = NULL, i = 10; handle == NULL && i >= 0; i--) {
421 char soname[256] = {0};
423 snprintf(soname, sizeof(soname), "libsocket.so.%d", i);
424 handle = dlopen(soname, flags);
427 swrap.libsocket_handle = handle;
433 handle = swrap.libc_handle;
435 if (handle == NULL) {
436 handle = dlopen(LIBC_SO, flags);
439 if (handle == NULL) {
440 for (handle = NULL, i = 10; handle == NULL && i >= 0; i--) {
441 char soname[256] = {0};
443 snprintf(soname, sizeof(soname), "libc.so.%d", i);
444 handle = dlopen(soname, flags);
447 swrap.libc_handle = handle;
452 if (handle == NULL) {
454 handle = swrap.libc_handle = swrap.libsocket_handle = RTLD_NEXT;
456 SWRAP_LOG(SWRAP_LOG_ERROR,
457 "Failed to dlopen library: %s\n",
466 static void *_swrap_load_lib_function(enum swrap_lib lib, const char *fn_name)
471 handle = swrap_load_lib_handle(lib);
473 func = dlsym(handle, fn_name);
475 SWRAP_LOG(SWRAP_LOG_ERROR,
476 "Failed to find %s: %s\n",
481 SWRAP_LOG(SWRAP_LOG_TRACE,
483 fn_name, swrap_str_lib(lib));
487 #define swrap_load_lib_function(lib, fn_name) \
488 if (swrap.fns.libc_##fn_name == NULL) { \
489 *(void **) (&swrap.fns.libc_##fn_name) = \
490 _swrap_load_lib_function(lib, #fn_name); \
497 * Functions especially from libc need to be loaded individually, you can't load
498 * all at once or gdb will segfault at startup. The same applies to valgrind and
499 * has probably something todo with with the linker.
500 * So we need load each function at the point it is called the first time.
502 static int libc_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
504 swrap_load_lib_function(SWRAP_LIBSOCKET, accept);
506 return swrap.fns.libc_accept(sockfd, addr, addrlen);
509 static int libc_bind(int sockfd,
510 const struct sockaddr *addr,
513 swrap_load_lib_function(SWRAP_LIBSOCKET, bind);
515 return swrap.fns.libc_bind(sockfd, addr, addrlen);
518 static int libc_close(int fd)
520 swrap_load_lib_function(SWRAP_LIBC, close);
522 return swrap.fns.libc_close(fd);
525 static int libc_connect(int sockfd,
526 const struct sockaddr *addr,
529 swrap_load_lib_function(SWRAP_LIBSOCKET, connect);
531 return swrap.fns.libc_connect(sockfd, addr, addrlen);
534 static int libc_dup(int fd)
536 swrap_load_lib_function(SWRAP_LIBC, dup);
538 return swrap.fns.libc_dup(fd);
541 static int libc_dup2(int oldfd, int newfd)
543 swrap_load_lib_function(SWRAP_LIBC, dup2);
545 return swrap.fns.libc_dup2(oldfd, newfd);
549 static int libc_eventfd(int count, int flags)
551 swrap_load_lib_function(SWRAP_LIBC, eventfd);
553 return swrap.fns.libc_eventfd(count, flags);
557 static int libc_getpeername(int sockfd,
558 struct sockaddr *addr,
561 swrap_load_lib_function(SWRAP_LIBSOCKET, getpeername);
563 return swrap.fns.libc_getpeername(sockfd, addr, addrlen);
566 static int libc_getsockname(int sockfd,
567 struct sockaddr *addr,
570 swrap_load_lib_function(SWRAP_LIBSOCKET, getsockname);
572 return swrap.fns.libc_getsockname(sockfd, addr, addrlen);
575 static int libc_getsockopt(int sockfd,
581 swrap_load_lib_function(SWRAP_LIBSOCKET, getsockopt);
583 return swrap.fns.libc_getsockopt(sockfd, level, optname, optval, optlen);
586 static int libc_vioctl(int d, unsigned long int request, va_list ap)
592 swrap_load_lib_function(SWRAP_LIBC, ioctl);
594 for (i = 0; i < 4; i++) {
595 args[i] = va_arg(ap, long int);
598 rc = swrap.fns.libc_ioctl(d,
608 static int libc_listen(int sockfd, int backlog)
610 swrap_load_lib_function(SWRAP_LIBSOCKET, listen);
612 return swrap.fns.libc_listen(sockfd, backlog);
615 static int libc_vopen(const char *pathname, int flags, va_list ap)
620 swrap_load_lib_function(SWRAP_LIBC, open);
622 mode = va_arg(ap, long int);
624 fd = swrap.fns.libc_open(pathname, flags, (mode_t)mode);
629 static int libc_open(const char *pathname, int flags, ...)
635 fd = libc_vopen(pathname, flags, ap);
641 static int libc_pipe(int pipefd[2])
643 swrap_load_lib_function(SWRAP_LIBSOCKET, pipe);
645 return swrap.fns.libc_pipe(pipefd);
648 static int libc_read(int fd, void *buf, size_t count)
650 swrap_load_lib_function(SWRAP_LIBC, read);
652 return swrap.fns.libc_read(fd, buf, count);
655 static ssize_t libc_readv(int fd, const struct iovec *iov, int iovcnt)
657 swrap_load_lib_function(SWRAP_LIBSOCKET, readv);
659 return swrap.fns.libc_readv(fd, iov, iovcnt);
662 static int libc_recv(int sockfd, void *buf, size_t len, int flags)
664 swrap_load_lib_function(SWRAP_LIBSOCKET, recv);
666 return swrap.fns.libc_recv(sockfd, buf, len, flags);
669 static int libc_recvfrom(int sockfd,
673 struct sockaddr *src_addr,
676 swrap_load_lib_function(SWRAP_LIBSOCKET, recvfrom);
678 return swrap.fns.libc_recvfrom(sockfd, buf, len, flags, src_addr, addrlen);
681 static int libc_recvmsg(int sockfd, struct msghdr *msg, int flags)
683 swrap_load_lib_function(SWRAP_LIBSOCKET, recvmsg);
685 return swrap.fns.libc_recvmsg(sockfd, msg, flags);
688 static int libc_send(int sockfd, const void *buf, size_t len, int flags)
690 swrap_load_lib_function(SWRAP_LIBSOCKET, send);
692 return swrap.fns.libc_send(sockfd, buf, len, flags);
695 static int libc_sendmsg(int sockfd, const struct msghdr *msg, int flags)
697 swrap_load_lib_function(SWRAP_LIBSOCKET, sendmsg);
699 return swrap.fns.libc_sendmsg(sockfd, msg, flags);
702 static int libc_sendto(int sockfd,
706 const struct sockaddr *dst_addr,
709 swrap_load_lib_function(SWRAP_LIBSOCKET, sendto);
711 return swrap.fns.libc_sendto(sockfd, buf, len, flags, dst_addr, addrlen);
714 static int libc_setsockopt(int sockfd,
720 swrap_load_lib_function(SWRAP_LIBSOCKET, setsockopt);
722 return swrap.fns.libc_setsockopt(sockfd, level, optname, optval, optlen);
726 static int libc_signalfd(int fd, const sigset_t *mask, int flags)
728 swrap_load_lib_function(SWRAP_LIBSOCKET, signalfd);
730 return swrap.fns.libc_signalfd(fd, mask, flags);
734 static int libc_socket(int domain, int type, int protocol)
736 swrap_load_lib_function(SWRAP_LIBSOCKET, socket);
738 return swrap.fns.libc_socket(domain, type, protocol);
741 static int libc_socketpair(int domain, int type, int protocol, int sv[2])
743 swrap_load_lib_function(SWRAP_LIBSOCKET, socketpair);
745 return swrap.fns.libc_socketpair(domain, type, protocol, sv);
748 #ifdef HAVE_TIMERFD_CREATE
749 static int libc_timerfd_create(int clockid, int flags)
751 swrap_load_lib_function(SWRAP_LIBC, timerfd_create);
753 return swrap.fns.libc_timerfd_create(clockid, flags);
757 static ssize_t libc_writev(int fd, const struct iovec *iov, int iovcnt)
759 swrap_load_lib_function(SWRAP_LIBSOCKET, writev);
761 return swrap.fns.libc_writev(fd, iov, iovcnt);
764 /*********************************************************
765 * SWRAP HELPER FUNCTIONS
766 *********************************************************/
772 static const struct in6_addr *swrap_ipv6(void)
774 static struct in6_addr v;
775 static int initialized;
783 ret = inet_pton(AF_INET6, "FD00::5357:5F00", &v);
792 static struct sockaddr *sockaddr_dup(const void *data, socklen_t len)
794 struct sockaddr *ret = (struct sockaddr *)malloc(len);
795 memcpy(ret, data, len);
799 static void set_port(int family, int prt, struct sockaddr *addr)
803 ((struct sockaddr_in *)addr)->sin_port = htons(prt);
807 ((struct sockaddr_in6 *)addr)->sin6_port = htons(prt);
813 static size_t socket_length(int family)
817 return sizeof(struct sockaddr_in);
820 return sizeof(struct sockaddr_in6);
826 static const char *socket_wrapper_dir(void)
828 const char *s = getenv("SOCKET_WRAPPER_DIR");
832 if (strncmp(s, "./", 2) == 0) {
836 SWRAP_LOG(SWRAP_LOG_TRACE, "socket_wrapper_dir: %s", s);
840 bool socket_wrapper_enabled(void)
842 const char *s = socket_wrapper_dir();
844 return s != NULL ? true : false;
847 static unsigned int socket_wrapper_default_iface(void)
849 const char *s = getenv("SOCKET_WRAPPER_DEFAULT_IFACE");
852 if (sscanf(s, "%u", &iface) == 1) {
853 if (iface >= 1 && iface <= MAX_WRAPPED_INTERFACES) {
859 return 1;/* 127.0.0.1 */
862 static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, socklen_t *len)
869 p = strrchr(un->sun_path, '/');
870 if (p) p++; else p = un->sun_path;
872 if (sscanf(p, SOCKET_FORMAT, &type, &iface, &prt) != 3) {
877 SWRAP_LOG(SWRAP_LOG_TRACE, "type %c iface %u port %u",
880 if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
891 case SOCKET_TYPE_CHAR_TCP:
892 case SOCKET_TYPE_CHAR_UDP: {
893 struct sockaddr_in *in2 = (struct sockaddr_in *)(void *)in;
895 if ((*len) < sizeof(*in2)) {
900 memset(in2, 0, sizeof(*in2));
901 in2->sin_family = AF_INET;
902 in2->sin_addr.s_addr = htonl((127<<24) | iface);
903 in2->sin_port = htons(prt);
909 case SOCKET_TYPE_CHAR_TCP_V6:
910 case SOCKET_TYPE_CHAR_UDP_V6: {
911 struct sockaddr_in6 *in2 = (struct sockaddr_in6 *)(void *)in;
913 if ((*len) < sizeof(*in2)) {
918 memset(in2, 0, sizeof(*in2));
919 in2->sin6_family = AF_INET6;
920 in2->sin6_addr = *swrap_ipv6();
921 in2->sin6_addr.s6_addr[15] = iface;
922 in2->sin6_port = htons(prt);
936 static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un,
944 if (bcast) *bcast = 0;
946 switch (inaddr->sa_family) {
948 const struct sockaddr_in *in =
949 (const struct sockaddr_in *)(const void *)inaddr;
950 unsigned int addr = ntohl(in->sin_addr.s_addr);
957 u_type = SOCKET_TYPE_CHAR_TCP;
960 u_type = SOCKET_TYPE_CHAR_UDP;
961 a_type = SOCKET_TYPE_CHAR_UDP;
962 b_type = SOCKET_TYPE_CHAR_UDP;
965 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
966 errno = ESOCKTNOSUPPORT;
970 prt = ntohs(in->sin_port);
971 if (a_type && addr == 0xFFFFFFFF) {
972 /* 255.255.255.255 only udp */
975 iface = socket_wrapper_default_iface();
976 } else if (b_type && addr == 0x7FFFFFFF) {
977 /* 127.255.255.255 only udp */
980 iface = socket_wrapper_default_iface();
981 } else if ((addr & 0xFFFFFF00) == 0x7F000000) {
985 iface = (addr & 0x000000FF);
990 if (bcast) *bcast = is_bcast;
995 const struct sockaddr_in6 *in =
996 (const struct sockaddr_in6 *)(const void *)inaddr;
997 struct in6_addr cmp1, cmp2;
1001 type = SOCKET_TYPE_CHAR_TCP_V6;
1004 type = SOCKET_TYPE_CHAR_UDP_V6;
1007 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1008 errno = ESOCKTNOSUPPORT;
1012 /* XXX no multicast/broadcast */
1014 prt = ntohs(in->sin6_port);
1016 cmp1 = *swrap_ipv6();
1017 cmp2 = in->sin6_addr;
1018 cmp2.s6_addr[15] = 0;
1019 if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
1020 iface = in->sin6_addr.s6_addr[15];
1022 errno = ENETUNREACH;
1030 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family!\n");
1031 errno = ENETUNREACH;
1036 SWRAP_LOG(SWRAP_LOG_WARN, "Port not set\n");
1042 snprintf(un->sun_path, sizeof(un->sun_path), "%s/EINVAL",
1043 socket_wrapper_dir());
1044 SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
1045 /* the caller need to do more processing */
1049 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT,
1050 socket_wrapper_dir(), type, iface, prt);
1051 SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
1056 static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un,
1065 if (bcast) *bcast = 0;
1067 switch (si->family) {
1069 const struct sockaddr_in *in =
1070 (const struct sockaddr_in *)(const void *)inaddr;
1071 unsigned int addr = ntohl(in->sin_addr.s_addr);
1077 prt = ntohs(in->sin_port);
1081 u_type = SOCKET_TYPE_CHAR_TCP;
1082 d_type = SOCKET_TYPE_CHAR_TCP;
1085 u_type = SOCKET_TYPE_CHAR_UDP;
1086 d_type = SOCKET_TYPE_CHAR_UDP;
1087 a_type = SOCKET_TYPE_CHAR_UDP;
1088 b_type = SOCKET_TYPE_CHAR_UDP;
1091 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1092 errno = ESOCKTNOSUPPORT;
1100 iface = socket_wrapper_default_iface();
1101 } else if (a_type && addr == 0xFFFFFFFF) {
1102 /* 255.255.255.255 only udp */
1105 iface = socket_wrapper_default_iface();
1106 } else if (b_type && addr == 0x7FFFFFFF) {
1107 /* 127.255.255.255 only udp */
1110 iface = socket_wrapper_default_iface();
1111 } else if ((addr & 0xFFFFFF00) == 0x7F000000) {
1115 iface = (addr & 0x000000FF);
1117 errno = EADDRNOTAVAIL;
1121 /* Store the bind address for connect() */
1122 if (si->bindname == NULL) {
1123 struct sockaddr_in bind_in;
1124 socklen_t blen = sizeof(struct sockaddr_in);
1126 ZERO_STRUCT(bind_in);
1127 bind_in.sin_family = in->sin_family;
1128 bind_in.sin_port = in->sin_port;
1129 bind_in.sin_addr.s_addr = htonl(0x7F000000 | iface);
1131 si->bindname = sockaddr_dup(&bind_in, blen);
1132 si->bindname_len = blen;
1139 const struct sockaddr_in6 *in =
1140 (const struct sockaddr_in6 *)(const void *)inaddr;
1141 struct in6_addr cmp1, cmp2;
1145 type = SOCKET_TYPE_CHAR_TCP_V6;
1148 type = SOCKET_TYPE_CHAR_UDP_V6;
1151 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1152 errno = ESOCKTNOSUPPORT;
1156 /* XXX no multicast/broadcast */
1158 prt = ntohs(in->sin6_port);
1160 cmp1 = *swrap_ipv6();
1161 cmp2 = in->sin6_addr;
1162 cmp2.s6_addr[15] = 0;
1163 if (IN6_IS_ADDR_UNSPECIFIED(&in->sin6_addr)) {
1164 iface = socket_wrapper_default_iface();
1165 } else if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
1166 iface = in->sin6_addr.s6_addr[15];
1168 errno = EADDRNOTAVAIL;
1172 /* Store the bind address for connect() */
1173 if (si->bindname == NULL) {
1174 struct sockaddr_in6 bind_in;
1175 socklen_t blen = sizeof(struct sockaddr_in6);
1177 ZERO_STRUCT(bind_in);
1178 bind_in.sin6_family = in->sin6_family;
1179 bind_in.sin6_port = in->sin6_port;
1181 bind_in.sin6_addr = *swrap_ipv6();
1182 bind_in.sin6_addr.s6_addr[15] = iface;
1184 si->bindname = sockaddr_dup(&bind_in, blen);
1185 si->bindname_len = blen;
1192 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n");
1193 errno = EADDRNOTAVAIL;
1198 if (bcast) *bcast = is_bcast;
1200 if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
1206 /* handle auto-allocation of ephemeral ports */
1207 for (prt = 5001; prt < 10000; prt++) {
1208 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT,
1209 socket_wrapper_dir(), type, iface, prt);
1210 if (stat(un->sun_path, &st) == 0) continue;
1212 set_port(si->family, prt, si->myname);
1213 set_port(si->family, prt, si->bindname);
1223 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT,
1224 socket_wrapper_dir(), type, iface, prt);
1225 SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
1229 static struct socket_info *find_socket_info(int fd)
1231 struct socket_info *i;
1233 for (i = sockets; i; i = i->next) {
1234 struct socket_info_fd *f;
1235 for (f = i->fds; f; f = f->next) {
1245 static void swrap_remove_stale(int fd)
1247 struct socket_info *si = find_socket_info(fd);
1248 struct socket_info_fd *fi;
1251 for (fi = si->fds; fi; fi = fi->next) {
1253 SWRAP_LOG(SWRAP_LOG_TRACE, "remove stale wrapper for %d", fd);
1254 SWRAP_DLIST_REMOVE(si->fds, fi);
1260 if (si->fds == NULL) {
1261 SWRAP_DLIST_REMOVE(sockets, si);
1266 static int sockaddr_convert_to_un(struct socket_info *si,
1267 const struct sockaddr *in_addr,
1269 struct sockaddr_un *out_addr,
1273 struct sockaddr *out = (struct sockaddr *)(void *)out_addr;
1275 (void) in_len; /* unused */
1277 if (out_addr == NULL) {
1281 out->sa_family = AF_UNIX;
1282 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
1283 out->sa_len = sizeof(*out_addr);
1286 switch (in_addr->sa_family) {
1296 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1297 errno = ESOCKTNOSUPPORT;
1301 return convert_in_un_alloc(si, in_addr, out_addr, bcast);
1303 return convert_in_un_remote(si, in_addr, out_addr, bcast);
1309 errno = EAFNOSUPPORT;
1310 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n");
1314 static int sockaddr_convert_from_un(const struct socket_info *si,
1315 const struct sockaddr_un *in_addr,
1316 socklen_t un_addrlen,
1318 struct sockaddr *out_addr,
1319 socklen_t *out_addrlen)
1323 if (out_addr == NULL || out_addrlen == NULL)
1326 if (un_addrlen == 0) {
1341 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1342 errno = ESOCKTNOSUPPORT;
1345 ret = convert_un_in(in_addr, out_addr, out_addrlen);
1346 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
1347 out_addr->sa_len = *out_addrlen;
1354 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n");
1355 errno = EAFNOSUPPORT;
1359 enum swrap_packet_type {
1361 SWRAP_CONNECT_UNREACH,
1369 SWRAP_SENDTO_UNREACH,
1380 struct swrap_file_hdr {
1382 uint16_t version_major;
1383 uint16_t version_minor;
1386 uint32_t frame_max_len;
1387 #define SWRAP_FRAME_LENGTH_MAX 0xFFFF
1390 #define SWRAP_FILE_HDR_SIZE 24
1392 struct swrap_packet_frame {
1394 uint32_t micro_seconds;
1395 uint32_t recorded_length;
1396 uint32_t full_length;
1398 #define SWRAP_PACKET_FRAME_SIZE 16
1400 union swrap_packet_ip {
1404 uint16_t packet_length;
1405 uint16_t identification;
1410 uint16_t hdr_checksum;
1414 #define SWRAP_PACKET_IP_V4_SIZE 20
1417 uint8_t flow_label_high;
1418 uint16_t flow_label_low;
1419 uint16_t payload_length;
1420 uint8_t next_header;
1422 uint8_t src_addr[16];
1423 uint8_t dest_addr[16];
1425 #define SWRAP_PACKET_IP_V6_SIZE 40
1427 #define SWRAP_PACKET_IP_SIZE 40
1429 union swrap_packet_payload {
1431 uint16_t source_port;
1441 #define SWRAP_PACKET_PAYLOAD_TCP_SIZE 20
1443 uint16_t source_port;
1448 #define SWRAP_PACKET_PAYLOAD_UDP_SIZE 8
1455 #define SWRAP_PACKET_PAYLOAD_ICMP4_SIZE 8
1462 #define SWRAP_PACKET_PAYLOAD_ICMP6_SIZE 8
1464 #define SWRAP_PACKET_PAYLOAD_SIZE 20
1466 #define SWRAP_PACKET_MIN_ALLOC \
1467 (SWRAP_PACKET_FRAME_SIZE + \
1468 SWRAP_PACKET_IP_SIZE + \
1469 SWRAP_PACKET_PAYLOAD_SIZE)
1471 static const char *socket_wrapper_pcap_file(void)
1473 static int initialized = 0;
1474 static const char *s = NULL;
1475 static const struct swrap_file_hdr h;
1476 static const struct swrap_packet_frame f;
1477 static const union swrap_packet_ip i;
1478 static const union swrap_packet_payload p;
1480 if (initialized == 1) {
1486 * TODO: don't use the structs use plain buffer offsets
1487 * and PUSH_U8(), PUSH_U16() and PUSH_U32()
1489 * for now make sure we disable PCAP support
1490 * if the struct has alignment!
1492 if (sizeof(h) != SWRAP_FILE_HDR_SIZE) {
1495 if (sizeof(f) != SWRAP_PACKET_FRAME_SIZE) {
1498 if (sizeof(i) != SWRAP_PACKET_IP_SIZE) {
1501 if (sizeof(i.v4) != SWRAP_PACKET_IP_V4_SIZE) {
1504 if (sizeof(i.v6) != SWRAP_PACKET_IP_V6_SIZE) {
1507 if (sizeof(p) != SWRAP_PACKET_PAYLOAD_SIZE) {
1510 if (sizeof(p.tcp) != SWRAP_PACKET_PAYLOAD_TCP_SIZE) {
1513 if (sizeof(p.udp) != SWRAP_PACKET_PAYLOAD_UDP_SIZE) {
1516 if (sizeof(p.icmp4) != SWRAP_PACKET_PAYLOAD_ICMP4_SIZE) {
1519 if (sizeof(p.icmp6) != SWRAP_PACKET_PAYLOAD_ICMP6_SIZE) {
1523 s = getenv("SOCKET_WRAPPER_PCAP_FILE");
1527 if (strncmp(s, "./", 2) == 0) {
1533 static uint8_t *swrap_packet_init(struct timeval *tval,
1534 const struct sockaddr *src,
1535 const struct sockaddr *dest,
1537 const uint8_t *payload,
1539 unsigned long tcp_seqno,
1540 unsigned long tcp_ack,
1541 unsigned char tcp_ctl,
1543 size_t *_packet_len)
1547 struct swrap_packet_frame *frame;
1548 union swrap_packet_ip *ip;
1549 union swrap_packet_payload *pay;
1552 size_t nonwire_len = sizeof(*frame);
1553 size_t wire_hdr_len = 0;
1554 size_t wire_len = 0;
1555 size_t ip_hdr_len = 0;
1556 size_t icmp_hdr_len = 0;
1557 size_t icmp_truncate_len = 0;
1558 uint8_t protocol = 0, icmp_protocol = 0;
1559 const struct sockaddr_in *src_in = NULL;
1560 const struct sockaddr_in *dest_in = NULL;
1562 const struct sockaddr_in6 *src_in6 = NULL;
1563 const struct sockaddr_in6 *dest_in6 = NULL;
1568 switch (src->sa_family) {
1570 src_in = (const struct sockaddr_in *)src;
1571 dest_in = (const struct sockaddr_in *)dest;
1572 src_port = src_in->sin_port;
1573 dest_port = dest_in->sin_port;
1574 ip_hdr_len = sizeof(ip->v4);
1578 src_in6 = (const struct sockaddr_in6 *)src;
1579 dest_in6 = (const struct sockaddr_in6 *)dest;
1580 src_port = src_in6->sin6_port;
1581 dest_port = dest_in6->sin6_port;
1582 ip_hdr_len = sizeof(ip->v6);
1589 switch (socket_type) {
1591 protocol = 0x06; /* TCP */
1592 wire_hdr_len = ip_hdr_len + sizeof(pay->tcp);
1593 wire_len = wire_hdr_len + payload_len;
1597 protocol = 0x11; /* UDP */
1598 wire_hdr_len = ip_hdr_len + sizeof(pay->udp);
1599 wire_len = wire_hdr_len + payload_len;
1607 icmp_protocol = protocol;
1608 switch (src->sa_family) {
1610 protocol = 0x01; /* ICMPv4 */
1611 icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp4);
1615 protocol = 0x3A; /* ICMPv6 */
1616 icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp6);
1620 if (wire_len > 64 ) {
1621 icmp_truncate_len = wire_len - 64;
1623 wire_hdr_len += icmp_hdr_len;
1624 wire_len += icmp_hdr_len;
1627 packet_len = nonwire_len + wire_len;
1628 alloc_len = packet_len;
1629 if (alloc_len < SWRAP_PACKET_MIN_ALLOC) {
1630 alloc_len = SWRAP_PACKET_MIN_ALLOC;
1633 base = (uint8_t *)malloc(alloc_len);
1637 memset(base, 0x0, alloc_len);
1641 frame = (struct swrap_packet_frame *)buf;
1642 frame->seconds = tval->tv_sec;
1643 frame->micro_seconds = tval->tv_usec;
1644 frame->recorded_length = wire_len - icmp_truncate_len;
1645 frame->full_length = wire_len - icmp_truncate_len;
1646 buf += SWRAP_PACKET_FRAME_SIZE;
1648 ip = (union swrap_packet_ip *)buf;
1649 switch (src->sa_family) {
1651 ip->v4.ver_hdrlen = 0x45; /* version 4 and 5 * 32 bit words */
1653 ip->v4.packet_length = htons(wire_len - icmp_truncate_len);
1654 ip->v4.identification = htons(0xFFFF);
1655 ip->v4.flags = 0x40; /* BIT 1 set - means don't fragment */
1656 ip->v4.fragment = htons(0x0000);
1658 ip->v4.protocol = protocol;
1659 ip->v4.hdr_checksum = htons(0x0000);
1660 ip->v4.src_addr = src_in->sin_addr.s_addr;
1661 ip->v4.dest_addr = dest_in->sin_addr.s_addr;
1662 buf += SWRAP_PACKET_IP_V4_SIZE;
1666 ip->v6.ver_prio = 0x60; /* version 4 and 5 * 32 bit words */
1667 ip->v6.flow_label_high = 0x00;
1668 ip->v6.flow_label_low = 0x0000;
1669 ip->v6.payload_length = htons(wire_len - icmp_truncate_len); /* TODO */
1670 ip->v6.next_header = protocol;
1671 memcpy(ip->v6.src_addr, src_in6->sin6_addr.s6_addr, 16);
1672 memcpy(ip->v6.dest_addr, dest_in6->sin6_addr.s6_addr, 16);
1673 buf += SWRAP_PACKET_IP_V6_SIZE;
1679 pay = (union swrap_packet_payload *)buf;
1680 switch (src->sa_family) {
1682 pay->icmp4.type = 0x03; /* destination unreachable */
1683 pay->icmp4.code = 0x01; /* host unreachable */
1684 pay->icmp4.checksum = htons(0x0000);
1685 pay->icmp4.unused = htonl(0x00000000);
1686 buf += SWRAP_PACKET_PAYLOAD_ICMP4_SIZE;
1688 /* set the ip header in the ICMP payload */
1689 ip = (union swrap_packet_ip *)buf;
1690 ip->v4.ver_hdrlen = 0x45; /* version 4 and 5 * 32 bit words */
1692 ip->v4.packet_length = htons(wire_len - icmp_hdr_len);
1693 ip->v4.identification = htons(0xFFFF);
1694 ip->v4.flags = 0x40; /* BIT 1 set - means don't fragment */
1695 ip->v4.fragment = htons(0x0000);
1697 ip->v4.protocol = icmp_protocol;
1698 ip->v4.hdr_checksum = htons(0x0000);
1699 ip->v4.src_addr = dest_in->sin_addr.s_addr;
1700 ip->v4.dest_addr = src_in->sin_addr.s_addr;
1701 buf += SWRAP_PACKET_IP_V4_SIZE;
1703 src_port = dest_in->sin_port;
1704 dest_port = src_in->sin_port;
1708 pay->icmp6.type = 0x01; /* destination unreachable */
1709 pay->icmp6.code = 0x03; /* address unreachable */
1710 pay->icmp6.checksum = htons(0x0000);
1711 pay->icmp6.unused = htonl(0x00000000);
1712 buf += SWRAP_PACKET_PAYLOAD_ICMP6_SIZE;
1714 /* set the ip header in the ICMP payload */
1715 ip = (union swrap_packet_ip *)buf;
1716 ip->v6.ver_prio = 0x60; /* version 4 and 5 * 32 bit words */
1717 ip->v6.flow_label_high = 0x00;
1718 ip->v6.flow_label_low = 0x0000;
1719 ip->v6.payload_length = htons(wire_len - icmp_truncate_len); /* TODO */
1720 ip->v6.next_header = protocol;
1721 memcpy(ip->v6.src_addr, dest_in6->sin6_addr.s6_addr, 16);
1722 memcpy(ip->v6.dest_addr, src_in6->sin6_addr.s6_addr, 16);
1723 buf += SWRAP_PACKET_IP_V6_SIZE;
1725 src_port = dest_in6->sin6_port;
1726 dest_port = src_in6->sin6_port;
1732 pay = (union swrap_packet_payload *)buf;
1734 switch (socket_type) {
1736 pay->tcp.source_port = src_port;
1737 pay->tcp.dest_port = dest_port;
1738 pay->tcp.seq_num = htonl(tcp_seqno);
1739 pay->tcp.ack_num = htonl(tcp_ack);
1740 pay->tcp.hdr_length = 0x50; /* 5 * 32 bit words */
1741 pay->tcp.control = tcp_ctl;
1742 pay->tcp.window = htons(0x7FFF);
1743 pay->tcp.checksum = htons(0x0000);
1744 pay->tcp.urg = htons(0x0000);
1745 buf += SWRAP_PACKET_PAYLOAD_TCP_SIZE;
1750 pay->udp.source_port = src_port;
1751 pay->udp.dest_port = dest_port;
1752 pay->udp.length = htons(8 + payload_len);
1753 pay->udp.checksum = htons(0x0000);
1754 buf += SWRAP_PACKET_PAYLOAD_UDP_SIZE;
1759 if (payload && payload_len > 0) {
1760 memcpy(buf, payload, payload_len);
1763 *_packet_len = packet_len - icmp_truncate_len;
1767 static int swrap_get_pcap_fd(const char *fname)
1771 if (fd != -1) return fd;
1773 fd = libc_open(fname, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0644);
1775 struct swrap_file_hdr file_hdr;
1776 file_hdr.magic = 0xA1B2C3D4;
1777 file_hdr.version_major = 0x0002;
1778 file_hdr.version_minor = 0x0004;
1779 file_hdr.timezone = 0x00000000;
1780 file_hdr.sigfigs = 0x00000000;
1781 file_hdr.frame_max_len = SWRAP_FRAME_LENGTH_MAX;
1782 file_hdr.link_type = 0x0065; /* 101 RAW IP */
1784 if (write(fd, &file_hdr, sizeof(file_hdr)) != sizeof(file_hdr)) {
1791 fd = libc_open(fname, O_WRONLY|O_APPEND, 0644);
1796 static uint8_t *swrap_marshall_packet(struct socket_info *si,
1797 const struct sockaddr *addr,
1798 enum swrap_packet_type type,
1799 const void *buf, size_t len,
1802 const struct sockaddr *src_addr;
1803 const struct sockaddr *dest_addr;
1804 unsigned long tcp_seqno = 0;
1805 unsigned long tcp_ack = 0;
1806 unsigned char tcp_ctl = 0;
1807 int unreachable = 0;
1811 switch (si->family) {
1823 case SWRAP_CONNECT_SEND:
1824 if (si->type != SOCK_STREAM) return NULL;
1826 src_addr = si->myname;
1829 tcp_seqno = si->io.pck_snd;
1830 tcp_ack = si->io.pck_rcv;
1831 tcp_ctl = 0x02; /* SYN */
1833 si->io.pck_snd += 1;
1837 case SWRAP_CONNECT_RECV:
1838 if (si->type != SOCK_STREAM) return NULL;
1840 dest_addr = si->myname;
1843 tcp_seqno = si->io.pck_rcv;
1844 tcp_ack = si->io.pck_snd;
1845 tcp_ctl = 0x12; /** SYN,ACK */
1847 si->io.pck_rcv += 1;
1851 case SWRAP_CONNECT_UNREACH:
1852 if (si->type != SOCK_STREAM) return NULL;
1854 dest_addr = si->myname;
1857 /* Unreachable: resend the data of SWRAP_CONNECT_SEND */
1858 tcp_seqno = si->io.pck_snd - 1;
1859 tcp_ack = si->io.pck_rcv;
1860 tcp_ctl = 0x02; /* SYN */
1865 case SWRAP_CONNECT_ACK:
1866 if (si->type != SOCK_STREAM) return NULL;
1868 src_addr = si->myname;
1871 tcp_seqno = si->io.pck_snd;
1872 tcp_ack = si->io.pck_rcv;
1873 tcp_ctl = 0x10; /* ACK */
1877 case SWRAP_ACCEPT_SEND:
1878 if (si->type != SOCK_STREAM) return NULL;
1880 dest_addr = si->myname;
1883 tcp_seqno = si->io.pck_rcv;
1884 tcp_ack = si->io.pck_snd;
1885 tcp_ctl = 0x02; /* SYN */
1887 si->io.pck_rcv += 1;
1891 case SWRAP_ACCEPT_RECV:
1892 if (si->type != SOCK_STREAM) return NULL;
1894 src_addr = si->myname;
1897 tcp_seqno = si->io.pck_snd;
1898 tcp_ack = si->io.pck_rcv;
1899 tcp_ctl = 0x12; /* SYN,ACK */
1901 si->io.pck_snd += 1;
1905 case SWRAP_ACCEPT_ACK:
1906 if (si->type != SOCK_STREAM) return NULL;
1908 dest_addr = si->myname;
1911 tcp_seqno = si->io.pck_rcv;
1912 tcp_ack = si->io.pck_snd;
1913 tcp_ctl = 0x10; /* ACK */
1918 src_addr = si->myname;
1919 dest_addr = si->peername;
1921 tcp_seqno = si->io.pck_snd;
1922 tcp_ack = si->io.pck_rcv;
1923 tcp_ctl = 0x18; /* PSH,ACK */
1925 si->io.pck_snd += len;
1929 case SWRAP_SEND_RST:
1930 dest_addr = si->myname;
1931 src_addr = si->peername;
1933 if (si->type == SOCK_DGRAM) {
1934 return swrap_marshall_packet(si, si->peername,
1935 SWRAP_SENDTO_UNREACH,
1936 buf, len, packet_len);
1939 tcp_seqno = si->io.pck_rcv;
1940 tcp_ack = si->io.pck_snd;
1941 tcp_ctl = 0x14; /** RST,ACK */
1945 case SWRAP_PENDING_RST:
1946 dest_addr = si->myname;
1947 src_addr = si->peername;
1949 if (si->type == SOCK_DGRAM) {
1953 tcp_seqno = si->io.pck_rcv;
1954 tcp_ack = si->io.pck_snd;
1955 tcp_ctl = 0x14; /* RST,ACK */
1960 dest_addr = si->myname;
1961 src_addr = si->peername;
1963 tcp_seqno = si->io.pck_rcv;
1964 tcp_ack = si->io.pck_snd;
1965 tcp_ctl = 0x18; /* PSH,ACK */
1967 si->io.pck_rcv += len;
1971 case SWRAP_RECV_RST:
1972 dest_addr = si->myname;
1973 src_addr = si->peername;
1975 if (si->type == SOCK_DGRAM) {
1979 tcp_seqno = si->io.pck_rcv;
1980 tcp_ack = si->io.pck_snd;
1981 tcp_ctl = 0x14; /* RST,ACK */
1986 src_addr = si->myname;
1989 si->io.pck_snd += len;
1993 case SWRAP_SENDTO_UNREACH:
1994 dest_addr = si->myname;
2001 case SWRAP_RECVFROM:
2002 dest_addr = si->myname;
2005 si->io.pck_rcv += len;
2009 case SWRAP_CLOSE_SEND:
2010 if (si->type != SOCK_STREAM) return NULL;
2012 src_addr = si->myname;
2013 dest_addr = si->peername;
2015 tcp_seqno = si->io.pck_snd;
2016 tcp_ack = si->io.pck_rcv;
2017 tcp_ctl = 0x11; /* FIN, ACK */
2019 si->io.pck_snd += 1;
2023 case SWRAP_CLOSE_RECV:
2024 if (si->type != SOCK_STREAM) return NULL;
2026 dest_addr = si->myname;
2027 src_addr = si->peername;
2029 tcp_seqno = si->io.pck_rcv;
2030 tcp_ack = si->io.pck_snd;
2031 tcp_ctl = 0x11; /* FIN,ACK */
2033 si->io.pck_rcv += 1;
2037 case SWRAP_CLOSE_ACK:
2038 if (si->type != SOCK_STREAM) return NULL;
2040 src_addr = si->myname;
2041 dest_addr = si->peername;
2043 tcp_seqno = si->io.pck_snd;
2044 tcp_ack = si->io.pck_rcv;
2045 tcp_ctl = 0x10; /* ACK */
2052 swrapGetTimeOfDay(&tv);
2054 return swrap_packet_init(&tv, src_addr, dest_addr, si->type,
2055 (const uint8_t *)buf, len,
2056 tcp_seqno, tcp_ack, tcp_ctl, unreachable,
2060 static void swrap_dump_packet(struct socket_info *si,
2061 const struct sockaddr *addr,
2062 enum swrap_packet_type type,
2063 const void *buf, size_t len)
2065 const char *file_name;
2067 size_t packet_len = 0;
2070 file_name = socket_wrapper_pcap_file();
2075 packet = swrap_marshall_packet(si, addr, type, buf, len, &packet_len);
2080 fd = swrap_get_pcap_fd(file_name);
2082 if (write(fd, packet, packet_len) != (ssize_t)packet_len) {
2091 /****************************************************************************
2093 ***************************************************************************/
2095 #ifdef HAVE_SIGNALFD
2096 static int swrap_signalfd(int fd, const sigset_t *mask, int flags)
2100 rc = libc_signalfd(fd, mask, flags);
2102 swrap_remove_stale(fd);
2108 int signalfd(int fd, const sigset_t *mask, int flags)
2110 return swrap_signalfd(fd, mask, flags);
2114 /****************************************************************************
2116 ***************************************************************************/
2118 static int swrap_socket(int family, int type, int protocol)
2120 struct socket_info *si;
2121 struct socket_info_fd *fi;
2123 int real_type = type;
2126 * Remove possible addition flags passed to socket() so
2127 * do not fail checking the type.
2128 * See https://lwn.net/Articles/281965/
2131 real_type &= ~SOCK_CLOEXEC;
2133 #ifdef SOCK_NONBLOCK
2134 real_type &= ~SOCK_NONBLOCK;
2137 if (!socket_wrapper_enabled()) {
2138 return libc_socket(family, type, protocol);
2148 return libc_socket(family, type, protocol);
2150 errno = EAFNOSUPPORT;
2154 switch (real_type) {
2160 errno = EPROTONOSUPPORT;
2168 if (real_type == SOCK_STREAM) {
2173 if (real_type == SOCK_DGRAM) {
2178 errno = EPROTONOSUPPORT;
2183 * We must call libc_socket with type, from the caller, not the version
2184 * we removed SOCK_CLOEXEC and SOCK_NONBLOCK from
2186 fd = libc_socket(AF_UNIX, type, 0);
2192 /* Check if we have a stale fd and remove it */
2193 si = find_socket_info(fd);
2195 swrap_remove_stale(fd);
2198 si = (struct socket_info *)malloc(sizeof(struct socket_info));
2199 memset(si, 0, sizeof(struct socket_info));
2205 si->family = family;
2207 /* however, the rest of the socket_wrapper code expects just
2208 * the type, not the flags */
2209 si->type = real_type;
2210 si->protocol = protocol;
2212 fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
2221 SWRAP_DLIST_ADD(si->fds, fi);
2222 SWRAP_DLIST_ADD(sockets, si);
2227 int socket(int family, int type, int protocol)
2229 return swrap_socket(family, type, protocol);
2232 /****************************************************************************
2234 ***************************************************************************/
2236 static int swrap_socketpair(int family, int type, int protocol, int sv[2])
2240 rc = libc_socketpair(family, type, protocol, sv);
2242 swrap_remove_stale(sv[0]);
2243 swrap_remove_stale(sv[1]);
2249 int socketpair(int family, int type, int protocol, int sv[2])
2251 return swrap_socketpair(family, type, protocol, sv);
2254 /****************************************************************************
2256 ***************************************************************************/
2258 #ifdef HAVE_TIMERFD_CREATE
2259 static int swrap_timerfd_create(int clockid, int flags)
2263 fd = libc_timerfd_create(clockid, flags);
2265 swrap_remove_stale(fd);
2271 int timerfd_create(int clockid, int flags)
2273 return swrap_timerfd_create(clockid, flags);
2277 /****************************************************************************
2279 ***************************************************************************/
2281 static int swrap_pipe(int pipefd[2])
2285 rc = libc_pipe(pipefd);
2287 swrap_remove_stale(pipefd[0]);
2288 swrap_remove_stale(pipefd[1]);
2294 int pipe(int pipefd[2])
2296 return swrap_pipe(pipefd);
2299 /****************************************************************************
2301 ***************************************************************************/
2303 static int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
2305 struct socket_info *parent_si, *child_si;
2306 struct socket_info_fd *child_fi;
2308 struct sockaddr_un un_addr;
2309 socklen_t un_addrlen = sizeof(un_addr);
2310 struct sockaddr_un un_my_addr;
2311 socklen_t un_my_addrlen = sizeof(un_my_addr);
2312 struct sockaddr *my_addr;
2313 socklen_t my_addrlen, len;
2316 parent_si = find_socket_info(s);
2318 return libc_accept(s, addr, addrlen);
2322 * assume out sockaddr have the same size as the in parent
2325 my_addrlen = socket_length(parent_si->family);
2326 if (my_addrlen <= 0) {
2331 my_addr = (struct sockaddr *)malloc(my_addrlen);
2332 if (my_addr == NULL) {
2336 memset(&un_addr, 0, sizeof(un_addr));
2337 memset(&un_my_addr, 0, sizeof(un_my_addr));
2339 ret = libc_accept(s, (struct sockaddr *)(void *)&un_addr, &un_addrlen);
2341 if (errno == ENOTSOCK) {
2342 /* Remove stale fds */
2343 swrap_remove_stale(s);
2352 ret = sockaddr_convert_from_un(parent_si, &un_addr, un_addrlen,
2353 parent_si->family, my_addr, &len);
2360 child_si = (struct socket_info *)malloc(sizeof(struct socket_info));
2361 memset(child_si, 0, sizeof(struct socket_info));
2363 child_fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
2364 if (child_fi == NULL) {
2374 SWRAP_DLIST_ADD(child_si->fds, child_fi);
2376 child_si->family = parent_si->family;
2377 child_si->type = parent_si->type;
2378 child_si->protocol = parent_si->protocol;
2379 child_si->bound = 1;
2380 child_si->is_server = 1;
2381 child_si->connected = 1;
2383 child_si->peername_len = len;
2384 child_si->peername = sockaddr_dup(my_addr, len);
2386 if (addr != NULL && addrlen != NULL) {
2387 size_t copy_len = MIN(*addrlen, len);
2389 memcpy(addr, my_addr, copy_len);
2394 ret = libc_getsockname(fd,
2395 (struct sockaddr *)(void *)&un_my_addr,
2406 ret = sockaddr_convert_from_un(child_si, &un_my_addr, un_my_addrlen,
2407 child_si->family, my_addr, &len);
2416 SWRAP_LOG(SWRAP_LOG_TRACE,
2417 "accept() path=%s, fd=%d",
2418 un_my_addr.sun_path, s);
2420 child_si->myname_len = len;
2421 child_si->myname = sockaddr_dup(my_addr, len);
2424 SWRAP_DLIST_ADD(sockets, child_si);
2427 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0);
2428 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_RECV, NULL, 0);
2429 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_ACK, NULL, 0);
2435 #ifdef HAVE_ACCEPT_PSOCKLEN_T
2436 int accept(int s, struct sockaddr *addr, Psocklen_t addrlen)
2438 int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
2441 return swrap_accept(s, addr, (socklen_t *)addrlen);
2444 static int autobind_start_init;
2445 static int autobind_start;
2447 /* using sendto() or connect() on an unbound socket would give the
2448 recipient no way to reply, as unlike UDP and TCP, a unix domain
2449 socket can't auto-assign ephemeral port numbers, so we need to
2451 Note: this might change the family from ipv6 to ipv4
2453 static int swrap_auto_bind(int fd, struct socket_info *si, int family)
2455 struct sockaddr_un un_addr;
2462 if (autobind_start_init != 1) {
2463 autobind_start_init = 1;
2464 autobind_start = getpid();
2465 autobind_start %= 50000;
2466 autobind_start += 10000;
2469 un_addr.sun_family = AF_UNIX;
2473 struct sockaddr_in in;
2477 type = SOCKET_TYPE_CHAR_TCP;
2480 type = SOCKET_TYPE_CHAR_UDP;
2483 errno = ESOCKTNOSUPPORT;
2487 memset(&in, 0, sizeof(in));
2488 in.sin_family = AF_INET;
2489 in.sin_addr.s_addr = htonl(127<<24 |
2490 socket_wrapper_default_iface());
2492 si->myname_len = sizeof(in);
2493 si->myname = sockaddr_dup(&in, si->myname_len);
2498 struct sockaddr_in6 in6;
2500 if (si->family != family) {
2501 errno = ENETUNREACH;
2507 type = SOCKET_TYPE_CHAR_TCP_V6;
2510 type = SOCKET_TYPE_CHAR_UDP_V6;
2513 errno = ESOCKTNOSUPPORT;
2517 memset(&in6, 0, sizeof(in6));
2518 in6.sin6_family = AF_INET6;
2519 in6.sin6_addr = *swrap_ipv6();
2520 in6.sin6_addr.s6_addr[15] = socket_wrapper_default_iface();
2521 si->myname_len = sizeof(in6);
2522 si->myname = sockaddr_dup(&in6, si->myname_len);
2527 errno = ESOCKTNOSUPPORT;
2531 if (autobind_start > 60000) {
2532 autobind_start = 10000;
2535 for (i = 0; i < SOCKET_MAX_SOCKETS; i++) {
2536 port = autobind_start + i;
2537 snprintf(un_addr.sun_path, sizeof(un_addr.sun_path),
2538 "%s/"SOCKET_FORMAT, socket_wrapper_dir(),
2539 type, socket_wrapper_default_iface(), port);
2540 if (stat(un_addr.sun_path, &st) == 0) continue;
2542 ret = libc_bind(fd, (struct sockaddr *)(void *)&un_addr,
2544 if (ret == -1) return ret;
2546 si->tmp_path = strdup(un_addr.sun_path);
2548 autobind_start = port + 1;
2551 if (i == SOCKET_MAX_SOCKETS) {
2552 SWRAP_LOG(SWRAP_LOG_ERROR, "Too many open unix sockets (%u) for "
2553 "interface "SOCKET_FORMAT,
2556 socket_wrapper_default_iface(),
2562 si->family = family;
2563 set_port(si->family, port, si->myname);
2568 /****************************************************************************
2570 ***************************************************************************/
2572 static int swrap_connect(int s, const struct sockaddr *serv_addr,
2576 struct sockaddr_un un_addr;
2577 struct socket_info *si = find_socket_info(s);
2581 return libc_connect(s, serv_addr, addrlen);
2584 if (si->bound == 0) {
2585 ret = swrap_auto_bind(s, si, serv_addr->sa_family);
2586 if (ret == -1) return -1;
2589 if (si->family != serv_addr->sa_family) {
2594 ret = sockaddr_convert_to_un(si, serv_addr,
2595 addrlen, &un_addr, 0, &bcast);
2596 if (ret == -1) return -1;
2599 errno = ENETUNREACH;
2603 if (si->type == SOCK_DGRAM) {
2604 si->defer_connect = 1;
2607 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0);
2609 ret = libc_connect(s,
2610 (struct sockaddr *)(void *)&un_addr,
2611 sizeof(struct sockaddr_un));
2614 SWRAP_LOG(SWRAP_LOG_TRACE,
2615 "connect() path=%s, fd=%d",
2616 un_addr.sun_path, s);
2619 /* to give better errors */
2620 if (ret == -1 && errno == ENOENT) {
2621 errno = EHOSTUNREACH;
2625 si->peername_len = addrlen;
2626 si->peername = sockaddr_dup(serv_addr, addrlen);
2630 * When we connect() on a socket than we have to bind the
2631 * outgoing connection on the interface we use for the
2632 * transport. We already bound it on the right interface
2633 * but here we have to update the name so getsockname()
2634 * returns correct information.
2636 if (si->bindname != NULL) {
2639 si->myname = si->bindname;
2640 si->myname_len = si->bindname_len;
2642 si->bindname = NULL;
2643 si->bindname_len = 0;
2646 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0);
2647 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0);
2649 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0);
2655 int connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen)
2657 return swrap_connect(s, serv_addr, addrlen);
2660 /****************************************************************************
2662 ***************************************************************************/
2664 static int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
2667 struct sockaddr_un un_addr;
2668 struct socket_info *si = find_socket_info(s);
2671 return libc_bind(s, myaddr, addrlen);
2674 si->myname_len = addrlen;
2675 si->myname = sockaddr_dup(myaddr, addrlen);
2677 ret = sockaddr_convert_to_un(si, myaddr, addrlen, &un_addr, 1, &si->bcast);
2678 if (ret == -1) return -1;
2680 unlink(un_addr.sun_path);
2682 ret = libc_bind(s, (struct sockaddr *)(void *)&un_addr,
2683 sizeof(struct sockaddr_un));
2685 SWRAP_LOG(SWRAP_LOG_TRACE,
2686 "bind() path=%s, fd=%d",
2687 un_addr.sun_path, s);
2696 int bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
2698 return swrap_bind(s, myaddr, addrlen);
2701 /****************************************************************************
2703 ***************************************************************************/
2705 static int swrap_listen(int s, int backlog)
2708 struct socket_info *si = find_socket_info(s);
2711 return libc_listen(s, backlog);
2714 ret = libc_listen(s, backlog);
2719 int listen(int s, int backlog)
2721 return swrap_listen(s, backlog);
2724 /****************************************************************************
2726 ***************************************************************************/
2728 static int swrap_vopen(const char *pathname, int flags, va_list ap)
2732 ret = libc_vopen(pathname, flags, ap);
2735 * There are methods for closing descriptors (libc-internal code
2736 * paths, direct syscalls) which close descriptors in ways that
2737 * we can't intercept, so try to recover when we notice that
2740 swrap_remove_stale(ret);
2745 int open(const char *pathname, int flags, ...)
2750 va_start(ap, flags);
2751 fd = swrap_vopen(pathname, flags, ap);
2757 /****************************************************************************
2759 ***************************************************************************/
2761 static int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
2763 struct socket_info *si = find_socket_info(s);
2766 return libc_getpeername(s, name, addrlen);
2775 memcpy(name, si->peername, si->peername_len);
2776 *addrlen = si->peername_len;
2781 #ifdef HAVE_ACCEPT_PSOCKLEN_T
2782 int getpeername(int s, struct sockaddr *name, Psocklen_t addrlen)
2784 int getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
2787 return swrap_getpeername(s, name, (socklen_t *)addrlen);
2790 /****************************************************************************
2792 ***************************************************************************/
2794 static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
2796 struct socket_info *si = find_socket_info(s);
2799 return libc_getsockname(s, name, addrlen);
2802 memcpy(name, si->myname, si->myname_len);
2803 *addrlen = si->myname_len;
2808 #ifdef HAVE_ACCEPT_PSOCKLEN_T
2809 int getsockname(int s, struct sockaddr *name, Psocklen_t addrlen)
2811 int getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
2814 return swrap_getsockname(s, name, (socklen_t *)addrlen);
2817 /****************************************************************************
2819 ***************************************************************************/
2821 static int swrap_getsockopt(int s, int level, int optname,
2822 void *optval, socklen_t *optlen)
2824 struct socket_info *si = find_socket_info(s);
2827 return libc_getsockopt(s,
2834 if (level == SOL_SOCKET) {
2835 return libc_getsockopt(s,
2842 errno = ENOPROTOOPT;
2846 #ifdef HAVE_ACCEPT_PSOCKLEN_T
2847 int getsockopt(int s, int level, int optname, void *optval, Psocklen_t optlen)
2849 int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
2852 return swrap_getsockopt(s, level, optname, optval, (socklen_t *)optlen);
2855 /****************************************************************************
2857 ***************************************************************************/
2859 static int swrap_setsockopt(int s, int level, int optname,
2860 const void *optval, socklen_t optlen)
2862 struct socket_info *si = find_socket_info(s);
2865 return libc_setsockopt(s,
2872 if (level == SOL_SOCKET) {
2873 return libc_setsockopt(s,
2880 switch (si->family) {
2882 if (level == IPPROTO_IP) {
2884 if (optname == IP_PKTINFO) {
2885 si->pktinfo = AF_INET;
2887 #endif /* IP_PKTINFO */
2892 if (level == IPPROTO_IPV6) {
2893 #ifdef IPV6_RECVPKTINFO
2894 if (optname == IPV6_RECVPKTINFO) {
2895 si->pktinfo = AF_INET6;
2897 #endif /* IPV6_PKTINFO */
2902 errno = ENOPROTOOPT;
2907 int setsockopt(int s, int level, int optname,
2908 const void *optval, socklen_t optlen)
2910 return swrap_setsockopt(s, level, optname, optval, optlen);
2913 /****************************************************************************
2915 ***************************************************************************/
2917 static int swrap_vioctl(int s, unsigned long int r, va_list va)
2919 struct socket_info *si = find_socket_info(s);
2925 return libc_vioctl(s, r, va);
2930 rc = libc_vioctl(s, r, va);
2934 value = *((int *)va_arg(ap, int *));
2936 if (rc == -1 && errno != EAGAIN && errno != ENOBUFS) {
2937 swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
2938 } else if (value == 0) { /* END OF FILE */
2939 swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
2949 #ifdef HAVE_IOCTL_INT
2950 int ioctl(int s, int r, ...)
2952 int ioctl(int s, unsigned long int r, ...)
2960 rc = swrap_vioctl(s, (unsigned long int) r, va);
2967 static ssize_t swrap_sendmsg_before(int fd,
2968 struct socket_info *si,
2970 struct iovec *tmp_iov,
2971 struct sockaddr_un *tmp_un,
2972 const struct sockaddr_un **to_un,
2973 const struct sockaddr **to,
2991 if (!si->connected) {
2996 if (msg->msg_iovlen == 0) {
3000 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3002 nlen = len + msg->msg_iov[i].iov_len;
3003 if (nlen > SOCKET_MAX_PACKET) {
3007 msg->msg_iovlen = i;
3008 if (msg->msg_iovlen == 0) {
3009 *tmp_iov = msg->msg_iov[0];
3010 tmp_iov->iov_len = MIN(tmp_iov->iov_len, SOCKET_MAX_PACKET);
3011 msg->msg_iov = tmp_iov;
3012 msg->msg_iovlen = 1;
3017 if (si->connected) {
3018 if (msg->msg_name) {
3023 const struct sockaddr *msg_name;
3024 msg_name = (const struct sockaddr *)msg->msg_name;
3026 if (msg_name == NULL) {
3032 ret = sockaddr_convert_to_un(si, msg_name, msg->msg_namelen,
3034 if (ret == -1) return -1;
3042 msg->msg_name = tmp_un;
3043 msg->msg_namelen = sizeof(*tmp_un);
3046 if (si->bound == 0) {
3047 ret = swrap_auto_bind(fd, si, si->family);
3049 if (errno == ENOTSOCK) {
3050 swrap_remove_stale(fd);
3053 SWRAP_LOG(SWRAP_LOG_ERROR, "swrap_sendmsg_before failed");
3059 if (!si->defer_connect) {
3063 ret = sockaddr_convert_to_un(si, si->peername, si->peername_len,
3065 if (ret == -1) return -1;
3067 ret = libc_connect(fd,
3068 (struct sockaddr *)(void *)tmp_un,
3071 /* to give better errors */
3072 if (ret == -1 && errno == ENOENT) {
3073 errno = EHOSTUNREACH;
3080 si->defer_connect = 0;
3083 errno = EHOSTUNREACH;
3090 static void swrap_sendmsg_after(int fd,
3091 struct socket_info *si,
3093 const struct sockaddr *to,
3096 int saved_errno = errno;
3103 /* to give better errors */
3105 if (saved_errno == ENOENT) {
3106 saved_errno = EHOSTUNREACH;
3107 } else if (saved_errno == ENOTSOCK) {
3108 /* If the fd is not a socket, remove it */
3109 swrap_remove_stale(fd);
3113 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3114 avail += msg->msg_iov[i].iov_len;
3118 remain = MIN(80, avail);
3123 /* we capture it as one single packet */
3124 buf = (uint8_t *)malloc(remain);
3126 /* we just not capture the packet */
3127 errno = saved_errno;
3131 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3132 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
3134 msg->msg_iov[i].iov_base,
3137 remain -= this_time;
3144 swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
3145 swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
3147 swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
3152 if (si->connected) {
3156 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
3157 swrap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);
3159 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
3165 errno = saved_errno;
3168 static int swrap_recvmsg_before(int fd,
3169 struct socket_info *si,
3171 struct iovec *tmp_iov)
3176 (void)fd; /* unused */
3180 if (!si->connected) {
3185 if (msg->msg_iovlen == 0) {
3189 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3191 nlen = len + msg->msg_iov[i].iov_len;
3192 if (nlen > SOCKET_MAX_PACKET) {
3196 msg->msg_iovlen = i;
3197 if (msg->msg_iovlen == 0) {
3198 *tmp_iov = msg->msg_iov[0];
3199 tmp_iov->iov_len = MIN(tmp_iov->iov_len, SOCKET_MAX_PACKET);
3200 msg->msg_iov = tmp_iov;
3201 msg->msg_iovlen = 1;
3206 if (msg->msg_name == NULL) {
3211 if (msg->msg_iovlen == 0) {
3215 if (si->bound == 0) {
3216 ret = swrap_auto_bind(fd, si, si->family);
3219 * When attempting to read or write to a
3220 * descriptor, if an underlying autobind fails
3221 * because it's not a socket, stop intercepting
3222 * uses of that descriptor.
3224 if (errno == ENOTSOCK) {
3225 swrap_remove_stale(fd);
3228 SWRAP_LOG(SWRAP_LOG_ERROR,
3229 "swrap_recvmsg_before failed");
3236 errno = EHOSTUNREACH;
3243 static int swrap_recvmsg_after(int fd,
3244 struct socket_info *si,
3246 const struct sockaddr_un *un_addr,
3247 socklen_t un_addrlen,
3250 int saved_errno = errno;
3252 uint8_t *buf = NULL;
3257 /* to give better errors */
3259 if (saved_errno == ENOENT) {
3260 saved_errno = EHOSTUNREACH;
3261 } else if (saved_errno == ENOTSOCK) {
3262 /* If the fd is not a socket, remove it */
3263 swrap_remove_stale(fd);
3267 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3268 avail += msg->msg_iov[i].iov_len;
3272 errno = saved_errno;
3277 remain = MIN(80, avail);
3282 /* we capture it as one single packet */
3283 buf = (uint8_t *)malloc(remain);
3285 /* we just not capture the packet */
3286 errno = saved_errno;
3290 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3291 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
3293 msg->msg_iov[i].iov_base,
3296 remain -= this_time;
3301 if (ret == -1 && saved_errno != EAGAIN && saved_errno != ENOBUFS) {
3302 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
3303 } else if (ret == 0) { /* END OF FILE */
3304 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
3305 } else if (ret > 0) {
3306 swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
3315 if (un_addr != NULL) {
3318 rc = sockaddr_convert_from_un(si,
3328 swrap_dump_packet(si,
3334 swrap_dump_packet(si,
3346 errno = saved_errno;
3350 /****************************************************************************
3352 ***************************************************************************/
3354 static ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags,
3355 struct sockaddr *from, socklen_t *fromlen)
3357 struct sockaddr_un from_addr;
3358 socklen_t from_addrlen = sizeof(from_addr);
3360 struct socket_info *si = find_socket_info(s);
3361 struct sockaddr_storage ss;
3362 socklen_t ss_len = sizeof(ss);
3368 return libc_recvfrom(s,
3380 if (from != NULL && fromlen != NULL) {
3381 msg.msg_name = from; /* optional address */
3382 msg.msg_namelen = *fromlen; /* size of address */
3384 msg.msg_name = (struct sockaddr *)(void *)&ss; /* optional address */
3385 msg.msg_namelen = ss_len; /* size of address */
3387 msg.msg_iov = &tmp; /* scatter/gather array */
3388 msg.msg_iovlen = 1; /* # elements in msg_iov */
3389 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3390 msg.msg_control = NULL; /* ancillary data, see below */
3391 msg.msg_controllen = 0; /* ancillary data buffer len */
3392 msg.msg_flags = 0; /* flags on received message */
3395 tret = swrap_recvmsg_before(s, si, &msg, &tmp);
3400 buf = msg.msg_iov[0].iov_base;
3401 len = msg.msg_iov[0].iov_len;
3403 /* irix 6.4 forgets to null terminate the sun_path string :-( */
3404 memset(&from_addr, 0, sizeof(from_addr));
3405 ret = libc_recvfrom(s,
3409 (struct sockaddr *)(void *)&from_addr,
3415 tret = swrap_recvmsg_after(s,
3425 if (from != NULL && fromlen != NULL) {
3426 *fromlen = msg.msg_namelen;
3432 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3433 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
3434 struct sockaddr *from, Psocklen_t fromlen)
3436 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
3437 struct sockaddr *from, socklen_t *fromlen)
3440 return swrap_recvfrom(s, buf, len, flags, from, (socklen_t *)fromlen);
3443 /****************************************************************************
3445 ***************************************************************************/
3447 static ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags,
3448 const struct sockaddr *to, socklen_t tolen)
3452 struct sockaddr_un un_addr;
3453 const struct sockaddr_un *to_un = NULL;
3456 struct socket_info *si = find_socket_info(s);
3460 return libc_sendto(s, buf, len, flags, to, tolen);
3463 tmp.iov_base = discard_const_p(char, buf);
3467 msg.msg_name = discard_const_p(struct sockaddr, to); /* optional address */
3468 msg.msg_namelen = tolen; /* size of address */
3469 msg.msg_iov = &tmp; /* scatter/gather array */
3470 msg.msg_iovlen = 1; /* # elements in msg_iov */
3471 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
3472 msg.msg_control = NULL; /* ancillary data, see below */
3473 msg.msg_controllen = 0; /* ancillary data buffer len */
3474 msg.msg_flags = 0; /* flags on received message */
3477 rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
3482 buf = msg.msg_iov[0].iov_base;
3483 len = msg.msg_iov[0].iov_len;
3488 unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port);
3491 type = SOCKET_TYPE_CHAR_UDP;
3493 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
3494 snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT,
3495 socket_wrapper_dir(), type, iface, prt);
3496 if (stat(un_addr.sun_path, &st) != 0) continue;
3498 /* ignore the any errors in broadcast sends */
3503 (struct sockaddr *)(void *)&un_addr,
3507 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
3512 ret = libc_sendto(s,
3516 (struct sockaddr *)msg.msg_name,
3519 swrap_sendmsg_after(s, si, &msg, to, ret);
3524 ssize_t sendto(int s, const void *buf, size_t len, int flags,
3525 const struct sockaddr *to, socklen_t tolen)
3527 return swrap_sendto(s, buf, len, flags, to, tolen);
3530 /****************************************************************************
3532 ***************************************************************************/
3534 static ssize_t swrap_recv(int s, void *buf, size_t len, int flags)
3536 struct socket_info *si;
3538 struct sockaddr_storage ss;
3539 socklen_t ss_len = sizeof(ss);
3544 si = find_socket_info(s);
3546 return libc_recv(s, buf, len, flags);
3553 msg.msg_name = (struct sockaddr *)(void *)&ss; /* optional address */
3554 msg.msg_namelen = ss_len; /* size of address */
3555 msg.msg_iov = &tmp; /* scatter/gather array */
3556 msg.msg_iovlen = 1; /* # elements in msg_iov */
3557 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3558 msg.msg_control = NULL; /* ancillary data, see below */
3559 msg.msg_controllen = 0; /* ancillary data buffer len */
3560 msg.msg_flags = 0; /* flags on received message */
3563 tret = swrap_recvmsg_before(s, si, &msg, &tmp);
3568 buf = msg.msg_iov[0].iov_base;
3569 len = msg.msg_iov[0].iov_len;
3571 ret = libc_recv(s, buf, len, flags);
3573 tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
3581 ssize_t recv(int s, void *buf, size_t len, int flags)
3583 return swrap_recv(s, buf, len, flags);
3586 /****************************************************************************
3588 ***************************************************************************/
3590 static ssize_t swrap_read(int s, void *buf, size_t len)
3592 struct socket_info *si;
3595 struct sockaddr_storage ss;
3596 socklen_t ss_len = sizeof(ss);
3600 si = find_socket_info(s);
3602 return libc_read(s, buf, len);
3609 msg.msg_name = (struct sockaddr *)(void *)&ss; /* optional address */
3610 msg.msg_namelen = ss_len; /* size of address */
3611 msg.msg_iov = &tmp; /* scatter/gather array */
3612 msg.msg_iovlen = 1; /* # elements in msg_iov */
3613 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3614 msg.msg_control = NULL; /* ancillary data, see below */
3615 msg.msg_controllen = 0; /* ancillary data buffer len */
3616 msg.msg_flags = 0; /* flags on received message */
3619 tret = swrap_recvmsg_before(s, si, &msg, &tmp);
3621 if (tret == -ENOTSOCK) {
3622 return libc_read(s, buf, len);
3627 buf = msg.msg_iov[0].iov_base;
3628 len = msg.msg_iov[0].iov_len;
3630 ret = libc_read(s, buf, len);
3632 tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
3640 ssize_t read(int s, void *buf, size_t len)
3642 return swrap_read(s, buf, len);
3645 /****************************************************************************
3647 ***************************************************************************/
3649 static ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
3653 struct sockaddr_un un_addr;
3656 struct socket_info *si = find_socket_info(s);
3659 return libc_send(s, buf, len, flags);
3662 tmp.iov_base = discard_const_p(char, buf);
3666 msg.msg_name = NULL; /* optional address */
3667 msg.msg_namelen = 0; /* size of address */
3668 msg.msg_iov = &tmp; /* scatter/gather array */
3669 msg.msg_iovlen = 1; /* # elements in msg_iov */
3670 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
3671 msg.msg_control = NULL; /* ancillary data, see below */
3672 msg.msg_controllen = 0; /* ancillary data buffer len */
3673 msg.msg_flags = 0; /* flags on received message */
3676 rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
3681 buf = msg.msg_iov[0].iov_base;
3682 len = msg.msg_iov[0].iov_len;
3684 ret = libc_send(s, buf, len, flags);
3686 swrap_sendmsg_after(s, si, &msg, NULL, ret);
3691 ssize_t send(int s, const void *buf, size_t len, int flags)
3693 return swrap_send(s, buf, len, flags);
3696 /****************************************************************************
3698 ***************************************************************************/
3700 static ssize_t swrap_recvmsg(int s, struct msghdr *omsg, int flags)
3702 struct sockaddr_un from_addr;
3703 socklen_t from_addrlen = sizeof(from_addr);
3704 struct socket_info *si;
3711 si = find_socket_info(s);
3713 return libc_recvmsg(s, omsg, flags);
3716 tmp.iov_base = NULL;
3720 msg.msg_name = (struct sockaddr *)&from_addr; /* optional address */
3721 msg.msg_namelen = from_addrlen; /* size of address */
3722 msg.msg_iov = omsg->msg_iov; /* scatter/gather array */
3723 msg.msg_iovlen = omsg->msg_iovlen; /* # elements in msg_iov */
3724 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3725 msg.msg_control = omsg->msg_control; /* ancillary data, see below */
3726 msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
3727 msg.msg_flags = omsg->msg_flags; /* flags on received message */
3730 rc = swrap_recvmsg_before(s, si, &msg, &tmp);
3735 ret = libc_recvmsg(s, &msg, flags);
3737 rc = swrap_recvmsg_after(s, si, omsg, &from_addr, from_addrlen, ret);
3745 ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)
3747 return swrap_recvmsg(sockfd, msg, flags);
3750 /****************************************************************************
3752 ***************************************************************************/
3754 static ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags)
3758 struct sockaddr_un un_addr;
3759 const struct sockaddr_un *to_un = NULL;
3760 const struct sockaddr *to = NULL;
3763 struct socket_info *si = find_socket_info(s);
3767 return libc_sendmsg(s, omsg, flags);
3770 ZERO_STRUCT(un_addr);
3772 tmp.iov_base = NULL;
3776 msg.msg_name = omsg->msg_name; /* optional address */
3777 msg.msg_namelen = omsg->msg_namelen; /* size of address */
3778 msg.msg_iov = omsg->msg_iov; /* scatter/gather array */
3779 msg.msg_iovlen = omsg->msg_iovlen; /* # elements in msg_iov */
3780 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3781 msg.msg_control = omsg->msg_control; /* ancillary data, see below */
3782 msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
3783 msg.msg_flags = omsg->msg_flags; /* flags on received message */
3786 rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
3794 unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port);
3802 for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
3803 avail += msg.msg_iov[i].iov_len;
3809 /* we capture it as one single packet */
3810 buf = (uint8_t *)malloc(remain);
3815 for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
3816 size_t this_time = MIN(remain, (size_t)msg.msg_iov[i].iov_len);
3818 msg.msg_iov[i].iov_base,
3821 remain -= this_time;
3824 type = SOCKET_TYPE_CHAR_UDP;
3826 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
3827 snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT,
3828 socket_wrapper_dir(), type, iface, prt);
3829 if (stat(un_addr.sun_path, &st) != 0) continue;
3831 msg.msg_name = &un_addr; /* optional address */
3832 msg.msg_namelen = sizeof(un_addr); /* size of address */
3834 /* ignore the any errors in broadcast sends */
3835 libc_sendmsg(s, &msg, flags);
3838 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
3844 ret = libc_sendmsg(s, &msg, flags);
3846 swrap_sendmsg_after(s, si, &msg, to, ret);
3851 ssize_t sendmsg(int s, const struct msghdr *omsg, int flags)
3853 return swrap_sendmsg(s, omsg, flags);
3856 /****************************************************************************
3858 ***************************************************************************/
3860 static ssize_t swrap_readv(int s, const struct iovec *vector, int count)
3862 struct socket_info *si;
3865 struct sockaddr_storage ss;
3866 socklen_t ss_len = sizeof(ss);
3870 si = find_socket_info(s);
3872 return libc_readv(s, vector, count);
3875 tmp.iov_base = NULL;
3879 msg.msg_name = (struct sockaddr *)(void *)&ss; /* optional address */
3880 msg.msg_namelen = ss_len; /* size of address */
3881 msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
3882 msg.msg_iovlen = count; /* # elements in msg_iov */
3883 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3884 msg.msg_control = NULL; /* ancillary data, see below */
3885 msg.msg_controllen = 0; /* ancillary data buffer len */
3886 msg.msg_flags = 0; /* flags on received message */
3889 rc = swrap_recvmsg_before(s, si, &msg, &tmp);
3891 if (rc == -ENOTSOCK) {
3892 return libc_readv(s, vector, count);
3897 ret = libc_readv(s, msg.msg_iov, msg.msg_iovlen);
3899 rc = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
3907 ssize_t readv(int s, const struct iovec *vector, int count)
3909 return swrap_readv(s, vector, count);
3912 /****************************************************************************
3914 ***************************************************************************/
3916 static ssize_t swrap_writev(int s, const struct iovec *vector, int count)
3920 struct sockaddr_un un_addr;
3923 struct socket_info *si = find_socket_info(s);
3926 return libc_writev(s, vector, count);
3929 tmp.iov_base = NULL;
3933 msg.msg_name = NULL; /* optional address */
3934 msg.msg_namelen = 0; /* size of address */
3935 msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
3936 msg.msg_iovlen = count; /* # elements in msg_iov */
3937 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
3938 msg.msg_control = NULL; /* ancillary data, see below */
3939 msg.msg_controllen = 0; /* ancillary data buffer len */
3940 msg.msg_flags = 0; /* flags on received message */
3943 rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
3945 if (rc == -ENOTSOCK) {
3946 return libc_readv(s, vector, count);
3951 ret = libc_writev(s, msg.msg_iov, msg.msg_iovlen);
3953 swrap_sendmsg_after(s, si, &msg, NULL, ret);
3958 ssize_t writev(int s, const struct iovec *vector, int count)
3960 return swrap_writev(s, vector, count);
3963 /****************************
3965 ***************************/
3967 static int swrap_close(int fd)
3969 struct socket_info *si = find_socket_info(fd);
3970 struct socket_info_fd *fi;
3974 return libc_close(fd);
3977 for (fi = si->fds; fi; fi = fi->next) {
3979 SWRAP_DLIST_REMOVE(si->fds, fi);
3986 /* there are still references left */
3987 return libc_close(fd);
3990 SWRAP_DLIST_REMOVE(sockets, si);
3992 if (si->myname && si->peername) {
3993 swrap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0);
3996 ret = libc_close(fd);
3998 if (si->myname && si->peername) {
3999 swrap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0);
4000 swrap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0);
4003 if (si->bindname != NULL) {
4007 if (si->myname) free(si->myname);
4008 if (si->peername) free(si->peername);
4010 unlink(si->tmp_path);
4020 return swrap_close(fd);
4023 /****************************
4025 ***************************/
4027 static int swrap_dup(int fd)
4029 struct socket_info *si;
4030 struct socket_info_fd *fi;
4032 si = find_socket_info(fd);
4035 return libc_dup(fd);
4038 fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
4044 fi->fd = libc_dup(fd);
4046 int saved_errno = errno;
4048 errno = saved_errno;
4052 /* Make sure we don't have an entry for the fd */
4053 swrap_remove_stale(fi->fd);
4055 SWRAP_DLIST_ADD(si->fds, fi);
4061 return swrap_dup(fd);
4064 /****************************
4066 ***************************/
4068 static int swrap_dup2(int fd, int newfd)
4070 struct socket_info *si;
4071 struct socket_info_fd *fi;
4073 si = find_socket_info(fd);
4076 return libc_dup2(fd, newfd);
4079 if (find_socket_info(newfd)) {
4080 /* dup2() does an implicit close of newfd, which we
4081 * need to emulate */
4085 fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
4091 fi->fd = libc_dup2(fd, newfd);
4093 int saved_errno = errno;
4095 errno = saved_errno;
4099 /* Make sure we don't have an entry for the fd */
4100 swrap_remove_stale(fi->fd);
4102 SWRAP_DLIST_ADD(si->fds, fi);
4106 int dup2(int fd, int newfd)
4108 return swrap_dup2(fd, newfd);
4111 /****************************
4113 ***************************/
4116 static int swrap_eventfd(int count, int flags)
4120 fd = libc_eventfd(count, flags);
4122 swrap_remove_stale(fd);
4128 int eventfd(int count, int flags)
4130 return swrap_eventfd(count, flags);
4134 /****************************
4136 ***************************/
4139 * This function is called when the library is unloaded and makes sure that
4140 * sockets get closed and the unix file for the socket are unlinked.
4142 void swrap_destructor(void)
4144 struct socket_info *s = sockets;
4147 struct socket_info_fd *f = s->fds;