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 expeciall 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_pipe(int pipefd[2])
613 swrap_load_lib_function(SWRAP_LIBSOCKET, pipe);
615 return swrap.fns.libc_pipe(pipefd);
618 static int libc_read(int fd, void *buf, size_t count)
620 swrap_load_lib_function(SWRAP_LIBC, read);
622 return swrap.fns.libc_read(fd, buf, count);
625 static ssize_t libc_readv(int fd, const struct iovec *iov, int iovcnt)
627 swrap_load_lib_function(SWRAP_LIBSOCKET, readv);
629 return swrap.fns.libc_readv(fd, iov, iovcnt);
632 static int libc_recv(int sockfd, void *buf, size_t len, int flags)
634 swrap_load_lib_function(SWRAP_LIBSOCKET, recv);
636 return swrap.fns.libc_recv(sockfd, buf, len, flags);
639 static int libc_recvfrom(int sockfd,
643 struct sockaddr *src_addr,
646 swrap_load_lib_function(SWRAP_LIBSOCKET, recvfrom);
648 return swrap.fns.libc_recvfrom(sockfd, buf, len, flags, src_addr, addrlen);
651 static int libc_recvmsg(int sockfd, struct msghdr *msg, int flags)
653 swrap_load_lib_function(SWRAP_LIBSOCKET, recvmsg);
655 return swrap.fns.libc_recvmsg(sockfd, msg, flags);
658 static int libc_send(int sockfd, const void *buf, size_t len, int flags)
660 swrap_load_lib_function(SWRAP_LIBSOCKET, send);
662 return swrap.fns.libc_send(sockfd, buf, len, flags);
665 static int libc_sendmsg(int sockfd, const struct msghdr *msg, int flags)
667 swrap_load_lib_function(SWRAP_LIBSOCKET, sendmsg);
669 return swrap.fns.libc_sendmsg(sockfd, msg, flags);
672 static int libc_sendto(int sockfd,
676 const struct sockaddr *dst_addr,
679 swrap_load_lib_function(SWRAP_LIBSOCKET, sendto);
681 return swrap.fns.libc_sendto(sockfd, buf, len, flags, dst_addr, addrlen);
684 static int libc_setsockopt(int sockfd,
690 swrap_load_lib_function(SWRAP_LIBSOCKET, setsockopt);
692 return swrap.fns.libc_setsockopt(sockfd, level, optname, optval, optlen);
696 static int libc_signalfd(int fd, const sigset_t *mask, int flags)
698 swrap_load_lib_function(SWRAP_LIBSOCKET, signalfd);
700 return swrap.fns.libc_signalfd(fd, mask, flags);
704 static int libc_socket(int domain, int type, int protocol)
706 swrap_load_lib_function(SWRAP_LIBSOCKET, socket);
708 return swrap.fns.libc_socket(domain, type, protocol);
711 static int libc_socketpair(int domain, int type, int protocol, int sv[2])
713 swrap_load_lib_function(SWRAP_LIBSOCKET, socketpair);
715 return swrap.fns.libc_socketpair(domain, type, protocol, sv);
718 #ifdef HAVE_TIMERFD_CREATE
719 static int libc_timerfd_create(int clockid, int flags)
721 swrap_load_lib_function(SWRAP_LIBC, timerfd_create);
723 return swrap.fns.libc_timerfd_create(clockid, flags);
727 static ssize_t libc_writev(int fd, const struct iovec *iov, int iovcnt)
729 swrap_load_lib_function(SWRAP_LIBSOCKET, writev);
731 return swrap.fns.libc_writev(fd, iov, iovcnt);
734 /*********************************************************
735 * SWRAP HELPER FUNCTIONS
736 *********************************************************/
742 static const struct in6_addr *swrap_ipv6(void)
744 static struct in6_addr v;
745 static int initialized;
753 ret = inet_pton(AF_INET6, "FD00::5357:5F00", &v);
762 static struct sockaddr *sockaddr_dup(const void *data, socklen_t len)
764 struct sockaddr *ret = (struct sockaddr *)malloc(len);
765 memcpy(ret, data, len);
769 static void set_port(int family, int prt, struct sockaddr *addr)
773 ((struct sockaddr_in *)addr)->sin_port = htons(prt);
777 ((struct sockaddr_in6 *)addr)->sin6_port = htons(prt);
783 static size_t socket_length(int family)
787 return sizeof(struct sockaddr_in);
790 return sizeof(struct sockaddr_in6);
796 static const char *socket_wrapper_dir(void)
798 const char *s = getenv("SOCKET_WRAPPER_DIR");
802 if (strncmp(s, "./", 2) == 0) {
806 SWRAP_LOG(SWRAP_LOG_TRACE, "socket_wrapper_dir: %s", s);
810 bool socket_wrapper_enabled(void)
812 const char *s = socket_wrapper_dir();
814 return s != NULL ? true : false;
817 static unsigned int socket_wrapper_default_iface(void)
819 const char *s = getenv("SOCKET_WRAPPER_DEFAULT_IFACE");
822 if (sscanf(s, "%u", &iface) == 1) {
823 if (iface >= 1 && iface <= MAX_WRAPPED_INTERFACES) {
829 return 1;/* 127.0.0.1 */
832 static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, socklen_t *len)
839 p = strrchr(un->sun_path, '/');
840 if (p) p++; else p = un->sun_path;
842 if (sscanf(p, SOCKET_FORMAT, &type, &iface, &prt) != 3) {
847 SWRAP_LOG(SWRAP_LOG_TRACE, "type %c iface %u port %u",
850 if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
861 case SOCKET_TYPE_CHAR_TCP:
862 case SOCKET_TYPE_CHAR_UDP: {
863 struct sockaddr_in *in2 = (struct sockaddr_in *)(void *)in;
865 if ((*len) < sizeof(*in2)) {
870 memset(in2, 0, sizeof(*in2));
871 in2->sin_family = AF_INET;
872 in2->sin_addr.s_addr = htonl((127<<24) | iface);
873 in2->sin_port = htons(prt);
879 case SOCKET_TYPE_CHAR_TCP_V6:
880 case SOCKET_TYPE_CHAR_UDP_V6: {
881 struct sockaddr_in6 *in2 = (struct sockaddr_in6 *)(void *)in;
883 if ((*len) < sizeof(*in2)) {
888 memset(in2, 0, sizeof(*in2));
889 in2->sin6_family = AF_INET6;
890 in2->sin6_addr = *swrap_ipv6();
891 in2->sin6_addr.s6_addr[15] = iface;
892 in2->sin6_port = htons(prt);
906 static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un,
914 if (bcast) *bcast = 0;
916 switch (inaddr->sa_family) {
918 const struct sockaddr_in *in =
919 (const struct sockaddr_in *)(const void *)inaddr;
920 unsigned int addr = ntohl(in->sin_addr.s_addr);
927 u_type = SOCKET_TYPE_CHAR_TCP;
930 u_type = SOCKET_TYPE_CHAR_UDP;
931 a_type = SOCKET_TYPE_CHAR_UDP;
932 b_type = SOCKET_TYPE_CHAR_UDP;
935 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
936 errno = ESOCKTNOSUPPORT;
940 prt = ntohs(in->sin_port);
941 if (a_type && addr == 0xFFFFFFFF) {
942 /* 255.255.255.255 only udp */
945 iface = socket_wrapper_default_iface();
946 } else if (b_type && addr == 0x7FFFFFFF) {
947 /* 127.255.255.255 only udp */
950 iface = socket_wrapper_default_iface();
951 } else if ((addr & 0xFFFFFF00) == 0x7F000000) {
955 iface = (addr & 0x000000FF);
960 if (bcast) *bcast = is_bcast;
965 const struct sockaddr_in6 *in =
966 (const struct sockaddr_in6 *)(const void *)inaddr;
967 struct in6_addr cmp1, cmp2;
971 type = SOCKET_TYPE_CHAR_TCP_V6;
974 type = SOCKET_TYPE_CHAR_UDP_V6;
977 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
978 errno = ESOCKTNOSUPPORT;
982 /* XXX no multicast/broadcast */
984 prt = ntohs(in->sin6_port);
986 cmp1 = *swrap_ipv6();
987 cmp2 = in->sin6_addr;
988 cmp2.s6_addr[15] = 0;
989 if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
990 iface = in->sin6_addr.s6_addr[15];
1000 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family!\n");
1001 errno = ENETUNREACH;
1006 SWRAP_LOG(SWRAP_LOG_WARN, "Port not set\n");
1012 snprintf(un->sun_path, sizeof(un->sun_path), "%s/EINVAL",
1013 socket_wrapper_dir());
1014 SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
1015 /* the caller need to do more processing */
1019 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT,
1020 socket_wrapper_dir(), type, iface, prt);
1021 SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
1026 static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un,
1035 if (bcast) *bcast = 0;
1037 switch (si->family) {
1039 const struct sockaddr_in *in =
1040 (const struct sockaddr_in *)(const void *)inaddr;
1041 unsigned int addr = ntohl(in->sin_addr.s_addr);
1047 prt = ntohs(in->sin_port);
1051 u_type = SOCKET_TYPE_CHAR_TCP;
1052 d_type = SOCKET_TYPE_CHAR_TCP;
1055 u_type = SOCKET_TYPE_CHAR_UDP;
1056 d_type = SOCKET_TYPE_CHAR_UDP;
1057 a_type = SOCKET_TYPE_CHAR_UDP;
1058 b_type = SOCKET_TYPE_CHAR_UDP;
1061 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1062 errno = ESOCKTNOSUPPORT;
1070 iface = socket_wrapper_default_iface();
1071 } else if (a_type && addr == 0xFFFFFFFF) {
1072 /* 255.255.255.255 only udp */
1075 iface = socket_wrapper_default_iface();
1076 } else if (b_type && addr == 0x7FFFFFFF) {
1077 /* 127.255.255.255 only udp */
1080 iface = socket_wrapper_default_iface();
1081 } else if ((addr & 0xFFFFFF00) == 0x7F000000) {
1085 iface = (addr & 0x000000FF);
1087 errno = EADDRNOTAVAIL;
1094 const struct sockaddr_in6 *in =
1095 (const struct sockaddr_in6 *)(const void *)inaddr;
1096 struct in6_addr cmp1, cmp2;
1100 type = SOCKET_TYPE_CHAR_TCP_V6;
1103 type = SOCKET_TYPE_CHAR_UDP_V6;
1106 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1107 errno = ESOCKTNOSUPPORT;
1111 /* XXX no multicast/broadcast */
1113 prt = ntohs(in->sin6_port);
1115 cmp1 = *swrap_ipv6();
1116 cmp2 = in->sin6_addr;
1117 cmp2.s6_addr[15] = 0;
1118 if (IN6_IS_ADDR_UNSPECIFIED(&in->sin6_addr)) {
1119 iface = socket_wrapper_default_iface();
1120 } else if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
1121 iface = in->sin6_addr.s6_addr[15];
1123 errno = EADDRNOTAVAIL;
1131 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n");
1132 errno = EADDRNOTAVAIL;
1137 if (bcast) *bcast = is_bcast;
1139 if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
1145 /* handle auto-allocation of ephemeral ports */
1146 for (prt = 5001; prt < 10000; prt++) {
1147 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT,
1148 socket_wrapper_dir(), type, iface, prt);
1149 if (stat(un->sun_path, &st) == 0) continue;
1151 set_port(si->family, prt, si->myname);
1160 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT,
1161 socket_wrapper_dir(), type, iface, prt);
1162 SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
1166 static struct socket_info *find_socket_info(int fd)
1168 struct socket_info *i;
1170 for (i = sockets; i; i = i->next) {
1171 struct socket_info_fd *f;
1172 for (f = i->fds; f; f = f->next) {
1182 static void swrap_remove_stale(int fd)
1184 struct socket_info *si = find_socket_info(fd);
1185 struct socket_info_fd *fi;
1188 for (fi = si->fds; fi; fi = fi->next) {
1190 SWRAP_LOG(SWRAP_LOG_TRACE, "remove stale wrapper for %d", fd);
1191 SWRAP_DLIST_REMOVE(si->fds, fi);
1197 if (si->fds == NULL) {
1198 SWRAP_DLIST_REMOVE(sockets, si);
1203 static int sockaddr_convert_to_un(struct socket_info *si,
1204 const struct sockaddr *in_addr,
1206 struct sockaddr_un *out_addr,
1210 struct sockaddr *out = (struct sockaddr *)(void *)out_addr;
1212 (void) in_len; /* unused */
1214 if (out_addr == NULL) {
1218 out->sa_family = AF_UNIX;
1219 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
1220 out->sa_len = sizeof(*out_addr);
1223 switch (in_addr->sa_family) {
1233 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1234 errno = ESOCKTNOSUPPORT;
1238 return convert_in_un_alloc(si, in_addr, out_addr, bcast);
1240 return convert_in_un_remote(si, in_addr, out_addr, bcast);
1246 errno = EAFNOSUPPORT;
1247 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n");
1251 static int sockaddr_convert_from_un(const struct socket_info *si,
1252 const struct sockaddr_un *in_addr,
1253 socklen_t un_addrlen,
1255 struct sockaddr *out_addr,
1256 socklen_t *out_addrlen)
1260 if (out_addr == NULL || out_addrlen == NULL)
1263 if (un_addrlen == 0) {
1278 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1279 errno = ESOCKTNOSUPPORT;
1282 ret = convert_un_in(in_addr, out_addr, out_addrlen);
1283 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
1284 out_addr->sa_len = *out_addrlen;
1291 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n");
1292 errno = EAFNOSUPPORT;
1296 enum swrap_packet_type {
1298 SWRAP_CONNECT_UNREACH,
1306 SWRAP_SENDTO_UNREACH,
1317 struct swrap_file_hdr {
1319 uint16_t version_major;
1320 uint16_t version_minor;
1323 uint32_t frame_max_len;
1324 #define SWRAP_FRAME_LENGTH_MAX 0xFFFF
1327 #define SWRAP_FILE_HDR_SIZE 24
1329 struct swrap_packet_frame {
1331 uint32_t micro_seconds;
1332 uint32_t recorded_length;
1333 uint32_t full_length;
1335 #define SWRAP_PACKET_FRAME_SIZE 16
1337 union swrap_packet_ip {
1341 uint16_t packet_length;
1342 uint16_t identification;
1347 uint16_t hdr_checksum;
1351 #define SWRAP_PACKET_IP_V4_SIZE 20
1354 uint8_t flow_label_high;
1355 uint16_t flow_label_low;
1356 uint16_t payload_length;
1357 uint8_t next_header;
1359 uint8_t src_addr[16];
1360 uint8_t dest_addr[16];
1362 #define SWRAP_PACKET_IP_V6_SIZE 40
1364 #define SWRAP_PACKET_IP_SIZE 40
1366 union swrap_packet_payload {
1368 uint16_t source_port;
1378 #define SWRAP_PACKET_PAYLOAD_TCP_SIZE 20
1380 uint16_t source_port;
1385 #define SWRAP_PACKET_PAYLOAD_UDP_SIZE 8
1392 #define SWRAP_PACKET_PAYLOAD_ICMP4_SIZE 8
1399 #define SWRAP_PACKET_PAYLOAD_ICMP6_SIZE 8
1401 #define SWRAP_PACKET_PAYLOAD_SIZE 20
1403 #define SWRAP_PACKET_MIN_ALLOC \
1404 (SWRAP_PACKET_FRAME_SIZE + \
1405 SWRAP_PACKET_IP_SIZE + \
1406 SWRAP_PACKET_PAYLOAD_SIZE)
1408 static const char *socket_wrapper_pcap_file(void)
1410 static int initialized = 0;
1411 static const char *s = NULL;
1412 static const struct swrap_file_hdr h;
1413 static const struct swrap_packet_frame f;
1414 static const union swrap_packet_ip i;
1415 static const union swrap_packet_payload p;
1417 if (initialized == 1) {
1423 * TODO: don't use the structs use plain buffer offsets
1424 * and PUSH_U8(), PUSH_U16() and PUSH_U32()
1426 * for now make sure we disable PCAP support
1427 * if the struct has alignment!
1429 if (sizeof(h) != SWRAP_FILE_HDR_SIZE) {
1432 if (sizeof(f) != SWRAP_PACKET_FRAME_SIZE) {
1435 if (sizeof(i) != SWRAP_PACKET_IP_SIZE) {
1438 if (sizeof(i.v4) != SWRAP_PACKET_IP_V4_SIZE) {
1441 if (sizeof(i.v6) != SWRAP_PACKET_IP_V6_SIZE) {
1444 if (sizeof(p) != SWRAP_PACKET_PAYLOAD_SIZE) {
1447 if (sizeof(p.tcp) != SWRAP_PACKET_PAYLOAD_TCP_SIZE) {
1450 if (sizeof(p.udp) != SWRAP_PACKET_PAYLOAD_UDP_SIZE) {
1453 if (sizeof(p.icmp4) != SWRAP_PACKET_PAYLOAD_ICMP4_SIZE) {
1456 if (sizeof(p.icmp6) != SWRAP_PACKET_PAYLOAD_ICMP6_SIZE) {
1460 s = getenv("SOCKET_WRAPPER_PCAP_FILE");
1464 if (strncmp(s, "./", 2) == 0) {
1470 static uint8_t *swrap_packet_init(struct timeval *tval,
1471 const struct sockaddr *src,
1472 const struct sockaddr *dest,
1474 const uint8_t *payload,
1476 unsigned long tcp_seqno,
1477 unsigned long tcp_ack,
1478 unsigned char tcp_ctl,
1480 size_t *_packet_len)
1484 struct swrap_packet_frame *frame;
1485 union swrap_packet_ip *ip;
1486 union swrap_packet_payload *pay;
1489 size_t nonwire_len = sizeof(*frame);
1490 size_t wire_hdr_len = 0;
1491 size_t wire_len = 0;
1492 size_t ip_hdr_len = 0;
1493 size_t icmp_hdr_len = 0;
1494 size_t icmp_truncate_len = 0;
1495 uint8_t protocol = 0, icmp_protocol = 0;
1496 const struct sockaddr_in *src_in = NULL;
1497 const struct sockaddr_in *dest_in = NULL;
1499 const struct sockaddr_in6 *src_in6 = NULL;
1500 const struct sockaddr_in6 *dest_in6 = NULL;
1505 switch (src->sa_family) {
1507 src_in = (const struct sockaddr_in *)src;
1508 dest_in = (const struct sockaddr_in *)dest;
1509 src_port = src_in->sin_port;
1510 dest_port = dest_in->sin_port;
1511 ip_hdr_len = sizeof(ip->v4);
1515 src_in6 = (const struct sockaddr_in6 *)src;
1516 dest_in6 = (const struct sockaddr_in6 *)dest;
1517 src_port = src_in6->sin6_port;
1518 dest_port = dest_in6->sin6_port;
1519 ip_hdr_len = sizeof(ip->v6);
1526 switch (socket_type) {
1528 protocol = 0x06; /* TCP */
1529 wire_hdr_len = ip_hdr_len + sizeof(pay->tcp);
1530 wire_len = wire_hdr_len + payload_len;
1534 protocol = 0x11; /* UDP */
1535 wire_hdr_len = ip_hdr_len + sizeof(pay->udp);
1536 wire_len = wire_hdr_len + payload_len;
1544 icmp_protocol = protocol;
1545 switch (src->sa_family) {
1547 protocol = 0x01; /* ICMPv4 */
1548 icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp4);
1552 protocol = 0x3A; /* ICMPv6 */
1553 icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp6);
1557 if (wire_len > 64 ) {
1558 icmp_truncate_len = wire_len - 64;
1560 wire_hdr_len += icmp_hdr_len;
1561 wire_len += icmp_hdr_len;
1564 packet_len = nonwire_len + wire_len;
1565 alloc_len = packet_len;
1566 if (alloc_len < SWRAP_PACKET_MIN_ALLOC) {
1567 alloc_len = SWRAP_PACKET_MIN_ALLOC;
1570 base = (uint8_t *)malloc(alloc_len);
1574 memset(base, 0x0, alloc_len);
1578 frame = (struct swrap_packet_frame *)buf;
1579 frame->seconds = tval->tv_sec;
1580 frame->micro_seconds = tval->tv_usec;
1581 frame->recorded_length = wire_len - icmp_truncate_len;
1582 frame->full_length = wire_len - icmp_truncate_len;
1583 buf += SWRAP_PACKET_FRAME_SIZE;
1585 ip = (union swrap_packet_ip *)buf;
1586 switch (src->sa_family) {
1588 ip->v4.ver_hdrlen = 0x45; /* version 4 and 5 * 32 bit words */
1590 ip->v4.packet_length = htons(wire_len - icmp_truncate_len);
1591 ip->v4.identification = htons(0xFFFF);
1592 ip->v4.flags = 0x40; /* BIT 1 set - means don't fraqment */
1593 ip->v4.fragment = htons(0x0000);
1595 ip->v4.protocol = protocol;
1596 ip->v4.hdr_checksum = htons(0x0000);
1597 ip->v4.src_addr = src_in->sin_addr.s_addr;
1598 ip->v4.dest_addr = dest_in->sin_addr.s_addr;
1599 buf += SWRAP_PACKET_IP_V4_SIZE;
1603 ip->v6.ver_prio = 0x60; /* version 4 and 5 * 32 bit words */
1604 ip->v6.flow_label_high = 0x00;
1605 ip->v6.flow_label_low = 0x0000;
1606 ip->v6.payload_length = htons(wire_len - icmp_truncate_len); /* TODO */
1607 ip->v6.next_header = protocol;
1608 memcpy(ip->v6.src_addr, src_in6->sin6_addr.s6_addr, 16);
1609 memcpy(ip->v6.dest_addr, dest_in6->sin6_addr.s6_addr, 16);
1610 buf += SWRAP_PACKET_IP_V6_SIZE;
1616 pay = (union swrap_packet_payload *)buf;
1617 switch (src->sa_family) {
1619 pay->icmp4.type = 0x03; /* destination unreachable */
1620 pay->icmp4.code = 0x01; /* host unreachable */
1621 pay->icmp4.checksum = htons(0x0000);
1622 pay->icmp4.unused = htonl(0x00000000);
1623 buf += SWRAP_PACKET_PAYLOAD_ICMP4_SIZE;
1625 /* set the ip header in the ICMP payload */
1626 ip = (union swrap_packet_ip *)buf;
1627 ip->v4.ver_hdrlen = 0x45; /* version 4 and 5 * 32 bit words */
1629 ip->v4.packet_length = htons(wire_len - icmp_hdr_len);
1630 ip->v4.identification = htons(0xFFFF);
1631 ip->v4.flags = 0x40; /* BIT 1 set - means don't fraqment */
1632 ip->v4.fragment = htons(0x0000);
1634 ip->v4.protocol = icmp_protocol;
1635 ip->v4.hdr_checksum = htons(0x0000);
1636 ip->v4.src_addr = dest_in->sin_addr.s_addr;
1637 ip->v4.dest_addr = src_in->sin_addr.s_addr;
1638 buf += SWRAP_PACKET_IP_V4_SIZE;
1640 src_port = dest_in->sin_port;
1641 dest_port = src_in->sin_port;
1645 pay->icmp6.type = 0x01; /* destination unreachable */
1646 pay->icmp6.code = 0x03; /* address unreachable */
1647 pay->icmp6.checksum = htons(0x0000);
1648 pay->icmp6.unused = htonl(0x00000000);
1649 buf += SWRAP_PACKET_PAYLOAD_ICMP6_SIZE;
1651 /* set the ip header in the ICMP payload */
1652 ip = (union swrap_packet_ip *)buf;
1653 ip->v6.ver_prio = 0x60; /* version 4 and 5 * 32 bit words */
1654 ip->v6.flow_label_high = 0x00;
1655 ip->v6.flow_label_low = 0x0000;
1656 ip->v6.payload_length = htons(wire_len - icmp_truncate_len); /* TODO */
1657 ip->v6.next_header = protocol;
1658 memcpy(ip->v6.src_addr, dest_in6->sin6_addr.s6_addr, 16);
1659 memcpy(ip->v6.dest_addr, src_in6->sin6_addr.s6_addr, 16);
1660 buf += SWRAP_PACKET_IP_V6_SIZE;
1662 src_port = dest_in6->sin6_port;
1663 dest_port = src_in6->sin6_port;
1669 pay = (union swrap_packet_payload *)buf;
1671 switch (socket_type) {
1673 pay->tcp.source_port = src_port;
1674 pay->tcp.dest_port = dest_port;
1675 pay->tcp.seq_num = htonl(tcp_seqno);
1676 pay->tcp.ack_num = htonl(tcp_ack);
1677 pay->tcp.hdr_length = 0x50; /* 5 * 32 bit words */
1678 pay->tcp.control = tcp_ctl;
1679 pay->tcp.window = htons(0x7FFF);
1680 pay->tcp.checksum = htons(0x0000);
1681 pay->tcp.urg = htons(0x0000);
1682 buf += SWRAP_PACKET_PAYLOAD_TCP_SIZE;
1687 pay->udp.source_port = src_port;
1688 pay->udp.dest_port = dest_port;
1689 pay->udp.length = htons(8 + payload_len);
1690 pay->udp.checksum = htons(0x0000);
1691 buf += SWRAP_PACKET_PAYLOAD_UDP_SIZE;
1696 if (payload && payload_len > 0) {
1697 memcpy(buf, payload, payload_len);
1700 *_packet_len = packet_len - icmp_truncate_len;
1704 static int swrap_get_pcap_fd(const char *fname)
1708 if (fd != -1) return fd;
1710 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0644);
1712 struct swrap_file_hdr file_hdr;
1713 file_hdr.magic = 0xA1B2C3D4;
1714 file_hdr.version_major = 0x0002;
1715 file_hdr.version_minor = 0x0004;
1716 file_hdr.timezone = 0x00000000;
1717 file_hdr.sigfigs = 0x00000000;
1718 file_hdr.frame_max_len = SWRAP_FRAME_LENGTH_MAX;
1719 file_hdr.link_type = 0x0065; /* 101 RAW IP */
1721 if (write(fd, &file_hdr, sizeof(file_hdr)) != sizeof(file_hdr)) {
1728 fd = open(fname, O_WRONLY|O_APPEND, 0644);
1733 static uint8_t *swrap_marshall_packet(struct socket_info *si,
1734 const struct sockaddr *addr,
1735 enum swrap_packet_type type,
1736 const void *buf, size_t len,
1739 const struct sockaddr *src_addr;
1740 const struct sockaddr *dest_addr;
1741 unsigned long tcp_seqno = 0;
1742 unsigned long tcp_ack = 0;
1743 unsigned char tcp_ctl = 0;
1744 int unreachable = 0;
1748 switch (si->family) {
1760 case SWRAP_CONNECT_SEND:
1761 if (si->type != SOCK_STREAM) return NULL;
1763 src_addr = si->myname;
1766 tcp_seqno = si->io.pck_snd;
1767 tcp_ack = si->io.pck_rcv;
1768 tcp_ctl = 0x02; /* SYN */
1770 si->io.pck_snd += 1;
1774 case SWRAP_CONNECT_RECV:
1775 if (si->type != SOCK_STREAM) return NULL;
1777 dest_addr = si->myname;
1780 tcp_seqno = si->io.pck_rcv;
1781 tcp_ack = si->io.pck_snd;
1782 tcp_ctl = 0x12; /** SYN,ACK */
1784 si->io.pck_rcv += 1;
1788 case SWRAP_CONNECT_UNREACH:
1789 if (si->type != SOCK_STREAM) return NULL;
1791 dest_addr = si->myname;
1794 /* Unreachable: resend the data of SWRAP_CONNECT_SEND */
1795 tcp_seqno = si->io.pck_snd - 1;
1796 tcp_ack = si->io.pck_rcv;
1797 tcp_ctl = 0x02; /* SYN */
1802 case SWRAP_CONNECT_ACK:
1803 if (si->type != SOCK_STREAM) return NULL;
1805 src_addr = si->myname;
1808 tcp_seqno = si->io.pck_snd;
1809 tcp_ack = si->io.pck_rcv;
1810 tcp_ctl = 0x10; /* ACK */
1814 case SWRAP_ACCEPT_SEND:
1815 if (si->type != SOCK_STREAM) return NULL;
1817 dest_addr = si->myname;
1820 tcp_seqno = si->io.pck_rcv;
1821 tcp_ack = si->io.pck_snd;
1822 tcp_ctl = 0x02; /* SYN */
1824 si->io.pck_rcv += 1;
1828 case SWRAP_ACCEPT_RECV:
1829 if (si->type != SOCK_STREAM) return NULL;
1831 src_addr = si->myname;
1834 tcp_seqno = si->io.pck_snd;
1835 tcp_ack = si->io.pck_rcv;
1836 tcp_ctl = 0x12; /* SYN,ACK */
1838 si->io.pck_snd += 1;
1842 case SWRAP_ACCEPT_ACK:
1843 if (si->type != SOCK_STREAM) return NULL;
1845 dest_addr = si->myname;
1848 tcp_seqno = si->io.pck_rcv;
1849 tcp_ack = si->io.pck_snd;
1850 tcp_ctl = 0x10; /* ACK */
1855 src_addr = si->myname;
1856 dest_addr = si->peername;
1858 tcp_seqno = si->io.pck_snd;
1859 tcp_ack = si->io.pck_rcv;
1860 tcp_ctl = 0x18; /* PSH,ACK */
1862 si->io.pck_snd += len;
1866 case SWRAP_SEND_RST:
1867 dest_addr = si->myname;
1868 src_addr = si->peername;
1870 if (si->type == SOCK_DGRAM) {
1871 return swrap_marshall_packet(si, si->peername,
1872 SWRAP_SENDTO_UNREACH,
1873 buf, len, packet_len);
1876 tcp_seqno = si->io.pck_rcv;
1877 tcp_ack = si->io.pck_snd;
1878 tcp_ctl = 0x14; /** RST,ACK */
1882 case SWRAP_PENDING_RST:
1883 dest_addr = si->myname;
1884 src_addr = si->peername;
1886 if (si->type == SOCK_DGRAM) {
1890 tcp_seqno = si->io.pck_rcv;
1891 tcp_ack = si->io.pck_snd;
1892 tcp_ctl = 0x14; /* RST,ACK */
1897 dest_addr = si->myname;
1898 src_addr = si->peername;
1900 tcp_seqno = si->io.pck_rcv;
1901 tcp_ack = si->io.pck_snd;
1902 tcp_ctl = 0x18; /* PSH,ACK */
1904 si->io.pck_rcv += len;
1908 case SWRAP_RECV_RST:
1909 dest_addr = si->myname;
1910 src_addr = si->peername;
1912 if (si->type == SOCK_DGRAM) {
1916 tcp_seqno = si->io.pck_rcv;
1917 tcp_ack = si->io.pck_snd;
1918 tcp_ctl = 0x14; /* RST,ACK */
1923 src_addr = si->myname;
1926 si->io.pck_snd += len;
1930 case SWRAP_SENDTO_UNREACH:
1931 dest_addr = si->myname;
1938 case SWRAP_RECVFROM:
1939 dest_addr = si->myname;
1942 si->io.pck_rcv += len;
1946 case SWRAP_CLOSE_SEND:
1947 if (si->type != SOCK_STREAM) return NULL;
1949 src_addr = si->myname;
1950 dest_addr = si->peername;
1952 tcp_seqno = si->io.pck_snd;
1953 tcp_ack = si->io.pck_rcv;
1954 tcp_ctl = 0x11; /* FIN, ACK */
1956 si->io.pck_snd += 1;
1960 case SWRAP_CLOSE_RECV:
1961 if (si->type != SOCK_STREAM) return NULL;
1963 dest_addr = si->myname;
1964 src_addr = si->peername;
1966 tcp_seqno = si->io.pck_rcv;
1967 tcp_ack = si->io.pck_snd;
1968 tcp_ctl = 0x11; /* FIN,ACK */
1970 si->io.pck_rcv += 1;
1974 case SWRAP_CLOSE_ACK:
1975 if (si->type != SOCK_STREAM) return NULL;
1977 src_addr = si->myname;
1978 dest_addr = si->peername;
1980 tcp_seqno = si->io.pck_snd;
1981 tcp_ack = si->io.pck_rcv;
1982 tcp_ctl = 0x10; /* ACK */
1989 swrapGetTimeOfDay(&tv);
1991 return swrap_packet_init(&tv, src_addr, dest_addr, si->type,
1992 (const uint8_t *)buf, len,
1993 tcp_seqno, tcp_ack, tcp_ctl, unreachable,
1997 static void swrap_dump_packet(struct socket_info *si,
1998 const struct sockaddr *addr,
1999 enum swrap_packet_type type,
2000 const void *buf, size_t len)
2002 const char *file_name;
2004 size_t packet_len = 0;
2007 file_name = socket_wrapper_pcap_file();
2012 packet = swrap_marshall_packet(si, addr, type, buf, len, &packet_len);
2017 fd = swrap_get_pcap_fd(file_name);
2019 if (write(fd, packet, packet_len) != (ssize_t)packet_len) {
2028 /****************************************************************************
2030 ***************************************************************************/
2032 #ifdef HAVE_SIGNALFD
2033 static int swrap_signalfd(int fd, const sigset_t *mask, int flags)
2037 rc = libc_signalfd(fd, mask, flags);
2039 swrap_remove_stale(fd);
2045 int signalfd(int fd, const sigset_t *mask, int flags)
2047 return swrap_signalfd(fd, mask, flags);
2051 /****************************************************************************
2053 ***************************************************************************/
2055 static int swrap_socket(int family, int type, int protocol)
2057 struct socket_info *si;
2058 struct socket_info_fd *fi;
2060 int real_type = type;
2063 * Remove possible addition flags passed to socket() so
2064 * do not fail checking the type.
2065 * See https://lwn.net/Articles/281965/
2068 real_type &= ~SOCK_CLOEXEC;
2070 #ifdef SOCK_NONBLOCK
2071 real_type &= ~SOCK_NONBLOCK;
2074 if (!socket_wrapper_enabled()) {
2075 return libc_socket(family, type, protocol);
2085 return libc_socket(family, type, protocol);
2087 errno = EAFNOSUPPORT;
2091 switch (real_type) {
2097 errno = EPROTONOSUPPORT;
2105 if (real_type == SOCK_STREAM) {
2110 if (real_type == SOCK_DGRAM) {
2115 errno = EPROTONOSUPPORT;
2120 * We must call libc_socket with type, from the caller, not the version
2121 * we removed SOCK_CLOEXEC and SOCK_NONBLOCK from
2123 fd = libc_socket(AF_UNIX, type, 0);
2129 /* Check if we have a stale fd and remove it */
2130 si = find_socket_info(fd);
2132 swrap_remove_stale(fd);
2135 si = (struct socket_info *)malloc(sizeof(struct socket_info));
2136 memset(si, 0, sizeof(struct socket_info));
2142 si->family = family;
2144 /* however, the rest of the socket_wrapper code expects just
2145 * the type, not the flags */
2146 si->type = real_type;
2147 si->protocol = protocol;
2149 fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
2158 SWRAP_DLIST_ADD(si->fds, fi);
2159 SWRAP_DLIST_ADD(sockets, si);
2164 int socket(int family, int type, int protocol)
2166 return swrap_socket(family, type, protocol);
2169 /****************************************************************************
2171 ***************************************************************************/
2173 static int swrap_socketpair(int family, int type, int protocol, int sv[2])
2177 rc = libc_socketpair(family, type, protocol, sv);
2179 swrap_remove_stale(sv[0]);
2180 swrap_remove_stale(sv[1]);
2186 int socketpair(int family, int type, int protocol, int sv[2])
2188 return swrap_socketpair(family, type, protocol, sv);
2191 /****************************************************************************
2193 ***************************************************************************/
2195 #ifdef HAVE_TIMERFD_CREATE
2196 static int swrap_timerfd_create(int clockid, int flags)
2200 fd = libc_timerfd_create(clockid, flags);
2202 swrap_remove_stale(fd);
2208 int timerfd_create(int clockid, int flags)
2210 return swrap_timerfd_create(clockid, flags);
2214 /****************************************************************************
2216 ***************************************************************************/
2218 static int swrap_pipe(int pipefd[2])
2222 rc = libc_pipe(pipefd);
2224 swrap_remove_stale(pipefd[0]);
2225 swrap_remove_stale(pipefd[1]);
2231 int pipe(int pipefd[2])
2233 return swrap_pipe(pipefd);
2236 /****************************************************************************
2238 ***************************************************************************/
2240 static int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
2242 struct socket_info *parent_si, *child_si;
2243 struct socket_info_fd *child_fi;
2245 struct sockaddr_un un_addr;
2246 socklen_t un_addrlen = sizeof(un_addr);
2247 struct sockaddr_un un_my_addr;
2248 socklen_t un_my_addrlen = sizeof(un_my_addr);
2249 struct sockaddr *my_addr;
2250 socklen_t my_addrlen, len;
2253 parent_si = find_socket_info(s);
2255 return libc_accept(s, addr, addrlen);
2259 * assume out sockaddr have the same size as the in parent
2262 my_addrlen = socket_length(parent_si->family);
2263 if (my_addrlen <= 0) {
2268 my_addr = (struct sockaddr *)malloc(my_addrlen);
2269 if (my_addr == NULL) {
2273 memset(&un_addr, 0, sizeof(un_addr));
2274 memset(&un_my_addr, 0, sizeof(un_my_addr));
2276 ret = libc_accept(s, (struct sockaddr *)(void *)&un_addr, &un_addrlen);
2278 if (errno == ENOTSOCK) {
2279 /* Remove stale fds */
2280 swrap_remove_stale(s);
2289 ret = sockaddr_convert_from_un(parent_si, &un_addr, un_addrlen,
2290 parent_si->family, my_addr, &len);
2297 child_si = (struct socket_info *)malloc(sizeof(struct socket_info));
2298 memset(child_si, 0, sizeof(struct socket_info));
2300 child_fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
2301 if (child_fi == NULL) {
2311 SWRAP_DLIST_ADD(child_si->fds, child_fi);
2313 child_si->family = parent_si->family;
2314 child_si->type = parent_si->type;
2315 child_si->protocol = parent_si->protocol;
2316 child_si->bound = 1;
2317 child_si->is_server = 1;
2318 child_si->connected = 1;
2320 child_si->peername_len = len;
2321 child_si->peername = sockaddr_dup(my_addr, len);
2323 if (addr != NULL && addrlen != NULL) {
2324 size_t copy_len = MIN(*addrlen, len);
2326 memcpy(addr, my_addr, copy_len);
2331 ret = libc_getsockname(fd,
2332 (struct sockaddr *)(void *)&un_my_addr,
2343 ret = sockaddr_convert_from_un(child_si, &un_my_addr, un_my_addrlen,
2344 child_si->family, my_addr, &len);
2353 SWRAP_LOG(SWRAP_LOG_TRACE,
2354 "accept() path=%s, fd=%d",
2355 un_my_addr.sun_path, s);
2357 child_si->myname_len = len;
2358 child_si->myname = sockaddr_dup(my_addr, len);
2361 SWRAP_DLIST_ADD(sockets, child_si);
2364 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0);
2365 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_RECV, NULL, 0);
2366 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_ACK, NULL, 0);
2372 #ifdef HAVE_ACCEPT_PSOCKLEN_T
2373 int accept(int s, struct sockaddr *addr, Psocklen_t addrlen)
2375 int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
2378 return swrap_accept(s, addr, (socklen_t *)addrlen);
2381 static int autobind_start_init;
2382 static int autobind_start;
2384 /* using sendto() or connect() on an unbound socket would give the
2385 recipient no way to reply, as unlike UDP and TCP, a unix domain
2386 socket can't auto-assign emphemeral port numbers, so we need to
2388 Note: this might change the family from ipv6 to ipv4
2390 static int swrap_auto_bind(int fd, struct socket_info *si, int family)
2392 struct sockaddr_un un_addr;
2399 if (autobind_start_init != 1) {
2400 autobind_start_init = 1;
2401 autobind_start = getpid();
2402 autobind_start %= 50000;
2403 autobind_start += 10000;
2406 un_addr.sun_family = AF_UNIX;
2410 struct sockaddr_in in;
2414 type = SOCKET_TYPE_CHAR_TCP;
2417 type = SOCKET_TYPE_CHAR_UDP;
2420 errno = ESOCKTNOSUPPORT;
2424 memset(&in, 0, sizeof(in));
2425 in.sin_family = AF_INET;
2426 in.sin_addr.s_addr = htonl(127<<24 |
2427 socket_wrapper_default_iface());
2429 si->myname_len = sizeof(in);
2430 si->myname = sockaddr_dup(&in, si->myname_len);
2435 struct sockaddr_in6 in6;
2437 if (si->family != family) {
2438 errno = ENETUNREACH;
2444 type = SOCKET_TYPE_CHAR_TCP_V6;
2447 type = SOCKET_TYPE_CHAR_UDP_V6;
2450 errno = ESOCKTNOSUPPORT;
2454 memset(&in6, 0, sizeof(in6));
2455 in6.sin6_family = AF_INET6;
2456 in6.sin6_addr = *swrap_ipv6();
2457 in6.sin6_addr.s6_addr[15] = socket_wrapper_default_iface();
2458 si->myname_len = sizeof(in6);
2459 si->myname = sockaddr_dup(&in6, si->myname_len);
2464 errno = ESOCKTNOSUPPORT;
2468 if (autobind_start > 60000) {
2469 autobind_start = 10000;
2472 for (i = 0; i < SOCKET_MAX_SOCKETS; i++) {
2473 port = autobind_start + i;
2474 snprintf(un_addr.sun_path, sizeof(un_addr.sun_path),
2475 "%s/"SOCKET_FORMAT, socket_wrapper_dir(),
2476 type, socket_wrapper_default_iface(), port);
2477 if (stat(un_addr.sun_path, &st) == 0) continue;
2479 ret = libc_bind(fd, (struct sockaddr *)(void *)&un_addr,
2481 if (ret == -1) return ret;
2483 si->tmp_path = strdup(un_addr.sun_path);
2485 autobind_start = port + 1;
2488 if (i == SOCKET_MAX_SOCKETS) {
2489 SWRAP_LOG(SWRAP_LOG_ERROR, "Too many open unix sockets (%u) for "
2490 "interface "SOCKET_FORMAT,
2493 socket_wrapper_default_iface(),
2499 si->family = family;
2500 set_port(si->family, port, si->myname);
2505 /****************************************************************************
2507 ***************************************************************************/
2509 static int swrap_connect(int s, const struct sockaddr *serv_addr,
2513 struct sockaddr_un un_addr;
2514 struct socket_info *si = find_socket_info(s);
2518 return libc_connect(s, serv_addr, addrlen);
2521 if (si->bound == 0) {
2522 ret = swrap_auto_bind(s, si, serv_addr->sa_family);
2523 if (ret == -1) return -1;
2526 if (si->family != serv_addr->sa_family) {
2531 ret = sockaddr_convert_to_un(si, serv_addr,
2532 addrlen, &un_addr, 0, &bcast);
2533 if (ret == -1) return -1;
2536 errno = ENETUNREACH;
2540 if (si->type == SOCK_DGRAM) {
2541 si->defer_connect = 1;
2544 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0);
2546 ret = libc_connect(s,
2547 (struct sockaddr *)(void *)&un_addr,
2548 sizeof(struct sockaddr_un));
2551 SWRAP_LOG(SWRAP_LOG_TRACE,
2552 "connect() path=%s, fd=%d",
2553 un_addr.sun_path, s);
2556 /* to give better errors */
2557 if (ret == -1 && errno == ENOENT) {
2558 errno = EHOSTUNREACH;
2562 si->peername_len = addrlen;
2563 si->peername = sockaddr_dup(serv_addr, addrlen);
2566 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0);
2567 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0);
2569 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0);
2575 int connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen)
2577 return swrap_connect(s, serv_addr, addrlen);
2580 /****************************************************************************
2582 ***************************************************************************/
2584 static int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
2587 struct sockaddr_un un_addr;
2588 struct socket_info *si = find_socket_info(s);
2591 return libc_bind(s, myaddr, addrlen);
2594 si->myname_len = addrlen;
2595 si->myname = sockaddr_dup(myaddr, addrlen);
2597 ret = sockaddr_convert_to_un(si, myaddr, addrlen, &un_addr, 1, &si->bcast);
2598 if (ret == -1) return -1;
2600 unlink(un_addr.sun_path);
2602 ret = libc_bind(s, (struct sockaddr *)(void *)&un_addr,
2603 sizeof(struct sockaddr_un));
2605 SWRAP_LOG(SWRAP_LOG_TRACE,
2606 "bind() path=%s, fd=%d",
2607 un_addr.sun_path, s);
2616 int bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
2618 return swrap_bind(s, myaddr, addrlen);
2621 /****************************************************************************
2623 ***************************************************************************/
2625 static int swrap_listen(int s, int backlog)
2628 struct socket_info *si = find_socket_info(s);
2631 return libc_listen(s, backlog);
2634 ret = libc_listen(s, backlog);
2639 int listen(int s, int backlog)
2641 return swrap_listen(s, backlog);
2644 /****************************************************************************
2646 ***************************************************************************/
2648 static int swrap_vopen(const char *pathname, int flags, va_list ap)
2652 ret = libc_vopen(pathname, flags, ap);
2655 * There are methods for closing descriptors (libc-internal code
2656 * paths, direct syscalls) which close descriptors in ways that
2657 * we can't intercept, so try to recover when we notice that
2660 swrap_remove_stale(ret);
2665 int open(const char *pathname, int flags, ...)
2670 va_start(ap, flags);
2671 fd = swrap_vopen(pathname, flags, ap);
2677 /****************************************************************************
2679 ***************************************************************************/
2681 static int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
2683 struct socket_info *si = find_socket_info(s);
2686 return libc_getpeername(s, name, addrlen);
2695 memcpy(name, si->peername, si->peername_len);
2696 *addrlen = si->peername_len;
2701 #ifdef HAVE_ACCEPT_PSOCKLEN_T
2702 int getpeername(int s, struct sockaddr *name, Psocklen_t addrlen)
2704 int getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
2707 return swrap_getpeername(s, name, (socklen_t *)addrlen);
2710 /****************************************************************************
2712 ***************************************************************************/
2714 static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
2716 struct socket_info *si = find_socket_info(s);
2719 return libc_getsockname(s, name, addrlen);
2722 memcpy(name, si->myname, si->myname_len);
2723 *addrlen = si->myname_len;
2728 #ifdef HAVE_ACCEPT_PSOCKLEN_T
2729 int getsockname(int s, struct sockaddr *name, Psocklen_t addrlen)
2731 int getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
2734 return swrap_getsockname(s, name, (socklen_t *)addrlen);
2737 /****************************************************************************
2739 ***************************************************************************/
2741 static int swrap_getsockopt(int s, int level, int optname,
2742 void *optval, socklen_t *optlen)
2744 struct socket_info *si = find_socket_info(s);
2747 return libc_getsockopt(s,
2754 if (level == SOL_SOCKET) {
2755 return libc_getsockopt(s,
2762 errno = ENOPROTOOPT;
2766 #ifdef HAVE_ACCEPT_PSOCKLEN_T
2767 int getsockopt(int s, int level, int optname, void *optval, Psocklen_t optlen)
2769 int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
2772 return swrap_getsockopt(s, level, optname, optval, (socklen_t *)optlen);
2775 /****************************************************************************
2777 ***************************************************************************/
2779 static int swrap_setsockopt(int s, int level, int optname,
2780 const void *optval, socklen_t optlen)
2782 struct socket_info *si = find_socket_info(s);
2785 return libc_setsockopt(s,
2792 if (level == SOL_SOCKET) {
2793 return libc_setsockopt(s,
2800 switch (si->family) {
2808 errno = ENOPROTOOPT;
2813 int setsockopt(int s, int level, int optname,
2814 const void *optval, socklen_t optlen)
2816 return swrap_setsockopt(s, level, optname, optval, optlen);
2819 /****************************************************************************
2821 ***************************************************************************/
2823 static int swrap_vioctl(int s, unsigned long int r, va_list va)
2825 struct socket_info *si = find_socket_info(s);
2831 return libc_vioctl(s, r, va);
2836 rc = libc_vioctl(s, r, va);
2840 value = *((int *)va_arg(ap, int *));
2842 if (rc == -1 && errno != EAGAIN && errno != ENOBUFS) {
2843 swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
2844 } else if (value == 0) { /* END OF FILE */
2845 swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
2855 #ifdef HAVE_IOCTL_INT
2856 int ioctl(int s, int r, ...)
2858 int ioctl(int s, unsigned long int r, ...)
2866 rc = swrap_vioctl(s, (unsigned long int) r, va);
2873 static ssize_t swrap_sendmsg_before(int fd,
2874 struct socket_info *si,
2876 struct iovec *tmp_iov,
2877 struct sockaddr_un *tmp_un,
2878 const struct sockaddr_un **to_un,
2879 const struct sockaddr **to,
2897 if (!si->connected) {
2902 if (msg->msg_iovlen == 0) {
2906 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
2908 nlen = len + msg->msg_iov[i].iov_len;
2909 if (nlen > SOCKET_MAX_PACKET) {
2913 msg->msg_iovlen = i;
2914 if (msg->msg_iovlen == 0) {
2915 *tmp_iov = msg->msg_iov[0];
2916 tmp_iov->iov_len = MIN(tmp_iov->iov_len, SOCKET_MAX_PACKET);
2917 msg->msg_iov = tmp_iov;
2918 msg->msg_iovlen = 1;
2923 if (si->connected) {
2924 if (msg->msg_name) {
2929 const struct sockaddr *msg_name;
2930 msg_name = (const struct sockaddr *)msg->msg_name;
2932 if (msg_name == NULL) {
2938 ret = sockaddr_convert_to_un(si, msg_name, msg->msg_namelen,
2940 if (ret == -1) return -1;
2948 msg->msg_name = tmp_un;
2949 msg->msg_namelen = sizeof(*tmp_un);
2952 if (si->bound == 0) {
2953 ret = swrap_auto_bind(fd, si, si->family);
2955 if (errno == ENOTSOCK) {
2956 swrap_remove_stale(fd);
2959 SWRAP_LOG(SWRAP_LOG_ERROR, "swrap_sendmsg_before failed");
2965 if (!si->defer_connect) {
2969 ret = sockaddr_convert_to_un(si, si->peername, si->peername_len,
2971 if (ret == -1) return -1;
2973 ret = libc_connect(fd,
2974 (struct sockaddr *)(void *)tmp_un,
2977 /* to give better errors */
2978 if (ret == -1 && errno == ENOENT) {
2979 errno = EHOSTUNREACH;
2986 si->defer_connect = 0;
2989 errno = EHOSTUNREACH;
2996 static void swrap_sendmsg_after(int fd,
2997 struct socket_info *si,
2999 const struct sockaddr *to,
3002 int saved_errno = errno;
3009 /* to give better errors */
3011 if (saved_errno == ENOENT) {
3012 saved_errno = EHOSTUNREACH;
3013 } else if (saved_errno == ENOTSOCK) {
3014 /* If the fd is not a socket, remove it */
3015 swrap_remove_stale(fd);
3019 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3020 avail += msg->msg_iov[i].iov_len;
3024 remain = MIN(80, avail);
3029 /* we capture it as one single packet */
3030 buf = (uint8_t *)malloc(remain);
3032 /* we just not capture the packet */
3033 errno = saved_errno;
3037 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3038 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
3040 msg->msg_iov[i].iov_base,
3043 remain -= this_time;
3050 swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
3051 swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
3053 swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
3058 if (si->connected) {
3062 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
3063 swrap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);
3065 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
3071 errno = saved_errno;
3074 static int swrap_recvmsg_before(int fd,
3075 struct socket_info *si,
3077 struct iovec *tmp_iov)
3082 (void)fd; /* unused */
3086 if (!si->connected) {
3091 if (msg->msg_iovlen == 0) {
3095 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3097 nlen = len + msg->msg_iov[i].iov_len;
3098 if (nlen > SOCKET_MAX_PACKET) {
3102 msg->msg_iovlen = i;
3103 if (msg->msg_iovlen == 0) {
3104 *tmp_iov = msg->msg_iov[0];
3105 tmp_iov->iov_len = MIN(tmp_iov->iov_len, SOCKET_MAX_PACKET);
3106 msg->msg_iov = tmp_iov;
3107 msg->msg_iovlen = 1;
3112 if (msg->msg_name == NULL) {
3117 if (msg->msg_iovlen == 0) {
3121 if (si->bound == 0) {
3122 ret = swrap_auto_bind(fd, si, si->family);
3125 * When attempting to read or write to a
3126 * descriptor, if an underlying autobind fails
3127 * because it's not a socket, stop intercepting
3128 * uses of that descriptor.
3130 if (errno == ENOTSOCK) {
3131 swrap_remove_stale(fd);
3134 SWRAP_LOG(SWRAP_LOG_ERROR,
3135 "swrap_recvmsg_before failed");
3142 errno = EHOSTUNREACH;
3149 static int swrap_recvmsg_after(int fd,
3150 struct socket_info *si,
3152 const struct sockaddr_un *un_addr,
3153 socklen_t un_addrlen,
3156 int saved_errno = errno;
3163 /* to give better errors */
3165 if (saved_errno == ENOENT) {
3166 saved_errno = EHOSTUNREACH;
3167 } else if (saved_errno == ENOTSOCK) {
3168 /* If the fd is not a socket, remove it */
3169 swrap_remove_stale(fd);
3173 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3174 avail += msg->msg_iov[i].iov_len;
3178 errno = saved_errno;
3183 remain = MIN(80, avail);
3188 /* we capture it as one single packet */
3189 buf = (uint8_t *)malloc(remain);
3191 /* we just not capture the packet */
3192 errno = saved_errno;
3196 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3197 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
3199 msg->msg_iov[i].iov_base,
3202 remain -= this_time;
3207 if (ret == -1 && saved_errno != EAGAIN && saved_errno != ENOBUFS) {
3208 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
3209 } else if (ret == 0) { /* END OF FILE */
3210 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
3211 } else if (ret > 0) {
3212 swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
3221 if (un_addr != NULL) {
3224 rc = sockaddr_convert_from_un(si,
3234 swrap_dump_packet(si,
3240 swrap_dump_packet(si,
3251 errno = saved_errno;
3255 /****************************************************************************
3257 ***************************************************************************/
3259 static ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags,
3260 struct sockaddr *from, socklen_t *fromlen)
3262 struct sockaddr_un from_addr;
3263 socklen_t from_addrlen = sizeof(from_addr);
3265 struct socket_info *si = find_socket_info(s);
3266 struct sockaddr_storage ss;
3267 socklen_t ss_len = sizeof(ss);
3273 return libc_recvfrom(s,
3285 if (from != NULL && fromlen != NULL) {
3286 msg.msg_name = from; /* optional address */
3287 msg.msg_namelen = *fromlen; /* size of address */
3289 msg.msg_name = (struct sockaddr *)(void *)&ss; /* optional address */
3290 msg.msg_namelen = ss_len; /* size of address */
3292 msg.msg_iov = &tmp; /* scatter/gather array */
3293 msg.msg_iovlen = 1; /* # elements in msg_iov */
3294 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3295 msg.msg_control = NULL; /* ancillary data, see below */
3296 msg.msg_controllen = 0; /* ancillary data buffer len */
3297 msg.msg_flags = 0; /* flags on received message */
3300 tret = swrap_recvmsg_before(s, si, &msg, &tmp);
3305 buf = msg.msg_iov[0].iov_base;
3306 len = msg.msg_iov[0].iov_len;
3308 /* irix 6.4 forgets to null terminate the sun_path string :-( */
3309 memset(&from_addr, 0, sizeof(from_addr));
3310 ret = libc_recvfrom(s,
3314 (struct sockaddr *)(void *)&from_addr,
3320 tret = swrap_recvmsg_after(s,
3330 if (from != NULL && fromlen != NULL) {
3331 *fromlen = msg.msg_namelen;
3337 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3338 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
3339 struct sockaddr *from, Psocklen_t fromlen)
3341 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
3342 struct sockaddr *from, socklen_t *fromlen)
3345 return swrap_recvfrom(s, buf, len, flags, from, (socklen_t *)fromlen);
3348 /****************************************************************************
3350 ***************************************************************************/
3352 static ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags,
3353 const struct sockaddr *to, socklen_t tolen)
3357 struct sockaddr_un un_addr;
3358 const struct sockaddr_un *to_un = NULL;
3361 struct socket_info *si = find_socket_info(s);
3365 return libc_sendto(s, buf, len, flags, to, tolen);
3368 tmp.iov_base = discard_const_p(char, buf);
3372 msg.msg_name = discard_const_p(struct sockaddr, to); /* optional address */
3373 msg.msg_namelen = tolen; /* size of address */
3374 msg.msg_iov = &tmp; /* scatter/gather array */
3375 msg.msg_iovlen = 1; /* # elements in msg_iov */
3376 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
3377 msg.msg_control = NULL; /* ancillary data, see below */
3378 msg.msg_controllen = 0; /* ancillary data buffer len */
3379 msg.msg_flags = 0; /* flags on received message */
3382 rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
3387 buf = msg.msg_iov[0].iov_base;
3388 len = msg.msg_iov[0].iov_len;
3393 unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port);
3396 type = SOCKET_TYPE_CHAR_UDP;
3398 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
3399 snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT,
3400 socket_wrapper_dir(), type, iface, prt);
3401 if (stat(un_addr.sun_path, &st) != 0) continue;
3403 /* ignore the any errors in broadcast sends */
3408 (struct sockaddr *)(void *)&un_addr,
3412 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
3417 ret = libc_sendto(s,
3421 (struct sockaddr *)msg.msg_name,
3424 swrap_sendmsg_after(s, si, &msg, to, ret);
3429 ssize_t sendto(int s, const void *buf, size_t len, int flags,
3430 const struct sockaddr *to, socklen_t tolen)
3432 return swrap_sendto(s, buf, len, flags, to, tolen);
3435 /****************************************************************************
3437 ***************************************************************************/
3439 static ssize_t swrap_recv(int s, void *buf, size_t len, int flags)
3441 struct socket_info *si;
3443 struct sockaddr_storage ss;
3444 socklen_t ss_len = sizeof(ss);
3449 si = find_socket_info(s);
3451 return libc_recv(s, buf, len, flags);
3458 msg.msg_name = (struct sockaddr *)(void *)&ss; /* optional address */
3459 msg.msg_namelen = ss_len; /* size of address */
3460 msg.msg_iov = &tmp; /* scatter/gather array */
3461 msg.msg_iovlen = 1; /* # elements in msg_iov */
3462 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3463 msg.msg_control = NULL; /* ancillary data, see below */
3464 msg.msg_controllen = 0; /* ancillary data buffer len */
3465 msg.msg_flags = 0; /* flags on received message */
3468 tret = swrap_recvmsg_before(s, si, &msg, &tmp);
3473 buf = msg.msg_iov[0].iov_base;
3474 len = msg.msg_iov[0].iov_len;
3476 ret = libc_recv(s, buf, len, flags);
3478 tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
3486 ssize_t recv(int s, void *buf, size_t len, int flags)
3488 return swrap_recv(s, buf, len, flags);
3491 /****************************************************************************
3493 ***************************************************************************/
3495 static ssize_t swrap_read(int s, void *buf, size_t len)
3497 struct socket_info *si;
3500 struct sockaddr_storage ss;
3501 socklen_t ss_len = sizeof(ss);
3505 si = find_socket_info(s);
3507 return libc_read(s, buf, len);
3514 msg.msg_name = (struct sockaddr *)(void *)&ss; /* optional address */
3515 msg.msg_namelen = ss_len; /* size of address */
3516 msg.msg_iov = &tmp; /* scatter/gather array */
3517 msg.msg_iovlen = 1; /* # elements in msg_iov */
3518 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3519 msg.msg_control = NULL; /* ancillary data, see below */
3520 msg.msg_controllen = 0; /* ancillary data buffer len */
3521 msg.msg_flags = 0; /* flags on received message */
3524 tret = swrap_recvmsg_before(s, si, &msg, &tmp);
3526 if (tret == -ENOTSOCK) {
3527 return libc_read(s, buf, len);
3532 buf = msg.msg_iov[0].iov_base;
3533 len = msg.msg_iov[0].iov_len;
3535 ret = libc_read(s, buf, len);
3537 tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
3545 ssize_t read(int s, void *buf, size_t len)
3547 return swrap_read(s, buf, len);
3550 /****************************************************************************
3552 ***************************************************************************/
3554 static ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
3558 struct sockaddr_un un_addr;
3561 struct socket_info *si = find_socket_info(s);
3564 return libc_send(s, buf, len, flags);
3567 tmp.iov_base = discard_const_p(char, buf);
3571 msg.msg_name = NULL; /* optional address */
3572 msg.msg_namelen = 0; /* size of address */
3573 msg.msg_iov = &tmp; /* scatter/gather array */
3574 msg.msg_iovlen = 1; /* # elements in msg_iov */
3575 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
3576 msg.msg_control = NULL; /* ancillary data, see below */
3577 msg.msg_controllen = 0; /* ancillary data buffer len */
3578 msg.msg_flags = 0; /* flags on received message */
3581 rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
3586 buf = msg.msg_iov[0].iov_base;
3587 len = msg.msg_iov[0].iov_len;
3589 ret = libc_send(s, buf, len, flags);
3591 swrap_sendmsg_after(s, si, &msg, NULL, ret);
3596 ssize_t send(int s, const void *buf, size_t len, int flags)
3598 return swrap_send(s, buf, len, flags);
3601 /****************************************************************************
3603 ***************************************************************************/
3605 static ssize_t swrap_recvmsg(int s, struct msghdr *omsg, int flags)
3607 struct sockaddr_un from_addr;
3608 socklen_t from_addrlen = sizeof(from_addr);
3609 struct socket_info *si;
3616 si = find_socket_info(s);
3618 return libc_recvmsg(s, omsg, flags);
3621 tmp.iov_base = NULL;
3625 msg.msg_name = (struct sockaddr *)&from_addr; /* optional address */
3626 msg.msg_namelen = from_addrlen; /* size of address */
3627 msg.msg_iov = omsg->msg_iov; /* scatter/gather array */
3628 msg.msg_iovlen = omsg->msg_iovlen; /* # elements in msg_iov */
3629 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3630 msg.msg_control = omsg->msg_control; /* ancillary data, see below */
3631 msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
3632 msg.msg_flags = omsg->msg_flags; /* flags on received message */
3635 rc = swrap_recvmsg_before(s, si, &msg, &tmp);
3640 ret = libc_recvmsg(s, &msg, flags);
3642 rc = swrap_recvmsg_after(s, si, omsg, &from_addr, from_addrlen, ret);
3650 ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)
3652 return swrap_recvmsg(sockfd, msg, flags);
3655 /****************************************************************************
3657 ***************************************************************************/
3659 static ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags)
3663 struct sockaddr_un un_addr;
3664 const struct sockaddr_un *to_un = NULL;
3665 const struct sockaddr *to = NULL;
3668 struct socket_info *si = find_socket_info(s);
3672 return libc_sendmsg(s, omsg, flags);
3675 ZERO_STRUCT(un_addr);
3677 tmp.iov_base = NULL;
3681 msg.msg_name = omsg->msg_name; /* optional address */
3682 msg.msg_namelen = omsg->msg_namelen; /* size of address */
3683 msg.msg_iov = omsg->msg_iov; /* scatter/gather array */
3684 msg.msg_iovlen = omsg->msg_iovlen; /* # elements in msg_iov */
3685 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3686 msg.msg_control = omsg->msg_control; /* ancillary data, see below */
3687 msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
3688 msg.msg_flags = omsg->msg_flags; /* flags on received message */
3691 rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
3699 unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port);
3707 for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
3708 avail += msg.msg_iov[i].iov_len;
3714 /* we capture it as one single packet */
3715 buf = (uint8_t *)malloc(remain);
3720 for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
3721 size_t this_time = MIN(remain, (size_t)msg.msg_iov[i].iov_len);
3723 msg.msg_iov[i].iov_base,
3726 remain -= this_time;
3729 type = SOCKET_TYPE_CHAR_UDP;
3731 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
3732 snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT,
3733 socket_wrapper_dir(), type, iface, prt);
3734 if (stat(un_addr.sun_path, &st) != 0) continue;
3736 msg.msg_name = &un_addr; /* optional address */
3737 msg.msg_namelen = sizeof(un_addr); /* size of address */
3739 /* ignore the any errors in broadcast sends */
3740 libc_sendmsg(s, &msg, flags);
3743 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
3749 ret = libc_sendmsg(s, &msg, flags);
3751 swrap_sendmsg_after(s, si, &msg, to, ret);
3756 ssize_t sendmsg(int s, const struct msghdr *omsg, int flags)
3758 return swrap_sendmsg(s, omsg, flags);
3761 /****************************************************************************
3763 ***************************************************************************/
3765 static ssize_t swrap_readv(int s, const struct iovec *vector, int count)
3767 struct socket_info *si;
3770 struct sockaddr_storage ss;
3771 socklen_t ss_len = sizeof(ss);
3775 si = find_socket_info(s);
3777 return libc_readv(s, vector, count);
3780 tmp.iov_base = NULL;
3784 msg.msg_name = (struct sockaddr *)(void *)&ss; /* optional address */
3785 msg.msg_namelen = ss_len; /* size of address */
3786 msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
3787 msg.msg_iovlen = count; /* # elements in msg_iov */
3788 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3789 msg.msg_control = NULL; /* ancillary data, see below */
3790 msg.msg_controllen = 0; /* ancillary data buffer len */
3791 msg.msg_flags = 0; /* flags on received message */
3794 rc = swrap_recvmsg_before(s, si, &msg, &tmp);
3796 if (rc == -ENOTSOCK) {
3797 return libc_readv(s, vector, count);
3802 ret = libc_readv(s, msg.msg_iov, msg.msg_iovlen);
3804 rc = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
3812 ssize_t readv(int s, const struct iovec *vector, int count)
3814 return swrap_readv(s, vector, count);
3817 /****************************************************************************
3819 ***************************************************************************/
3821 static ssize_t swrap_writev(int s, const struct iovec *vector, int count)
3825 struct sockaddr_un un_addr;
3828 struct socket_info *si = find_socket_info(s);
3831 return libc_writev(s, vector, count);
3834 tmp.iov_base = NULL;
3838 msg.msg_name = NULL; /* optional address */
3839 msg.msg_namelen = 0; /* size of address */
3840 msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
3841 msg.msg_iovlen = count; /* # elements in msg_iov */
3842 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
3843 msg.msg_control = NULL; /* ancillary data, see below */
3844 msg.msg_controllen = 0; /* ancillary data buffer len */
3845 msg.msg_flags = 0; /* flags on received message */
3848 rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
3850 if (rc == -ENOTSOCK) {
3851 return libc_readv(s, vector, count);
3856 ret = libc_writev(s, msg.msg_iov, msg.msg_iovlen);
3858 swrap_sendmsg_after(s, si, &msg, NULL, ret);
3863 ssize_t writev(int s, const struct iovec *vector, int count)
3865 return swrap_writev(s, vector, count);
3868 /****************************
3870 ***************************/
3872 static int swrap_close(int fd)
3874 struct socket_info *si = find_socket_info(fd);
3875 struct socket_info_fd *fi;
3879 return libc_close(fd);
3882 for (fi = si->fds; fi; fi = fi->next) {
3884 SWRAP_DLIST_REMOVE(si->fds, fi);
3891 /* there are still references left */
3892 return libc_close(fd);
3895 SWRAP_DLIST_REMOVE(sockets, si);
3897 if (si->myname && si->peername) {
3898 swrap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0);
3901 ret = libc_close(fd);
3903 if (si->myname && si->peername) {
3904 swrap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0);
3905 swrap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0);
3908 if (si->myname) free(si->myname);
3909 if (si->peername) free(si->peername);
3911 unlink(si->tmp_path);
3921 return swrap_close(fd);
3924 /****************************
3926 ***************************/
3928 static int swrap_dup(int fd)
3930 struct socket_info *si;
3931 struct socket_info_fd *fi;
3933 si = find_socket_info(fd);
3936 return libc_dup(fd);
3939 fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
3945 fi->fd = libc_dup(fd);
3947 int saved_errno = errno;
3949 errno = saved_errno;
3953 /* Make sure we don't have an entry for the fd */
3954 swrap_remove_stale(fi->fd);
3956 SWRAP_DLIST_ADD(si->fds, fi);
3962 return swrap_dup(fd);
3965 /****************************
3967 ***************************/
3969 static int swrap_dup2(int fd, int newfd)
3971 struct socket_info *si;
3972 struct socket_info_fd *fi;
3974 si = find_socket_info(fd);
3977 return libc_dup2(fd, newfd);
3980 if (find_socket_info(newfd)) {
3981 /* dup2() does an implicit close of newfd, which we
3982 * need to emulate */
3986 fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
3992 fi->fd = libc_dup2(fd, newfd);
3994 int saved_errno = errno;
3996 errno = saved_errno;
4000 /* Make sure we don't have an entry for the fd */
4001 swrap_remove_stale(fi->fd);
4003 SWRAP_DLIST_ADD(si->fds, fi);
4007 int dup2(int fd, int newfd)
4009 return swrap_dup2(fd, newfd);
4012 /****************************
4014 ***************************/
4017 static int swrap_eventfd(int count, int flags)
4021 fd = libc_eventfd(count, flags);
4023 swrap_remove_stale(fd);
4029 int eventfd(int count, int flags)
4031 return swrap_eventfd(count, flags);
4035 /****************************
4037 ***************************/
4040 * This function is called when the library is unloaded and makes sure that
4041 * sockets get closed and the unix file for the socket are unlinked.
4043 void swrap_destructor(void)
4045 struct socket_info *s = sockets;
4048 struct socket_info_fd *f = s->fds;