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>
84 /* GCC have printf type attribute check. */
85 #ifdef HAVE_FUNCTION_ATTRIBUTE_FORMAT
86 #define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
88 #define PRINTF_ATTRIBUTE(a,b)
89 #endif /* HAVE_FUNCTION_ATTRIBUTE_FORMAT */
91 #ifdef HAVE_DESTRUCTOR_ATTRIBUTE
92 #define DESTRUCTOR_ATTRIBUTE __attribute__ ((destructor))
94 #define DESTRUCTOR_ATTRIBUTE
97 #ifdef HAVE_GCC_THREAD_LOCAL_STORAGE
98 # define SWRAP_THREAD __thread
100 # define SWRAP_THREAD
104 #define MIN(a,b) ((a)<(b)?(a):(b))
108 #define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
111 #ifndef discard_const
112 #define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
115 #ifndef discard_const_p
116 #define discard_const_p(type, ptr) ((type *)discard_const(ptr))
119 #define SWRAP_DLIST_ADD(list,item) do { \
121 (item)->prev = NULL; \
122 (item)->next = NULL; \
125 (item)->prev = NULL; \
126 (item)->next = (list); \
127 (list)->prev = (item); \
132 #define SWRAP_DLIST_REMOVE(list,item) do { \
133 if ((list) == (item)) { \
134 (list) = (item)->next; \
136 (list)->prev = NULL; \
139 if ((item)->prev) { \
140 (item)->prev->next = (item)->next; \
142 if ((item)->next) { \
143 (item)->next->prev = (item)->prev; \
146 (item)->prev = NULL; \
147 (item)->next = NULL; \
150 #if defined(HAVE_GETTIMEOFDAY_TZ) || defined(HAVE_GETTIMEOFDAY_TZ_VOID)
151 #define swrapGetTimeOfDay(tval) gettimeofday(tval,NULL)
153 #define swrapGetTimeOfDay(tval) gettimeofday(tval)
156 /* we need to use a very terse format here as IRIX 6.4 silently
157 truncates names to 16 chars, so if we use a longer name then we
158 can't tell which port a packet came from with recvfrom()
160 with this format we have 8 chars left for the directory name
162 #define SOCKET_FORMAT "%c%02X%04X"
163 #define SOCKET_TYPE_CHAR_TCP 'T'
164 #define SOCKET_TYPE_CHAR_UDP 'U'
165 #define SOCKET_TYPE_CHAR_TCP_V6 'X'
166 #define SOCKET_TYPE_CHAR_UDP_V6 'Y'
169 * Cut down to 1500 byte packets for stream sockets,
170 * which makes it easier to format PCAP capture files
171 * (as the caller will simply continue from here)
173 #define SOCKET_MAX_PACKET 1500
175 #define SOCKET_MAX_SOCKETS 1024
177 /* This limit is to avoid broadcast sendto() needing to stat too many
178 * files. It may be raised (with a performance cost) to up to 254
179 * without changing the format above */
180 #define MAX_WRAPPED_INTERFACES 40
182 struct socket_info_fd {
183 struct socket_info_fd *prev, *next;
189 struct socket_info_fd *fds;
202 struct sockaddr *myname;
203 socklen_t myname_len;
205 struct sockaddr *peername;
206 socklen_t peername_len;
209 unsigned long pck_snd;
210 unsigned long pck_rcv;
213 struct socket_info *prev, *next;
217 * File descriptors are shared between threads so we should share socket
220 struct socket_info *sockets;
222 /* Function prototypes */
224 bool socket_wrapper_enabled(void);
225 void swrap_destructor(void) DESTRUCTOR_ATTRIBUTE;
228 # define SWRAP_LOG(...)
231 static void swrap_log(enum swrap_dbglvl_e dbglvl, const char *format, ...) PRINTF_ATTRIBUTE(2, 3);
232 # define SWRAP_LOG(dbglvl, ...) swrap_log((dbglvl), __VA_ARGS__)
234 static void swrap_log(enum swrap_dbglvl_e dbglvl, const char *format, ...)
239 unsigned int lvl = 0;
241 d = getenv("SOCKET_WRAPPER_DEBUGLEVEL");
246 va_start(va, format);
247 vsnprintf(buffer, sizeof(buffer), format, va);
252 case SWRAP_LOG_ERROR:
254 "SWRAP_ERROR(%d): %s\n",
255 (int)getpid(), buffer);
259 "SWRAP_WARN(%d): %s\n",
260 (int)getpid(), buffer);
262 case SWRAP_LOG_DEBUG:
264 "SWRAP_DEBUG(%d): %s\n",
265 (int)getpid(), buffer);
267 case SWRAP_LOG_TRACE:
269 "SWRAP_TRACE(%d): %s\n",
270 (int)getpid(), buffer);
277 /*********************************************************
278 * SWRAP LOADING LIBC FUNCTIONS
279 *********************************************************/
283 struct swrap_libc_fns {
284 int (*libc_accept)(int sockfd,
285 struct sockaddr *addr,
287 int (*libc_bind)(int sockfd,
288 const struct sockaddr *addr,
290 int (*libc_close)(int fd);
291 int (*libc_connect)(int sockfd,
292 const struct sockaddr *addr,
294 int (*libc_dup)(int fd);
295 int (*libc_dup2)(int oldfd, int newfd);
297 int (*libc_eventfd)(int count, int flags);
299 int (*libc_getpeername)(int sockfd,
300 struct sockaddr *addr,
302 int (*libc_getsockname)(int sockfd,
303 struct sockaddr *addr,
305 int (*libc_getsockopt)(int sockfd,
310 int (*libc_ioctl)(int d, unsigned long int request, ...);
311 int (*libc_listen)(int sockfd, int backlog);
312 int (*libc_open)(const char *pathname, int flags, mode_t mode);
313 int (*libc_pipe)(int pipefd[2]);
314 int (*libc_read)(int fd, void *buf, size_t count);
315 ssize_t (*libc_readv)(int fd, const struct iovec *iov, int iovcnt);
316 int (*libc_recv)(int sockfd, void *buf, size_t len, int flags);
317 int (*libc_recvfrom)(int sockfd,
321 struct sockaddr *src_addr,
323 int (*libc_recvmsg)(int sockfd, const struct msghdr *msg, int flags);
324 int (*libc_send)(int sockfd, const void *buf, size_t len, int flags);
325 int (*libc_sendmsg)(int sockfd, const struct msghdr *msg, int flags);
326 int (*libc_sendto)(int sockfd,
330 const struct sockaddr *dst_addr,
332 int (*libc_setsockopt)(int sockfd,
338 int (*libc_signalfd)(int fd, const sigset_t *mask, int flags);
340 int (*libc_socket)(int domain, int type, int protocol);
341 int (*libc_socketpair)(int domain, int type, int protocol, int sv[2]);
342 #ifdef HAVE_TIMERFD_CREATE
343 int (*libc_timerfd_create)(int clockid, int flags);
345 ssize_t (*libc_writev)(int fd, const struct iovec *iov, int iovcnt);
350 void *libsocket_handle;
357 struct swrap_libc_fns fns;
360 static struct swrap swrap;
363 static const char *socket_wrapper_dir(void);
365 #define LIBC_NAME "libc.so"
374 static const char *swrap_str_lib(enum swrap_lib lib)
381 case SWRAP_LIBSOCKET:
385 /* Compiler would warn us about unhandled enum value if we get here */
390 static void *swrap_load_lib_handle(enum swrap_lib lib)
392 int flags = RTLD_LAZY;
401 flags |= RTLD_DEEPBIND;
407 case SWRAP_LIBSOCKET:
408 #ifdef HAVE_LIBSOCKET
409 handle = swrap.libsocket_handle;
410 if (handle == NULL) {
411 for (handle = NULL, i = 10; handle == NULL && i >= 0; i--) {
412 char soname[256] = {0};
414 snprintf(soname, sizeof(soname), "libsocket.so.%d", i);
415 handle = dlopen(soname, flags);
418 swrap.libsocket_handle = handle;
424 handle = swrap.libc_handle;
425 if (handle == NULL) {
426 for (handle = NULL, i = 10; handle == NULL && i >= 0; i--) {
427 char soname[256] = {0};
429 snprintf(soname, sizeof(soname), "libc.so.%d", i);
430 handle = dlopen(soname, flags);
433 swrap.libc_handle = handle;
438 if (handle == NULL) {
439 SWRAP_LOG(SWRAP_LOG_ERROR,
440 "Failed to dlopen library: %s\n",
448 static void *_swrap_load_lib_function(enum swrap_lib lib, const char *fn_name)
453 handle = swrap_load_lib_handle(lib);
455 func = dlsym(handle, fn_name);
457 SWRAP_LOG(SWRAP_LOG_ERROR,
458 "Failed to find %s: %s\n",
463 SWRAP_LOG(SWRAP_LOG_TRACE,
465 fn_name, swrap_str_lib(lib));
469 #define swrap_load_lib_function(lib, fn_name) \
470 if (swrap.fns.libc_##fn_name == NULL) { \
471 *(void **) (&swrap.fns.libc_##fn_name) = \
472 _swrap_load_lib_function(lib, #fn_name); \
479 * Functions especially from libc need to be loaded individually, you can't load
480 * all at once or gdb will segfault at startup. The same applies to valgrind and
481 * has probably something todo with with the linker.
482 * So we need load each function at the point it is called the first time.
484 static int libc_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
486 swrap_load_lib_function(SWRAP_LIBSOCKET, accept);
488 return swrap.fns.libc_accept(sockfd, addr, addrlen);
491 static int libc_bind(int sockfd,
492 const struct sockaddr *addr,
495 swrap_load_lib_function(SWRAP_LIBSOCKET, bind);
497 return swrap.fns.libc_bind(sockfd, addr, addrlen);
500 static int libc_close(int fd)
502 swrap_load_lib_function(SWRAP_LIBC, close);
504 return swrap.fns.libc_close(fd);
507 static int libc_connect(int sockfd,
508 const struct sockaddr *addr,
511 swrap_load_lib_function(SWRAP_LIBSOCKET, connect);
513 return swrap.fns.libc_connect(sockfd, addr, addrlen);
516 static int libc_dup(int fd)
518 swrap_load_lib_function(SWRAP_LIBC, dup);
520 return swrap.fns.libc_dup(fd);
523 static int libc_dup2(int oldfd, int newfd)
525 swrap_load_lib_function(SWRAP_LIBC, dup2);
527 return swrap.fns.libc_dup2(oldfd, newfd);
531 static int libc_eventfd(int count, int flags)
533 swrap_load_lib_function(SWRAP_LIBC, eventfd);
535 return swrap.fns.libc_eventfd(count, flags);
539 static int libc_getpeername(int sockfd,
540 struct sockaddr *addr,
543 swrap_load_lib_function(SWRAP_LIBSOCKET, getpeername);
545 return swrap.fns.libc_getpeername(sockfd, addr, addrlen);
548 static int libc_getsockname(int sockfd,
549 struct sockaddr *addr,
552 swrap_load_lib_function(SWRAP_LIBSOCKET, getsockname);
554 return swrap.fns.libc_getsockname(sockfd, addr, addrlen);
557 static int libc_getsockopt(int sockfd,
563 swrap_load_lib_function(SWRAP_LIBSOCKET, getsockopt);
565 return swrap.fns.libc_getsockopt(sockfd, level, optname, optval, optlen);
568 static int libc_vioctl(int d, unsigned long int request, va_list ap)
574 swrap_load_lib_function(SWRAP_LIBC, ioctl);
576 for (i = 0; i < 4; i++) {
577 args[i] = va_arg(ap, long int);
580 rc = swrap.fns.libc_ioctl(d,
590 static int libc_listen(int sockfd, int backlog)
592 swrap_load_lib_function(SWRAP_LIBSOCKET, listen);
594 return swrap.fns.libc_listen(sockfd, backlog);
597 static int libc_vopen(const char *pathname, int flags, va_list ap)
602 swrap_load_lib_function(SWRAP_LIBC, open);
604 mode = va_arg(ap, long int);
606 fd = swrap.fns.libc_open(pathname, flags, (mode_t)mode);
611 static int libc_open(const char *pathname, int flags, ...)
617 fd = libc_vopen(pathname, flags, ap);
623 static int libc_pipe(int pipefd[2])
625 swrap_load_lib_function(SWRAP_LIBSOCKET, pipe);
627 return swrap.fns.libc_pipe(pipefd);
630 static int libc_read(int fd, void *buf, size_t count)
632 swrap_load_lib_function(SWRAP_LIBC, read);
634 return swrap.fns.libc_read(fd, buf, count);
637 static ssize_t libc_readv(int fd, const struct iovec *iov, int iovcnt)
639 swrap_load_lib_function(SWRAP_LIBSOCKET, readv);
641 return swrap.fns.libc_readv(fd, iov, iovcnt);
644 static int libc_recv(int sockfd, void *buf, size_t len, int flags)
646 swrap_load_lib_function(SWRAP_LIBSOCKET, recv);
648 return swrap.fns.libc_recv(sockfd, buf, len, flags);
651 static int libc_recvfrom(int sockfd,
655 struct sockaddr *src_addr,
658 swrap_load_lib_function(SWRAP_LIBSOCKET, recvfrom);
660 return swrap.fns.libc_recvfrom(sockfd, buf, len, flags, src_addr, addrlen);
663 static int libc_recvmsg(int sockfd, struct msghdr *msg, int flags)
665 swrap_load_lib_function(SWRAP_LIBSOCKET, recvmsg);
667 return swrap.fns.libc_recvmsg(sockfd, msg, flags);
670 static int libc_send(int sockfd, const void *buf, size_t len, int flags)
672 swrap_load_lib_function(SWRAP_LIBSOCKET, send);
674 return swrap.fns.libc_send(sockfd, buf, len, flags);
677 static int libc_sendmsg(int sockfd, const struct msghdr *msg, int flags)
679 swrap_load_lib_function(SWRAP_LIBSOCKET, sendmsg);
681 return swrap.fns.libc_sendmsg(sockfd, msg, flags);
684 static int libc_sendto(int sockfd,
688 const struct sockaddr *dst_addr,
691 swrap_load_lib_function(SWRAP_LIBSOCKET, sendto);
693 return swrap.fns.libc_sendto(sockfd, buf, len, flags, dst_addr, addrlen);
696 static int libc_setsockopt(int sockfd,
702 swrap_load_lib_function(SWRAP_LIBSOCKET, setsockopt);
704 return swrap.fns.libc_setsockopt(sockfd, level, optname, optval, optlen);
708 static int libc_signalfd(int fd, const sigset_t *mask, int flags)
710 swrap_load_lib_function(SWRAP_LIBSOCKET, signalfd);
712 return swrap.fns.libc_signalfd(fd, mask, flags);
716 static int libc_socket(int domain, int type, int protocol)
718 swrap_load_lib_function(SWRAP_LIBSOCKET, socket);
720 return swrap.fns.libc_socket(domain, type, protocol);
723 static int libc_socketpair(int domain, int type, int protocol, int sv[2])
725 swrap_load_lib_function(SWRAP_LIBSOCKET, socketpair);
727 return swrap.fns.libc_socketpair(domain, type, protocol, sv);
730 #ifdef HAVE_TIMERFD_CREATE
731 static int libc_timerfd_create(int clockid, int flags)
733 swrap_load_lib_function(SWRAP_LIBC, timerfd_create);
735 return swrap.fns.libc_timerfd_create(clockid, flags);
739 static ssize_t libc_writev(int fd, const struct iovec *iov, int iovcnt)
741 swrap_load_lib_function(SWRAP_LIBSOCKET, writev);
743 return swrap.fns.libc_writev(fd, iov, iovcnt);
746 /*********************************************************
747 * SWRAP HELPER FUNCTIONS
748 *********************************************************/
754 static const struct in6_addr *swrap_ipv6(void)
756 static struct in6_addr v;
757 static int initialized;
765 ret = inet_pton(AF_INET6, "FD00::5357:5F00", &v);
774 static struct sockaddr *sockaddr_dup(const void *data, socklen_t len)
776 struct sockaddr *ret = (struct sockaddr *)malloc(len);
777 memcpy(ret, data, len);
781 static void set_port(int family, int prt, struct sockaddr *addr)
785 ((struct sockaddr_in *)addr)->sin_port = htons(prt);
789 ((struct sockaddr_in6 *)addr)->sin6_port = htons(prt);
795 static size_t socket_length(int family)
799 return sizeof(struct sockaddr_in);
802 return sizeof(struct sockaddr_in6);
808 static const char *socket_wrapper_dir(void)
810 const char *s = getenv("SOCKET_WRAPPER_DIR");
814 if (strncmp(s, "./", 2) == 0) {
818 SWRAP_LOG(SWRAP_LOG_TRACE, "socket_wrapper_dir: %s", s);
822 bool socket_wrapper_enabled(void)
824 const char *s = socket_wrapper_dir();
826 return s != NULL ? true : false;
829 static unsigned int socket_wrapper_default_iface(void)
831 const char *s = getenv("SOCKET_WRAPPER_DEFAULT_IFACE");
834 if (sscanf(s, "%u", &iface) == 1) {
835 if (iface >= 1 && iface <= MAX_WRAPPED_INTERFACES) {
841 return 1;/* 127.0.0.1 */
844 static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, socklen_t *len)
851 p = strrchr(un->sun_path, '/');
852 if (p) p++; else p = un->sun_path;
854 if (sscanf(p, SOCKET_FORMAT, &type, &iface, &prt) != 3) {
859 SWRAP_LOG(SWRAP_LOG_TRACE, "type %c iface %u port %u",
862 if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
873 case SOCKET_TYPE_CHAR_TCP:
874 case SOCKET_TYPE_CHAR_UDP: {
875 struct sockaddr_in *in2 = (struct sockaddr_in *)(void *)in;
877 if ((*len) < sizeof(*in2)) {
882 memset(in2, 0, sizeof(*in2));
883 in2->sin_family = AF_INET;
884 in2->sin_addr.s_addr = htonl((127<<24) | iface);
885 in2->sin_port = htons(prt);
891 case SOCKET_TYPE_CHAR_TCP_V6:
892 case SOCKET_TYPE_CHAR_UDP_V6: {
893 struct sockaddr_in6 *in2 = (struct sockaddr_in6 *)(void *)in;
895 if ((*len) < sizeof(*in2)) {
900 memset(in2, 0, sizeof(*in2));
901 in2->sin6_family = AF_INET6;
902 in2->sin6_addr = *swrap_ipv6();
903 in2->sin6_addr.s6_addr[15] = iface;
904 in2->sin6_port = htons(prt);
918 static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un,
926 if (bcast) *bcast = 0;
928 switch (inaddr->sa_family) {
930 const struct sockaddr_in *in =
931 (const struct sockaddr_in *)(const void *)inaddr;
932 unsigned int addr = ntohl(in->sin_addr.s_addr);
939 u_type = SOCKET_TYPE_CHAR_TCP;
942 u_type = SOCKET_TYPE_CHAR_UDP;
943 a_type = SOCKET_TYPE_CHAR_UDP;
944 b_type = SOCKET_TYPE_CHAR_UDP;
947 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
948 errno = ESOCKTNOSUPPORT;
952 prt = ntohs(in->sin_port);
953 if (a_type && addr == 0xFFFFFFFF) {
954 /* 255.255.255.255 only udp */
957 iface = socket_wrapper_default_iface();
958 } else if (b_type && addr == 0x7FFFFFFF) {
959 /* 127.255.255.255 only udp */
962 iface = socket_wrapper_default_iface();
963 } else if ((addr & 0xFFFFFF00) == 0x7F000000) {
967 iface = (addr & 0x000000FF);
972 if (bcast) *bcast = is_bcast;
977 const struct sockaddr_in6 *in =
978 (const struct sockaddr_in6 *)(const void *)inaddr;
979 struct in6_addr cmp1, cmp2;
983 type = SOCKET_TYPE_CHAR_TCP_V6;
986 type = SOCKET_TYPE_CHAR_UDP_V6;
989 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
990 errno = ESOCKTNOSUPPORT;
994 /* XXX no multicast/broadcast */
996 prt = ntohs(in->sin6_port);
998 cmp1 = *swrap_ipv6();
999 cmp2 = in->sin6_addr;
1000 cmp2.s6_addr[15] = 0;
1001 if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
1002 iface = in->sin6_addr.s6_addr[15];
1004 errno = ENETUNREACH;
1012 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family!\n");
1013 errno = ENETUNREACH;
1018 SWRAP_LOG(SWRAP_LOG_WARN, "Port not set\n");
1024 snprintf(un->sun_path, sizeof(un->sun_path), "%s/EINVAL",
1025 socket_wrapper_dir());
1026 SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
1027 /* the caller need to do more processing */
1031 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT,
1032 socket_wrapper_dir(), type, iface, prt);
1033 SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
1038 static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un,
1047 if (bcast) *bcast = 0;
1049 switch (si->family) {
1051 const struct sockaddr_in *in =
1052 (const struct sockaddr_in *)(const void *)inaddr;
1053 unsigned int addr = ntohl(in->sin_addr.s_addr);
1059 prt = ntohs(in->sin_port);
1063 u_type = SOCKET_TYPE_CHAR_TCP;
1064 d_type = SOCKET_TYPE_CHAR_TCP;
1067 u_type = SOCKET_TYPE_CHAR_UDP;
1068 d_type = SOCKET_TYPE_CHAR_UDP;
1069 a_type = SOCKET_TYPE_CHAR_UDP;
1070 b_type = SOCKET_TYPE_CHAR_UDP;
1073 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1074 errno = ESOCKTNOSUPPORT;
1082 iface = socket_wrapper_default_iface();
1083 } else if (a_type && addr == 0xFFFFFFFF) {
1084 /* 255.255.255.255 only udp */
1087 iface = socket_wrapper_default_iface();
1088 } else if (b_type && addr == 0x7FFFFFFF) {
1089 /* 127.255.255.255 only udp */
1092 iface = socket_wrapper_default_iface();
1093 } else if ((addr & 0xFFFFFF00) == 0x7F000000) {
1097 iface = (addr & 0x000000FF);
1099 errno = EADDRNOTAVAIL;
1106 const struct sockaddr_in6 *in =
1107 (const struct sockaddr_in6 *)(const void *)inaddr;
1108 struct in6_addr cmp1, cmp2;
1112 type = SOCKET_TYPE_CHAR_TCP_V6;
1115 type = SOCKET_TYPE_CHAR_UDP_V6;
1118 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1119 errno = ESOCKTNOSUPPORT;
1123 /* XXX no multicast/broadcast */
1125 prt = ntohs(in->sin6_port);
1127 cmp1 = *swrap_ipv6();
1128 cmp2 = in->sin6_addr;
1129 cmp2.s6_addr[15] = 0;
1130 if (IN6_IS_ADDR_UNSPECIFIED(&in->sin6_addr)) {
1131 iface = socket_wrapper_default_iface();
1132 } else if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
1133 iface = in->sin6_addr.s6_addr[15];
1135 errno = EADDRNOTAVAIL;
1143 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n");
1144 errno = EADDRNOTAVAIL;
1149 if (bcast) *bcast = is_bcast;
1151 if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
1157 /* handle auto-allocation of ephemeral ports */
1158 for (prt = 5001; prt < 10000; prt++) {
1159 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT,
1160 socket_wrapper_dir(), type, iface, prt);
1161 if (stat(un->sun_path, &st) == 0) continue;
1163 set_port(si->family, prt, si->myname);
1172 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT,
1173 socket_wrapper_dir(), type, iface, prt);
1174 SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
1178 static struct socket_info *find_socket_info(int fd)
1180 struct socket_info *i;
1182 for (i = sockets; i; i = i->next) {
1183 struct socket_info_fd *f;
1184 for (f = i->fds; f; f = f->next) {
1194 static void swrap_remove_stale(int fd)
1196 struct socket_info *si = find_socket_info(fd);
1197 struct socket_info_fd *fi;
1200 for (fi = si->fds; fi; fi = fi->next) {
1202 SWRAP_LOG(SWRAP_LOG_TRACE, "remove stale wrapper for %d", fd);
1203 SWRAP_DLIST_REMOVE(si->fds, fi);
1209 if (si->fds == NULL) {
1210 SWRAP_DLIST_REMOVE(sockets, si);
1215 static int sockaddr_convert_to_un(struct socket_info *si,
1216 const struct sockaddr *in_addr,
1218 struct sockaddr_un *out_addr,
1222 struct sockaddr *out = (struct sockaddr *)(void *)out_addr;
1224 (void) in_len; /* unused */
1226 if (out_addr == NULL) {
1230 out->sa_family = AF_UNIX;
1231 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
1232 out->sa_len = sizeof(*out_addr);
1235 switch (in_addr->sa_family) {
1245 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1246 errno = ESOCKTNOSUPPORT;
1250 return convert_in_un_alloc(si, in_addr, out_addr, bcast);
1252 return convert_in_un_remote(si, in_addr, out_addr, bcast);
1258 errno = EAFNOSUPPORT;
1259 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n");
1263 static int sockaddr_convert_from_un(const struct socket_info *si,
1264 const struct sockaddr_un *in_addr,
1265 socklen_t un_addrlen,
1267 struct sockaddr *out_addr,
1268 socklen_t *out_addrlen)
1272 if (out_addr == NULL || out_addrlen == NULL)
1275 if (un_addrlen == 0) {
1290 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1291 errno = ESOCKTNOSUPPORT;
1294 ret = convert_un_in(in_addr, out_addr, out_addrlen);
1295 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
1296 out_addr->sa_len = *out_addrlen;
1303 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n");
1304 errno = EAFNOSUPPORT;
1308 enum swrap_packet_type {
1310 SWRAP_CONNECT_UNREACH,
1318 SWRAP_SENDTO_UNREACH,
1329 struct swrap_file_hdr {
1331 uint16_t version_major;
1332 uint16_t version_minor;
1335 uint32_t frame_max_len;
1336 #define SWRAP_FRAME_LENGTH_MAX 0xFFFF
1339 #define SWRAP_FILE_HDR_SIZE 24
1341 struct swrap_packet_frame {
1343 uint32_t micro_seconds;
1344 uint32_t recorded_length;
1345 uint32_t full_length;
1347 #define SWRAP_PACKET_FRAME_SIZE 16
1349 union swrap_packet_ip {
1353 uint16_t packet_length;
1354 uint16_t identification;
1359 uint16_t hdr_checksum;
1363 #define SWRAP_PACKET_IP_V4_SIZE 20
1366 uint8_t flow_label_high;
1367 uint16_t flow_label_low;
1368 uint16_t payload_length;
1369 uint8_t next_header;
1371 uint8_t src_addr[16];
1372 uint8_t dest_addr[16];
1374 #define SWRAP_PACKET_IP_V6_SIZE 40
1376 #define SWRAP_PACKET_IP_SIZE 40
1378 union swrap_packet_payload {
1380 uint16_t source_port;
1390 #define SWRAP_PACKET_PAYLOAD_TCP_SIZE 20
1392 uint16_t source_port;
1397 #define SWRAP_PACKET_PAYLOAD_UDP_SIZE 8
1404 #define SWRAP_PACKET_PAYLOAD_ICMP4_SIZE 8
1411 #define SWRAP_PACKET_PAYLOAD_ICMP6_SIZE 8
1413 #define SWRAP_PACKET_PAYLOAD_SIZE 20
1415 #define SWRAP_PACKET_MIN_ALLOC \
1416 (SWRAP_PACKET_FRAME_SIZE + \
1417 SWRAP_PACKET_IP_SIZE + \
1418 SWRAP_PACKET_PAYLOAD_SIZE)
1420 static const char *socket_wrapper_pcap_file(void)
1422 static int initialized = 0;
1423 static const char *s = NULL;
1424 static const struct swrap_file_hdr h;
1425 static const struct swrap_packet_frame f;
1426 static const union swrap_packet_ip i;
1427 static const union swrap_packet_payload p;
1429 if (initialized == 1) {
1435 * TODO: don't use the structs use plain buffer offsets
1436 * and PUSH_U8(), PUSH_U16() and PUSH_U32()
1438 * for now make sure we disable PCAP support
1439 * if the struct has alignment!
1441 if (sizeof(h) != SWRAP_FILE_HDR_SIZE) {
1444 if (sizeof(f) != SWRAP_PACKET_FRAME_SIZE) {
1447 if (sizeof(i) != SWRAP_PACKET_IP_SIZE) {
1450 if (sizeof(i.v4) != SWRAP_PACKET_IP_V4_SIZE) {
1453 if (sizeof(i.v6) != SWRAP_PACKET_IP_V6_SIZE) {
1456 if (sizeof(p) != SWRAP_PACKET_PAYLOAD_SIZE) {
1459 if (sizeof(p.tcp) != SWRAP_PACKET_PAYLOAD_TCP_SIZE) {
1462 if (sizeof(p.udp) != SWRAP_PACKET_PAYLOAD_UDP_SIZE) {
1465 if (sizeof(p.icmp4) != SWRAP_PACKET_PAYLOAD_ICMP4_SIZE) {
1468 if (sizeof(p.icmp6) != SWRAP_PACKET_PAYLOAD_ICMP6_SIZE) {
1472 s = getenv("SOCKET_WRAPPER_PCAP_FILE");
1476 if (strncmp(s, "./", 2) == 0) {
1482 static uint8_t *swrap_packet_init(struct timeval *tval,
1483 const struct sockaddr *src,
1484 const struct sockaddr *dest,
1486 const uint8_t *payload,
1488 unsigned long tcp_seqno,
1489 unsigned long tcp_ack,
1490 unsigned char tcp_ctl,
1492 size_t *_packet_len)
1496 struct swrap_packet_frame *frame;
1497 union swrap_packet_ip *ip;
1498 union swrap_packet_payload *pay;
1501 size_t nonwire_len = sizeof(*frame);
1502 size_t wire_hdr_len = 0;
1503 size_t wire_len = 0;
1504 size_t ip_hdr_len = 0;
1505 size_t icmp_hdr_len = 0;
1506 size_t icmp_truncate_len = 0;
1507 uint8_t protocol = 0, icmp_protocol = 0;
1508 const struct sockaddr_in *src_in = NULL;
1509 const struct sockaddr_in *dest_in = NULL;
1511 const struct sockaddr_in6 *src_in6 = NULL;
1512 const struct sockaddr_in6 *dest_in6 = NULL;
1517 switch (src->sa_family) {
1519 src_in = (const struct sockaddr_in *)src;
1520 dest_in = (const struct sockaddr_in *)dest;
1521 src_port = src_in->sin_port;
1522 dest_port = dest_in->sin_port;
1523 ip_hdr_len = sizeof(ip->v4);
1527 src_in6 = (const struct sockaddr_in6 *)src;
1528 dest_in6 = (const struct sockaddr_in6 *)dest;
1529 src_port = src_in6->sin6_port;
1530 dest_port = dest_in6->sin6_port;
1531 ip_hdr_len = sizeof(ip->v6);
1538 switch (socket_type) {
1540 protocol = 0x06; /* TCP */
1541 wire_hdr_len = ip_hdr_len + sizeof(pay->tcp);
1542 wire_len = wire_hdr_len + payload_len;
1546 protocol = 0x11; /* UDP */
1547 wire_hdr_len = ip_hdr_len + sizeof(pay->udp);
1548 wire_len = wire_hdr_len + payload_len;
1556 icmp_protocol = protocol;
1557 switch (src->sa_family) {
1559 protocol = 0x01; /* ICMPv4 */
1560 icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp4);
1564 protocol = 0x3A; /* ICMPv6 */
1565 icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp6);
1569 if (wire_len > 64 ) {
1570 icmp_truncate_len = wire_len - 64;
1572 wire_hdr_len += icmp_hdr_len;
1573 wire_len += icmp_hdr_len;
1576 packet_len = nonwire_len + wire_len;
1577 alloc_len = packet_len;
1578 if (alloc_len < SWRAP_PACKET_MIN_ALLOC) {
1579 alloc_len = SWRAP_PACKET_MIN_ALLOC;
1582 base = (uint8_t *)malloc(alloc_len);
1586 memset(base, 0x0, alloc_len);
1590 frame = (struct swrap_packet_frame *)buf;
1591 frame->seconds = tval->tv_sec;
1592 frame->micro_seconds = tval->tv_usec;
1593 frame->recorded_length = wire_len - icmp_truncate_len;
1594 frame->full_length = wire_len - icmp_truncate_len;
1595 buf += SWRAP_PACKET_FRAME_SIZE;
1597 ip = (union swrap_packet_ip *)buf;
1598 switch (src->sa_family) {
1600 ip->v4.ver_hdrlen = 0x45; /* version 4 and 5 * 32 bit words */
1602 ip->v4.packet_length = htons(wire_len - icmp_truncate_len);
1603 ip->v4.identification = htons(0xFFFF);
1604 ip->v4.flags = 0x40; /* BIT 1 set - means don't fragment */
1605 ip->v4.fragment = htons(0x0000);
1607 ip->v4.protocol = protocol;
1608 ip->v4.hdr_checksum = htons(0x0000);
1609 ip->v4.src_addr = src_in->sin_addr.s_addr;
1610 ip->v4.dest_addr = dest_in->sin_addr.s_addr;
1611 buf += SWRAP_PACKET_IP_V4_SIZE;
1615 ip->v6.ver_prio = 0x60; /* version 4 and 5 * 32 bit words */
1616 ip->v6.flow_label_high = 0x00;
1617 ip->v6.flow_label_low = 0x0000;
1618 ip->v6.payload_length = htons(wire_len - icmp_truncate_len); /* TODO */
1619 ip->v6.next_header = protocol;
1620 memcpy(ip->v6.src_addr, src_in6->sin6_addr.s6_addr, 16);
1621 memcpy(ip->v6.dest_addr, dest_in6->sin6_addr.s6_addr, 16);
1622 buf += SWRAP_PACKET_IP_V6_SIZE;
1628 pay = (union swrap_packet_payload *)buf;
1629 switch (src->sa_family) {
1631 pay->icmp4.type = 0x03; /* destination unreachable */
1632 pay->icmp4.code = 0x01; /* host unreachable */
1633 pay->icmp4.checksum = htons(0x0000);
1634 pay->icmp4.unused = htonl(0x00000000);
1635 buf += SWRAP_PACKET_PAYLOAD_ICMP4_SIZE;
1637 /* set the ip header in the ICMP payload */
1638 ip = (union swrap_packet_ip *)buf;
1639 ip->v4.ver_hdrlen = 0x45; /* version 4 and 5 * 32 bit words */
1641 ip->v4.packet_length = htons(wire_len - icmp_hdr_len);
1642 ip->v4.identification = htons(0xFFFF);
1643 ip->v4.flags = 0x40; /* BIT 1 set - means don't fragment */
1644 ip->v4.fragment = htons(0x0000);
1646 ip->v4.protocol = icmp_protocol;
1647 ip->v4.hdr_checksum = htons(0x0000);
1648 ip->v4.src_addr = dest_in->sin_addr.s_addr;
1649 ip->v4.dest_addr = src_in->sin_addr.s_addr;
1650 buf += SWRAP_PACKET_IP_V4_SIZE;
1652 src_port = dest_in->sin_port;
1653 dest_port = src_in->sin_port;
1657 pay->icmp6.type = 0x01; /* destination unreachable */
1658 pay->icmp6.code = 0x03; /* address unreachable */
1659 pay->icmp6.checksum = htons(0x0000);
1660 pay->icmp6.unused = htonl(0x00000000);
1661 buf += SWRAP_PACKET_PAYLOAD_ICMP6_SIZE;
1663 /* set the ip header in the ICMP payload */
1664 ip = (union swrap_packet_ip *)buf;
1665 ip->v6.ver_prio = 0x60; /* version 4 and 5 * 32 bit words */
1666 ip->v6.flow_label_high = 0x00;
1667 ip->v6.flow_label_low = 0x0000;
1668 ip->v6.payload_length = htons(wire_len - icmp_truncate_len); /* TODO */
1669 ip->v6.next_header = protocol;
1670 memcpy(ip->v6.src_addr, dest_in6->sin6_addr.s6_addr, 16);
1671 memcpy(ip->v6.dest_addr, src_in6->sin6_addr.s6_addr, 16);
1672 buf += SWRAP_PACKET_IP_V6_SIZE;
1674 src_port = dest_in6->sin6_port;
1675 dest_port = src_in6->sin6_port;
1681 pay = (union swrap_packet_payload *)buf;
1683 switch (socket_type) {
1685 pay->tcp.source_port = src_port;
1686 pay->tcp.dest_port = dest_port;
1687 pay->tcp.seq_num = htonl(tcp_seqno);
1688 pay->tcp.ack_num = htonl(tcp_ack);
1689 pay->tcp.hdr_length = 0x50; /* 5 * 32 bit words */
1690 pay->tcp.control = tcp_ctl;
1691 pay->tcp.window = htons(0x7FFF);
1692 pay->tcp.checksum = htons(0x0000);
1693 pay->tcp.urg = htons(0x0000);
1694 buf += SWRAP_PACKET_PAYLOAD_TCP_SIZE;
1699 pay->udp.source_port = src_port;
1700 pay->udp.dest_port = dest_port;
1701 pay->udp.length = htons(8 + payload_len);
1702 pay->udp.checksum = htons(0x0000);
1703 buf += SWRAP_PACKET_PAYLOAD_UDP_SIZE;
1708 if (payload && payload_len > 0) {
1709 memcpy(buf, payload, payload_len);
1712 *_packet_len = packet_len - icmp_truncate_len;
1716 static int swrap_get_pcap_fd(const char *fname)
1720 if (fd != -1) return fd;
1722 fd = libc_open(fname, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0644);
1724 struct swrap_file_hdr file_hdr;
1725 file_hdr.magic = 0xA1B2C3D4;
1726 file_hdr.version_major = 0x0002;
1727 file_hdr.version_minor = 0x0004;
1728 file_hdr.timezone = 0x00000000;
1729 file_hdr.sigfigs = 0x00000000;
1730 file_hdr.frame_max_len = SWRAP_FRAME_LENGTH_MAX;
1731 file_hdr.link_type = 0x0065; /* 101 RAW IP */
1733 if (write(fd, &file_hdr, sizeof(file_hdr)) != sizeof(file_hdr)) {
1740 fd = libc_open(fname, O_WRONLY|O_APPEND, 0644);
1745 static uint8_t *swrap_marshall_packet(struct socket_info *si,
1746 const struct sockaddr *addr,
1747 enum swrap_packet_type type,
1748 const void *buf, size_t len,
1751 const struct sockaddr *src_addr;
1752 const struct sockaddr *dest_addr;
1753 unsigned long tcp_seqno = 0;
1754 unsigned long tcp_ack = 0;
1755 unsigned char tcp_ctl = 0;
1756 int unreachable = 0;
1760 switch (si->family) {
1772 case SWRAP_CONNECT_SEND:
1773 if (si->type != SOCK_STREAM) return NULL;
1775 src_addr = si->myname;
1778 tcp_seqno = si->io.pck_snd;
1779 tcp_ack = si->io.pck_rcv;
1780 tcp_ctl = 0x02; /* SYN */
1782 si->io.pck_snd += 1;
1786 case SWRAP_CONNECT_RECV:
1787 if (si->type != SOCK_STREAM) return NULL;
1789 dest_addr = si->myname;
1792 tcp_seqno = si->io.pck_rcv;
1793 tcp_ack = si->io.pck_snd;
1794 tcp_ctl = 0x12; /** SYN,ACK */
1796 si->io.pck_rcv += 1;
1800 case SWRAP_CONNECT_UNREACH:
1801 if (si->type != SOCK_STREAM) return NULL;
1803 dest_addr = si->myname;
1806 /* Unreachable: resend the data of SWRAP_CONNECT_SEND */
1807 tcp_seqno = si->io.pck_snd - 1;
1808 tcp_ack = si->io.pck_rcv;
1809 tcp_ctl = 0x02; /* SYN */
1814 case SWRAP_CONNECT_ACK:
1815 if (si->type != SOCK_STREAM) return NULL;
1817 src_addr = si->myname;
1820 tcp_seqno = si->io.pck_snd;
1821 tcp_ack = si->io.pck_rcv;
1822 tcp_ctl = 0x10; /* ACK */
1826 case SWRAP_ACCEPT_SEND:
1827 if (si->type != SOCK_STREAM) return NULL;
1829 dest_addr = si->myname;
1832 tcp_seqno = si->io.pck_rcv;
1833 tcp_ack = si->io.pck_snd;
1834 tcp_ctl = 0x02; /* SYN */
1836 si->io.pck_rcv += 1;
1840 case SWRAP_ACCEPT_RECV:
1841 if (si->type != SOCK_STREAM) return NULL;
1843 src_addr = si->myname;
1846 tcp_seqno = si->io.pck_snd;
1847 tcp_ack = si->io.pck_rcv;
1848 tcp_ctl = 0x12; /* SYN,ACK */
1850 si->io.pck_snd += 1;
1854 case SWRAP_ACCEPT_ACK:
1855 if (si->type != SOCK_STREAM) return NULL;
1857 dest_addr = si->myname;
1860 tcp_seqno = si->io.pck_rcv;
1861 tcp_ack = si->io.pck_snd;
1862 tcp_ctl = 0x10; /* ACK */
1867 src_addr = si->myname;
1868 dest_addr = si->peername;
1870 tcp_seqno = si->io.pck_snd;
1871 tcp_ack = si->io.pck_rcv;
1872 tcp_ctl = 0x18; /* PSH,ACK */
1874 si->io.pck_snd += len;
1878 case SWRAP_SEND_RST:
1879 dest_addr = si->myname;
1880 src_addr = si->peername;
1882 if (si->type == SOCK_DGRAM) {
1883 return swrap_marshall_packet(si, si->peername,
1884 SWRAP_SENDTO_UNREACH,
1885 buf, len, packet_len);
1888 tcp_seqno = si->io.pck_rcv;
1889 tcp_ack = si->io.pck_snd;
1890 tcp_ctl = 0x14; /** RST,ACK */
1894 case SWRAP_PENDING_RST:
1895 dest_addr = si->myname;
1896 src_addr = si->peername;
1898 if (si->type == SOCK_DGRAM) {
1902 tcp_seqno = si->io.pck_rcv;
1903 tcp_ack = si->io.pck_snd;
1904 tcp_ctl = 0x14; /* RST,ACK */
1909 dest_addr = si->myname;
1910 src_addr = si->peername;
1912 tcp_seqno = si->io.pck_rcv;
1913 tcp_ack = si->io.pck_snd;
1914 tcp_ctl = 0x18; /* PSH,ACK */
1916 si->io.pck_rcv += len;
1920 case SWRAP_RECV_RST:
1921 dest_addr = si->myname;
1922 src_addr = si->peername;
1924 if (si->type == SOCK_DGRAM) {
1928 tcp_seqno = si->io.pck_rcv;
1929 tcp_ack = si->io.pck_snd;
1930 tcp_ctl = 0x14; /* RST,ACK */
1935 src_addr = si->myname;
1938 si->io.pck_snd += len;
1942 case SWRAP_SENDTO_UNREACH:
1943 dest_addr = si->myname;
1950 case SWRAP_RECVFROM:
1951 dest_addr = si->myname;
1954 si->io.pck_rcv += len;
1958 case SWRAP_CLOSE_SEND:
1959 if (si->type != SOCK_STREAM) return NULL;
1961 src_addr = si->myname;
1962 dest_addr = si->peername;
1964 tcp_seqno = si->io.pck_snd;
1965 tcp_ack = si->io.pck_rcv;
1966 tcp_ctl = 0x11; /* FIN, ACK */
1968 si->io.pck_snd += 1;
1972 case SWRAP_CLOSE_RECV:
1973 if (si->type != SOCK_STREAM) return NULL;
1975 dest_addr = si->myname;
1976 src_addr = si->peername;
1978 tcp_seqno = si->io.pck_rcv;
1979 tcp_ack = si->io.pck_snd;
1980 tcp_ctl = 0x11; /* FIN,ACK */
1982 si->io.pck_rcv += 1;
1986 case SWRAP_CLOSE_ACK:
1987 if (si->type != SOCK_STREAM) return NULL;
1989 src_addr = si->myname;
1990 dest_addr = si->peername;
1992 tcp_seqno = si->io.pck_snd;
1993 tcp_ack = si->io.pck_rcv;
1994 tcp_ctl = 0x10; /* ACK */
2001 swrapGetTimeOfDay(&tv);
2003 return swrap_packet_init(&tv, src_addr, dest_addr, si->type,
2004 (const uint8_t *)buf, len,
2005 tcp_seqno, tcp_ack, tcp_ctl, unreachable,
2009 static void swrap_dump_packet(struct socket_info *si,
2010 const struct sockaddr *addr,
2011 enum swrap_packet_type type,
2012 const void *buf, size_t len)
2014 const char *file_name;
2016 size_t packet_len = 0;
2019 file_name = socket_wrapper_pcap_file();
2024 packet = swrap_marshall_packet(si, addr, type, buf, len, &packet_len);
2029 fd = swrap_get_pcap_fd(file_name);
2031 if (write(fd, packet, packet_len) != (ssize_t)packet_len) {
2040 /****************************************************************************
2042 ***************************************************************************/
2044 #ifdef HAVE_SIGNALFD
2045 static int swrap_signalfd(int fd, const sigset_t *mask, int flags)
2049 rc = libc_signalfd(fd, mask, flags);
2051 swrap_remove_stale(fd);
2057 int signalfd(int fd, const sigset_t *mask, int flags)
2059 return swrap_signalfd(fd, mask, flags);
2063 /****************************************************************************
2065 ***************************************************************************/
2067 static int swrap_socket(int family, int type, int protocol)
2069 struct socket_info *si;
2070 struct socket_info_fd *fi;
2072 int real_type = type;
2075 * Remove possible addition flags passed to socket() so
2076 * do not fail checking the type.
2077 * See https://lwn.net/Articles/281965/
2080 real_type &= ~SOCK_CLOEXEC;
2082 #ifdef SOCK_NONBLOCK
2083 real_type &= ~SOCK_NONBLOCK;
2086 if (!socket_wrapper_enabled()) {
2087 return libc_socket(family, type, protocol);
2097 return libc_socket(family, type, protocol);
2099 errno = EAFNOSUPPORT;
2103 switch (real_type) {
2109 errno = EPROTONOSUPPORT;
2117 if (real_type == SOCK_STREAM) {
2122 if (real_type == SOCK_DGRAM) {
2127 errno = EPROTONOSUPPORT;
2132 * We must call libc_socket with type, from the caller, not the version
2133 * we removed SOCK_CLOEXEC and SOCK_NONBLOCK from
2135 fd = libc_socket(AF_UNIX, type, 0);
2141 /* Check if we have a stale fd and remove it */
2142 si = find_socket_info(fd);
2144 swrap_remove_stale(fd);
2147 si = (struct socket_info *)malloc(sizeof(struct socket_info));
2148 memset(si, 0, sizeof(struct socket_info));
2154 si->family = family;
2156 /* however, the rest of the socket_wrapper code expects just
2157 * the type, not the flags */
2158 si->type = real_type;
2159 si->protocol = protocol;
2161 fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
2170 SWRAP_DLIST_ADD(si->fds, fi);
2171 SWRAP_DLIST_ADD(sockets, si);
2176 int socket(int family, int type, int protocol)
2178 return swrap_socket(family, type, protocol);
2181 /****************************************************************************
2183 ***************************************************************************/
2185 static int swrap_socketpair(int family, int type, int protocol, int sv[2])
2189 rc = libc_socketpair(family, type, protocol, sv);
2191 swrap_remove_stale(sv[0]);
2192 swrap_remove_stale(sv[1]);
2198 int socketpair(int family, int type, int protocol, int sv[2])
2200 return swrap_socketpair(family, type, protocol, sv);
2203 /****************************************************************************
2205 ***************************************************************************/
2207 #ifdef HAVE_TIMERFD_CREATE
2208 static int swrap_timerfd_create(int clockid, int flags)
2212 fd = libc_timerfd_create(clockid, flags);
2214 swrap_remove_stale(fd);
2220 int timerfd_create(int clockid, int flags)
2222 return swrap_timerfd_create(clockid, flags);
2226 /****************************************************************************
2228 ***************************************************************************/
2230 static int swrap_pipe(int pipefd[2])
2234 rc = libc_pipe(pipefd);
2236 swrap_remove_stale(pipefd[0]);
2237 swrap_remove_stale(pipefd[1]);
2243 int pipe(int pipefd[2])
2245 return swrap_pipe(pipefd);
2248 /****************************************************************************
2250 ***************************************************************************/
2252 static int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
2254 struct socket_info *parent_si, *child_si;
2255 struct socket_info_fd *child_fi;
2257 struct sockaddr_un un_addr;
2258 socklen_t un_addrlen = sizeof(un_addr);
2259 struct sockaddr_un un_my_addr;
2260 socklen_t un_my_addrlen = sizeof(un_my_addr);
2261 struct sockaddr *my_addr;
2262 socklen_t my_addrlen, len;
2265 parent_si = find_socket_info(s);
2267 return libc_accept(s, addr, addrlen);
2271 * assume out sockaddr have the same size as the in parent
2274 my_addrlen = socket_length(parent_si->family);
2275 if (my_addrlen <= 0) {
2280 my_addr = (struct sockaddr *)malloc(my_addrlen);
2281 if (my_addr == NULL) {
2285 memset(&un_addr, 0, sizeof(un_addr));
2286 memset(&un_my_addr, 0, sizeof(un_my_addr));
2288 ret = libc_accept(s, (struct sockaddr *)(void *)&un_addr, &un_addrlen);
2290 if (errno == ENOTSOCK) {
2291 /* Remove stale fds */
2292 swrap_remove_stale(s);
2301 ret = sockaddr_convert_from_un(parent_si, &un_addr, un_addrlen,
2302 parent_si->family, my_addr, &len);
2309 child_si = (struct socket_info *)malloc(sizeof(struct socket_info));
2310 memset(child_si, 0, sizeof(struct socket_info));
2312 child_fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
2313 if (child_fi == NULL) {
2323 SWRAP_DLIST_ADD(child_si->fds, child_fi);
2325 child_si->family = parent_si->family;
2326 child_si->type = parent_si->type;
2327 child_si->protocol = parent_si->protocol;
2328 child_si->bound = 1;
2329 child_si->is_server = 1;
2330 child_si->connected = 1;
2332 child_si->peername_len = len;
2333 child_si->peername = sockaddr_dup(my_addr, len);
2335 if (addr != NULL && addrlen != NULL) {
2336 size_t copy_len = MIN(*addrlen, len);
2338 memcpy(addr, my_addr, copy_len);
2343 ret = libc_getsockname(fd,
2344 (struct sockaddr *)(void *)&un_my_addr,
2355 ret = sockaddr_convert_from_un(child_si, &un_my_addr, un_my_addrlen,
2356 child_si->family, my_addr, &len);
2365 SWRAP_LOG(SWRAP_LOG_TRACE,
2366 "accept() path=%s, fd=%d",
2367 un_my_addr.sun_path, s);
2369 child_si->myname_len = len;
2370 child_si->myname = sockaddr_dup(my_addr, len);
2373 SWRAP_DLIST_ADD(sockets, child_si);
2376 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0);
2377 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_RECV, NULL, 0);
2378 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_ACK, NULL, 0);
2384 #ifdef HAVE_ACCEPT_PSOCKLEN_T
2385 int accept(int s, struct sockaddr *addr, Psocklen_t addrlen)
2387 int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
2390 return swrap_accept(s, addr, (socklen_t *)addrlen);
2393 static int autobind_start_init;
2394 static int autobind_start;
2396 /* using sendto() or connect() on an unbound socket would give the
2397 recipient no way to reply, as unlike UDP and TCP, a unix domain
2398 socket can't auto-assign ephemeral port numbers, so we need to
2400 Note: this might change the family from ipv6 to ipv4
2402 static int swrap_auto_bind(int fd, struct socket_info *si, int family)
2404 struct sockaddr_un un_addr;
2411 if (autobind_start_init != 1) {
2412 autobind_start_init = 1;
2413 autobind_start = getpid();
2414 autobind_start %= 50000;
2415 autobind_start += 10000;
2418 un_addr.sun_family = AF_UNIX;
2422 struct sockaddr_in in;
2426 type = SOCKET_TYPE_CHAR_TCP;
2429 type = SOCKET_TYPE_CHAR_UDP;
2432 errno = ESOCKTNOSUPPORT;
2436 memset(&in, 0, sizeof(in));
2437 in.sin_family = AF_INET;
2438 in.sin_addr.s_addr = htonl(127<<24 |
2439 socket_wrapper_default_iface());
2441 si->myname_len = sizeof(in);
2442 si->myname = sockaddr_dup(&in, si->myname_len);
2447 struct sockaddr_in6 in6;
2449 if (si->family != family) {
2450 errno = ENETUNREACH;
2456 type = SOCKET_TYPE_CHAR_TCP_V6;
2459 type = SOCKET_TYPE_CHAR_UDP_V6;
2462 errno = ESOCKTNOSUPPORT;
2466 memset(&in6, 0, sizeof(in6));
2467 in6.sin6_family = AF_INET6;
2468 in6.sin6_addr = *swrap_ipv6();
2469 in6.sin6_addr.s6_addr[15] = socket_wrapper_default_iface();
2470 si->myname_len = sizeof(in6);
2471 si->myname = sockaddr_dup(&in6, si->myname_len);
2476 errno = ESOCKTNOSUPPORT;
2480 if (autobind_start > 60000) {
2481 autobind_start = 10000;
2484 for (i = 0; i < SOCKET_MAX_SOCKETS; i++) {
2485 port = autobind_start + i;
2486 snprintf(un_addr.sun_path, sizeof(un_addr.sun_path),
2487 "%s/"SOCKET_FORMAT, socket_wrapper_dir(),
2488 type, socket_wrapper_default_iface(), port);
2489 if (stat(un_addr.sun_path, &st) == 0) continue;
2491 ret = libc_bind(fd, (struct sockaddr *)(void *)&un_addr,
2493 if (ret == -1) return ret;
2495 si->tmp_path = strdup(un_addr.sun_path);
2497 autobind_start = port + 1;
2500 if (i == SOCKET_MAX_SOCKETS) {
2501 SWRAP_LOG(SWRAP_LOG_ERROR, "Too many open unix sockets (%u) for "
2502 "interface "SOCKET_FORMAT,
2505 socket_wrapper_default_iface(),
2511 si->family = family;
2512 set_port(si->family, port, si->myname);
2517 /****************************************************************************
2519 ***************************************************************************/
2521 static int swrap_connect(int s, const struct sockaddr *serv_addr,
2525 struct sockaddr_un un_addr;
2526 struct socket_info *si = find_socket_info(s);
2530 return libc_connect(s, serv_addr, addrlen);
2533 if (si->bound == 0) {
2534 ret = swrap_auto_bind(s, si, serv_addr->sa_family);
2535 if (ret == -1) return -1;
2538 if (si->family != serv_addr->sa_family) {
2543 ret = sockaddr_convert_to_un(si, serv_addr,
2544 addrlen, &un_addr, 0, &bcast);
2545 if (ret == -1) return -1;
2548 errno = ENETUNREACH;
2552 if (si->type == SOCK_DGRAM) {
2553 si->defer_connect = 1;
2556 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0);
2558 ret = libc_connect(s,
2559 (struct sockaddr *)(void *)&un_addr,
2560 sizeof(struct sockaddr_un));
2563 SWRAP_LOG(SWRAP_LOG_TRACE,
2564 "connect() path=%s, fd=%d",
2565 un_addr.sun_path, s);
2568 /* to give better errors */
2569 if (ret == -1 && errno == ENOENT) {
2570 errno = EHOSTUNREACH;
2574 si->peername_len = addrlen;
2575 si->peername = sockaddr_dup(serv_addr, addrlen);
2578 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0);
2579 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0);
2581 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0);
2587 int connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen)
2589 return swrap_connect(s, serv_addr, addrlen);
2592 /****************************************************************************
2594 ***************************************************************************/
2596 static int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
2599 struct sockaddr_un un_addr;
2600 struct socket_info *si = find_socket_info(s);
2603 return libc_bind(s, myaddr, addrlen);
2606 si->myname_len = addrlen;
2607 si->myname = sockaddr_dup(myaddr, addrlen);
2609 ret = sockaddr_convert_to_un(si, myaddr, addrlen, &un_addr, 1, &si->bcast);
2610 if (ret == -1) return -1;
2612 unlink(un_addr.sun_path);
2614 ret = libc_bind(s, (struct sockaddr *)(void *)&un_addr,
2615 sizeof(struct sockaddr_un));
2617 SWRAP_LOG(SWRAP_LOG_TRACE,
2618 "bind() path=%s, fd=%d",
2619 un_addr.sun_path, s);
2628 int bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
2630 return swrap_bind(s, myaddr, addrlen);
2633 /****************************************************************************
2635 ***************************************************************************/
2637 static int swrap_listen(int s, int backlog)
2640 struct socket_info *si = find_socket_info(s);
2643 return libc_listen(s, backlog);
2646 ret = libc_listen(s, backlog);
2651 int listen(int s, int backlog)
2653 return swrap_listen(s, backlog);
2656 /****************************************************************************
2658 ***************************************************************************/
2660 static int swrap_vopen(const char *pathname, int flags, va_list ap)
2664 ret = libc_vopen(pathname, flags, ap);
2667 * There are methods for closing descriptors (libc-internal code
2668 * paths, direct syscalls) which close descriptors in ways that
2669 * we can't intercept, so try to recover when we notice that
2672 swrap_remove_stale(ret);
2677 int open(const char *pathname, int flags, ...)
2682 va_start(ap, flags);
2683 fd = swrap_vopen(pathname, flags, ap);
2689 /****************************************************************************
2691 ***************************************************************************/
2693 static int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
2695 struct socket_info *si = find_socket_info(s);
2698 return libc_getpeername(s, name, addrlen);
2707 memcpy(name, si->peername, si->peername_len);
2708 *addrlen = si->peername_len;
2713 #ifdef HAVE_ACCEPT_PSOCKLEN_T
2714 int getpeername(int s, struct sockaddr *name, Psocklen_t addrlen)
2716 int getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
2719 return swrap_getpeername(s, name, (socklen_t *)addrlen);
2722 /****************************************************************************
2724 ***************************************************************************/
2726 static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
2728 struct socket_info *si = find_socket_info(s);
2731 return libc_getsockname(s, name, addrlen);
2734 memcpy(name, si->myname, si->myname_len);
2735 *addrlen = si->myname_len;
2740 #ifdef HAVE_ACCEPT_PSOCKLEN_T
2741 int getsockname(int s, struct sockaddr *name, Psocklen_t addrlen)
2743 int getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
2746 return swrap_getsockname(s, name, (socklen_t *)addrlen);
2749 /****************************************************************************
2751 ***************************************************************************/
2753 static int swrap_getsockopt(int s, int level, int optname,
2754 void *optval, socklen_t *optlen)
2756 struct socket_info *si = find_socket_info(s);
2759 return libc_getsockopt(s,
2766 if (level == SOL_SOCKET) {
2767 return libc_getsockopt(s,
2774 errno = ENOPROTOOPT;
2778 #ifdef HAVE_ACCEPT_PSOCKLEN_T
2779 int getsockopt(int s, int level, int optname, void *optval, Psocklen_t optlen)
2781 int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
2784 return swrap_getsockopt(s, level, optname, optval, (socklen_t *)optlen);
2787 /****************************************************************************
2789 ***************************************************************************/
2791 static int swrap_setsockopt(int s, int level, int optname,
2792 const void *optval, socklen_t optlen)
2794 struct socket_info *si = find_socket_info(s);
2797 return libc_setsockopt(s,
2804 if (level == SOL_SOCKET) {
2805 return libc_setsockopt(s,
2812 switch (si->family) {
2820 errno = ENOPROTOOPT;
2825 int setsockopt(int s, int level, int optname,
2826 const void *optval, socklen_t optlen)
2828 return swrap_setsockopt(s, level, optname, optval, optlen);
2831 /****************************************************************************
2833 ***************************************************************************/
2835 static int swrap_vioctl(int s, unsigned long int r, va_list va)
2837 struct socket_info *si = find_socket_info(s);
2843 return libc_vioctl(s, r, va);
2848 rc = libc_vioctl(s, r, va);
2852 value = *((int *)va_arg(ap, int *));
2854 if (rc == -1 && errno != EAGAIN && errno != ENOBUFS) {
2855 swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
2856 } else if (value == 0) { /* END OF FILE */
2857 swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
2867 #ifdef HAVE_IOCTL_INT
2868 int ioctl(int s, int r, ...)
2870 int ioctl(int s, unsigned long int r, ...)
2878 rc = swrap_vioctl(s, (unsigned long int) r, va);
2885 static ssize_t swrap_sendmsg_before(int fd,
2886 struct socket_info *si,
2888 struct iovec *tmp_iov,
2889 struct sockaddr_un *tmp_un,
2890 const struct sockaddr_un **to_un,
2891 const struct sockaddr **to,
2909 if (!si->connected) {
2914 if (msg->msg_iovlen == 0) {
2918 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
2920 nlen = len + msg->msg_iov[i].iov_len;
2921 if (nlen > SOCKET_MAX_PACKET) {
2925 msg->msg_iovlen = i;
2926 if (msg->msg_iovlen == 0) {
2927 *tmp_iov = msg->msg_iov[0];
2928 tmp_iov->iov_len = MIN(tmp_iov->iov_len, SOCKET_MAX_PACKET);
2929 msg->msg_iov = tmp_iov;
2930 msg->msg_iovlen = 1;
2935 if (si->connected) {
2936 if (msg->msg_name) {
2941 const struct sockaddr *msg_name;
2942 msg_name = (const struct sockaddr *)msg->msg_name;
2944 if (msg_name == NULL) {
2950 ret = sockaddr_convert_to_un(si, msg_name, msg->msg_namelen,
2952 if (ret == -1) return -1;
2960 msg->msg_name = tmp_un;
2961 msg->msg_namelen = sizeof(*tmp_un);
2964 if (si->bound == 0) {
2965 ret = swrap_auto_bind(fd, si, si->family);
2967 if (errno == ENOTSOCK) {
2968 swrap_remove_stale(fd);
2971 SWRAP_LOG(SWRAP_LOG_ERROR, "swrap_sendmsg_before failed");
2977 if (!si->defer_connect) {
2981 ret = sockaddr_convert_to_un(si, si->peername, si->peername_len,
2983 if (ret == -1) return -1;
2985 ret = libc_connect(fd,
2986 (struct sockaddr *)(void *)tmp_un,
2989 /* to give better errors */
2990 if (ret == -1 && errno == ENOENT) {
2991 errno = EHOSTUNREACH;
2998 si->defer_connect = 0;
3001 errno = EHOSTUNREACH;
3008 static void swrap_sendmsg_after(int fd,
3009 struct socket_info *si,
3011 const struct sockaddr *to,
3014 int saved_errno = errno;
3021 /* to give better errors */
3023 if (saved_errno == ENOENT) {
3024 saved_errno = EHOSTUNREACH;
3025 } else if (saved_errno == ENOTSOCK) {
3026 /* If the fd is not a socket, remove it */
3027 swrap_remove_stale(fd);
3031 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3032 avail += msg->msg_iov[i].iov_len;
3036 remain = MIN(80, avail);
3041 /* we capture it as one single packet */
3042 buf = (uint8_t *)malloc(remain);
3044 /* we just not capture the packet */
3045 errno = saved_errno;
3049 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3050 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
3052 msg->msg_iov[i].iov_base,
3055 remain -= this_time;
3062 swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
3063 swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
3065 swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
3070 if (si->connected) {
3074 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
3075 swrap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);
3077 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
3083 errno = saved_errno;
3086 static int swrap_recvmsg_before(int fd,
3087 struct socket_info *si,
3089 struct iovec *tmp_iov)
3094 (void)fd; /* unused */
3098 if (!si->connected) {
3103 if (msg->msg_iovlen == 0) {
3107 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3109 nlen = len + msg->msg_iov[i].iov_len;
3110 if (nlen > SOCKET_MAX_PACKET) {
3114 msg->msg_iovlen = i;
3115 if (msg->msg_iovlen == 0) {
3116 *tmp_iov = msg->msg_iov[0];
3117 tmp_iov->iov_len = MIN(tmp_iov->iov_len, SOCKET_MAX_PACKET);
3118 msg->msg_iov = tmp_iov;
3119 msg->msg_iovlen = 1;
3124 if (msg->msg_name == NULL) {
3129 if (msg->msg_iovlen == 0) {
3133 if (si->bound == 0) {
3134 ret = swrap_auto_bind(fd, si, si->family);
3137 * When attempting to read or write to a
3138 * descriptor, if an underlying autobind fails
3139 * because it's not a socket, stop intercepting
3140 * uses of that descriptor.
3142 if (errno == ENOTSOCK) {
3143 swrap_remove_stale(fd);
3146 SWRAP_LOG(SWRAP_LOG_ERROR,
3147 "swrap_recvmsg_before failed");
3154 errno = EHOSTUNREACH;
3161 static int swrap_recvmsg_after(int fd,
3162 struct socket_info *si,
3164 const struct sockaddr_un *un_addr,
3165 socklen_t un_addrlen,
3168 int saved_errno = errno;
3170 uint8_t *buf = NULL;
3175 /* to give better errors */
3177 if (saved_errno == ENOENT) {
3178 saved_errno = EHOSTUNREACH;
3179 } else if (saved_errno == ENOTSOCK) {
3180 /* If the fd is not a socket, remove it */
3181 swrap_remove_stale(fd);
3185 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3186 avail += msg->msg_iov[i].iov_len;
3190 errno = saved_errno;
3195 remain = MIN(80, avail);
3200 /* we capture it as one single packet */
3201 buf = (uint8_t *)malloc(remain);
3203 /* we just not capture the packet */
3204 errno = saved_errno;
3208 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3209 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
3211 msg->msg_iov[i].iov_base,
3214 remain -= this_time;
3219 if (ret == -1 && saved_errno != EAGAIN && saved_errno != ENOBUFS) {
3220 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
3221 } else if (ret == 0) { /* END OF FILE */
3222 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
3223 } else if (ret > 0) {
3224 swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
3233 if (un_addr != NULL) {
3236 rc = sockaddr_convert_from_un(si,
3246 swrap_dump_packet(si,
3252 swrap_dump_packet(si,
3264 errno = saved_errno;
3268 /****************************************************************************
3270 ***************************************************************************/
3272 static ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags,
3273 struct sockaddr *from, socklen_t *fromlen)
3275 struct sockaddr_un from_addr;
3276 socklen_t from_addrlen = sizeof(from_addr);
3278 struct socket_info *si = find_socket_info(s);
3279 struct sockaddr_storage ss;
3280 socklen_t ss_len = sizeof(ss);
3286 return libc_recvfrom(s,
3298 if (from != NULL && fromlen != NULL) {
3299 msg.msg_name = from; /* optional address */
3300 msg.msg_namelen = *fromlen; /* size of address */
3302 msg.msg_name = (struct sockaddr *)(void *)&ss; /* optional address */
3303 msg.msg_namelen = ss_len; /* size of address */
3305 msg.msg_iov = &tmp; /* scatter/gather array */
3306 msg.msg_iovlen = 1; /* # elements in msg_iov */
3307 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3308 msg.msg_control = NULL; /* ancillary data, see below */
3309 msg.msg_controllen = 0; /* ancillary data buffer len */
3310 msg.msg_flags = 0; /* flags on received message */
3313 tret = swrap_recvmsg_before(s, si, &msg, &tmp);
3318 buf = msg.msg_iov[0].iov_base;
3319 len = msg.msg_iov[0].iov_len;
3321 /* irix 6.4 forgets to null terminate the sun_path string :-( */
3322 memset(&from_addr, 0, sizeof(from_addr));
3323 ret = libc_recvfrom(s,
3327 (struct sockaddr *)(void *)&from_addr,
3333 tret = swrap_recvmsg_after(s,
3343 if (from != NULL && fromlen != NULL) {
3344 *fromlen = msg.msg_namelen;
3350 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3351 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
3352 struct sockaddr *from, Psocklen_t fromlen)
3354 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
3355 struct sockaddr *from, socklen_t *fromlen)
3358 return swrap_recvfrom(s, buf, len, flags, from, (socklen_t *)fromlen);
3361 /****************************************************************************
3363 ***************************************************************************/
3365 static ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags,
3366 const struct sockaddr *to, socklen_t tolen)
3370 struct sockaddr_un un_addr;
3371 const struct sockaddr_un *to_un = NULL;
3374 struct socket_info *si = find_socket_info(s);
3378 return libc_sendto(s, buf, len, flags, to, tolen);
3381 tmp.iov_base = discard_const_p(char, buf);
3385 msg.msg_name = discard_const_p(struct sockaddr, to); /* optional address */
3386 msg.msg_namelen = tolen; /* size of address */
3387 msg.msg_iov = &tmp; /* scatter/gather array */
3388 msg.msg_iovlen = 1; /* # elements in msg_iov */
3389 #if 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 rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
3400 buf = msg.msg_iov[0].iov_base;
3401 len = msg.msg_iov[0].iov_len;
3406 unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port);
3409 type = SOCKET_TYPE_CHAR_UDP;
3411 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
3412 snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT,
3413 socket_wrapper_dir(), type, iface, prt);
3414 if (stat(un_addr.sun_path, &st) != 0) continue;
3416 /* ignore the any errors in broadcast sends */
3421 (struct sockaddr *)(void *)&un_addr,
3425 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
3430 ret = libc_sendto(s,
3434 (struct sockaddr *)msg.msg_name,
3437 swrap_sendmsg_after(s, si, &msg, to, ret);
3442 ssize_t sendto(int s, const void *buf, size_t len, int flags,
3443 const struct sockaddr *to, socklen_t tolen)
3445 return swrap_sendto(s, buf, len, flags, to, tolen);
3448 /****************************************************************************
3450 ***************************************************************************/
3452 static ssize_t swrap_recv(int s, void *buf, size_t len, int flags)
3454 struct socket_info *si;
3456 struct sockaddr_storage ss;
3457 socklen_t ss_len = sizeof(ss);
3462 si = find_socket_info(s);
3464 return libc_recv(s, buf, len, flags);
3471 msg.msg_name = (struct sockaddr *)(void *)&ss; /* optional address */
3472 msg.msg_namelen = ss_len; /* size of address */
3473 msg.msg_iov = &tmp; /* scatter/gather array */
3474 msg.msg_iovlen = 1; /* # elements in msg_iov */
3475 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3476 msg.msg_control = NULL; /* ancillary data, see below */
3477 msg.msg_controllen = 0; /* ancillary data buffer len */
3478 msg.msg_flags = 0; /* flags on received message */
3481 tret = swrap_recvmsg_before(s, si, &msg, &tmp);
3486 buf = msg.msg_iov[0].iov_base;
3487 len = msg.msg_iov[0].iov_len;
3489 ret = libc_recv(s, buf, len, flags);
3491 tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
3499 ssize_t recv(int s, void *buf, size_t len, int flags)
3501 return swrap_recv(s, buf, len, flags);
3504 /****************************************************************************
3506 ***************************************************************************/
3508 static ssize_t swrap_read(int s, void *buf, size_t len)
3510 struct socket_info *si;
3513 struct sockaddr_storage ss;
3514 socklen_t ss_len = sizeof(ss);
3518 si = find_socket_info(s);
3520 return libc_read(s, buf, len);
3527 msg.msg_name = (struct sockaddr *)(void *)&ss; /* optional address */
3528 msg.msg_namelen = ss_len; /* size of address */
3529 msg.msg_iov = &tmp; /* scatter/gather array */
3530 msg.msg_iovlen = 1; /* # elements in msg_iov */
3531 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3532 msg.msg_control = NULL; /* ancillary data, see below */
3533 msg.msg_controllen = 0; /* ancillary data buffer len */
3534 msg.msg_flags = 0; /* flags on received message */
3537 tret = swrap_recvmsg_before(s, si, &msg, &tmp);
3539 if (tret == -ENOTSOCK) {
3540 return libc_read(s, buf, len);
3545 buf = msg.msg_iov[0].iov_base;
3546 len = msg.msg_iov[0].iov_len;
3548 ret = libc_read(s, buf, len);
3550 tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
3558 ssize_t read(int s, void *buf, size_t len)
3560 return swrap_read(s, buf, len);
3563 /****************************************************************************
3565 ***************************************************************************/
3567 static ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
3571 struct sockaddr_un un_addr;
3574 struct socket_info *si = find_socket_info(s);
3577 return libc_send(s, buf, len, flags);
3580 tmp.iov_base = discard_const_p(char, buf);
3584 msg.msg_name = NULL; /* optional address */
3585 msg.msg_namelen = 0; /* size of address */
3586 msg.msg_iov = &tmp; /* scatter/gather array */
3587 msg.msg_iovlen = 1; /* # elements in msg_iov */
3588 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
3589 msg.msg_control = NULL; /* ancillary data, see below */
3590 msg.msg_controllen = 0; /* ancillary data buffer len */
3591 msg.msg_flags = 0; /* flags on received message */
3594 rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
3599 buf = msg.msg_iov[0].iov_base;
3600 len = msg.msg_iov[0].iov_len;
3602 ret = libc_send(s, buf, len, flags);
3604 swrap_sendmsg_after(s, si, &msg, NULL, ret);
3609 ssize_t send(int s, const void *buf, size_t len, int flags)
3611 return swrap_send(s, buf, len, flags);
3614 /****************************************************************************
3616 ***************************************************************************/
3618 static ssize_t swrap_recvmsg(int s, struct msghdr *omsg, int flags)
3620 struct sockaddr_un from_addr;
3621 socklen_t from_addrlen = sizeof(from_addr);
3622 struct socket_info *si;
3629 si = find_socket_info(s);
3631 return libc_recvmsg(s, omsg, flags);
3634 tmp.iov_base = NULL;
3638 msg.msg_name = (struct sockaddr *)&from_addr; /* optional address */
3639 msg.msg_namelen = from_addrlen; /* size of address */
3640 msg.msg_iov = omsg->msg_iov; /* scatter/gather array */
3641 msg.msg_iovlen = omsg->msg_iovlen; /* # elements in msg_iov */
3642 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3643 msg.msg_control = omsg->msg_control; /* ancillary data, see below */
3644 msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
3645 msg.msg_flags = omsg->msg_flags; /* flags on received message */
3648 rc = swrap_recvmsg_before(s, si, &msg, &tmp);
3653 ret = libc_recvmsg(s, &msg, flags);
3655 rc = swrap_recvmsg_after(s, si, omsg, &from_addr, from_addrlen, ret);
3663 ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)
3665 return swrap_recvmsg(sockfd, msg, flags);
3668 /****************************************************************************
3670 ***************************************************************************/
3672 static ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags)
3676 struct sockaddr_un un_addr;
3677 const struct sockaddr_un *to_un = NULL;
3678 const struct sockaddr *to = NULL;
3681 struct socket_info *si = find_socket_info(s);
3685 return libc_sendmsg(s, omsg, flags);
3688 ZERO_STRUCT(un_addr);
3690 tmp.iov_base = NULL;
3694 msg.msg_name = omsg->msg_name; /* optional address */
3695 msg.msg_namelen = omsg->msg_namelen; /* size of address */
3696 msg.msg_iov = omsg->msg_iov; /* scatter/gather array */
3697 msg.msg_iovlen = omsg->msg_iovlen; /* # elements in msg_iov */
3698 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3699 msg.msg_control = omsg->msg_control; /* ancillary data, see below */
3700 msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
3701 msg.msg_flags = omsg->msg_flags; /* flags on received message */
3704 rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
3712 unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port);
3720 for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
3721 avail += msg.msg_iov[i].iov_len;
3727 /* we capture it as one single packet */
3728 buf = (uint8_t *)malloc(remain);
3733 for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
3734 size_t this_time = MIN(remain, (size_t)msg.msg_iov[i].iov_len);
3736 msg.msg_iov[i].iov_base,
3739 remain -= this_time;
3742 type = SOCKET_TYPE_CHAR_UDP;
3744 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
3745 snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT,
3746 socket_wrapper_dir(), type, iface, prt);
3747 if (stat(un_addr.sun_path, &st) != 0) continue;
3749 msg.msg_name = &un_addr; /* optional address */
3750 msg.msg_namelen = sizeof(un_addr); /* size of address */
3752 /* ignore the any errors in broadcast sends */
3753 libc_sendmsg(s, &msg, flags);
3756 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
3762 ret = libc_sendmsg(s, &msg, flags);
3764 swrap_sendmsg_after(s, si, &msg, to, ret);
3769 ssize_t sendmsg(int s, const struct msghdr *omsg, int flags)
3771 return swrap_sendmsg(s, omsg, flags);
3774 /****************************************************************************
3776 ***************************************************************************/
3778 static ssize_t swrap_readv(int s, const struct iovec *vector, int count)
3780 struct socket_info *si;
3783 struct sockaddr_storage ss;
3784 socklen_t ss_len = sizeof(ss);
3788 si = find_socket_info(s);
3790 return libc_readv(s, vector, count);
3793 tmp.iov_base = NULL;
3797 msg.msg_name = (struct sockaddr *)(void *)&ss; /* optional address */
3798 msg.msg_namelen = ss_len; /* size of address */
3799 msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
3800 msg.msg_iovlen = count; /* # elements in msg_iov */
3801 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3802 msg.msg_control = NULL; /* ancillary data, see below */
3803 msg.msg_controllen = 0; /* ancillary data buffer len */
3804 msg.msg_flags = 0; /* flags on received message */
3807 rc = swrap_recvmsg_before(s, si, &msg, &tmp);
3809 if (rc == -ENOTSOCK) {
3810 return libc_readv(s, vector, count);
3815 ret = libc_readv(s, msg.msg_iov, msg.msg_iovlen);
3817 rc = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
3825 ssize_t readv(int s, const struct iovec *vector, int count)
3827 return swrap_readv(s, vector, count);
3830 /****************************************************************************
3832 ***************************************************************************/
3834 static ssize_t swrap_writev(int s, const struct iovec *vector, int count)
3838 struct sockaddr_un un_addr;
3841 struct socket_info *si = find_socket_info(s);
3844 return libc_writev(s, vector, count);
3847 tmp.iov_base = NULL;
3851 msg.msg_name = NULL; /* optional address */
3852 msg.msg_namelen = 0; /* size of address */
3853 msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
3854 msg.msg_iovlen = count; /* # elements in msg_iov */
3855 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
3856 msg.msg_control = NULL; /* ancillary data, see below */
3857 msg.msg_controllen = 0; /* ancillary data buffer len */
3858 msg.msg_flags = 0; /* flags on received message */
3861 rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
3863 if (rc == -ENOTSOCK) {
3864 return libc_readv(s, vector, count);
3869 ret = libc_writev(s, msg.msg_iov, msg.msg_iovlen);
3871 swrap_sendmsg_after(s, si, &msg, NULL, ret);
3876 ssize_t writev(int s, const struct iovec *vector, int count)
3878 return swrap_writev(s, vector, count);
3881 /****************************
3883 ***************************/
3885 static int swrap_close(int fd)
3887 struct socket_info *si = find_socket_info(fd);
3888 struct socket_info_fd *fi;
3892 return libc_close(fd);
3895 for (fi = si->fds; fi; fi = fi->next) {
3897 SWRAP_DLIST_REMOVE(si->fds, fi);
3904 /* there are still references left */
3905 return libc_close(fd);
3908 SWRAP_DLIST_REMOVE(sockets, si);
3910 if (si->myname && si->peername) {
3911 swrap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0);
3914 ret = libc_close(fd);
3916 if (si->myname && si->peername) {
3917 swrap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0);
3918 swrap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0);
3921 if (si->myname) free(si->myname);
3922 if (si->peername) free(si->peername);
3924 unlink(si->tmp_path);
3934 return swrap_close(fd);
3937 /****************************
3939 ***************************/
3941 static int swrap_dup(int fd)
3943 struct socket_info *si;
3944 struct socket_info_fd *fi;
3946 si = find_socket_info(fd);
3949 return libc_dup(fd);
3952 fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
3958 fi->fd = libc_dup(fd);
3960 int saved_errno = errno;
3962 errno = saved_errno;
3966 /* Make sure we don't have an entry for the fd */
3967 swrap_remove_stale(fi->fd);
3969 SWRAP_DLIST_ADD(si->fds, fi);
3975 return swrap_dup(fd);
3978 /****************************
3980 ***************************/
3982 static int swrap_dup2(int fd, int newfd)
3984 struct socket_info *si;
3985 struct socket_info_fd *fi;
3987 si = find_socket_info(fd);
3990 return libc_dup2(fd, newfd);
3993 if (find_socket_info(newfd)) {
3994 /* dup2() does an implicit close of newfd, which we
3995 * need to emulate */
3999 fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
4005 fi->fd = libc_dup2(fd, newfd);
4007 int saved_errno = errno;
4009 errno = saved_errno;
4013 /* Make sure we don't have an entry for the fd */
4014 swrap_remove_stale(fi->fd);
4016 SWRAP_DLIST_ADD(si->fds, fi);
4020 int dup2(int fd, int newfd)
4022 return swrap_dup2(fd, newfd);
4025 /****************************
4027 ***************************/
4030 static int swrap_eventfd(int count, int flags)
4034 fd = libc_eventfd(count, flags);
4036 swrap_remove_stale(fd);
4042 int eventfd(int count, int flags)
4044 return swrap_eventfd(count, flags);
4048 /****************************
4050 ***************************/
4053 * This function is called when the library is unloaded and makes sure that
4054 * sockets get closed and the unix file for the socket are unlinked.
4056 void swrap_destructor(void)
4058 struct socket_info *s = sockets;
4061 struct socket_info_fd *f = s->fds;