2 * Copyright (C) Jelmer Vernooij 2005,2008 <jelmer@samba.org>
3 * Copyright (C) Stefan Metzmacher 2006-2009 <metze@samba.org>
4 * Copyright (C) Andreas Schneider 2013 <asn@samba.org>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the author nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 Socket wrapper library. Passes all socket communication over
39 unix domain sockets if the environment variable SOCKET_WRAPPER_DIR
45 #include <sys/types.h>
48 #include <sys/socket.h>
49 #include <sys/ioctl.h>
50 #ifdef HAVE_SYS_FILIO_H
51 #include <sys/filio.h>
53 #ifdef HAVE_SYS_SIGNALFD_H
54 #include <sys/signalfd.h>
56 #ifdef HAVE_SYS_EVENTFD_H
57 #include <sys/eventfd.h>
59 #ifdef HAVE_SYS_TIMERFD_H
60 #include <sys/timerfd.h>
65 #include <netinet/in.h>
66 #include <netinet/tcp.h>
67 #include <arpa/inet.h>
76 #ifdef HAVE_GNU_LIB_NAMES_H
77 #include <gnu/lib-names.h>
87 /* GCC have printf type attribute check. */
88 #ifdef HAVE_FUNCTION_ATTRIBUTE_FORMAT
89 #define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
91 #define PRINTF_ATTRIBUTE(a,b)
92 #endif /* HAVE_FUNCTION_ATTRIBUTE_FORMAT */
94 #ifdef HAVE_DESTRUCTOR_ATTRIBUTE
95 #define DESTRUCTOR_ATTRIBUTE __attribute__ ((destructor))
97 #define DESTRUCTOR_ATTRIBUTE
100 #ifdef HAVE_GCC_THREAD_LOCAL_STORAGE
101 # define SWRAP_THREAD __thread
103 # define SWRAP_THREAD
107 #define MIN(a,b) ((a)<(b)?(a):(b))
111 #define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
114 #ifndef discard_const
115 #define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
118 #ifndef discard_const_p
119 #define discard_const_p(type, ptr) ((type *)discard_const(ptr))
122 #define SWRAP_DLIST_ADD(list,item) do { \
124 (item)->prev = NULL; \
125 (item)->next = NULL; \
128 (item)->prev = NULL; \
129 (item)->next = (list); \
130 (list)->prev = (item); \
135 #define SWRAP_DLIST_REMOVE(list,item) do { \
136 if ((list) == (item)) { \
137 (list) = (item)->next; \
139 (list)->prev = NULL; \
142 if ((item)->prev) { \
143 (item)->prev->next = (item)->next; \
145 if ((item)->next) { \
146 (item)->next->prev = (item)->prev; \
149 (item)->prev = NULL; \
150 (item)->next = NULL; \
153 #if defined(HAVE_GETTIMEOFDAY_TZ) || defined(HAVE_GETTIMEOFDAY_TZ_VOID)
154 #define swrapGetTimeOfDay(tval) gettimeofday(tval,NULL)
156 #define swrapGetTimeOfDay(tval) gettimeofday(tval)
159 /* we need to use a very terse format here as IRIX 6.4 silently
160 truncates names to 16 chars, so if we use a longer name then we
161 can't tell which port a packet came from with recvfrom()
163 with this format we have 8 chars left for the directory name
165 #define SOCKET_FORMAT "%c%02X%04X"
166 #define SOCKET_TYPE_CHAR_TCP 'T'
167 #define SOCKET_TYPE_CHAR_UDP 'U'
168 #define SOCKET_TYPE_CHAR_TCP_V6 'X'
169 #define SOCKET_TYPE_CHAR_UDP_V6 'Y'
172 * Cut down to 1500 byte packets for stream sockets,
173 * which makes it easier to format PCAP capture files
174 * (as the caller will simply continue from here)
176 #define SOCKET_MAX_PACKET 1500
178 #define SOCKET_MAX_SOCKETS 1024
180 /* This limit is to avoid broadcast sendto() needing to stat too many
181 * files. It may be raised (with a performance cost) to up to 254
182 * without changing the format above */
183 #define MAX_WRAPPED_INTERFACES 40
185 struct socket_info_fd {
186 struct socket_info_fd *prev, *next;
192 struct socket_info_fd *fds;
205 struct sockaddr *bindname;
206 socklen_t bindname_len;
208 struct sockaddr *myname;
209 socklen_t myname_len;
211 struct sockaddr *peername;
212 socklen_t peername_len;
215 unsigned long pck_snd;
216 unsigned long pck_rcv;
219 struct socket_info *prev, *next;
223 * File descriptors are shared between threads so we should share socket
226 struct socket_info *sockets;
228 /* Function prototypes */
230 bool socket_wrapper_enabled(void);
231 void swrap_destructor(void) DESTRUCTOR_ATTRIBUTE;
234 # define SWRAP_LOG(...)
237 static void swrap_log(enum swrap_dbglvl_e dbglvl, const char *format, ...) PRINTF_ATTRIBUTE(2, 3);
238 # define SWRAP_LOG(dbglvl, ...) swrap_log((dbglvl), __VA_ARGS__)
240 static void swrap_log(enum swrap_dbglvl_e dbglvl, const char *format, ...)
245 unsigned int lvl = 0;
247 d = getenv("SOCKET_WRAPPER_DEBUGLEVEL");
252 va_start(va, format);
253 vsnprintf(buffer, sizeof(buffer), format, va);
258 case SWRAP_LOG_ERROR:
260 "SWRAP_ERROR(%d): %s\n",
261 (int)getpid(), buffer);
265 "SWRAP_WARN(%d): %s\n",
266 (int)getpid(), buffer);
268 case SWRAP_LOG_DEBUG:
270 "SWRAP_DEBUG(%d): %s\n",
271 (int)getpid(), buffer);
273 case SWRAP_LOG_TRACE:
275 "SWRAP_TRACE(%d): %s\n",
276 (int)getpid(), buffer);
283 /*********************************************************
284 * SWRAP LOADING LIBC FUNCTIONS
285 *********************************************************/
289 struct swrap_libc_fns {
290 int (*libc_accept)(int sockfd,
291 struct sockaddr *addr,
293 int (*libc_bind)(int sockfd,
294 const struct sockaddr *addr,
296 int (*libc_close)(int fd);
297 int (*libc_connect)(int sockfd,
298 const struct sockaddr *addr,
300 int (*libc_dup)(int fd);
301 int (*libc_dup2)(int oldfd, int newfd);
303 int (*libc_eventfd)(int count, int flags);
305 int (*libc_getpeername)(int sockfd,
306 struct sockaddr *addr,
308 int (*libc_getsockname)(int sockfd,
309 struct sockaddr *addr,
311 int (*libc_getsockopt)(int sockfd,
316 int (*libc_ioctl)(int d, unsigned long int request, ...);
317 int (*libc_listen)(int sockfd, int backlog);
318 int (*libc_open)(const char *pathname, int flags, mode_t mode);
319 int (*libc_pipe)(int pipefd[2]);
320 int (*libc_read)(int fd, void *buf, size_t count);
321 ssize_t (*libc_readv)(int fd, const struct iovec *iov, int iovcnt);
322 int (*libc_recv)(int sockfd, void *buf, size_t len, int flags);
323 int (*libc_recvfrom)(int sockfd,
327 struct sockaddr *src_addr,
329 int (*libc_recvmsg)(int sockfd, const struct msghdr *msg, int flags);
330 int (*libc_send)(int sockfd, const void *buf, size_t len, int flags);
331 int (*libc_sendmsg)(int sockfd, const struct msghdr *msg, int flags);
332 int (*libc_sendto)(int sockfd,
336 const struct sockaddr *dst_addr,
338 int (*libc_setsockopt)(int sockfd,
344 int (*libc_signalfd)(int fd, const sigset_t *mask, int flags);
346 int (*libc_socket)(int domain, int type, int protocol);
347 int (*libc_socketpair)(int domain, int type, int protocol, int sv[2]);
348 #ifdef HAVE_TIMERFD_CREATE
349 int (*libc_timerfd_create)(int clockid, int flags);
351 ssize_t (*libc_writev)(int fd, const struct iovec *iov, int iovcnt);
356 void *libsocket_handle;
363 struct swrap_libc_fns fns;
366 static struct swrap swrap;
369 static const char *socket_wrapper_dir(void);
371 #define LIBC_NAME "libc.so"
380 static const char *swrap_str_lib(enum swrap_lib lib)
387 case SWRAP_LIBSOCKET:
391 /* Compiler would warn us about unhandled enum value if we get here */
396 static void *swrap_load_lib_handle(enum swrap_lib lib)
398 int flags = RTLD_LAZY;
403 flags |= RTLD_DEEPBIND;
409 case SWRAP_LIBSOCKET:
410 #ifdef HAVE_LIBSOCKET
411 handle = swrap.libsocket_handle;
412 if (handle == NULL) {
413 for (handle = NULL, i = 10; handle == NULL && i >= 0; i--) {
414 char soname[256] = {0};
416 snprintf(soname, sizeof(soname), "libsocket.so.%d", i);
417 handle = dlopen(soname, flags);
420 swrap.libsocket_handle = handle;
426 handle = swrap.libc_handle;
428 if (handle == NULL) {
429 handle = dlopen(LIBC_SO, flags);
432 if (handle == NULL) {
433 for (handle = NULL, i = 10; handle == NULL && i >= 0; i--) {
434 char soname[256] = {0};
436 snprintf(soname, sizeof(soname), "libc.so.%d", i);
437 handle = dlopen(soname, flags);
440 swrap.libc_handle = handle;
445 if (handle == NULL) {
447 handle = swrap.libc_handle = swrap.libsocket_handle = RTLD_NEXT;
449 SWRAP_LOG(SWRAP_LOG_ERROR,
450 "Failed to dlopen library: %s\n",
459 static void *_swrap_load_lib_function(enum swrap_lib lib, const char *fn_name)
464 handle = swrap_load_lib_handle(lib);
466 func = dlsym(handle, fn_name);
468 SWRAP_LOG(SWRAP_LOG_ERROR,
469 "Failed to find %s: %s\n",
474 SWRAP_LOG(SWRAP_LOG_TRACE,
476 fn_name, swrap_str_lib(lib));
480 #define swrap_load_lib_function(lib, fn_name) \
481 if (swrap.fns.libc_##fn_name == NULL) { \
482 *(void **) (&swrap.fns.libc_##fn_name) = \
483 _swrap_load_lib_function(lib, #fn_name); \
490 * Functions especially from libc need to be loaded individually, you can't load
491 * all at once or gdb will segfault at startup. The same applies to valgrind and
492 * has probably something todo with with the linker.
493 * So we need load each function at the point it is called the first time.
495 static int libc_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
497 swrap_load_lib_function(SWRAP_LIBSOCKET, accept);
499 return swrap.fns.libc_accept(sockfd, addr, addrlen);
502 static int libc_bind(int sockfd,
503 const struct sockaddr *addr,
506 swrap_load_lib_function(SWRAP_LIBSOCKET, bind);
508 return swrap.fns.libc_bind(sockfd, addr, addrlen);
511 static int libc_close(int fd)
513 swrap_load_lib_function(SWRAP_LIBC, close);
515 return swrap.fns.libc_close(fd);
518 static int libc_connect(int sockfd,
519 const struct sockaddr *addr,
522 swrap_load_lib_function(SWRAP_LIBSOCKET, connect);
524 return swrap.fns.libc_connect(sockfd, addr, addrlen);
527 static int libc_dup(int fd)
529 swrap_load_lib_function(SWRAP_LIBC, dup);
531 return swrap.fns.libc_dup(fd);
534 static int libc_dup2(int oldfd, int newfd)
536 swrap_load_lib_function(SWRAP_LIBC, dup2);
538 return swrap.fns.libc_dup2(oldfd, newfd);
542 static int libc_eventfd(int count, int flags)
544 swrap_load_lib_function(SWRAP_LIBC, eventfd);
546 return swrap.fns.libc_eventfd(count, flags);
550 static int libc_getpeername(int sockfd,
551 struct sockaddr *addr,
554 swrap_load_lib_function(SWRAP_LIBSOCKET, getpeername);
556 return swrap.fns.libc_getpeername(sockfd, addr, addrlen);
559 static int libc_getsockname(int sockfd,
560 struct sockaddr *addr,
563 swrap_load_lib_function(SWRAP_LIBSOCKET, getsockname);
565 return swrap.fns.libc_getsockname(sockfd, addr, addrlen);
568 static int libc_getsockopt(int sockfd,
574 swrap_load_lib_function(SWRAP_LIBSOCKET, getsockopt);
576 return swrap.fns.libc_getsockopt(sockfd, level, optname, optval, optlen);
579 static int libc_vioctl(int d, unsigned long int request, va_list ap)
585 swrap_load_lib_function(SWRAP_LIBC, ioctl);
587 for (i = 0; i < 4; i++) {
588 args[i] = va_arg(ap, long int);
591 rc = swrap.fns.libc_ioctl(d,
601 static int libc_listen(int sockfd, int backlog)
603 swrap_load_lib_function(SWRAP_LIBSOCKET, listen);
605 return swrap.fns.libc_listen(sockfd, backlog);
608 static int libc_vopen(const char *pathname, int flags, va_list ap)
613 swrap_load_lib_function(SWRAP_LIBC, open);
615 mode = va_arg(ap, long int);
617 fd = swrap.fns.libc_open(pathname, flags, (mode_t)mode);
622 static int libc_open(const char *pathname, int flags, ...)
628 fd = libc_vopen(pathname, flags, ap);
634 static int libc_pipe(int pipefd[2])
636 swrap_load_lib_function(SWRAP_LIBSOCKET, pipe);
638 return swrap.fns.libc_pipe(pipefd);
641 static int libc_read(int fd, void *buf, size_t count)
643 swrap_load_lib_function(SWRAP_LIBC, read);
645 return swrap.fns.libc_read(fd, buf, count);
648 static ssize_t libc_readv(int fd, const struct iovec *iov, int iovcnt)
650 swrap_load_lib_function(SWRAP_LIBSOCKET, readv);
652 return swrap.fns.libc_readv(fd, iov, iovcnt);
655 static int libc_recv(int sockfd, void *buf, size_t len, int flags)
657 swrap_load_lib_function(SWRAP_LIBSOCKET, recv);
659 return swrap.fns.libc_recv(sockfd, buf, len, flags);
662 static int libc_recvfrom(int sockfd,
666 struct sockaddr *src_addr,
669 swrap_load_lib_function(SWRAP_LIBSOCKET, recvfrom);
671 return swrap.fns.libc_recvfrom(sockfd, buf, len, flags, src_addr, addrlen);
674 static int libc_recvmsg(int sockfd, struct msghdr *msg, int flags)
676 swrap_load_lib_function(SWRAP_LIBSOCKET, recvmsg);
678 return swrap.fns.libc_recvmsg(sockfd, msg, flags);
681 static int libc_send(int sockfd, const void *buf, size_t len, int flags)
683 swrap_load_lib_function(SWRAP_LIBSOCKET, send);
685 return swrap.fns.libc_send(sockfd, buf, len, flags);
688 static int libc_sendmsg(int sockfd, const struct msghdr *msg, int flags)
690 swrap_load_lib_function(SWRAP_LIBSOCKET, sendmsg);
692 return swrap.fns.libc_sendmsg(sockfd, msg, flags);
695 static int libc_sendto(int sockfd,
699 const struct sockaddr *dst_addr,
702 swrap_load_lib_function(SWRAP_LIBSOCKET, sendto);
704 return swrap.fns.libc_sendto(sockfd, buf, len, flags, dst_addr, addrlen);
707 static int libc_setsockopt(int sockfd,
713 swrap_load_lib_function(SWRAP_LIBSOCKET, setsockopt);
715 return swrap.fns.libc_setsockopt(sockfd, level, optname, optval, optlen);
719 static int libc_signalfd(int fd, const sigset_t *mask, int flags)
721 swrap_load_lib_function(SWRAP_LIBSOCKET, signalfd);
723 return swrap.fns.libc_signalfd(fd, mask, flags);
727 static int libc_socket(int domain, int type, int protocol)
729 swrap_load_lib_function(SWRAP_LIBSOCKET, socket);
731 return swrap.fns.libc_socket(domain, type, protocol);
734 static int libc_socketpair(int domain, int type, int protocol, int sv[2])
736 swrap_load_lib_function(SWRAP_LIBSOCKET, socketpair);
738 return swrap.fns.libc_socketpair(domain, type, protocol, sv);
741 #ifdef HAVE_TIMERFD_CREATE
742 static int libc_timerfd_create(int clockid, int flags)
744 swrap_load_lib_function(SWRAP_LIBC, timerfd_create);
746 return swrap.fns.libc_timerfd_create(clockid, flags);
750 static ssize_t libc_writev(int fd, const struct iovec *iov, int iovcnt)
752 swrap_load_lib_function(SWRAP_LIBSOCKET, writev);
754 return swrap.fns.libc_writev(fd, iov, iovcnt);
757 /*********************************************************
758 * SWRAP HELPER FUNCTIONS
759 *********************************************************/
765 static const struct in6_addr *swrap_ipv6(void)
767 static struct in6_addr v;
768 static int initialized;
776 ret = inet_pton(AF_INET6, "FD00::5357:5F00", &v);
785 static struct sockaddr *sockaddr_dup(const void *data, socklen_t len)
787 struct sockaddr *ret = (struct sockaddr *)malloc(len);
788 memcpy(ret, data, len);
792 static void set_port(int family, int prt, struct sockaddr *addr)
796 ((struct sockaddr_in *)addr)->sin_port = htons(prt);
800 ((struct sockaddr_in6 *)addr)->sin6_port = htons(prt);
806 static size_t socket_length(int family)
810 return sizeof(struct sockaddr_in);
813 return sizeof(struct sockaddr_in6);
819 static const char *socket_wrapper_dir(void)
821 const char *s = getenv("SOCKET_WRAPPER_DIR");
825 if (strncmp(s, "./", 2) == 0) {
829 SWRAP_LOG(SWRAP_LOG_TRACE, "socket_wrapper_dir: %s", s);
833 bool socket_wrapper_enabled(void)
835 const char *s = socket_wrapper_dir();
837 return s != NULL ? true : false;
840 static unsigned int socket_wrapper_default_iface(void)
842 const char *s = getenv("SOCKET_WRAPPER_DEFAULT_IFACE");
845 if (sscanf(s, "%u", &iface) == 1) {
846 if (iface >= 1 && iface <= MAX_WRAPPED_INTERFACES) {
852 return 1;/* 127.0.0.1 */
855 static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, socklen_t *len)
862 p = strrchr(un->sun_path, '/');
863 if (p) p++; else p = un->sun_path;
865 if (sscanf(p, SOCKET_FORMAT, &type, &iface, &prt) != 3) {
870 SWRAP_LOG(SWRAP_LOG_TRACE, "type %c iface %u port %u",
873 if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
884 case SOCKET_TYPE_CHAR_TCP:
885 case SOCKET_TYPE_CHAR_UDP: {
886 struct sockaddr_in *in2 = (struct sockaddr_in *)(void *)in;
888 if ((*len) < sizeof(*in2)) {
893 memset(in2, 0, sizeof(*in2));
894 in2->sin_family = AF_INET;
895 in2->sin_addr.s_addr = htonl((127<<24) | iface);
896 in2->sin_port = htons(prt);
902 case SOCKET_TYPE_CHAR_TCP_V6:
903 case SOCKET_TYPE_CHAR_UDP_V6: {
904 struct sockaddr_in6 *in2 = (struct sockaddr_in6 *)(void *)in;
906 if ((*len) < sizeof(*in2)) {
911 memset(in2, 0, sizeof(*in2));
912 in2->sin6_family = AF_INET6;
913 in2->sin6_addr = *swrap_ipv6();
914 in2->sin6_addr.s6_addr[15] = iface;
915 in2->sin6_port = htons(prt);
929 static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un,
937 if (bcast) *bcast = 0;
939 switch (inaddr->sa_family) {
941 const struct sockaddr_in *in =
942 (const struct sockaddr_in *)(const void *)inaddr;
943 unsigned int addr = ntohl(in->sin_addr.s_addr);
950 u_type = SOCKET_TYPE_CHAR_TCP;
953 u_type = SOCKET_TYPE_CHAR_UDP;
954 a_type = SOCKET_TYPE_CHAR_UDP;
955 b_type = SOCKET_TYPE_CHAR_UDP;
958 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
959 errno = ESOCKTNOSUPPORT;
963 prt = ntohs(in->sin_port);
964 if (a_type && addr == 0xFFFFFFFF) {
965 /* 255.255.255.255 only udp */
968 iface = socket_wrapper_default_iface();
969 } else if (b_type && addr == 0x7FFFFFFF) {
970 /* 127.255.255.255 only udp */
973 iface = socket_wrapper_default_iface();
974 } else if ((addr & 0xFFFFFF00) == 0x7F000000) {
978 iface = (addr & 0x000000FF);
983 if (bcast) *bcast = is_bcast;
988 const struct sockaddr_in6 *in =
989 (const struct sockaddr_in6 *)(const void *)inaddr;
990 struct in6_addr cmp1, cmp2;
994 type = SOCKET_TYPE_CHAR_TCP_V6;
997 type = SOCKET_TYPE_CHAR_UDP_V6;
1000 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1001 errno = ESOCKTNOSUPPORT;
1005 /* XXX no multicast/broadcast */
1007 prt = ntohs(in->sin6_port);
1009 cmp1 = *swrap_ipv6();
1010 cmp2 = in->sin6_addr;
1011 cmp2.s6_addr[15] = 0;
1012 if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
1013 iface = in->sin6_addr.s6_addr[15];
1015 errno = ENETUNREACH;
1023 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family!\n");
1024 errno = ENETUNREACH;
1029 SWRAP_LOG(SWRAP_LOG_WARN, "Port not set\n");
1035 snprintf(un->sun_path, sizeof(un->sun_path), "%s/EINVAL",
1036 socket_wrapper_dir());
1037 SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
1038 /* the caller need to do more processing */
1042 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT,
1043 socket_wrapper_dir(), type, iface, prt);
1044 SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
1049 static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un,
1058 if (bcast) *bcast = 0;
1060 switch (si->family) {
1062 const struct sockaddr_in *in =
1063 (const struct sockaddr_in *)(const void *)inaddr;
1064 unsigned int addr = ntohl(in->sin_addr.s_addr);
1070 prt = ntohs(in->sin_port);
1074 u_type = SOCKET_TYPE_CHAR_TCP;
1075 d_type = SOCKET_TYPE_CHAR_TCP;
1078 u_type = SOCKET_TYPE_CHAR_UDP;
1079 d_type = SOCKET_TYPE_CHAR_UDP;
1080 a_type = SOCKET_TYPE_CHAR_UDP;
1081 b_type = SOCKET_TYPE_CHAR_UDP;
1084 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1085 errno = ESOCKTNOSUPPORT;
1093 iface = socket_wrapper_default_iface();
1094 } else if (a_type && addr == 0xFFFFFFFF) {
1095 /* 255.255.255.255 only udp */
1098 iface = socket_wrapper_default_iface();
1099 } else if (b_type && addr == 0x7FFFFFFF) {
1100 /* 127.255.255.255 only udp */
1103 iface = socket_wrapper_default_iface();
1104 } else if ((addr & 0xFFFFFF00) == 0x7F000000) {
1108 iface = (addr & 0x000000FF);
1110 errno = EADDRNOTAVAIL;
1114 /* Store the bind address for connect() */
1115 if (si->bindname == NULL) {
1116 struct sockaddr_in bind_in;
1117 socklen_t blen = sizeof(struct sockaddr_in);
1119 ZERO_STRUCT(bind_in);
1120 bind_in.sin_family = in->sin_family;
1121 bind_in.sin_port = in->sin_port;
1122 bind_in.sin_addr.s_addr = htonl(0x7F000000 | iface);
1124 si->bindname = sockaddr_dup(&bind_in, blen);
1125 si->bindname_len = blen;
1132 const struct sockaddr_in6 *in =
1133 (const struct sockaddr_in6 *)(const void *)inaddr;
1134 struct in6_addr cmp1, cmp2;
1138 type = SOCKET_TYPE_CHAR_TCP_V6;
1141 type = SOCKET_TYPE_CHAR_UDP_V6;
1144 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1145 errno = ESOCKTNOSUPPORT;
1149 /* XXX no multicast/broadcast */
1151 prt = ntohs(in->sin6_port);
1153 cmp1 = *swrap_ipv6();
1154 cmp2 = in->sin6_addr;
1155 cmp2.s6_addr[15] = 0;
1156 if (IN6_IS_ADDR_UNSPECIFIED(&in->sin6_addr)) {
1157 iface = socket_wrapper_default_iface();
1158 } else if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
1159 iface = in->sin6_addr.s6_addr[15];
1161 errno = EADDRNOTAVAIL;
1165 /* Store the bind address for connect() */
1166 if (si->bindname == NULL) {
1167 struct sockaddr_in6 bind_in;
1168 socklen_t blen = sizeof(struct sockaddr_in6);
1170 ZERO_STRUCT(bind_in);
1171 bind_in.sin6_family = in->sin6_family;
1172 bind_in.sin6_port = in->sin6_port;
1174 bind_in.sin6_addr = *swrap_ipv6();
1175 bind_in.sin6_addr.s6_addr[15] = iface;
1177 si->bindname = sockaddr_dup(&bind_in, blen);
1178 si->bindname_len = blen;
1185 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n");
1186 errno = EADDRNOTAVAIL;
1191 if (bcast) *bcast = is_bcast;
1193 if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
1199 /* handle auto-allocation of ephemeral ports */
1200 for (prt = 5001; prt < 10000; prt++) {
1201 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT,
1202 socket_wrapper_dir(), type, iface, prt);
1203 if (stat(un->sun_path, &st) == 0) continue;
1205 set_port(si->family, prt, si->myname);
1206 set_port(si->family, prt, si->bindname);
1216 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT,
1217 socket_wrapper_dir(), type, iface, prt);
1218 SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
1222 static struct socket_info *find_socket_info(int fd)
1224 struct socket_info *i;
1226 for (i = sockets; i; i = i->next) {
1227 struct socket_info_fd *f;
1228 for (f = i->fds; f; f = f->next) {
1238 static void swrap_remove_stale(int fd)
1240 struct socket_info *si = find_socket_info(fd);
1241 struct socket_info_fd *fi;
1244 for (fi = si->fds; fi; fi = fi->next) {
1246 SWRAP_LOG(SWRAP_LOG_TRACE, "remove stale wrapper for %d", fd);
1247 SWRAP_DLIST_REMOVE(si->fds, fi);
1253 if (si->fds == NULL) {
1254 SWRAP_DLIST_REMOVE(sockets, si);
1259 static int sockaddr_convert_to_un(struct socket_info *si,
1260 const struct sockaddr *in_addr,
1262 struct sockaddr_un *out_addr,
1266 struct sockaddr *out = (struct sockaddr *)(void *)out_addr;
1268 (void) in_len; /* unused */
1270 if (out_addr == NULL) {
1274 out->sa_family = AF_UNIX;
1275 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
1276 out->sa_len = sizeof(*out_addr);
1279 switch (in_addr->sa_family) {
1289 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1290 errno = ESOCKTNOSUPPORT;
1294 return convert_in_un_alloc(si, in_addr, out_addr, bcast);
1296 return convert_in_un_remote(si, in_addr, out_addr, bcast);
1302 errno = EAFNOSUPPORT;
1303 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n");
1307 static int sockaddr_convert_from_un(const struct socket_info *si,
1308 const struct sockaddr_un *in_addr,
1309 socklen_t un_addrlen,
1311 struct sockaddr *out_addr,
1312 socklen_t *out_addrlen)
1316 if (out_addr == NULL || out_addrlen == NULL)
1319 if (un_addrlen == 0) {
1334 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1335 errno = ESOCKTNOSUPPORT;
1338 ret = convert_un_in(in_addr, out_addr, out_addrlen);
1339 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
1340 out_addr->sa_len = *out_addrlen;
1347 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n");
1348 errno = EAFNOSUPPORT;
1352 enum swrap_packet_type {
1354 SWRAP_CONNECT_UNREACH,
1362 SWRAP_SENDTO_UNREACH,
1373 struct swrap_file_hdr {
1375 uint16_t version_major;
1376 uint16_t version_minor;
1379 uint32_t frame_max_len;
1380 #define SWRAP_FRAME_LENGTH_MAX 0xFFFF
1383 #define SWRAP_FILE_HDR_SIZE 24
1385 struct swrap_packet_frame {
1387 uint32_t micro_seconds;
1388 uint32_t recorded_length;
1389 uint32_t full_length;
1391 #define SWRAP_PACKET_FRAME_SIZE 16
1393 union swrap_packet_ip {
1397 uint16_t packet_length;
1398 uint16_t identification;
1403 uint16_t hdr_checksum;
1407 #define SWRAP_PACKET_IP_V4_SIZE 20
1410 uint8_t flow_label_high;
1411 uint16_t flow_label_low;
1412 uint16_t payload_length;
1413 uint8_t next_header;
1415 uint8_t src_addr[16];
1416 uint8_t dest_addr[16];
1418 #define SWRAP_PACKET_IP_V6_SIZE 40
1420 #define SWRAP_PACKET_IP_SIZE 40
1422 union swrap_packet_payload {
1424 uint16_t source_port;
1434 #define SWRAP_PACKET_PAYLOAD_TCP_SIZE 20
1436 uint16_t source_port;
1441 #define SWRAP_PACKET_PAYLOAD_UDP_SIZE 8
1448 #define SWRAP_PACKET_PAYLOAD_ICMP4_SIZE 8
1455 #define SWRAP_PACKET_PAYLOAD_ICMP6_SIZE 8
1457 #define SWRAP_PACKET_PAYLOAD_SIZE 20
1459 #define SWRAP_PACKET_MIN_ALLOC \
1460 (SWRAP_PACKET_FRAME_SIZE + \
1461 SWRAP_PACKET_IP_SIZE + \
1462 SWRAP_PACKET_PAYLOAD_SIZE)
1464 static const char *socket_wrapper_pcap_file(void)
1466 static int initialized = 0;
1467 static const char *s = NULL;
1468 static const struct swrap_file_hdr h;
1469 static const struct swrap_packet_frame f;
1470 static const union swrap_packet_ip i;
1471 static const union swrap_packet_payload p;
1473 if (initialized == 1) {
1479 * TODO: don't use the structs use plain buffer offsets
1480 * and PUSH_U8(), PUSH_U16() and PUSH_U32()
1482 * for now make sure we disable PCAP support
1483 * if the struct has alignment!
1485 if (sizeof(h) != SWRAP_FILE_HDR_SIZE) {
1488 if (sizeof(f) != SWRAP_PACKET_FRAME_SIZE) {
1491 if (sizeof(i) != SWRAP_PACKET_IP_SIZE) {
1494 if (sizeof(i.v4) != SWRAP_PACKET_IP_V4_SIZE) {
1497 if (sizeof(i.v6) != SWRAP_PACKET_IP_V6_SIZE) {
1500 if (sizeof(p) != SWRAP_PACKET_PAYLOAD_SIZE) {
1503 if (sizeof(p.tcp) != SWRAP_PACKET_PAYLOAD_TCP_SIZE) {
1506 if (sizeof(p.udp) != SWRAP_PACKET_PAYLOAD_UDP_SIZE) {
1509 if (sizeof(p.icmp4) != SWRAP_PACKET_PAYLOAD_ICMP4_SIZE) {
1512 if (sizeof(p.icmp6) != SWRAP_PACKET_PAYLOAD_ICMP6_SIZE) {
1516 s = getenv("SOCKET_WRAPPER_PCAP_FILE");
1520 if (strncmp(s, "./", 2) == 0) {
1526 static uint8_t *swrap_packet_init(struct timeval *tval,
1527 const struct sockaddr *src,
1528 const struct sockaddr *dest,
1530 const uint8_t *payload,
1532 unsigned long tcp_seqno,
1533 unsigned long tcp_ack,
1534 unsigned char tcp_ctl,
1536 size_t *_packet_len)
1540 struct swrap_packet_frame *frame;
1541 union swrap_packet_ip *ip;
1542 union swrap_packet_payload *pay;
1545 size_t nonwire_len = sizeof(*frame);
1546 size_t wire_hdr_len = 0;
1547 size_t wire_len = 0;
1548 size_t ip_hdr_len = 0;
1549 size_t icmp_hdr_len = 0;
1550 size_t icmp_truncate_len = 0;
1551 uint8_t protocol = 0, icmp_protocol = 0;
1552 const struct sockaddr_in *src_in = NULL;
1553 const struct sockaddr_in *dest_in = NULL;
1555 const struct sockaddr_in6 *src_in6 = NULL;
1556 const struct sockaddr_in6 *dest_in6 = NULL;
1561 switch (src->sa_family) {
1563 src_in = (const struct sockaddr_in *)src;
1564 dest_in = (const struct sockaddr_in *)dest;
1565 src_port = src_in->sin_port;
1566 dest_port = dest_in->sin_port;
1567 ip_hdr_len = sizeof(ip->v4);
1571 src_in6 = (const struct sockaddr_in6 *)src;
1572 dest_in6 = (const struct sockaddr_in6 *)dest;
1573 src_port = src_in6->sin6_port;
1574 dest_port = dest_in6->sin6_port;
1575 ip_hdr_len = sizeof(ip->v6);
1582 switch (socket_type) {
1584 protocol = 0x06; /* TCP */
1585 wire_hdr_len = ip_hdr_len + sizeof(pay->tcp);
1586 wire_len = wire_hdr_len + payload_len;
1590 protocol = 0x11; /* UDP */
1591 wire_hdr_len = ip_hdr_len + sizeof(pay->udp);
1592 wire_len = wire_hdr_len + payload_len;
1600 icmp_protocol = protocol;
1601 switch (src->sa_family) {
1603 protocol = 0x01; /* ICMPv4 */
1604 icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp4);
1608 protocol = 0x3A; /* ICMPv6 */
1609 icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp6);
1613 if (wire_len > 64 ) {
1614 icmp_truncate_len = wire_len - 64;
1616 wire_hdr_len += icmp_hdr_len;
1617 wire_len += icmp_hdr_len;
1620 packet_len = nonwire_len + wire_len;
1621 alloc_len = packet_len;
1622 if (alloc_len < SWRAP_PACKET_MIN_ALLOC) {
1623 alloc_len = SWRAP_PACKET_MIN_ALLOC;
1626 base = (uint8_t *)malloc(alloc_len);
1630 memset(base, 0x0, alloc_len);
1634 frame = (struct swrap_packet_frame *)buf;
1635 frame->seconds = tval->tv_sec;
1636 frame->micro_seconds = tval->tv_usec;
1637 frame->recorded_length = wire_len - icmp_truncate_len;
1638 frame->full_length = wire_len - icmp_truncate_len;
1639 buf += SWRAP_PACKET_FRAME_SIZE;
1641 ip = (union swrap_packet_ip *)buf;
1642 switch (src->sa_family) {
1644 ip->v4.ver_hdrlen = 0x45; /* version 4 and 5 * 32 bit words */
1646 ip->v4.packet_length = htons(wire_len - icmp_truncate_len);
1647 ip->v4.identification = htons(0xFFFF);
1648 ip->v4.flags = 0x40; /* BIT 1 set - means don't fragment */
1649 ip->v4.fragment = htons(0x0000);
1651 ip->v4.protocol = protocol;
1652 ip->v4.hdr_checksum = htons(0x0000);
1653 ip->v4.src_addr = src_in->sin_addr.s_addr;
1654 ip->v4.dest_addr = dest_in->sin_addr.s_addr;
1655 buf += SWRAP_PACKET_IP_V4_SIZE;
1659 ip->v6.ver_prio = 0x60; /* version 4 and 5 * 32 bit words */
1660 ip->v6.flow_label_high = 0x00;
1661 ip->v6.flow_label_low = 0x0000;
1662 ip->v6.payload_length = htons(wire_len - icmp_truncate_len); /* TODO */
1663 ip->v6.next_header = protocol;
1664 memcpy(ip->v6.src_addr, src_in6->sin6_addr.s6_addr, 16);
1665 memcpy(ip->v6.dest_addr, dest_in6->sin6_addr.s6_addr, 16);
1666 buf += SWRAP_PACKET_IP_V6_SIZE;
1672 pay = (union swrap_packet_payload *)buf;
1673 switch (src->sa_family) {
1675 pay->icmp4.type = 0x03; /* destination unreachable */
1676 pay->icmp4.code = 0x01; /* host unreachable */
1677 pay->icmp4.checksum = htons(0x0000);
1678 pay->icmp4.unused = htonl(0x00000000);
1679 buf += SWRAP_PACKET_PAYLOAD_ICMP4_SIZE;
1681 /* set the ip header in the ICMP payload */
1682 ip = (union swrap_packet_ip *)buf;
1683 ip->v4.ver_hdrlen = 0x45; /* version 4 and 5 * 32 bit words */
1685 ip->v4.packet_length = htons(wire_len - icmp_hdr_len);
1686 ip->v4.identification = htons(0xFFFF);
1687 ip->v4.flags = 0x40; /* BIT 1 set - means don't fragment */
1688 ip->v4.fragment = htons(0x0000);
1690 ip->v4.protocol = icmp_protocol;
1691 ip->v4.hdr_checksum = htons(0x0000);
1692 ip->v4.src_addr = dest_in->sin_addr.s_addr;
1693 ip->v4.dest_addr = src_in->sin_addr.s_addr;
1694 buf += SWRAP_PACKET_IP_V4_SIZE;
1696 src_port = dest_in->sin_port;
1697 dest_port = src_in->sin_port;
1701 pay->icmp6.type = 0x01; /* destination unreachable */
1702 pay->icmp6.code = 0x03; /* address unreachable */
1703 pay->icmp6.checksum = htons(0x0000);
1704 pay->icmp6.unused = htonl(0x00000000);
1705 buf += SWRAP_PACKET_PAYLOAD_ICMP6_SIZE;
1707 /* set the ip header in the ICMP payload */
1708 ip = (union swrap_packet_ip *)buf;
1709 ip->v6.ver_prio = 0x60; /* version 4 and 5 * 32 bit words */
1710 ip->v6.flow_label_high = 0x00;
1711 ip->v6.flow_label_low = 0x0000;
1712 ip->v6.payload_length = htons(wire_len - icmp_truncate_len); /* TODO */
1713 ip->v6.next_header = protocol;
1714 memcpy(ip->v6.src_addr, dest_in6->sin6_addr.s6_addr, 16);
1715 memcpy(ip->v6.dest_addr, src_in6->sin6_addr.s6_addr, 16);
1716 buf += SWRAP_PACKET_IP_V6_SIZE;
1718 src_port = dest_in6->sin6_port;
1719 dest_port = src_in6->sin6_port;
1725 pay = (union swrap_packet_payload *)buf;
1727 switch (socket_type) {
1729 pay->tcp.source_port = src_port;
1730 pay->tcp.dest_port = dest_port;
1731 pay->tcp.seq_num = htonl(tcp_seqno);
1732 pay->tcp.ack_num = htonl(tcp_ack);
1733 pay->tcp.hdr_length = 0x50; /* 5 * 32 bit words */
1734 pay->tcp.control = tcp_ctl;
1735 pay->tcp.window = htons(0x7FFF);
1736 pay->tcp.checksum = htons(0x0000);
1737 pay->tcp.urg = htons(0x0000);
1738 buf += SWRAP_PACKET_PAYLOAD_TCP_SIZE;
1743 pay->udp.source_port = src_port;
1744 pay->udp.dest_port = dest_port;
1745 pay->udp.length = htons(8 + payload_len);
1746 pay->udp.checksum = htons(0x0000);
1747 buf += SWRAP_PACKET_PAYLOAD_UDP_SIZE;
1752 if (payload && payload_len > 0) {
1753 memcpy(buf, payload, payload_len);
1756 *_packet_len = packet_len - icmp_truncate_len;
1760 static int swrap_get_pcap_fd(const char *fname)
1764 if (fd != -1) return fd;
1766 fd = libc_open(fname, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0644);
1768 struct swrap_file_hdr file_hdr;
1769 file_hdr.magic = 0xA1B2C3D4;
1770 file_hdr.version_major = 0x0002;
1771 file_hdr.version_minor = 0x0004;
1772 file_hdr.timezone = 0x00000000;
1773 file_hdr.sigfigs = 0x00000000;
1774 file_hdr.frame_max_len = SWRAP_FRAME_LENGTH_MAX;
1775 file_hdr.link_type = 0x0065; /* 101 RAW IP */
1777 if (write(fd, &file_hdr, sizeof(file_hdr)) != sizeof(file_hdr)) {
1784 fd = libc_open(fname, O_WRONLY|O_APPEND, 0644);
1789 static uint8_t *swrap_marshall_packet(struct socket_info *si,
1790 const struct sockaddr *addr,
1791 enum swrap_packet_type type,
1792 const void *buf, size_t len,
1795 const struct sockaddr *src_addr;
1796 const struct sockaddr *dest_addr;
1797 unsigned long tcp_seqno = 0;
1798 unsigned long tcp_ack = 0;
1799 unsigned char tcp_ctl = 0;
1800 int unreachable = 0;
1804 switch (si->family) {
1816 case SWRAP_CONNECT_SEND:
1817 if (si->type != SOCK_STREAM) return NULL;
1819 src_addr = si->myname;
1822 tcp_seqno = si->io.pck_snd;
1823 tcp_ack = si->io.pck_rcv;
1824 tcp_ctl = 0x02; /* SYN */
1826 si->io.pck_snd += 1;
1830 case SWRAP_CONNECT_RECV:
1831 if (si->type != SOCK_STREAM) return NULL;
1833 dest_addr = si->myname;
1836 tcp_seqno = si->io.pck_rcv;
1837 tcp_ack = si->io.pck_snd;
1838 tcp_ctl = 0x12; /** SYN,ACK */
1840 si->io.pck_rcv += 1;
1844 case SWRAP_CONNECT_UNREACH:
1845 if (si->type != SOCK_STREAM) return NULL;
1847 dest_addr = si->myname;
1850 /* Unreachable: resend the data of SWRAP_CONNECT_SEND */
1851 tcp_seqno = si->io.pck_snd - 1;
1852 tcp_ack = si->io.pck_rcv;
1853 tcp_ctl = 0x02; /* SYN */
1858 case SWRAP_CONNECT_ACK:
1859 if (si->type != SOCK_STREAM) return NULL;
1861 src_addr = si->myname;
1864 tcp_seqno = si->io.pck_snd;
1865 tcp_ack = si->io.pck_rcv;
1866 tcp_ctl = 0x10; /* ACK */
1870 case SWRAP_ACCEPT_SEND:
1871 if (si->type != SOCK_STREAM) return NULL;
1873 dest_addr = si->myname;
1876 tcp_seqno = si->io.pck_rcv;
1877 tcp_ack = si->io.pck_snd;
1878 tcp_ctl = 0x02; /* SYN */
1880 si->io.pck_rcv += 1;
1884 case SWRAP_ACCEPT_RECV:
1885 if (si->type != SOCK_STREAM) return NULL;
1887 src_addr = si->myname;
1890 tcp_seqno = si->io.pck_snd;
1891 tcp_ack = si->io.pck_rcv;
1892 tcp_ctl = 0x12; /* SYN,ACK */
1894 si->io.pck_snd += 1;
1898 case SWRAP_ACCEPT_ACK:
1899 if (si->type != SOCK_STREAM) return NULL;
1901 dest_addr = si->myname;
1904 tcp_seqno = si->io.pck_rcv;
1905 tcp_ack = si->io.pck_snd;
1906 tcp_ctl = 0x10; /* ACK */
1911 src_addr = si->myname;
1912 dest_addr = si->peername;
1914 tcp_seqno = si->io.pck_snd;
1915 tcp_ack = si->io.pck_rcv;
1916 tcp_ctl = 0x18; /* PSH,ACK */
1918 si->io.pck_snd += len;
1922 case SWRAP_SEND_RST:
1923 dest_addr = si->myname;
1924 src_addr = si->peername;
1926 if (si->type == SOCK_DGRAM) {
1927 return swrap_marshall_packet(si, si->peername,
1928 SWRAP_SENDTO_UNREACH,
1929 buf, len, packet_len);
1932 tcp_seqno = si->io.pck_rcv;
1933 tcp_ack = si->io.pck_snd;
1934 tcp_ctl = 0x14; /** RST,ACK */
1938 case SWRAP_PENDING_RST:
1939 dest_addr = si->myname;
1940 src_addr = si->peername;
1942 if (si->type == SOCK_DGRAM) {
1946 tcp_seqno = si->io.pck_rcv;
1947 tcp_ack = si->io.pck_snd;
1948 tcp_ctl = 0x14; /* RST,ACK */
1953 dest_addr = si->myname;
1954 src_addr = si->peername;
1956 tcp_seqno = si->io.pck_rcv;
1957 tcp_ack = si->io.pck_snd;
1958 tcp_ctl = 0x18; /* PSH,ACK */
1960 si->io.pck_rcv += len;
1964 case SWRAP_RECV_RST:
1965 dest_addr = si->myname;
1966 src_addr = si->peername;
1968 if (si->type == SOCK_DGRAM) {
1972 tcp_seqno = si->io.pck_rcv;
1973 tcp_ack = si->io.pck_snd;
1974 tcp_ctl = 0x14; /* RST,ACK */
1979 src_addr = si->myname;
1982 si->io.pck_snd += len;
1986 case SWRAP_SENDTO_UNREACH:
1987 dest_addr = si->myname;
1994 case SWRAP_RECVFROM:
1995 dest_addr = si->myname;
1998 si->io.pck_rcv += len;
2002 case SWRAP_CLOSE_SEND:
2003 if (si->type != SOCK_STREAM) return NULL;
2005 src_addr = si->myname;
2006 dest_addr = si->peername;
2008 tcp_seqno = si->io.pck_snd;
2009 tcp_ack = si->io.pck_rcv;
2010 tcp_ctl = 0x11; /* FIN, ACK */
2012 si->io.pck_snd += 1;
2016 case SWRAP_CLOSE_RECV:
2017 if (si->type != SOCK_STREAM) return NULL;
2019 dest_addr = si->myname;
2020 src_addr = si->peername;
2022 tcp_seqno = si->io.pck_rcv;
2023 tcp_ack = si->io.pck_snd;
2024 tcp_ctl = 0x11; /* FIN,ACK */
2026 si->io.pck_rcv += 1;
2030 case SWRAP_CLOSE_ACK:
2031 if (si->type != SOCK_STREAM) return NULL;
2033 src_addr = si->myname;
2034 dest_addr = si->peername;
2036 tcp_seqno = si->io.pck_snd;
2037 tcp_ack = si->io.pck_rcv;
2038 tcp_ctl = 0x10; /* ACK */
2045 swrapGetTimeOfDay(&tv);
2047 return swrap_packet_init(&tv, src_addr, dest_addr, si->type,
2048 (const uint8_t *)buf, len,
2049 tcp_seqno, tcp_ack, tcp_ctl, unreachable,
2053 static void swrap_dump_packet(struct socket_info *si,
2054 const struct sockaddr *addr,
2055 enum swrap_packet_type type,
2056 const void *buf, size_t len)
2058 const char *file_name;
2060 size_t packet_len = 0;
2063 file_name = socket_wrapper_pcap_file();
2068 packet = swrap_marshall_packet(si, addr, type, buf, len, &packet_len);
2073 fd = swrap_get_pcap_fd(file_name);
2075 if (write(fd, packet, packet_len) != (ssize_t)packet_len) {
2084 /****************************************************************************
2086 ***************************************************************************/
2088 #ifdef HAVE_SIGNALFD
2089 static int swrap_signalfd(int fd, const sigset_t *mask, int flags)
2093 rc = libc_signalfd(fd, mask, flags);
2095 swrap_remove_stale(fd);
2101 int signalfd(int fd, const sigset_t *mask, int flags)
2103 return swrap_signalfd(fd, mask, flags);
2107 /****************************************************************************
2109 ***************************************************************************/
2111 static int swrap_socket(int family, int type, int protocol)
2113 struct socket_info *si;
2114 struct socket_info_fd *fi;
2116 int real_type = type;
2119 * Remove possible addition flags passed to socket() so
2120 * do not fail checking the type.
2121 * See https://lwn.net/Articles/281965/
2124 real_type &= ~SOCK_CLOEXEC;
2126 #ifdef SOCK_NONBLOCK
2127 real_type &= ~SOCK_NONBLOCK;
2130 if (!socket_wrapper_enabled()) {
2131 return libc_socket(family, type, protocol);
2141 return libc_socket(family, type, protocol);
2143 errno = EAFNOSUPPORT;
2147 switch (real_type) {
2153 errno = EPROTONOSUPPORT;
2161 if (real_type == SOCK_STREAM) {
2166 if (real_type == SOCK_DGRAM) {
2171 errno = EPROTONOSUPPORT;
2176 * We must call libc_socket with type, from the caller, not the version
2177 * we removed SOCK_CLOEXEC and SOCK_NONBLOCK from
2179 fd = libc_socket(AF_UNIX, type, 0);
2185 /* Check if we have a stale fd and remove it */
2186 si = find_socket_info(fd);
2188 swrap_remove_stale(fd);
2191 si = (struct socket_info *)malloc(sizeof(struct socket_info));
2192 memset(si, 0, sizeof(struct socket_info));
2198 si->family = family;
2200 /* however, the rest of the socket_wrapper code expects just
2201 * the type, not the flags */
2202 si->type = real_type;
2203 si->protocol = protocol;
2205 fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
2214 SWRAP_DLIST_ADD(si->fds, fi);
2215 SWRAP_DLIST_ADD(sockets, si);
2220 int socket(int family, int type, int protocol)
2222 return swrap_socket(family, type, protocol);
2225 /****************************************************************************
2227 ***************************************************************************/
2229 static int swrap_socketpair(int family, int type, int protocol, int sv[2])
2233 rc = libc_socketpair(family, type, protocol, sv);
2235 swrap_remove_stale(sv[0]);
2236 swrap_remove_stale(sv[1]);
2242 int socketpair(int family, int type, int protocol, int sv[2])
2244 return swrap_socketpair(family, type, protocol, sv);
2247 /****************************************************************************
2249 ***************************************************************************/
2251 #ifdef HAVE_TIMERFD_CREATE
2252 static int swrap_timerfd_create(int clockid, int flags)
2256 fd = libc_timerfd_create(clockid, flags);
2258 swrap_remove_stale(fd);
2264 int timerfd_create(int clockid, int flags)
2266 return swrap_timerfd_create(clockid, flags);
2270 /****************************************************************************
2272 ***************************************************************************/
2274 static int swrap_pipe(int pipefd[2])
2278 rc = libc_pipe(pipefd);
2280 swrap_remove_stale(pipefd[0]);
2281 swrap_remove_stale(pipefd[1]);
2287 int pipe(int pipefd[2])
2289 return swrap_pipe(pipefd);
2292 /****************************************************************************
2294 ***************************************************************************/
2296 static int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
2298 struct socket_info *parent_si, *child_si;
2299 struct socket_info_fd *child_fi;
2301 struct sockaddr_un un_addr;
2302 socklen_t un_addrlen = sizeof(un_addr);
2303 struct sockaddr_un un_my_addr;
2304 socklen_t un_my_addrlen = sizeof(un_my_addr);
2305 struct sockaddr *my_addr;
2306 socklen_t my_addrlen, len;
2309 parent_si = find_socket_info(s);
2311 return libc_accept(s, addr, addrlen);
2315 * assume out sockaddr have the same size as the in parent
2318 my_addrlen = socket_length(parent_si->family);
2319 if (my_addrlen <= 0) {
2324 my_addr = (struct sockaddr *)malloc(my_addrlen);
2325 if (my_addr == NULL) {
2329 memset(&un_addr, 0, sizeof(un_addr));
2330 memset(&un_my_addr, 0, sizeof(un_my_addr));
2332 ret = libc_accept(s, (struct sockaddr *)(void *)&un_addr, &un_addrlen);
2334 if (errno == ENOTSOCK) {
2335 /* Remove stale fds */
2336 swrap_remove_stale(s);
2345 ret = sockaddr_convert_from_un(parent_si, &un_addr, un_addrlen,
2346 parent_si->family, my_addr, &len);
2353 child_si = (struct socket_info *)malloc(sizeof(struct socket_info));
2354 memset(child_si, 0, sizeof(struct socket_info));
2356 child_fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
2357 if (child_fi == NULL) {
2367 SWRAP_DLIST_ADD(child_si->fds, child_fi);
2369 child_si->family = parent_si->family;
2370 child_si->type = parent_si->type;
2371 child_si->protocol = parent_si->protocol;
2372 child_si->bound = 1;
2373 child_si->is_server = 1;
2374 child_si->connected = 1;
2376 child_si->peername_len = len;
2377 child_si->peername = sockaddr_dup(my_addr, len);
2379 if (addr != NULL && addrlen != NULL) {
2380 size_t copy_len = MIN(*addrlen, len);
2382 memcpy(addr, my_addr, copy_len);
2387 ret = libc_getsockname(fd,
2388 (struct sockaddr *)(void *)&un_my_addr,
2399 ret = sockaddr_convert_from_un(child_si, &un_my_addr, un_my_addrlen,
2400 child_si->family, my_addr, &len);
2409 SWRAP_LOG(SWRAP_LOG_TRACE,
2410 "accept() path=%s, fd=%d",
2411 un_my_addr.sun_path, s);
2413 child_si->myname_len = len;
2414 child_si->myname = sockaddr_dup(my_addr, len);
2417 SWRAP_DLIST_ADD(sockets, child_si);
2420 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0);
2421 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_RECV, NULL, 0);
2422 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_ACK, NULL, 0);
2428 #ifdef HAVE_ACCEPT_PSOCKLEN_T
2429 int accept(int s, struct sockaddr *addr, Psocklen_t addrlen)
2431 int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
2434 return swrap_accept(s, addr, (socklen_t *)addrlen);
2437 static int autobind_start_init;
2438 static int autobind_start;
2440 /* using sendto() or connect() on an unbound socket would give the
2441 recipient no way to reply, as unlike UDP and TCP, a unix domain
2442 socket can't auto-assign ephemeral port numbers, so we need to
2444 Note: this might change the family from ipv6 to ipv4
2446 static int swrap_auto_bind(int fd, struct socket_info *si, int family)
2448 struct sockaddr_un un_addr;
2455 if (autobind_start_init != 1) {
2456 autobind_start_init = 1;
2457 autobind_start = getpid();
2458 autobind_start %= 50000;
2459 autobind_start += 10000;
2462 un_addr.sun_family = AF_UNIX;
2466 struct sockaddr_in in;
2470 type = SOCKET_TYPE_CHAR_TCP;
2473 type = SOCKET_TYPE_CHAR_UDP;
2476 errno = ESOCKTNOSUPPORT;
2480 memset(&in, 0, sizeof(in));
2481 in.sin_family = AF_INET;
2482 in.sin_addr.s_addr = htonl(127<<24 |
2483 socket_wrapper_default_iface());
2485 si->myname_len = sizeof(in);
2486 si->myname = sockaddr_dup(&in, si->myname_len);
2491 struct sockaddr_in6 in6;
2493 if (si->family != family) {
2494 errno = ENETUNREACH;
2500 type = SOCKET_TYPE_CHAR_TCP_V6;
2503 type = SOCKET_TYPE_CHAR_UDP_V6;
2506 errno = ESOCKTNOSUPPORT;
2510 memset(&in6, 0, sizeof(in6));
2511 in6.sin6_family = AF_INET6;
2512 in6.sin6_addr = *swrap_ipv6();
2513 in6.sin6_addr.s6_addr[15] = socket_wrapper_default_iface();
2514 si->myname_len = sizeof(in6);
2515 si->myname = sockaddr_dup(&in6, si->myname_len);
2520 errno = ESOCKTNOSUPPORT;
2524 if (autobind_start > 60000) {
2525 autobind_start = 10000;
2528 for (i = 0; i < SOCKET_MAX_SOCKETS; i++) {
2529 port = autobind_start + i;
2530 snprintf(un_addr.sun_path, sizeof(un_addr.sun_path),
2531 "%s/"SOCKET_FORMAT, socket_wrapper_dir(),
2532 type, socket_wrapper_default_iface(), port);
2533 if (stat(un_addr.sun_path, &st) == 0) continue;
2535 ret = libc_bind(fd, (struct sockaddr *)(void *)&un_addr,
2537 if (ret == -1) return ret;
2539 si->tmp_path = strdup(un_addr.sun_path);
2541 autobind_start = port + 1;
2544 if (i == SOCKET_MAX_SOCKETS) {
2545 SWRAP_LOG(SWRAP_LOG_ERROR, "Too many open unix sockets (%u) for "
2546 "interface "SOCKET_FORMAT,
2549 socket_wrapper_default_iface(),
2555 si->family = family;
2556 set_port(si->family, port, si->myname);
2561 /****************************************************************************
2563 ***************************************************************************/
2565 static int swrap_connect(int s, const struct sockaddr *serv_addr,
2569 struct sockaddr_un un_addr;
2570 struct socket_info *si = find_socket_info(s);
2574 return libc_connect(s, serv_addr, addrlen);
2577 if (si->bound == 0) {
2578 ret = swrap_auto_bind(s, si, serv_addr->sa_family);
2579 if (ret == -1) return -1;
2582 if (si->family != serv_addr->sa_family) {
2587 ret = sockaddr_convert_to_un(si, serv_addr,
2588 addrlen, &un_addr, 0, &bcast);
2589 if (ret == -1) return -1;
2592 errno = ENETUNREACH;
2596 if (si->type == SOCK_DGRAM) {
2597 si->defer_connect = 1;
2600 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0);
2602 ret = libc_connect(s,
2603 (struct sockaddr *)(void *)&un_addr,
2604 sizeof(struct sockaddr_un));
2607 SWRAP_LOG(SWRAP_LOG_TRACE,
2608 "connect() path=%s, fd=%d",
2609 un_addr.sun_path, s);
2612 /* to give better errors */
2613 if (ret == -1 && errno == ENOENT) {
2614 errno = EHOSTUNREACH;
2618 si->peername_len = addrlen;
2619 si->peername = sockaddr_dup(serv_addr, addrlen);
2623 * When we connect() on a socket than we have to bind the
2624 * outgoing connection on the interface we use for the
2625 * transport. We already bound it on the right interface
2626 * but here we have to update the name so getsockname()
2627 * returns correct information.
2629 if (si->bindname != NULL) {
2632 si->myname = si->bindname;
2633 si->myname_len = si->bindname_len;
2635 si->bindname = NULL;
2636 si->bindname_len = 0;
2639 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0);
2640 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0);
2642 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0);
2648 int connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen)
2650 return swrap_connect(s, serv_addr, addrlen);
2653 /****************************************************************************
2655 ***************************************************************************/
2657 static int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
2660 struct sockaddr_un un_addr;
2661 struct socket_info *si = find_socket_info(s);
2664 return libc_bind(s, myaddr, addrlen);
2667 si->myname_len = addrlen;
2668 si->myname = sockaddr_dup(myaddr, addrlen);
2670 ret = sockaddr_convert_to_un(si, myaddr, addrlen, &un_addr, 1, &si->bcast);
2671 if (ret == -1) return -1;
2673 unlink(un_addr.sun_path);
2675 ret = libc_bind(s, (struct sockaddr *)(void *)&un_addr,
2676 sizeof(struct sockaddr_un));
2678 SWRAP_LOG(SWRAP_LOG_TRACE,
2679 "bind() path=%s, fd=%d",
2680 un_addr.sun_path, s);
2689 int bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
2691 return swrap_bind(s, myaddr, addrlen);
2694 /****************************************************************************
2696 ***************************************************************************/
2698 static int swrap_listen(int s, int backlog)
2701 struct socket_info *si = find_socket_info(s);
2704 return libc_listen(s, backlog);
2707 ret = libc_listen(s, backlog);
2712 int listen(int s, int backlog)
2714 return swrap_listen(s, backlog);
2717 /****************************************************************************
2719 ***************************************************************************/
2721 static int swrap_vopen(const char *pathname, int flags, va_list ap)
2725 ret = libc_vopen(pathname, flags, ap);
2728 * There are methods for closing descriptors (libc-internal code
2729 * paths, direct syscalls) which close descriptors in ways that
2730 * we can't intercept, so try to recover when we notice that
2733 swrap_remove_stale(ret);
2738 int open(const char *pathname, int flags, ...)
2743 va_start(ap, flags);
2744 fd = swrap_vopen(pathname, flags, ap);
2750 /****************************************************************************
2752 ***************************************************************************/
2754 static int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
2756 struct socket_info *si = find_socket_info(s);
2759 return libc_getpeername(s, name, addrlen);
2768 memcpy(name, si->peername, si->peername_len);
2769 *addrlen = si->peername_len;
2774 #ifdef HAVE_ACCEPT_PSOCKLEN_T
2775 int getpeername(int s, struct sockaddr *name, Psocklen_t addrlen)
2777 int getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
2780 return swrap_getpeername(s, name, (socklen_t *)addrlen);
2783 /****************************************************************************
2785 ***************************************************************************/
2787 static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
2789 struct socket_info *si = find_socket_info(s);
2792 return libc_getsockname(s, name, addrlen);
2795 memcpy(name, si->myname, si->myname_len);
2796 *addrlen = si->myname_len;
2801 #ifdef HAVE_ACCEPT_PSOCKLEN_T
2802 int getsockname(int s, struct sockaddr *name, Psocklen_t addrlen)
2804 int getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
2807 return swrap_getsockname(s, name, (socklen_t *)addrlen);
2810 /****************************************************************************
2812 ***************************************************************************/
2814 static int swrap_getsockopt(int s, int level, int optname,
2815 void *optval, socklen_t *optlen)
2817 struct socket_info *si = find_socket_info(s);
2820 return libc_getsockopt(s,
2827 if (level == SOL_SOCKET) {
2828 return libc_getsockopt(s,
2835 errno = ENOPROTOOPT;
2839 #ifdef HAVE_ACCEPT_PSOCKLEN_T
2840 int getsockopt(int s, int level, int optname, void *optval, Psocklen_t optlen)
2842 int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
2845 return swrap_getsockopt(s, level, optname, optval, (socklen_t *)optlen);
2848 /****************************************************************************
2850 ***************************************************************************/
2852 static int swrap_setsockopt(int s, int level, int optname,
2853 const void *optval, socklen_t optlen)
2855 struct socket_info *si = find_socket_info(s);
2858 return libc_setsockopt(s,
2865 if (level == SOL_SOCKET) {
2866 return libc_setsockopt(s,
2873 switch (si->family) {
2881 errno = ENOPROTOOPT;
2886 int setsockopt(int s, int level, int optname,
2887 const void *optval, socklen_t optlen)
2889 return swrap_setsockopt(s, level, optname, optval, optlen);
2892 /****************************************************************************
2894 ***************************************************************************/
2896 static int swrap_vioctl(int s, unsigned long int r, va_list va)
2898 struct socket_info *si = find_socket_info(s);
2904 return libc_vioctl(s, r, va);
2909 rc = libc_vioctl(s, r, va);
2913 value = *((int *)va_arg(ap, int *));
2915 if (rc == -1 && errno != EAGAIN && errno != ENOBUFS) {
2916 swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
2917 } else if (value == 0) { /* END OF FILE */
2918 swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
2928 #ifdef HAVE_IOCTL_INT
2929 int ioctl(int s, int r, ...)
2931 int ioctl(int s, unsigned long int r, ...)
2939 rc = swrap_vioctl(s, (unsigned long int) r, va);
2946 static ssize_t swrap_sendmsg_before(int fd,
2947 struct socket_info *si,
2949 struct iovec *tmp_iov,
2950 struct sockaddr_un *tmp_un,
2951 const struct sockaddr_un **to_un,
2952 const struct sockaddr **to,
2970 if (!si->connected) {
2975 if (msg->msg_iovlen == 0) {
2979 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
2981 nlen = len + msg->msg_iov[i].iov_len;
2982 if (nlen > SOCKET_MAX_PACKET) {
2986 msg->msg_iovlen = i;
2987 if (msg->msg_iovlen == 0) {
2988 *tmp_iov = msg->msg_iov[0];
2989 tmp_iov->iov_len = MIN(tmp_iov->iov_len, SOCKET_MAX_PACKET);
2990 msg->msg_iov = tmp_iov;
2991 msg->msg_iovlen = 1;
2996 if (si->connected) {
2997 if (msg->msg_name) {
3002 const struct sockaddr *msg_name;
3003 msg_name = (const struct sockaddr *)msg->msg_name;
3005 if (msg_name == NULL) {
3011 ret = sockaddr_convert_to_un(si, msg_name, msg->msg_namelen,
3013 if (ret == -1) return -1;
3021 msg->msg_name = tmp_un;
3022 msg->msg_namelen = sizeof(*tmp_un);
3025 if (si->bound == 0) {
3026 ret = swrap_auto_bind(fd, si, si->family);
3028 if (errno == ENOTSOCK) {
3029 swrap_remove_stale(fd);
3032 SWRAP_LOG(SWRAP_LOG_ERROR, "swrap_sendmsg_before failed");
3038 if (!si->defer_connect) {
3042 ret = sockaddr_convert_to_un(si, si->peername, si->peername_len,
3044 if (ret == -1) return -1;
3046 ret = libc_connect(fd,
3047 (struct sockaddr *)(void *)tmp_un,
3050 /* to give better errors */
3051 if (ret == -1 && errno == ENOENT) {
3052 errno = EHOSTUNREACH;
3059 si->defer_connect = 0;
3062 errno = EHOSTUNREACH;
3069 static void swrap_sendmsg_after(int fd,
3070 struct socket_info *si,
3072 const struct sockaddr *to,
3075 int saved_errno = errno;
3082 /* to give better errors */
3084 if (saved_errno == ENOENT) {
3085 saved_errno = EHOSTUNREACH;
3086 } else if (saved_errno == ENOTSOCK) {
3087 /* If the fd is not a socket, remove it */
3088 swrap_remove_stale(fd);
3092 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3093 avail += msg->msg_iov[i].iov_len;
3097 remain = MIN(80, avail);
3102 /* we capture it as one single packet */
3103 buf = (uint8_t *)malloc(remain);
3105 /* we just not capture the packet */
3106 errno = saved_errno;
3110 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3111 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
3113 msg->msg_iov[i].iov_base,
3116 remain -= this_time;
3123 swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
3124 swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
3126 swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
3131 if (si->connected) {
3135 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
3136 swrap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);
3138 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
3144 errno = saved_errno;
3147 static int swrap_recvmsg_before(int fd,
3148 struct socket_info *si,
3150 struct iovec *tmp_iov)
3155 (void)fd; /* unused */
3159 if (!si->connected) {
3164 if (msg->msg_iovlen == 0) {
3168 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3170 nlen = len + msg->msg_iov[i].iov_len;
3171 if (nlen > SOCKET_MAX_PACKET) {
3175 msg->msg_iovlen = i;
3176 if (msg->msg_iovlen == 0) {
3177 *tmp_iov = msg->msg_iov[0];
3178 tmp_iov->iov_len = MIN(tmp_iov->iov_len, SOCKET_MAX_PACKET);
3179 msg->msg_iov = tmp_iov;
3180 msg->msg_iovlen = 1;
3185 if (msg->msg_name == NULL) {
3190 if (msg->msg_iovlen == 0) {
3194 if (si->bound == 0) {
3195 ret = swrap_auto_bind(fd, si, si->family);
3198 * When attempting to read or write to a
3199 * descriptor, if an underlying autobind fails
3200 * because it's not a socket, stop intercepting
3201 * uses of that descriptor.
3203 if (errno == ENOTSOCK) {
3204 swrap_remove_stale(fd);
3207 SWRAP_LOG(SWRAP_LOG_ERROR,
3208 "swrap_recvmsg_before failed");
3215 errno = EHOSTUNREACH;
3222 static int swrap_recvmsg_after(int fd,
3223 struct socket_info *si,
3225 const struct sockaddr_un *un_addr,
3226 socklen_t un_addrlen,
3229 int saved_errno = errno;
3231 uint8_t *buf = NULL;
3236 /* to give better errors */
3238 if (saved_errno == ENOENT) {
3239 saved_errno = EHOSTUNREACH;
3240 } else if (saved_errno == ENOTSOCK) {
3241 /* If the fd is not a socket, remove it */
3242 swrap_remove_stale(fd);
3246 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3247 avail += msg->msg_iov[i].iov_len;
3251 errno = saved_errno;
3256 remain = MIN(80, avail);
3261 /* we capture it as one single packet */
3262 buf = (uint8_t *)malloc(remain);
3264 /* we just not capture the packet */
3265 errno = saved_errno;
3269 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3270 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
3272 msg->msg_iov[i].iov_base,
3275 remain -= this_time;
3280 if (ret == -1 && saved_errno != EAGAIN && saved_errno != ENOBUFS) {
3281 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
3282 } else if (ret == 0) { /* END OF FILE */
3283 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
3284 } else if (ret > 0) {
3285 swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
3294 if (un_addr != NULL) {
3297 rc = sockaddr_convert_from_un(si,
3307 swrap_dump_packet(si,
3313 swrap_dump_packet(si,
3325 errno = saved_errno;
3329 /****************************************************************************
3331 ***************************************************************************/
3333 static ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags,
3334 struct sockaddr *from, socklen_t *fromlen)
3336 struct sockaddr_un from_addr;
3337 socklen_t from_addrlen = sizeof(from_addr);
3339 struct socket_info *si = find_socket_info(s);
3340 struct sockaddr_storage ss;
3341 socklen_t ss_len = sizeof(ss);
3347 return libc_recvfrom(s,
3359 if (from != NULL && fromlen != NULL) {
3360 msg.msg_name = from; /* optional address */
3361 msg.msg_namelen = *fromlen; /* size of address */
3363 msg.msg_name = (struct sockaddr *)(void *)&ss; /* optional address */
3364 msg.msg_namelen = ss_len; /* size of address */
3366 msg.msg_iov = &tmp; /* scatter/gather array */
3367 msg.msg_iovlen = 1; /* # elements in msg_iov */
3368 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3369 msg.msg_control = NULL; /* ancillary data, see below */
3370 msg.msg_controllen = 0; /* ancillary data buffer len */
3371 msg.msg_flags = 0; /* flags on received message */
3374 tret = swrap_recvmsg_before(s, si, &msg, &tmp);
3379 buf = msg.msg_iov[0].iov_base;
3380 len = msg.msg_iov[0].iov_len;
3382 /* irix 6.4 forgets to null terminate the sun_path string :-( */
3383 memset(&from_addr, 0, sizeof(from_addr));
3384 ret = libc_recvfrom(s,
3388 (struct sockaddr *)(void *)&from_addr,
3394 tret = swrap_recvmsg_after(s,
3404 if (from != NULL && fromlen != NULL) {
3405 *fromlen = msg.msg_namelen;
3411 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3412 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
3413 struct sockaddr *from, Psocklen_t fromlen)
3415 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
3416 struct sockaddr *from, socklen_t *fromlen)
3419 return swrap_recvfrom(s, buf, len, flags, from, (socklen_t *)fromlen);
3422 /****************************************************************************
3424 ***************************************************************************/
3426 static ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags,
3427 const struct sockaddr *to, socklen_t tolen)
3431 struct sockaddr_un un_addr;
3432 const struct sockaddr_un *to_un = NULL;
3435 struct socket_info *si = find_socket_info(s);
3439 return libc_sendto(s, buf, len, flags, to, tolen);
3442 tmp.iov_base = discard_const_p(char, buf);
3446 msg.msg_name = discard_const_p(struct sockaddr, to); /* optional address */
3447 msg.msg_namelen = tolen; /* size of address */
3448 msg.msg_iov = &tmp; /* scatter/gather array */
3449 msg.msg_iovlen = 1; /* # elements in msg_iov */
3450 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
3451 msg.msg_control = NULL; /* ancillary data, see below */
3452 msg.msg_controllen = 0; /* ancillary data buffer len */
3453 msg.msg_flags = 0; /* flags on received message */
3456 rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
3461 buf = msg.msg_iov[0].iov_base;
3462 len = msg.msg_iov[0].iov_len;
3467 unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port);
3470 type = SOCKET_TYPE_CHAR_UDP;
3472 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
3473 snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT,
3474 socket_wrapper_dir(), type, iface, prt);
3475 if (stat(un_addr.sun_path, &st) != 0) continue;
3477 /* ignore the any errors in broadcast sends */
3482 (struct sockaddr *)(void *)&un_addr,
3486 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
3491 ret = libc_sendto(s,
3495 (struct sockaddr *)msg.msg_name,
3498 swrap_sendmsg_after(s, si, &msg, to, ret);
3503 ssize_t sendto(int s, const void *buf, size_t len, int flags,
3504 const struct sockaddr *to, socklen_t tolen)
3506 return swrap_sendto(s, buf, len, flags, to, tolen);
3509 /****************************************************************************
3511 ***************************************************************************/
3513 static ssize_t swrap_recv(int s, void *buf, size_t len, int flags)
3515 struct socket_info *si;
3517 struct sockaddr_storage ss;
3518 socklen_t ss_len = sizeof(ss);
3523 si = find_socket_info(s);
3525 return libc_recv(s, buf, len, flags);
3532 msg.msg_name = (struct sockaddr *)(void *)&ss; /* optional address */
3533 msg.msg_namelen = ss_len; /* size of address */
3534 msg.msg_iov = &tmp; /* scatter/gather array */
3535 msg.msg_iovlen = 1; /* # elements in msg_iov */
3536 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3537 msg.msg_control = NULL; /* ancillary data, see below */
3538 msg.msg_controllen = 0; /* ancillary data buffer len */
3539 msg.msg_flags = 0; /* flags on received message */
3542 tret = swrap_recvmsg_before(s, si, &msg, &tmp);
3547 buf = msg.msg_iov[0].iov_base;
3548 len = msg.msg_iov[0].iov_len;
3550 ret = libc_recv(s, buf, len, flags);
3552 tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
3560 ssize_t recv(int s, void *buf, size_t len, int flags)
3562 return swrap_recv(s, buf, len, flags);
3565 /****************************************************************************
3567 ***************************************************************************/
3569 static ssize_t swrap_read(int s, void *buf, size_t len)
3571 struct socket_info *si;
3574 struct sockaddr_storage ss;
3575 socklen_t ss_len = sizeof(ss);
3579 si = find_socket_info(s);
3581 return libc_read(s, buf, len);
3588 msg.msg_name = (struct sockaddr *)(void *)&ss; /* optional address */
3589 msg.msg_namelen = ss_len; /* size of address */
3590 msg.msg_iov = &tmp; /* scatter/gather array */
3591 msg.msg_iovlen = 1; /* # elements in msg_iov */
3592 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3593 msg.msg_control = NULL; /* ancillary data, see below */
3594 msg.msg_controllen = 0; /* ancillary data buffer len */
3595 msg.msg_flags = 0; /* flags on received message */
3598 tret = swrap_recvmsg_before(s, si, &msg, &tmp);
3600 if (tret == -ENOTSOCK) {
3601 return libc_read(s, buf, len);
3606 buf = msg.msg_iov[0].iov_base;
3607 len = msg.msg_iov[0].iov_len;
3609 ret = libc_read(s, buf, len);
3611 tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
3619 ssize_t read(int s, void *buf, size_t len)
3621 return swrap_read(s, buf, len);
3624 /****************************************************************************
3626 ***************************************************************************/
3628 static ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
3632 struct sockaddr_un un_addr;
3635 struct socket_info *si = find_socket_info(s);
3638 return libc_send(s, buf, len, flags);
3641 tmp.iov_base = discard_const_p(char, buf);
3645 msg.msg_name = NULL; /* optional address */
3646 msg.msg_namelen = 0; /* size of address */
3647 msg.msg_iov = &tmp; /* scatter/gather array */
3648 msg.msg_iovlen = 1; /* # elements in msg_iov */
3649 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
3650 msg.msg_control = NULL; /* ancillary data, see below */
3651 msg.msg_controllen = 0; /* ancillary data buffer len */
3652 msg.msg_flags = 0; /* flags on received message */
3655 rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
3660 buf = msg.msg_iov[0].iov_base;
3661 len = msg.msg_iov[0].iov_len;
3663 ret = libc_send(s, buf, len, flags);
3665 swrap_sendmsg_after(s, si, &msg, NULL, ret);
3670 ssize_t send(int s, const void *buf, size_t len, int flags)
3672 return swrap_send(s, buf, len, flags);
3675 /****************************************************************************
3677 ***************************************************************************/
3679 static ssize_t swrap_recvmsg(int s, struct msghdr *omsg, int flags)
3681 struct sockaddr_un from_addr;
3682 socklen_t from_addrlen = sizeof(from_addr);
3683 struct socket_info *si;
3690 si = find_socket_info(s);
3692 return libc_recvmsg(s, omsg, flags);
3695 tmp.iov_base = NULL;
3699 msg.msg_name = (struct sockaddr *)&from_addr; /* optional address */
3700 msg.msg_namelen = from_addrlen; /* size of address */
3701 msg.msg_iov = omsg->msg_iov; /* scatter/gather array */
3702 msg.msg_iovlen = omsg->msg_iovlen; /* # elements in msg_iov */
3703 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3704 msg.msg_control = omsg->msg_control; /* ancillary data, see below */
3705 msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
3706 msg.msg_flags = omsg->msg_flags; /* flags on received message */
3709 rc = swrap_recvmsg_before(s, si, &msg, &tmp);
3714 ret = libc_recvmsg(s, &msg, flags);
3716 rc = swrap_recvmsg_after(s, si, omsg, &from_addr, from_addrlen, ret);
3724 ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)
3726 return swrap_recvmsg(sockfd, msg, flags);
3729 /****************************************************************************
3731 ***************************************************************************/
3733 static ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags)
3737 struct sockaddr_un un_addr;
3738 const struct sockaddr_un *to_un = NULL;
3739 const struct sockaddr *to = NULL;
3742 struct socket_info *si = find_socket_info(s);
3746 return libc_sendmsg(s, omsg, flags);
3749 ZERO_STRUCT(un_addr);
3751 tmp.iov_base = NULL;
3755 msg.msg_name = omsg->msg_name; /* optional address */
3756 msg.msg_namelen = omsg->msg_namelen; /* size of address */
3757 msg.msg_iov = omsg->msg_iov; /* scatter/gather array */
3758 msg.msg_iovlen = omsg->msg_iovlen; /* # elements in msg_iov */
3759 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3760 msg.msg_control = omsg->msg_control; /* ancillary data, see below */
3761 msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
3762 msg.msg_flags = omsg->msg_flags; /* flags on received message */
3765 rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
3773 unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port);
3781 for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
3782 avail += msg.msg_iov[i].iov_len;
3788 /* we capture it as one single packet */
3789 buf = (uint8_t *)malloc(remain);
3794 for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
3795 size_t this_time = MIN(remain, (size_t)msg.msg_iov[i].iov_len);
3797 msg.msg_iov[i].iov_base,
3800 remain -= this_time;
3803 type = SOCKET_TYPE_CHAR_UDP;
3805 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
3806 snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT,
3807 socket_wrapper_dir(), type, iface, prt);
3808 if (stat(un_addr.sun_path, &st) != 0) continue;
3810 msg.msg_name = &un_addr; /* optional address */
3811 msg.msg_namelen = sizeof(un_addr); /* size of address */
3813 /* ignore the any errors in broadcast sends */
3814 libc_sendmsg(s, &msg, flags);
3817 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
3823 ret = libc_sendmsg(s, &msg, flags);
3825 swrap_sendmsg_after(s, si, &msg, to, ret);
3830 ssize_t sendmsg(int s, const struct msghdr *omsg, int flags)
3832 return swrap_sendmsg(s, omsg, flags);
3835 /****************************************************************************
3837 ***************************************************************************/
3839 static ssize_t swrap_readv(int s, const struct iovec *vector, int count)
3841 struct socket_info *si;
3844 struct sockaddr_storage ss;
3845 socklen_t ss_len = sizeof(ss);
3849 si = find_socket_info(s);
3851 return libc_readv(s, vector, count);
3854 tmp.iov_base = NULL;
3858 msg.msg_name = (struct sockaddr *)(void *)&ss; /* optional address */
3859 msg.msg_namelen = ss_len; /* size of address */
3860 msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
3861 msg.msg_iovlen = count; /* # elements in msg_iov */
3862 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3863 msg.msg_control = NULL; /* ancillary data, see below */
3864 msg.msg_controllen = 0; /* ancillary data buffer len */
3865 msg.msg_flags = 0; /* flags on received message */
3868 rc = swrap_recvmsg_before(s, si, &msg, &tmp);
3870 if (rc == -ENOTSOCK) {
3871 return libc_readv(s, vector, count);
3876 ret = libc_readv(s, msg.msg_iov, msg.msg_iovlen);
3878 rc = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
3886 ssize_t readv(int s, const struct iovec *vector, int count)
3888 return swrap_readv(s, vector, count);
3891 /****************************************************************************
3893 ***************************************************************************/
3895 static ssize_t swrap_writev(int s, const struct iovec *vector, int count)
3899 struct sockaddr_un un_addr;
3902 struct socket_info *si = find_socket_info(s);
3905 return libc_writev(s, vector, count);
3908 tmp.iov_base = NULL;
3912 msg.msg_name = NULL; /* optional address */
3913 msg.msg_namelen = 0; /* size of address */
3914 msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
3915 msg.msg_iovlen = count; /* # elements in msg_iov */
3916 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
3917 msg.msg_control = NULL; /* ancillary data, see below */
3918 msg.msg_controllen = 0; /* ancillary data buffer len */
3919 msg.msg_flags = 0; /* flags on received message */
3922 rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
3924 if (rc == -ENOTSOCK) {
3925 return libc_readv(s, vector, count);
3930 ret = libc_writev(s, msg.msg_iov, msg.msg_iovlen);
3932 swrap_sendmsg_after(s, si, &msg, NULL, ret);
3937 ssize_t writev(int s, const struct iovec *vector, int count)
3939 return swrap_writev(s, vector, count);
3942 /****************************
3944 ***************************/
3946 static int swrap_close(int fd)
3948 struct socket_info *si = find_socket_info(fd);
3949 struct socket_info_fd *fi;
3953 return libc_close(fd);
3956 for (fi = si->fds; fi; fi = fi->next) {
3958 SWRAP_DLIST_REMOVE(si->fds, fi);
3965 /* there are still references left */
3966 return libc_close(fd);
3969 SWRAP_DLIST_REMOVE(sockets, si);
3971 if (si->myname && si->peername) {
3972 swrap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0);
3975 ret = libc_close(fd);
3977 if (si->myname && si->peername) {
3978 swrap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0);
3979 swrap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0);
3982 if (si->bindname != NULL) {
3986 if (si->myname) free(si->myname);
3987 if (si->peername) free(si->peername);
3989 unlink(si->tmp_path);
3999 return swrap_close(fd);
4002 /****************************
4004 ***************************/
4006 static int swrap_dup(int fd)
4008 struct socket_info *si;
4009 struct socket_info_fd *fi;
4011 si = find_socket_info(fd);
4014 return libc_dup(fd);
4017 fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
4023 fi->fd = libc_dup(fd);
4025 int saved_errno = errno;
4027 errno = saved_errno;
4031 /* Make sure we don't have an entry for the fd */
4032 swrap_remove_stale(fi->fd);
4034 SWRAP_DLIST_ADD(si->fds, fi);
4040 return swrap_dup(fd);
4043 /****************************
4045 ***************************/
4047 static int swrap_dup2(int fd, int newfd)
4049 struct socket_info *si;
4050 struct socket_info_fd *fi;
4052 si = find_socket_info(fd);
4055 return libc_dup2(fd, newfd);
4058 if (find_socket_info(newfd)) {
4059 /* dup2() does an implicit close of newfd, which we
4060 * need to emulate */
4064 fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
4070 fi->fd = libc_dup2(fd, newfd);
4072 int saved_errno = errno;
4074 errno = saved_errno;
4078 /* Make sure we don't have an entry for the fd */
4079 swrap_remove_stale(fi->fd);
4081 SWRAP_DLIST_ADD(si->fds, fi);
4085 int dup2(int fd, int newfd)
4087 return swrap_dup2(fd, newfd);
4090 /****************************
4092 ***************************/
4095 static int swrap_eventfd(int count, int flags)
4099 fd = libc_eventfd(count, flags);
4101 swrap_remove_stale(fd);
4107 int eventfd(int count, int flags)
4109 return swrap_eventfd(count, flags);
4113 /****************************
4115 ***************************/
4118 * This function is called when the library is unloaded and makes sure that
4119 * sockets get closed and the unix file for the socket are unlinked.
4121 void swrap_destructor(void)
4123 struct socket_info *s = sockets;
4126 struct socket_info_fd *f = s->fds;