2 * Copyright (c) 2005-2008 Jelmer Vernooij <jelmer@samba.org>
3 * Copyright (C) 2006-2014 Stefan Metzmacher <metze@samba.org>
4 * Copyright (C) 2013-2014 Andreas Schneider <asn@samba.org>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the author nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 Socket wrapper library. Passes all socket communication over
39 unix domain sockets if the environment variable SOCKET_WRAPPER_DIR
45 #include <sys/types.h>
48 #include <sys/socket.h>
49 #include <sys/ioctl.h>
50 #ifdef HAVE_SYS_FILIO_H
51 #include <sys/filio.h>
53 #ifdef HAVE_SYS_SIGNALFD_H
54 #include <sys/signalfd.h>
56 #ifdef HAVE_SYS_EVENTFD_H
57 #include <sys/eventfd.h>
59 #ifdef HAVE_SYS_TIMERFD_H
60 #include <sys/timerfd.h>
65 #include <netinet/in.h>
66 #include <netinet/tcp.h>
67 #include <arpa/inet.h>
76 #ifdef HAVE_GNU_LIB_NAMES_H
77 #include <gnu/lib-names.h>
90 /* GCC have printf type attribute check. */
91 #ifdef HAVE_FUNCTION_ATTRIBUTE_FORMAT
92 #define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
94 #define PRINTF_ATTRIBUTE(a,b)
95 #endif /* HAVE_FUNCTION_ATTRIBUTE_FORMAT */
97 #ifdef HAVE_DESTRUCTOR_ATTRIBUTE
98 #define DESTRUCTOR_ATTRIBUTE __attribute__ ((destructor))
100 #define DESTRUCTOR_ATTRIBUTE
103 #ifdef HAVE_ADDRESS_SANITIZER_ATTRIBUTE
104 #define DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE __attribute__((no_sanitize_address))
106 #define DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
109 #ifdef HAVE_GCC_THREAD_LOCAL_STORAGE
110 # define SWRAP_THREAD __thread
112 # define SWRAP_THREAD
116 #define MIN(a,b) ((a)<(b)?(a):(b))
120 #define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
124 #define ZERO_STRUCTP(x) do { \
126 memset((char *)(x), 0, sizeof(*(x))); \
130 #ifndef discard_const
131 #define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
134 #ifndef discard_const_p
135 #define discard_const_p(type, ptr) ((type *)discard_const(ptr))
139 # ifndef IPV6_RECVPKTINFO
140 # define IPV6_RECVPKTINFO IPV6_PKTINFO
141 # endif /* IPV6_RECVPKTINFO */
142 #endif /* IPV6_PKTINFO */
145 * On BSD IP_PKTINFO has a different name because during
146 * the time when they implemented it, there was no RFC.
147 * The name for IPv6 is the same as on Linux.
150 # ifdef IP_RECVDSTADDR
151 # define IP_PKTINFO IP_RECVDSTADDR
156 #define SWRAP_DLIST_ADD(list,item) do { \
158 (item)->prev = NULL; \
159 (item)->next = NULL; \
162 (item)->prev = NULL; \
163 (item)->next = (list); \
164 (list)->prev = (item); \
169 #define SWRAP_DLIST_REMOVE(list,item) do { \
170 if ((list) == (item)) { \
171 (list) = (item)->next; \
173 (list)->prev = NULL; \
176 if ((item)->prev) { \
177 (item)->prev->next = (item)->next; \
179 if ((item)->next) { \
180 (item)->next->prev = (item)->prev; \
183 (item)->prev = NULL; \
184 (item)->next = NULL; \
187 #define SWRAP_DLIST_ADD_AFTER(list, item, el) \
189 if ((list) != NULL || (el) != NULL) { \
190 SWRAP_DLIST_ADD(list, item); \
192 (item)->prev = (el); \
193 (item)->next = (el)->next; \
194 (el)->next = (item); \
195 if ((item)->next != NULL) { \
196 (item)->next->prev = (item); \
201 #if defined(HAVE_GETTIMEOFDAY_TZ) || defined(HAVE_GETTIMEOFDAY_TZ_VOID)
202 #define swrapGetTimeOfDay(tval) gettimeofday(tval,NULL)
204 #define swrapGetTimeOfDay(tval) gettimeofday(tval)
207 /* we need to use a very terse format here as IRIX 6.4 silently
208 truncates names to 16 chars, so if we use a longer name then we
209 can't tell which port a packet came from with recvfrom()
211 with this format we have 8 chars left for the directory name
213 #define SOCKET_FORMAT "%c%02X%04X"
214 #define SOCKET_TYPE_CHAR_TCP 'T'
215 #define SOCKET_TYPE_CHAR_UDP 'U'
216 #define SOCKET_TYPE_CHAR_TCP_V6 'X'
217 #define SOCKET_TYPE_CHAR_UDP_V6 'Y'
220 * Set the packet MTU to 1500 bytes for stream sockets to make it it easier to
221 * format PCAP capture files (as the caller will simply continue from here).
223 #define SOCKET_WRAPPER_MTU_DEFAULT 1500
224 #define SOCKET_WRAPPER_MTU_MIN 512
225 #define SOCKET_WRAPPER_MTU_MAX 32768
227 #define SOCKET_MAX_SOCKETS 1024
229 /* This limit is to avoid broadcast sendto() needing to stat too many
230 * files. It may be raised (with a performance cost) to up to 254
231 * without changing the format above */
232 #define MAX_WRAPPED_INTERFACES 40
234 struct swrap_address {
235 socklen_t sa_socklen;
238 struct sockaddr_in in;
240 struct sockaddr_in6 in6;
242 struct sockaddr_un un;
243 struct sockaddr_storage ss;
247 struct socket_info_fd {
248 struct socket_info_fd *prev, *next;
251 /* Points to list of socket_info structures */
252 struct socket_info *si;
257 unsigned int refcount;
270 /* The unix path so we can unlink it on close() */
271 struct sockaddr_un un_addr;
273 struct swrap_address bindname;
274 struct swrap_address myname;
275 struct swrap_address peername;
278 unsigned long pck_snd;
279 unsigned long pck_rcv;
284 * While socket file descriptors are passed among different processes, the
285 * numerical value gets changed. So its better to store it locally to each
286 * process rather than including it within socket_info which will be shared.
288 static struct socket_info_fd *socket_fds;
290 /* Function prototypes */
292 bool socket_wrapper_enabled(void);
293 void swrap_destructor(void) DESTRUCTOR_ATTRIBUTE;
296 # define SWRAP_LOG(...)
299 static void swrap_log(enum swrap_dbglvl_e dbglvl, const char *func, const char *format, ...) PRINTF_ATTRIBUTE(3, 4);
300 # define SWRAP_LOG(dbglvl, ...) swrap_log((dbglvl), __func__, __VA_ARGS__)
302 static void swrap_log(enum swrap_dbglvl_e dbglvl,
304 const char *format, ...)
309 unsigned int lvl = 0;
311 d = getenv("SOCKET_WRAPPER_DEBUGLEVEL");
316 va_start(va, format);
317 vsnprintf(buffer, sizeof(buffer), format, va);
322 case SWRAP_LOG_ERROR:
324 "SWRAP_ERROR(%d) - %s: %s\n",
325 (int)getpid(), func, buffer);
329 "SWRAP_WARN(%d) - %s: %s\n",
330 (int)getpid(), func, buffer);
332 case SWRAP_LOG_DEBUG:
334 "SWRAP_DEBUG(%d) - %s: %s\n",
335 (int)getpid(), func, buffer);
337 case SWRAP_LOG_TRACE:
339 "SWRAP_TRACE(%d) - %s: %s\n",
340 (int)getpid(), func, buffer);
347 /*********************************************************
348 * SWRAP LOADING LIBC FUNCTIONS
349 *********************************************************/
353 struct swrap_libc_fns {
355 int (*libc_accept4)(int sockfd,
356 struct sockaddr *addr,
360 int (*libc_accept)(int sockfd,
361 struct sockaddr *addr,
364 int (*libc_bind)(int sockfd,
365 const struct sockaddr *addr,
367 int (*libc_close)(int fd);
368 int (*libc_connect)(int sockfd,
369 const struct sockaddr *addr,
371 int (*libc_dup)(int fd);
372 int (*libc_dup2)(int oldfd, int newfd);
373 int (*libc_fcntl)(int fd, int cmd, ...);
374 FILE *(*libc_fopen)(const char *name, const char *mode);
376 int (*libc_eventfd)(int count, int flags);
378 int (*libc_getpeername)(int sockfd,
379 struct sockaddr *addr,
381 int (*libc_getsockname)(int sockfd,
382 struct sockaddr *addr,
384 int (*libc_getsockopt)(int sockfd,
389 int (*libc_ioctl)(int d, unsigned long int request, ...);
390 int (*libc_listen)(int sockfd, int backlog);
391 int (*libc_open)(const char *pathname, int flags, mode_t mode);
392 int (*libc_pipe)(int pipefd[2]);
393 int (*libc_read)(int fd, void *buf, size_t count);
394 ssize_t (*libc_readv)(int fd, const struct iovec *iov, int iovcnt);
395 int (*libc_recv)(int sockfd, void *buf, size_t len, int flags);
396 int (*libc_recvfrom)(int sockfd,
400 struct sockaddr *src_addr,
402 int (*libc_recvmsg)(int sockfd, const struct msghdr *msg, int flags);
403 int (*libc_send)(int sockfd, const void *buf, size_t len, int flags);
404 int (*libc_sendmsg)(int sockfd, const struct msghdr *msg, int flags);
405 int (*libc_sendto)(int sockfd,
409 const struct sockaddr *dst_addr,
411 int (*libc_setsockopt)(int sockfd,
417 int (*libc_signalfd)(int fd, const sigset_t *mask, int flags);
419 int (*libc_socket)(int domain, int type, int protocol);
420 int (*libc_socketpair)(int domain, int type, int protocol, int sv[2]);
421 #ifdef HAVE_TIMERFD_CREATE
422 int (*libc_timerfd_create)(int clockid, int flags);
424 ssize_t (*libc_write)(int fd, const void *buf, size_t count);
425 ssize_t (*libc_writev)(int fd, const struct iovec *iov, int iovcnt);
430 void *libsocket_handle;
432 struct swrap_libc_fns fns;
435 static struct swrap swrap;
438 static const char *socket_wrapper_dir(void);
440 #define LIBC_NAME "libc.so"
449 static const char *swrap_str_lib(enum swrap_lib lib)
456 case SWRAP_LIBSOCKET:
460 /* Compiler would warn us about unhandled enum value if we get here */
465 static void *swrap_load_lib_handle(enum swrap_lib lib)
467 int flags = RTLD_LAZY;
472 flags |= RTLD_DEEPBIND;
478 case SWRAP_LIBSOCKET:
479 #ifdef HAVE_LIBSOCKET
480 handle = swrap.libsocket_handle;
481 if (handle == NULL) {
482 for (i = 10; i >= 0; i--) {
483 char soname[256] = {0};
485 snprintf(soname, sizeof(soname), "libsocket.so.%d", i);
486 handle = dlopen(soname, flags);
487 if (handle != NULL) {
492 swrap.libsocket_handle = handle;
498 handle = swrap.libc_handle;
500 if (handle == NULL) {
501 handle = dlopen(LIBC_SO, flags);
503 swrap.libc_handle = handle;
506 if (handle == NULL) {
507 for (i = 10; i >= 0; i--) {
508 char soname[256] = {0};
510 snprintf(soname, sizeof(soname), "libc.so.%d", i);
511 handle = dlopen(soname, flags);
512 if (handle != NULL) {
517 swrap.libc_handle = handle;
522 if (handle == NULL) {
524 handle = swrap.libc_handle = swrap.libsocket_handle = RTLD_NEXT;
526 SWRAP_LOG(SWRAP_LOG_ERROR,
527 "Failed to dlopen library: %s\n",
536 static void *_swrap_load_lib_function(enum swrap_lib lib, const char *fn_name)
541 handle = swrap_load_lib_handle(lib);
543 func = dlsym(handle, fn_name);
545 SWRAP_LOG(SWRAP_LOG_ERROR,
546 "Failed to find %s: %s\n",
551 SWRAP_LOG(SWRAP_LOG_TRACE,
553 fn_name, swrap_str_lib(lib));
557 #define swrap_load_lib_function(lib, fn_name) \
558 if (swrap.fns.libc_##fn_name == NULL) { \
559 void *swrap_cast_ptr = _swrap_load_lib_function(lib, #fn_name); \
560 *(void **) (&swrap.fns.libc_##fn_name) = \
568 * Functions especially from libc need to be loaded individually, you can't load
569 * all at once or gdb will segfault at startup. The same applies to valgrind and
570 * has probably something todo with with the linker.
571 * So we need load each function at the point it is called the first time.
574 static int libc_accept4(int sockfd,
575 struct sockaddr *addr,
579 swrap_load_lib_function(SWRAP_LIBSOCKET, accept4);
581 return swrap.fns.libc_accept4(sockfd, addr, addrlen, flags);
584 #else /* HAVE_ACCEPT4 */
586 static int libc_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
588 swrap_load_lib_function(SWRAP_LIBSOCKET, accept);
590 return swrap.fns.libc_accept(sockfd, addr, addrlen);
592 #endif /* HAVE_ACCEPT4 */
594 static int libc_bind(int sockfd,
595 const struct sockaddr *addr,
598 swrap_load_lib_function(SWRAP_LIBSOCKET, bind);
600 return swrap.fns.libc_bind(sockfd, addr, addrlen);
603 static int libc_close(int fd)
605 swrap_load_lib_function(SWRAP_LIBC, close);
607 return swrap.fns.libc_close(fd);
610 static int libc_connect(int sockfd,
611 const struct sockaddr *addr,
614 swrap_load_lib_function(SWRAP_LIBSOCKET, connect);
616 return swrap.fns.libc_connect(sockfd, addr, addrlen);
619 static int libc_dup(int fd)
621 swrap_load_lib_function(SWRAP_LIBC, dup);
623 return swrap.fns.libc_dup(fd);
626 static int libc_dup2(int oldfd, int newfd)
628 swrap_load_lib_function(SWRAP_LIBC, dup2);
630 return swrap.fns.libc_dup2(oldfd, newfd);
634 static int libc_eventfd(int count, int flags)
636 swrap_load_lib_function(SWRAP_LIBC, eventfd);
638 return swrap.fns.libc_eventfd(count, flags);
642 DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
643 static int libc_vfcntl(int fd, int cmd, va_list ap)
649 swrap_load_lib_function(SWRAP_LIBC, fcntl);
651 for (i = 0; i < 4; i++) {
652 args[i] = va_arg(ap, long int);
655 rc = swrap.fns.libc_fcntl(fd,
665 static int libc_getpeername(int sockfd,
666 struct sockaddr *addr,
669 swrap_load_lib_function(SWRAP_LIBSOCKET, getpeername);
671 return swrap.fns.libc_getpeername(sockfd, addr, addrlen);
674 static int libc_getsockname(int sockfd,
675 struct sockaddr *addr,
678 swrap_load_lib_function(SWRAP_LIBSOCKET, getsockname);
680 return swrap.fns.libc_getsockname(sockfd, addr, addrlen);
683 static int libc_getsockopt(int sockfd,
689 swrap_load_lib_function(SWRAP_LIBSOCKET, getsockopt);
691 return swrap.fns.libc_getsockopt(sockfd, level, optname, optval, optlen);
694 DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
695 static int libc_vioctl(int d, unsigned long int request, va_list ap)
701 swrap_load_lib_function(SWRAP_LIBC, ioctl);
703 for (i = 0; i < 4; i++) {
704 args[i] = va_arg(ap, long int);
707 rc = swrap.fns.libc_ioctl(d,
717 static int libc_listen(int sockfd, int backlog)
719 swrap_load_lib_function(SWRAP_LIBSOCKET, listen);
721 return swrap.fns.libc_listen(sockfd, backlog);
724 static FILE *libc_fopen(const char *name, const char *mode)
726 swrap_load_lib_function(SWRAP_LIBC, fopen);
728 return swrap.fns.libc_fopen(name, mode);
731 static int libc_vopen(const char *pathname, int flags, va_list ap)
736 swrap_load_lib_function(SWRAP_LIBC, open);
738 mode = va_arg(ap, long int);
740 fd = swrap.fns.libc_open(pathname, flags, (mode_t)mode);
745 static int libc_open(const char *pathname, int flags, ...)
751 fd = libc_vopen(pathname, flags, ap);
757 static int libc_pipe(int pipefd[2])
759 swrap_load_lib_function(SWRAP_LIBSOCKET, pipe);
761 return swrap.fns.libc_pipe(pipefd);
764 static int libc_read(int fd, void *buf, size_t count)
766 swrap_load_lib_function(SWRAP_LIBC, read);
768 return swrap.fns.libc_read(fd, buf, count);
771 static ssize_t libc_readv(int fd, const struct iovec *iov, int iovcnt)
773 swrap_load_lib_function(SWRAP_LIBSOCKET, readv);
775 return swrap.fns.libc_readv(fd, iov, iovcnt);
778 static int libc_recv(int sockfd, void *buf, size_t len, int flags)
780 swrap_load_lib_function(SWRAP_LIBSOCKET, recv);
782 return swrap.fns.libc_recv(sockfd, buf, len, flags);
785 static int libc_recvfrom(int sockfd,
789 struct sockaddr *src_addr,
792 swrap_load_lib_function(SWRAP_LIBSOCKET, recvfrom);
794 return swrap.fns.libc_recvfrom(sockfd, buf, len, flags, src_addr, addrlen);
797 static int libc_recvmsg(int sockfd, struct msghdr *msg, int flags)
799 swrap_load_lib_function(SWRAP_LIBSOCKET, recvmsg);
801 return swrap.fns.libc_recvmsg(sockfd, msg, flags);
804 static int libc_send(int sockfd, const void *buf, size_t len, int flags)
806 swrap_load_lib_function(SWRAP_LIBSOCKET, send);
808 return swrap.fns.libc_send(sockfd, buf, len, flags);
811 static int libc_sendmsg(int sockfd, const struct msghdr *msg, int flags)
813 swrap_load_lib_function(SWRAP_LIBSOCKET, sendmsg);
815 return swrap.fns.libc_sendmsg(sockfd, msg, flags);
818 static int libc_sendto(int sockfd,
822 const struct sockaddr *dst_addr,
825 swrap_load_lib_function(SWRAP_LIBSOCKET, sendto);
827 return swrap.fns.libc_sendto(sockfd, buf, len, flags, dst_addr, addrlen);
830 static int libc_setsockopt(int sockfd,
836 swrap_load_lib_function(SWRAP_LIBSOCKET, setsockopt);
838 return swrap.fns.libc_setsockopt(sockfd, level, optname, optval, optlen);
842 static int libc_signalfd(int fd, const sigset_t *mask, int flags)
844 swrap_load_lib_function(SWRAP_LIBSOCKET, signalfd);
846 return swrap.fns.libc_signalfd(fd, mask, flags);
850 static int libc_socket(int domain, int type, int protocol)
852 swrap_load_lib_function(SWRAP_LIBSOCKET, socket);
854 return swrap.fns.libc_socket(domain, type, protocol);
857 static int libc_socketpair(int domain, int type, int protocol, int sv[2])
859 swrap_load_lib_function(SWRAP_LIBSOCKET, socketpair);
861 return swrap.fns.libc_socketpair(domain, type, protocol, sv);
864 #ifdef HAVE_TIMERFD_CREATE
865 static int libc_timerfd_create(int clockid, int flags)
867 swrap_load_lib_function(SWRAP_LIBC, timerfd_create);
869 return swrap.fns.libc_timerfd_create(clockid, flags);
873 static ssize_t libc_write(int fd, const void *buf, size_t count)
875 swrap_load_lib_function(SWRAP_LIBC, write);
877 return swrap.fns.libc_write(fd, buf, count);
880 static ssize_t libc_writev(int fd, const struct iovec *iov, int iovcnt)
882 swrap_load_lib_function(SWRAP_LIBSOCKET, writev);
884 return swrap.fns.libc_writev(fd, iov, iovcnt);
887 /*********************************************************
888 * SWRAP HELPER FUNCTIONS
889 *********************************************************/
895 static const struct in6_addr *swrap_ipv6(void)
897 static struct in6_addr v;
898 static int initialized;
906 ret = inet_pton(AF_INET6, "FD00::5357:5F00", &v);
915 static void set_port(int family, int prt, struct swrap_address *addr)
919 addr->sa.in.sin_port = htons(prt);
923 addr->sa.in6.sin6_port = htons(prt);
929 static size_t socket_length(int family)
933 return sizeof(struct sockaddr_in);
936 return sizeof(struct sockaddr_in6);
942 static const char *socket_wrapper_dir(void)
944 const char *s = getenv("SOCKET_WRAPPER_DIR");
948 /* TODO use realpath(3) here, when we add support for threads */
949 if (strncmp(s, "./", 2) == 0) {
953 SWRAP_LOG(SWRAP_LOG_TRACE, "socket_wrapper_dir: %s", s);
957 static unsigned int socket_wrapper_mtu(void)
959 static unsigned int max_mtu = 0;
968 max_mtu = SOCKET_WRAPPER_MTU_DEFAULT;
970 s = getenv("SOCKET_WRAPPER_MTU");
975 tmp = strtol(s, &endp, 10);
980 if (tmp < SOCKET_WRAPPER_MTU_MIN || tmp > SOCKET_WRAPPER_MTU_MAX) {
989 bool socket_wrapper_enabled(void)
991 const char *s = socket_wrapper_dir();
993 return s != NULL ? true : false;
996 static unsigned int socket_wrapper_default_iface(void)
998 const char *s = getenv("SOCKET_WRAPPER_DEFAULT_IFACE");
1001 if (sscanf(s, "%u", &iface) == 1) {
1002 if (iface >= 1 && iface <= MAX_WRAPPED_INTERFACES) {
1008 return 1;/* 127.0.0.1 */
1011 static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, socklen_t *len)
1018 p = strrchr(un->sun_path, '/');
1019 if (p) p++; else p = un->sun_path;
1021 if (sscanf(p, SOCKET_FORMAT, &type, &iface, &prt) != 3) {
1026 SWRAP_LOG(SWRAP_LOG_TRACE, "type %c iface %u port %u",
1029 if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
1040 case SOCKET_TYPE_CHAR_TCP:
1041 case SOCKET_TYPE_CHAR_UDP: {
1042 struct sockaddr_in *in2 = (struct sockaddr_in *)(void *)in;
1044 if ((*len) < sizeof(*in2)) {
1049 memset(in2, 0, sizeof(*in2));
1050 in2->sin_family = AF_INET;
1051 in2->sin_addr.s_addr = htonl((127<<24) | iface);
1052 in2->sin_port = htons(prt);
1054 *len = sizeof(*in2);
1058 case SOCKET_TYPE_CHAR_TCP_V6:
1059 case SOCKET_TYPE_CHAR_UDP_V6: {
1060 struct sockaddr_in6 *in2 = (struct sockaddr_in6 *)(void *)in;
1062 if ((*len) < sizeof(*in2)) {
1067 memset(in2, 0, sizeof(*in2));
1068 in2->sin6_family = AF_INET6;
1069 in2->sin6_addr = *swrap_ipv6();
1070 in2->sin6_addr.s6_addr[15] = iface;
1071 in2->sin6_port = htons(prt);
1073 *len = sizeof(*in2);
1085 static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un,
1093 if (bcast) *bcast = 0;
1095 switch (inaddr->sa_family) {
1097 const struct sockaddr_in *in =
1098 (const struct sockaddr_in *)(const void *)inaddr;
1099 unsigned int addr = ntohl(in->sin_addr.s_addr);
1106 u_type = SOCKET_TYPE_CHAR_TCP;
1109 u_type = SOCKET_TYPE_CHAR_UDP;
1110 a_type = SOCKET_TYPE_CHAR_UDP;
1111 b_type = SOCKET_TYPE_CHAR_UDP;
1114 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1115 errno = ESOCKTNOSUPPORT;
1119 prt = ntohs(in->sin_port);
1120 if (a_type && addr == 0xFFFFFFFF) {
1121 /* 255.255.255.255 only udp */
1124 iface = socket_wrapper_default_iface();
1125 } else if (b_type && addr == 0x7FFFFFFF) {
1126 /* 127.255.255.255 only udp */
1129 iface = socket_wrapper_default_iface();
1130 } else if ((addr & 0xFFFFFF00) == 0x7F000000) {
1134 iface = (addr & 0x000000FF);
1136 errno = ENETUNREACH;
1139 if (bcast) *bcast = is_bcast;
1144 const struct sockaddr_in6 *in =
1145 (const struct sockaddr_in6 *)(const void *)inaddr;
1146 struct in6_addr cmp1, cmp2;
1150 type = SOCKET_TYPE_CHAR_TCP_V6;
1153 type = SOCKET_TYPE_CHAR_UDP_V6;
1156 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1157 errno = ESOCKTNOSUPPORT;
1161 /* XXX no multicast/broadcast */
1163 prt = ntohs(in->sin6_port);
1165 cmp1 = *swrap_ipv6();
1166 cmp2 = in->sin6_addr;
1167 cmp2.s6_addr[15] = 0;
1168 if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
1169 iface = in->sin6_addr.s6_addr[15];
1171 errno = ENETUNREACH;
1179 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family!\n");
1180 errno = ENETUNREACH;
1185 SWRAP_LOG(SWRAP_LOG_WARN, "Port not set\n");
1191 snprintf(un->sun_path, sizeof(un->sun_path), "%s/EINVAL",
1192 socket_wrapper_dir());
1193 SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
1194 /* the caller need to do more processing */
1198 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT,
1199 socket_wrapper_dir(), type, iface, prt);
1200 SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
1205 static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un,
1214 if (bcast) *bcast = 0;
1216 switch (si->family) {
1218 const struct sockaddr_in *in =
1219 (const struct sockaddr_in *)(const void *)inaddr;
1220 unsigned int addr = ntohl(in->sin_addr.s_addr);
1226 prt = ntohs(in->sin_port);
1230 u_type = SOCKET_TYPE_CHAR_TCP;
1231 d_type = SOCKET_TYPE_CHAR_TCP;
1234 u_type = SOCKET_TYPE_CHAR_UDP;
1235 d_type = SOCKET_TYPE_CHAR_UDP;
1236 a_type = SOCKET_TYPE_CHAR_UDP;
1237 b_type = SOCKET_TYPE_CHAR_UDP;
1240 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1241 errno = ESOCKTNOSUPPORT;
1249 iface = socket_wrapper_default_iface();
1250 } else if (a_type && addr == 0xFFFFFFFF) {
1251 /* 255.255.255.255 only udp */
1254 iface = socket_wrapper_default_iface();
1255 } else if (b_type && addr == 0x7FFFFFFF) {
1256 /* 127.255.255.255 only udp */
1259 iface = socket_wrapper_default_iface();
1260 } else if ((addr & 0xFFFFFF00) == 0x7F000000) {
1264 iface = (addr & 0x000000FF);
1266 errno = EADDRNOTAVAIL;
1270 /* Store the bind address for connect() */
1271 if (si->bindname.sa_socklen == 0) {
1272 struct sockaddr_in bind_in;
1273 socklen_t blen = sizeof(struct sockaddr_in);
1275 ZERO_STRUCT(bind_in);
1276 bind_in.sin_family = in->sin_family;
1277 bind_in.sin_port = in->sin_port;
1278 bind_in.sin_addr.s_addr = htonl(0x7F000000 | iface);
1280 si->bindname.sa_socklen = blen;
1281 memcpy(&si->bindname.sa.in, &bind_in, blen);
1288 const struct sockaddr_in6 *in =
1289 (const struct sockaddr_in6 *)(const void *)inaddr;
1290 struct in6_addr cmp1, cmp2;
1294 type = SOCKET_TYPE_CHAR_TCP_V6;
1297 type = SOCKET_TYPE_CHAR_UDP_V6;
1300 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1301 errno = ESOCKTNOSUPPORT;
1305 /* XXX no multicast/broadcast */
1307 prt = ntohs(in->sin6_port);
1309 cmp1 = *swrap_ipv6();
1310 cmp2 = in->sin6_addr;
1311 cmp2.s6_addr[15] = 0;
1312 if (IN6_IS_ADDR_UNSPECIFIED(&in->sin6_addr)) {
1313 iface = socket_wrapper_default_iface();
1314 } else if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
1315 iface = in->sin6_addr.s6_addr[15];
1317 errno = EADDRNOTAVAIL;
1321 /* Store the bind address for connect() */
1322 if (si->bindname.sa_socklen == 0) {
1323 struct sockaddr_in6 bind_in;
1324 socklen_t blen = sizeof(struct sockaddr_in6);
1326 ZERO_STRUCT(bind_in);
1327 bind_in.sin6_family = in->sin6_family;
1328 bind_in.sin6_port = in->sin6_port;
1330 bind_in.sin6_addr = *swrap_ipv6();
1331 bind_in.sin6_addr.s6_addr[15] = iface;
1333 memcpy(&si->bindname.sa.in6, &bind_in, blen);
1334 si->bindname.sa_socklen = blen;
1341 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n");
1342 errno = EADDRNOTAVAIL;
1347 if (bcast) *bcast = is_bcast;
1349 if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
1355 /* handle auto-allocation of ephemeral ports */
1356 for (prt = 5001; prt < 10000; prt++) {
1357 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT,
1358 socket_wrapper_dir(), type, iface, prt);
1359 if (stat(un->sun_path, &st) == 0) continue;
1361 set_port(si->family, prt, &si->myname);
1362 set_port(si->family, prt, &si->bindname);
1372 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT,
1373 socket_wrapper_dir(), type, iface, prt);
1374 SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
1378 static struct socket_info_fd *find_socket_info_fd(int fd)
1380 struct socket_info_fd *f;
1382 for (f = socket_fds; f; f = f->next) {
1391 static struct socket_info *find_socket_info(int fd)
1393 struct socket_info_fd *fi = find_socket_info_fd(fd);
1403 static bool check_addr_port_in_use(const struct sockaddr *sa, socklen_t len)
1405 struct socket_info_fd *f;
1407 /* first catch invalid input */
1408 switch (sa->sa_family) {
1410 if (len < sizeof(struct sockaddr_in)) {
1416 if (len < sizeof(struct sockaddr_in6)) {
1426 for (f = socket_fds; f; f = f->next) {
1427 struct socket_info *s = f->si;
1429 if (s->myname == NULL) {
1432 if (s->myname->sa_family != sa->sa_family) {
1435 switch (s->myname->sa_family) {
1437 struct sockaddr_in *sin1, *sin2;
1439 sin1 = (struct sockaddr_in *)s->myname;
1440 sin2 = (struct sockaddr_in *)sa;
1442 if (sin1->sin_addr.s_addr == htonl(INADDR_ANY)) {
1445 if (sin1->sin_port != sin2->sin_port) {
1448 if (sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) {
1458 struct sockaddr_in6 *sin1, *sin2;
1460 sin1 = (struct sockaddr_in6 *)s->myname;
1461 sin2 = (struct sockaddr_in6 *)sa;
1463 if (sin1->sin6_port != sin2->sin6_port) {
1466 if (!IN6_ARE_ADDR_EQUAL(&sin1->sin6_addr,
1488 static void swrap_remove_stale(int fd)
1490 struct socket_info_fd *fi = find_socket_info_fd(fd);
1491 struct socket_info *si;
1499 SWRAP_LOG(SWRAP_LOG_TRACE, "remove stale wrapper for %d", fd);
1500 SWRAP_DLIST_REMOVE(socket_fds, fi);
1505 if (si->refcount > 0) {
1509 if (si->un_addr.sun_path[0] != '\0') {
1510 unlink(si->un_addr.sun_path);
1515 static int sockaddr_convert_to_un(struct socket_info *si,
1516 const struct sockaddr *in_addr,
1518 struct sockaddr_un *out_addr,
1522 struct sockaddr *out = (struct sockaddr *)(void *)out_addr;
1524 (void) in_len; /* unused */
1526 if (out_addr == NULL) {
1530 out->sa_family = AF_UNIX;
1531 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
1532 out->sa_len = sizeof(*out_addr);
1535 switch (in_addr->sa_family) {
1537 const struct sockaddr_in *sin;
1538 if (si->family != AF_INET) {
1541 if (in_len < sizeof(struct sockaddr_in)) {
1544 sin = (const struct sockaddr_in *)(const void *)in_addr;
1545 if(sin->sin_addr.s_addr != htonl(INADDR_ANY)) {
1550 * Note: in the special case of AF_UNSPEC and INADDR_ANY,
1551 * AF_UNSPEC is mapped to AF_INET and must be treated here.
1565 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1566 errno = ESOCKTNOSUPPORT;
1570 return convert_in_un_alloc(si, in_addr, out_addr, bcast);
1572 return convert_in_un_remote(si, in_addr, out_addr, bcast);
1578 errno = EAFNOSUPPORT;
1579 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n");
1583 static int sockaddr_convert_from_un(const struct socket_info *si,
1584 const struct sockaddr_un *in_addr,
1585 socklen_t un_addrlen,
1587 struct sockaddr *out_addr,
1588 socklen_t *out_addrlen)
1592 if (out_addr == NULL || out_addrlen == NULL)
1595 if (un_addrlen == 0) {
1610 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1611 errno = ESOCKTNOSUPPORT;
1614 ret = convert_un_in(in_addr, out_addr, out_addrlen);
1615 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
1616 out_addr->sa_len = *out_addrlen;
1623 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n");
1624 errno = EAFNOSUPPORT;
1628 enum swrap_packet_type {
1630 SWRAP_CONNECT_UNREACH,
1638 SWRAP_SENDTO_UNREACH,
1649 struct swrap_file_hdr {
1651 uint16_t version_major;
1652 uint16_t version_minor;
1655 uint32_t frame_max_len;
1656 #define SWRAP_FRAME_LENGTH_MAX 0xFFFF
1659 #define SWRAP_FILE_HDR_SIZE 24
1661 struct swrap_packet_frame {
1663 uint32_t micro_seconds;
1664 uint32_t recorded_length;
1665 uint32_t full_length;
1667 #define SWRAP_PACKET_FRAME_SIZE 16
1669 union swrap_packet_ip {
1673 uint16_t packet_length;
1674 uint16_t identification;
1679 uint16_t hdr_checksum;
1683 #define SWRAP_PACKET_IP_V4_SIZE 20
1686 uint8_t flow_label_high;
1687 uint16_t flow_label_low;
1688 uint16_t payload_length;
1689 uint8_t next_header;
1691 uint8_t src_addr[16];
1692 uint8_t dest_addr[16];
1694 #define SWRAP_PACKET_IP_V6_SIZE 40
1696 #define SWRAP_PACKET_IP_SIZE 40
1698 union swrap_packet_payload {
1700 uint16_t source_port;
1710 #define SWRAP_PACKET_PAYLOAD_TCP_SIZE 20
1712 uint16_t source_port;
1717 #define SWRAP_PACKET_PAYLOAD_UDP_SIZE 8
1724 #define SWRAP_PACKET_PAYLOAD_ICMP4_SIZE 8
1731 #define SWRAP_PACKET_PAYLOAD_ICMP6_SIZE 8
1733 #define SWRAP_PACKET_PAYLOAD_SIZE 20
1735 #define SWRAP_PACKET_MIN_ALLOC \
1736 (SWRAP_PACKET_FRAME_SIZE + \
1737 SWRAP_PACKET_IP_SIZE + \
1738 SWRAP_PACKET_PAYLOAD_SIZE)
1740 static const char *swrap_pcap_init_file(void)
1742 static int initialized = 0;
1743 static const char *s = NULL;
1744 static const struct swrap_file_hdr h;
1745 static const struct swrap_packet_frame f;
1746 static const union swrap_packet_ip i;
1747 static const union swrap_packet_payload p;
1749 if (initialized == 1) {
1755 * TODO: don't use the structs use plain buffer offsets
1756 * and PUSH_U8(), PUSH_U16() and PUSH_U32()
1758 * for now make sure we disable PCAP support
1759 * if the struct has alignment!
1761 if (sizeof(h) != SWRAP_FILE_HDR_SIZE) {
1764 if (sizeof(f) != SWRAP_PACKET_FRAME_SIZE) {
1767 if (sizeof(i) != SWRAP_PACKET_IP_SIZE) {
1770 if (sizeof(i.v4) != SWRAP_PACKET_IP_V4_SIZE) {
1773 if (sizeof(i.v6) != SWRAP_PACKET_IP_V6_SIZE) {
1776 if (sizeof(p) != SWRAP_PACKET_PAYLOAD_SIZE) {
1779 if (sizeof(p.tcp) != SWRAP_PACKET_PAYLOAD_TCP_SIZE) {
1782 if (sizeof(p.udp) != SWRAP_PACKET_PAYLOAD_UDP_SIZE) {
1785 if (sizeof(p.icmp4) != SWRAP_PACKET_PAYLOAD_ICMP4_SIZE) {
1788 if (sizeof(p.icmp6) != SWRAP_PACKET_PAYLOAD_ICMP6_SIZE) {
1792 s = getenv("SOCKET_WRAPPER_PCAP_FILE");
1796 if (strncmp(s, "./", 2) == 0) {
1802 static uint8_t *swrap_pcap_packet_init(struct timeval *tval,
1803 const struct sockaddr *src,
1804 const struct sockaddr *dest,
1806 const uint8_t *payload,
1808 unsigned long tcp_seqno,
1809 unsigned long tcp_ack,
1810 unsigned char tcp_ctl,
1812 size_t *_packet_len)
1816 struct swrap_packet_frame *frame;
1817 union swrap_packet_ip *ip;
1818 union swrap_packet_payload *pay;
1821 size_t nonwire_len = sizeof(*frame);
1822 size_t wire_hdr_len = 0;
1823 size_t wire_len = 0;
1824 size_t ip_hdr_len = 0;
1825 size_t icmp_hdr_len = 0;
1826 size_t icmp_truncate_len = 0;
1827 uint8_t protocol = 0, icmp_protocol = 0;
1828 const struct sockaddr_in *src_in = NULL;
1829 const struct sockaddr_in *dest_in = NULL;
1831 const struct sockaddr_in6 *src_in6 = NULL;
1832 const struct sockaddr_in6 *dest_in6 = NULL;
1837 switch (src->sa_family) {
1839 src_in = (const struct sockaddr_in *)(const void *)src;
1840 dest_in = (const struct sockaddr_in *)(const void *)dest;
1841 src_port = src_in->sin_port;
1842 dest_port = dest_in->sin_port;
1843 ip_hdr_len = sizeof(ip->v4);
1847 src_in6 = (const struct sockaddr_in6 *)(const void *)src;
1848 dest_in6 = (const struct sockaddr_in6 *)(const void *)dest;
1849 src_port = src_in6->sin6_port;
1850 dest_port = dest_in6->sin6_port;
1851 ip_hdr_len = sizeof(ip->v6);
1858 switch (socket_type) {
1860 protocol = 0x06; /* TCP */
1861 wire_hdr_len = ip_hdr_len + sizeof(pay->tcp);
1862 wire_len = wire_hdr_len + payload_len;
1866 protocol = 0x11; /* UDP */
1867 wire_hdr_len = ip_hdr_len + sizeof(pay->udp);
1868 wire_len = wire_hdr_len + payload_len;
1876 icmp_protocol = protocol;
1877 switch (src->sa_family) {
1879 protocol = 0x01; /* ICMPv4 */
1880 icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp4);
1884 protocol = 0x3A; /* ICMPv6 */
1885 icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp6);
1889 if (wire_len > 64 ) {
1890 icmp_truncate_len = wire_len - 64;
1892 wire_hdr_len += icmp_hdr_len;
1893 wire_len += icmp_hdr_len;
1896 packet_len = nonwire_len + wire_len;
1897 alloc_len = packet_len;
1898 if (alloc_len < SWRAP_PACKET_MIN_ALLOC) {
1899 alloc_len = SWRAP_PACKET_MIN_ALLOC;
1902 base = (uint8_t *)calloc(1, alloc_len);
1909 frame = (struct swrap_packet_frame *)(void *)buf;
1910 frame->seconds = tval->tv_sec;
1911 frame->micro_seconds = tval->tv_usec;
1912 frame->recorded_length = wire_len - icmp_truncate_len;
1913 frame->full_length = wire_len - icmp_truncate_len;
1914 buf += SWRAP_PACKET_FRAME_SIZE;
1916 ip = (union swrap_packet_ip *)(void *)buf;
1917 switch (src->sa_family) {
1919 ip->v4.ver_hdrlen = 0x45; /* version 4 and 5 * 32 bit words */
1921 ip->v4.packet_length = htons(wire_len - icmp_truncate_len);
1922 ip->v4.identification = htons(0xFFFF);
1923 ip->v4.flags = 0x40; /* BIT 1 set - means don't fragment */
1924 ip->v4.fragment = htons(0x0000);
1926 ip->v4.protocol = protocol;
1927 ip->v4.hdr_checksum = htons(0x0000);
1928 ip->v4.src_addr = src_in->sin_addr.s_addr;
1929 ip->v4.dest_addr = dest_in->sin_addr.s_addr;
1930 buf += SWRAP_PACKET_IP_V4_SIZE;
1934 ip->v6.ver_prio = 0x60; /* version 4 and 5 * 32 bit words */
1935 ip->v6.flow_label_high = 0x00;
1936 ip->v6.flow_label_low = 0x0000;
1937 ip->v6.payload_length = htons(wire_len - icmp_truncate_len); /* TODO */
1938 ip->v6.next_header = protocol;
1939 memcpy(ip->v6.src_addr, src_in6->sin6_addr.s6_addr, 16);
1940 memcpy(ip->v6.dest_addr, dest_in6->sin6_addr.s6_addr, 16);
1941 buf += SWRAP_PACKET_IP_V6_SIZE;
1947 pay = (union swrap_packet_payload *)(void *)buf;
1948 switch (src->sa_family) {
1950 pay->icmp4.type = 0x03; /* destination unreachable */
1951 pay->icmp4.code = 0x01; /* host unreachable */
1952 pay->icmp4.checksum = htons(0x0000);
1953 pay->icmp4.unused = htonl(0x00000000);
1954 buf += SWRAP_PACKET_PAYLOAD_ICMP4_SIZE;
1956 /* set the ip header in the ICMP payload */
1957 ip = (union swrap_packet_ip *)(void *)buf;
1958 ip->v4.ver_hdrlen = 0x45; /* version 4 and 5 * 32 bit words */
1960 ip->v4.packet_length = htons(wire_len - icmp_hdr_len);
1961 ip->v4.identification = htons(0xFFFF);
1962 ip->v4.flags = 0x40; /* BIT 1 set - means don't fragment */
1963 ip->v4.fragment = htons(0x0000);
1965 ip->v4.protocol = icmp_protocol;
1966 ip->v4.hdr_checksum = htons(0x0000);
1967 ip->v4.src_addr = dest_in->sin_addr.s_addr;
1968 ip->v4.dest_addr = src_in->sin_addr.s_addr;
1969 buf += SWRAP_PACKET_IP_V4_SIZE;
1971 src_port = dest_in->sin_port;
1972 dest_port = src_in->sin_port;
1976 pay->icmp6.type = 0x01; /* destination unreachable */
1977 pay->icmp6.code = 0x03; /* address unreachable */
1978 pay->icmp6.checksum = htons(0x0000);
1979 pay->icmp6.unused = htonl(0x00000000);
1980 buf += SWRAP_PACKET_PAYLOAD_ICMP6_SIZE;
1982 /* set the ip header in the ICMP payload */
1983 ip = (union swrap_packet_ip *)(void *)buf;
1984 ip->v6.ver_prio = 0x60; /* version 4 and 5 * 32 bit words */
1985 ip->v6.flow_label_high = 0x00;
1986 ip->v6.flow_label_low = 0x0000;
1987 ip->v6.payload_length = htons(wire_len - icmp_truncate_len); /* TODO */
1988 ip->v6.next_header = protocol;
1989 memcpy(ip->v6.src_addr, dest_in6->sin6_addr.s6_addr, 16);
1990 memcpy(ip->v6.dest_addr, src_in6->sin6_addr.s6_addr, 16);
1991 buf += SWRAP_PACKET_IP_V6_SIZE;
1993 src_port = dest_in6->sin6_port;
1994 dest_port = src_in6->sin6_port;
2000 pay = (union swrap_packet_payload *)(void *)buf;
2002 switch (socket_type) {
2004 pay->tcp.source_port = src_port;
2005 pay->tcp.dest_port = dest_port;
2006 pay->tcp.seq_num = htonl(tcp_seqno);
2007 pay->tcp.ack_num = htonl(tcp_ack);
2008 pay->tcp.hdr_length = 0x50; /* 5 * 32 bit words */
2009 pay->tcp.control = tcp_ctl;
2010 pay->tcp.window = htons(0x7FFF);
2011 pay->tcp.checksum = htons(0x0000);
2012 pay->tcp.urg = htons(0x0000);
2013 buf += SWRAP_PACKET_PAYLOAD_TCP_SIZE;
2018 pay->udp.source_port = src_port;
2019 pay->udp.dest_port = dest_port;
2020 pay->udp.length = htons(8 + payload_len);
2021 pay->udp.checksum = htons(0x0000);
2022 buf += SWRAP_PACKET_PAYLOAD_UDP_SIZE;
2027 if (payload && payload_len > 0) {
2028 memcpy(buf, payload, payload_len);
2031 *_packet_len = packet_len - icmp_truncate_len;
2035 static int swrap_pcap_get_fd(const char *fname)
2039 if (fd != -1) return fd;
2041 fd = libc_open(fname, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0644);
2043 struct swrap_file_hdr file_hdr;
2044 file_hdr.magic = 0xA1B2C3D4;
2045 file_hdr.version_major = 0x0002;
2046 file_hdr.version_minor = 0x0004;
2047 file_hdr.timezone = 0x00000000;
2048 file_hdr.sigfigs = 0x00000000;
2049 file_hdr.frame_max_len = SWRAP_FRAME_LENGTH_MAX;
2050 file_hdr.link_type = 0x0065; /* 101 RAW IP */
2052 if (write(fd, &file_hdr, sizeof(file_hdr)) != sizeof(file_hdr)) {
2059 fd = libc_open(fname, O_WRONLY|O_APPEND, 0644);
2064 static uint8_t *swrap_pcap_marshall_packet(struct socket_info *si,
2065 const struct sockaddr *addr,
2066 enum swrap_packet_type type,
2067 const void *buf, size_t len,
2070 const struct sockaddr *src_addr;
2071 const struct sockaddr *dest_addr;
2072 unsigned long tcp_seqno = 0;
2073 unsigned long tcp_ack = 0;
2074 unsigned char tcp_ctl = 0;
2075 int unreachable = 0;
2079 switch (si->family) {
2091 case SWRAP_CONNECT_SEND:
2092 if (si->type != SOCK_STREAM) return NULL;
2094 src_addr = &si->myname.sa.s;
2097 tcp_seqno = si->io.pck_snd;
2098 tcp_ack = si->io.pck_rcv;
2099 tcp_ctl = 0x02; /* SYN */
2101 si->io.pck_snd += 1;
2105 case SWRAP_CONNECT_RECV:
2106 if (si->type != SOCK_STREAM) return NULL;
2108 dest_addr = &si->myname.sa.s;
2111 tcp_seqno = si->io.pck_rcv;
2112 tcp_ack = si->io.pck_snd;
2113 tcp_ctl = 0x12; /** SYN,ACK */
2115 si->io.pck_rcv += 1;
2119 case SWRAP_CONNECT_UNREACH:
2120 if (si->type != SOCK_STREAM) return NULL;
2122 dest_addr = &si->myname.sa.s;
2125 /* Unreachable: resend the data of SWRAP_CONNECT_SEND */
2126 tcp_seqno = si->io.pck_snd - 1;
2127 tcp_ack = si->io.pck_rcv;
2128 tcp_ctl = 0x02; /* SYN */
2133 case SWRAP_CONNECT_ACK:
2134 if (si->type != SOCK_STREAM) return NULL;
2136 src_addr = &si->myname.sa.s;
2139 tcp_seqno = si->io.pck_snd;
2140 tcp_ack = si->io.pck_rcv;
2141 tcp_ctl = 0x10; /* ACK */
2145 case SWRAP_ACCEPT_SEND:
2146 if (si->type != SOCK_STREAM) return NULL;
2148 dest_addr = &si->myname.sa.s;
2151 tcp_seqno = si->io.pck_rcv;
2152 tcp_ack = si->io.pck_snd;
2153 tcp_ctl = 0x02; /* SYN */
2155 si->io.pck_rcv += 1;
2159 case SWRAP_ACCEPT_RECV:
2160 if (si->type != SOCK_STREAM) return NULL;
2162 src_addr = &si->myname.sa.s;
2165 tcp_seqno = si->io.pck_snd;
2166 tcp_ack = si->io.pck_rcv;
2167 tcp_ctl = 0x12; /* SYN,ACK */
2169 si->io.pck_snd += 1;
2173 case SWRAP_ACCEPT_ACK:
2174 if (si->type != SOCK_STREAM) return NULL;
2176 dest_addr = &si->myname.sa.s;
2179 tcp_seqno = si->io.pck_rcv;
2180 tcp_ack = si->io.pck_snd;
2181 tcp_ctl = 0x10; /* ACK */
2186 src_addr = &si->myname.sa.s;
2187 dest_addr = &si->peername.sa.s;
2189 tcp_seqno = si->io.pck_snd;
2190 tcp_ack = si->io.pck_rcv;
2191 tcp_ctl = 0x18; /* PSH,ACK */
2193 si->io.pck_snd += len;
2197 case SWRAP_SEND_RST:
2198 dest_addr = &si->myname.sa.s;
2199 src_addr = &si->peername.sa.s;
2201 if (si->type == SOCK_DGRAM) {
2202 return swrap_pcap_marshall_packet(si,
2204 SWRAP_SENDTO_UNREACH,
2210 tcp_seqno = si->io.pck_rcv;
2211 tcp_ack = si->io.pck_snd;
2212 tcp_ctl = 0x14; /** RST,ACK */
2216 case SWRAP_PENDING_RST:
2217 dest_addr = &si->myname.sa.s;
2218 src_addr = &si->peername.sa.s;
2220 if (si->type == SOCK_DGRAM) {
2224 tcp_seqno = si->io.pck_rcv;
2225 tcp_ack = si->io.pck_snd;
2226 tcp_ctl = 0x14; /* RST,ACK */
2231 dest_addr = &si->myname.sa.s;
2232 src_addr = &si->peername.sa.s;
2234 tcp_seqno = si->io.pck_rcv;
2235 tcp_ack = si->io.pck_snd;
2236 tcp_ctl = 0x18; /* PSH,ACK */
2238 si->io.pck_rcv += len;
2242 case SWRAP_RECV_RST:
2243 dest_addr = &si->myname.sa.s;
2244 src_addr = &si->peername.sa.s;
2246 if (si->type == SOCK_DGRAM) {
2250 tcp_seqno = si->io.pck_rcv;
2251 tcp_ack = si->io.pck_snd;
2252 tcp_ctl = 0x14; /* RST,ACK */
2257 src_addr = &si->myname.sa.s;
2260 si->io.pck_snd += len;
2264 case SWRAP_SENDTO_UNREACH:
2265 dest_addr = &si->myname.sa.s;
2272 case SWRAP_RECVFROM:
2273 dest_addr = &si->myname.sa.s;
2276 si->io.pck_rcv += len;
2280 case SWRAP_CLOSE_SEND:
2281 if (si->type != SOCK_STREAM) return NULL;
2283 src_addr = &si->myname.sa.s;
2284 dest_addr = &si->peername.sa.s;
2286 tcp_seqno = si->io.pck_snd;
2287 tcp_ack = si->io.pck_rcv;
2288 tcp_ctl = 0x11; /* FIN, ACK */
2290 si->io.pck_snd += 1;
2294 case SWRAP_CLOSE_RECV:
2295 if (si->type != SOCK_STREAM) return NULL;
2297 dest_addr = &si->myname.sa.s;
2298 src_addr = &si->peername.sa.s;
2300 tcp_seqno = si->io.pck_rcv;
2301 tcp_ack = si->io.pck_snd;
2302 tcp_ctl = 0x11; /* FIN,ACK */
2304 si->io.pck_rcv += 1;
2308 case SWRAP_CLOSE_ACK:
2309 if (si->type != SOCK_STREAM) return NULL;
2311 src_addr = &si->myname.sa.s;
2312 dest_addr = &si->peername.sa.s;
2314 tcp_seqno = si->io.pck_snd;
2315 tcp_ack = si->io.pck_rcv;
2316 tcp_ctl = 0x10; /* ACK */
2323 swrapGetTimeOfDay(&tv);
2325 return swrap_pcap_packet_init(&tv,
2329 (const uint8_t *)buf,
2338 static void swrap_pcap_dump_packet(struct socket_info *si,
2339 const struct sockaddr *addr,
2340 enum swrap_packet_type type,
2341 const void *buf, size_t len)
2343 const char *file_name;
2345 size_t packet_len = 0;
2348 file_name = swrap_pcap_init_file();
2353 packet = swrap_pcap_marshall_packet(si,
2359 if (packet == NULL) {
2363 fd = swrap_pcap_get_fd(file_name);
2365 if (write(fd, packet, packet_len) != (ssize_t)packet_len) {
2374 /****************************************************************************
2376 ***************************************************************************/
2378 #ifdef HAVE_SIGNALFD
2379 static int swrap_signalfd(int fd, const sigset_t *mask, int flags)
2383 rc = libc_signalfd(fd, mask, flags);
2385 swrap_remove_stale(fd);
2391 int signalfd(int fd, const sigset_t *mask, int flags)
2393 return swrap_signalfd(fd, mask, flags);
2397 /****************************************************************************
2399 ***************************************************************************/
2401 static int swrap_socket(int family, int type, int protocol)
2403 struct socket_info *si;
2404 struct socket_info_fd *fi;
2406 int real_type = type;
2409 * Remove possible addition flags passed to socket() so
2410 * do not fail checking the type.
2411 * See https://lwn.net/Articles/281965/
2414 real_type &= ~SOCK_CLOEXEC;
2416 #ifdef SOCK_NONBLOCK
2417 real_type &= ~SOCK_NONBLOCK;
2420 if (!socket_wrapper_enabled()) {
2421 return libc_socket(family, type, protocol);
2432 #endif /* AF_NETLINK */
2435 #endif /* AF_PACKET */
2437 return libc_socket(family, type, protocol);
2439 errno = EAFNOSUPPORT;
2443 switch (real_type) {
2449 errno = EPROTONOSUPPORT;
2457 if (real_type == SOCK_STREAM) {
2462 if (real_type == SOCK_DGRAM) {
2467 errno = EPROTONOSUPPORT;
2472 * We must call libc_socket with type, from the caller, not the version
2473 * we removed SOCK_CLOEXEC and SOCK_NONBLOCK from
2475 fd = libc_socket(AF_UNIX, type, 0);
2481 /* Check if we have a stale fd and remove it */
2482 swrap_remove_stale(fd);
2484 si = (struct socket_info *)calloc(1, sizeof(struct socket_info));
2490 si->family = family;
2492 /* however, the rest of the socket_wrapper code expects just
2493 * the type, not the flags */
2494 si->type = real_type;
2495 si->protocol = protocol;
2498 * Setup myname so getsockname() can succeed to find out the socket
2501 switch(si->family) {
2503 struct sockaddr_in sin = {
2504 .sin_family = AF_INET,
2507 si->myname.sa_socklen = sizeof(struct sockaddr_in);
2508 memcpy(&si->myname.sa.in, &sin, si->myname.sa_socklen);
2512 struct sockaddr_in6 sin6 = {
2513 .sin6_family = AF_INET6,
2516 si->myname.sa_socklen = sizeof(struct sockaddr_in6);
2517 memcpy(&si->myname.sa.in6, &sin6, si->myname.sa_socklen);
2526 fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
2537 SWRAP_DLIST_ADD(socket_fds, fi);
2539 SWRAP_LOG(SWRAP_LOG_TRACE,
2540 "Created %s socket for protocol %s",
2541 si->family == AF_INET ? "IPv4" : "IPv6",
2542 si->type == SOCK_DGRAM ? "UDP" : "TCP");
2547 int socket(int family, int type, int protocol)
2549 return swrap_socket(family, type, protocol);
2552 /****************************************************************************
2554 ***************************************************************************/
2556 static int swrap_socketpair(int family, int type, int protocol, int sv[2])
2560 rc = libc_socketpair(family, type, protocol, sv);
2562 swrap_remove_stale(sv[0]);
2563 swrap_remove_stale(sv[1]);
2569 int socketpair(int family, int type, int protocol, int sv[2])
2571 return swrap_socketpair(family, type, protocol, sv);
2574 /****************************************************************************
2576 ***************************************************************************/
2578 #ifdef HAVE_TIMERFD_CREATE
2579 static int swrap_timerfd_create(int clockid, int flags)
2583 fd = libc_timerfd_create(clockid, flags);
2585 swrap_remove_stale(fd);
2591 int timerfd_create(int clockid, int flags)
2593 return swrap_timerfd_create(clockid, flags);
2597 /****************************************************************************
2599 ***************************************************************************/
2601 static int swrap_pipe(int pipefd[2])
2605 rc = libc_pipe(pipefd);
2607 swrap_remove_stale(pipefd[0]);
2608 swrap_remove_stale(pipefd[1]);
2614 int pipe(int pipefd[2])
2616 return swrap_pipe(pipefd);
2619 /****************************************************************************
2621 ***************************************************************************/
2623 static int swrap_accept(int s,
2624 struct sockaddr *addr,
2628 struct socket_info *parent_si, *child_si;
2629 struct socket_info_fd *child_fi;
2631 struct swrap_address un_addr = {
2632 .sa_socklen = sizeof(struct sockaddr_un),
2634 struct swrap_address un_my_addr = {
2635 .sa_socklen = sizeof(struct sockaddr_un),
2637 struct swrap_address in_addr = {
2638 .sa_socklen = sizeof(struct sockaddr_storage),
2640 struct swrap_address in_my_addr = {
2641 .sa_socklen = sizeof(struct sockaddr_storage),
2645 parent_si = find_socket_info(s);
2648 return libc_accept4(s, addr, addrlen, flags);
2650 return libc_accept(s, addr, addrlen);
2655 * assume out sockaddr have the same size as the in parent
2658 in_addr.sa_socklen = socket_length(parent_si->family);
2659 if (in_addr.sa_socklen <= 0) {
2665 ret = libc_accept4(s, &un_addr.sa.s, &un_addr.sa_socklen, flags);
2667 ret = libc_accept(s, &un_addr.sa.s, &un_addr.sa_socklen);
2670 if (errno == ENOTSOCK) {
2671 /* Remove stale fds */
2672 swrap_remove_stale(s);
2679 ret = sockaddr_convert_from_un(parent_si,
2684 &in_addr.sa_socklen);
2690 child_si = (struct socket_info *)calloc(1, sizeof(struct socket_info));
2691 if (child_si == NULL) {
2697 child_fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
2698 if (child_fi == NULL) {
2707 child_si->family = parent_si->family;
2708 child_si->type = parent_si->type;
2709 child_si->protocol = parent_si->protocol;
2710 child_si->bound = 1;
2711 child_si->is_server = 1;
2712 child_si->connected = 1;
2714 child_si->peername = (struct swrap_address) {
2715 .sa_socklen = in_addr.sa_socklen,
2717 memcpy(&child_si->peername.sa.ss, &in_addr.sa.ss, in_addr.sa_socklen);
2719 if (addr != NULL && addrlen != NULL) {
2720 size_t copy_len = MIN(*addrlen, in_addr.sa_socklen);
2722 memcpy(addr, &in_addr.sa.ss, copy_len);
2724 *addrlen = in_addr.sa_socklen;
2727 ret = libc_getsockname(fd,
2729 &un_my_addr.sa_socklen);
2737 ret = sockaddr_convert_from_un(child_si,
2739 un_my_addr.sa_socklen,
2742 &in_my_addr.sa_socklen);
2750 SWRAP_LOG(SWRAP_LOG_TRACE,
2751 "accept() path=%s, fd=%d",
2752 un_my_addr.sa.un.sun_path, s);
2754 child_si->myname = (struct swrap_address) {
2755 .sa_socklen = in_my_addr.sa_socklen,
2757 memcpy(&child_si->myname.sa.ss, &in_my_addr.sa.ss, in_my_addr.sa_socklen);
2759 child_si->refcount = 1;
2760 child_fi->si = child_si;
2762 SWRAP_DLIST_ADD(socket_fds, child_fi);
2765 swrap_pcap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0);
2766 swrap_pcap_dump_packet(child_si, addr, SWRAP_ACCEPT_RECV, NULL, 0);
2767 swrap_pcap_dump_packet(child_si, addr, SWRAP_ACCEPT_ACK, NULL, 0);
2774 int accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags)
2776 return swrap_accept(s, addr, (socklen_t *)addrlen, flags);
2780 #ifdef HAVE_ACCEPT_PSOCKLEN_T
2781 int accept(int s, struct sockaddr *addr, Psocklen_t addrlen)
2783 int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
2786 return swrap_accept(s, addr, (socklen_t *)addrlen, 0);
2789 static int autobind_start_init;
2790 static int autobind_start;
2792 /* using sendto() or connect() on an unbound socket would give the
2793 recipient no way to reply, as unlike UDP and TCP, a unix domain
2794 socket can't auto-assign ephemeral port numbers, so we need to
2796 Note: this might change the family from ipv6 to ipv4
2798 static int swrap_auto_bind(int fd, struct socket_info *si, int family)
2800 struct swrap_address un_addr = {
2801 .sa_socklen = sizeof(struct sockaddr_un),
2809 if (autobind_start_init != 1) {
2810 autobind_start_init = 1;
2811 autobind_start = getpid();
2812 autobind_start %= 50000;
2813 autobind_start += 10000;
2816 un_addr.sa.un.sun_family = AF_UNIX;
2820 struct sockaddr_in in;
2824 type = SOCKET_TYPE_CHAR_TCP;
2827 type = SOCKET_TYPE_CHAR_UDP;
2830 errno = ESOCKTNOSUPPORT;
2834 memset(&in, 0, sizeof(in));
2835 in.sin_family = AF_INET;
2836 in.sin_addr.s_addr = htonl(127<<24 |
2837 socket_wrapper_default_iface());
2839 si->myname = (struct swrap_address) {
2840 .sa_socklen = sizeof(in),
2842 memcpy(&si->myname.sa.in, &in, si->myname.sa_socklen);
2847 struct sockaddr_in6 in6;
2849 if (si->family != family) {
2850 errno = ENETUNREACH;
2856 type = SOCKET_TYPE_CHAR_TCP_V6;
2859 type = SOCKET_TYPE_CHAR_UDP_V6;
2862 errno = ESOCKTNOSUPPORT;
2866 memset(&in6, 0, sizeof(in6));
2867 in6.sin6_family = AF_INET6;
2868 in6.sin6_addr = *swrap_ipv6();
2869 in6.sin6_addr.s6_addr[15] = socket_wrapper_default_iface();
2871 si->myname = (struct swrap_address) {
2872 .sa_socklen = sizeof(in6),
2874 memcpy(&si->myname.sa.in6, &in6, si->myname.sa_socklen);
2879 errno = ESOCKTNOSUPPORT;
2883 if (autobind_start > 60000) {
2884 autobind_start = 10000;
2887 for (i = 0; i < SOCKET_MAX_SOCKETS; i++) {
2888 port = autobind_start + i;
2889 snprintf(un_addr.sa.un.sun_path, sizeof(un_addr.sa.un.sun_path),
2890 "%s/"SOCKET_FORMAT, socket_wrapper_dir(),
2891 type, socket_wrapper_default_iface(), port);
2892 if (stat(un_addr.sa.un.sun_path, &st) == 0) continue;
2894 ret = libc_bind(fd, &un_addr.sa.s, un_addr.sa_socklen);
2895 if (ret == -1) return ret;
2897 si->un_addr = un_addr.sa.un;
2900 autobind_start = port + 1;
2903 if (i == SOCKET_MAX_SOCKETS) {
2904 SWRAP_LOG(SWRAP_LOG_ERROR, "Too many open unix sockets (%u) for "
2905 "interface "SOCKET_FORMAT,
2908 socket_wrapper_default_iface(),
2914 si->family = family;
2915 set_port(si->family, port, &si->myname);
2920 /****************************************************************************
2922 ***************************************************************************/
2924 static int swrap_connect(int s, const struct sockaddr *serv_addr,
2928 struct swrap_address un_addr = {
2929 .sa_socklen = sizeof(struct sockaddr_un),
2931 struct socket_info *si = find_socket_info(s);
2935 return libc_connect(s, serv_addr, addrlen);
2938 if (si->bound == 0) {
2939 ret = swrap_auto_bind(s, si, serv_addr->sa_family);
2940 if (ret == -1) return -1;
2943 if (si->family != serv_addr->sa_family) {
2948 ret = sockaddr_convert_to_un(si, serv_addr,
2949 addrlen, &un_addr.sa.un, 0, &bcast);
2950 if (ret == -1) return -1;
2953 errno = ENETUNREACH;
2957 if (si->type == SOCK_DGRAM) {
2958 si->defer_connect = 1;
2961 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0);
2963 ret = libc_connect(s,
2965 un_addr.sa_socklen);
2968 SWRAP_LOG(SWRAP_LOG_TRACE,
2969 "connect() path=%s, fd=%d",
2970 un_addr.sa.un.sun_path, s);
2973 /* to give better errors */
2974 if (ret == -1 && errno == ENOENT) {
2975 errno = EHOSTUNREACH;
2979 si->peername = (struct swrap_address) {
2980 .sa_socklen = addrlen,
2983 memcpy(&si->peername.sa.ss, serv_addr, addrlen);
2987 * When we connect() on a socket than we have to bind the
2988 * outgoing connection on the interface we use for the
2989 * transport. We already bound it on the right interface
2990 * but here we have to update the name so getsockname()
2991 * returns correct information.
2993 if (si->bindname.sa_socklen > 0) {
2994 si->myname = (struct swrap_address) {
2995 .sa_socklen = si->bindname.sa_socklen,
2998 memcpy(&si->myname.sa.ss,
2999 &si->bindname.sa.ss,
3000 si->bindname.sa_socklen);
3002 /* Cleanup bindname */
3003 si->bindname = (struct swrap_address) {
3008 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0);
3009 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0);
3011 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0);
3017 int connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen)
3019 return swrap_connect(s, serv_addr, addrlen);
3022 /****************************************************************************
3024 ***************************************************************************/
3026 static int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
3029 struct swrap_address un_addr = {
3030 .sa_socklen = sizeof(struct sockaddr_un),
3032 struct socket_info *si = find_socket_info(s);
3039 return libc_bind(s, myaddr, addrlen);
3042 switch (si->family) {
3044 const struct sockaddr_in *sin;
3045 if (addrlen < sizeof(struct sockaddr_in)) {
3046 bind_error = EINVAL;
3050 sin = (const struct sockaddr_in *)(const void *)myaddr;
3052 if (sin->sin_family != AF_INET) {
3053 bind_error = EAFNOSUPPORT;
3056 /* special case for AF_UNSPEC */
3057 if (sin->sin_family == AF_UNSPEC &&
3058 (sin->sin_addr.s_addr == htonl(INADDR_ANY)))
3067 const struct sockaddr_in6 *sin6;
3068 if (addrlen < sizeof(struct sockaddr_in6)) {
3069 bind_error = EINVAL;
3073 sin6 = (const struct sockaddr_in6 *)(const void *)myaddr;
3075 if (sin6->sin6_family != AF_INET6) {
3076 bind_error = EAFNOSUPPORT;
3083 bind_error = EINVAL;
3087 if (bind_error != 0) {
3093 in_use = check_addr_port_in_use(myaddr, addrlen);
3100 si->myname.sa_socklen = addrlen;
3101 memcpy(&si->myname.sa.ss, myaddr, addrlen);
3103 ret = sockaddr_convert_to_un(si,
3109 if (ret == -1) return -1;
3111 unlink(un_addr.sa.un.sun_path);
3113 ret = libc_bind(s, &un_addr.sa.s, un_addr.sa_socklen);
3115 SWRAP_LOG(SWRAP_LOG_TRACE,
3116 "bind() path=%s, fd=%d",
3117 un_addr.sa.un.sun_path, s);
3126 int bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
3128 return swrap_bind(s, myaddr, addrlen);
3131 /****************************************************************************
3133 ***************************************************************************/
3135 #ifdef HAVE_BINDRESVPORT
3136 static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen);
3138 static int swrap_bindresvport_sa(int sd, struct sockaddr *sa)
3140 struct swrap_address myaddr = {
3141 .sa_socklen = sizeof(struct sockaddr_storage),
3144 static uint16_t port;
3149 #define SWRAP_STARTPORT 600
3150 #define SWRAP_ENDPORT (IPPORT_RESERVED - 1)
3151 #define SWRAP_NPORTS (SWRAP_ENDPORT - SWRAP_STARTPORT + 1)
3154 port = (getpid() % SWRAP_NPORTS) + SWRAP_STARTPORT;
3158 salen = myaddr.sa_socklen;
3161 rc = swrap_getsockname(sd, &myaddr.sa.s, &salen);
3167 memset(&myaddr.sa.ss, 0, salen);
3172 for (i = 0; i < SWRAP_NPORTS; i++, port++) {
3175 struct sockaddr_in *sinp = (struct sockaddr_in *)(void *)sa;
3177 salen = sizeof(struct sockaddr_in);
3178 sinp->sin_port = htons(port);
3182 struct sockaddr_in6 *sin6p = (struct sockaddr_in6 *)(void *)sa;
3184 salen = sizeof(struct sockaddr_in6);
3185 sin6p->sin6_port = htons(port);
3189 errno = EAFNOSUPPORT;
3194 if (port > SWRAP_ENDPORT) {
3195 port = SWRAP_STARTPORT;
3198 rc = swrap_bind(sd, (struct sockaddr *)sa, salen);
3199 if (rc == 0 || errno != EADDRINUSE) {
3207 int bindresvport(int sockfd, struct sockaddr_in *sinp)
3209 return swrap_bindresvport_sa(sockfd, (struct sockaddr *)sinp);
3213 /****************************************************************************
3215 ***************************************************************************/
3217 static int swrap_listen(int s, int backlog)
3220 struct socket_info *si = find_socket_info(s);
3223 return libc_listen(s, backlog);
3226 if (si->bound == 0) {
3227 ret = swrap_auto_bind(s, si, si->family);
3234 ret = libc_listen(s, backlog);
3239 int listen(int s, int backlog)
3241 return swrap_listen(s, backlog);
3244 /****************************************************************************
3246 ***************************************************************************/
3248 static FILE *swrap_fopen(const char *name, const char *mode)
3252 fp = libc_fopen(name, mode);
3254 int fd = fileno(fp);
3256 swrap_remove_stale(fd);
3262 FILE *fopen(const char *name, const char *mode)
3264 return swrap_fopen(name, mode);
3267 /****************************************************************************
3269 ***************************************************************************/
3271 static int swrap_vopen(const char *pathname, int flags, va_list ap)
3275 ret = libc_vopen(pathname, flags, ap);
3278 * There are methods for closing descriptors (libc-internal code
3279 * paths, direct syscalls) which close descriptors in ways that
3280 * we can't intercept, so try to recover when we notice that
3283 swrap_remove_stale(ret);
3288 int open(const char *pathname, int flags, ...)
3293 va_start(ap, flags);
3294 fd = swrap_vopen(pathname, flags, ap);
3300 /****************************************************************************
3302 ***************************************************************************/
3304 static int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
3306 struct socket_info *si = find_socket_info(s);
3310 return libc_getpeername(s, name, addrlen);
3313 if (si->peername.sa_socklen == 0)
3319 len = MIN(*addrlen, si->peername.sa_socklen);
3324 memcpy(name, &si->peername.sa.ss, len);
3325 *addrlen = si->peername.sa_socklen;
3330 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3331 int getpeername(int s, struct sockaddr *name, Psocklen_t addrlen)
3333 int getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
3336 return swrap_getpeername(s, name, (socklen_t *)addrlen);
3339 /****************************************************************************
3341 ***************************************************************************/
3343 static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
3345 struct socket_info *si = find_socket_info(s);
3349 return libc_getsockname(s, name, addrlen);
3352 len = MIN(*addrlen, si->myname.sa_socklen);
3357 memcpy(name, &si->myname.sa.ss, len);
3358 *addrlen = si->myname.sa_socklen;
3363 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3364 int getsockname(int s, struct sockaddr *name, Psocklen_t addrlen)
3366 int getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
3369 return swrap_getsockname(s, name, (socklen_t *)addrlen);
3372 /****************************************************************************
3374 ***************************************************************************/
3377 # ifdef SO_PROTOTYPE /* The Solaris name */
3378 # define SO_PROTOCOL SO_PROTOTYPE
3379 # endif /* SO_PROTOTYPE */
3380 #endif /* SO_PROTOCOL */
3382 static int swrap_getsockopt(int s, int level, int optname,
3383 void *optval, socklen_t *optlen)
3385 struct socket_info *si = find_socket_info(s);
3388 return libc_getsockopt(s,
3395 if (level == SOL_SOCKET) {
3399 if (optval == NULL || optlen == NULL ||
3400 *optlen < (socklen_t)sizeof(int)) {
3405 *optlen = sizeof(int);
3406 *(int *)optval = si->family;
3408 #endif /* SO_DOMAIN */
3412 if (optval == NULL || optlen == NULL ||
3413 *optlen < (socklen_t)sizeof(int)) {
3418 *optlen = sizeof(int);
3419 *(int *)optval = si->protocol;
3421 #endif /* SO_PROTOCOL */
3423 if (optval == NULL || optlen == NULL ||
3424 *optlen < (socklen_t)sizeof(int)) {
3429 *optlen = sizeof(int);
3430 *(int *)optval = si->type;
3433 return libc_getsockopt(s,
3439 } else if (level == IPPROTO_TCP) {
3444 * This enables sending packets directly out over TCP.
3445 * As a unix socket is doing that any way, report it as
3448 if (optval == NULL || optlen == NULL ||
3449 *optlen < (socklen_t)sizeof(int)) {
3454 *optlen = sizeof(int);
3455 *(int *)optval = si->tcp_nodelay;
3458 #endif /* TCP_NODELAY */
3464 errno = ENOPROTOOPT;
3468 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3469 int getsockopt(int s, int level, int optname, void *optval, Psocklen_t optlen)
3471 int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
3474 return swrap_getsockopt(s, level, optname, optval, (socklen_t *)optlen);
3477 /****************************************************************************
3479 ***************************************************************************/
3481 static int swrap_setsockopt(int s, int level, int optname,
3482 const void *optval, socklen_t optlen)
3484 struct socket_info *si = find_socket_info(s);
3487 return libc_setsockopt(s,
3494 if (level == SOL_SOCKET) {
3495 return libc_setsockopt(s,
3500 } else if (level == IPPROTO_TCP) {
3507 * This enables sending packets directly out over TCP.
3508 * A unix socket is doing that any way.
3510 if (optval == NULL || optlen == 0 ||
3511 optlen < (socklen_t)sizeof(int)) {
3516 i = *discard_const_p(int, optval);
3517 if (i != 0 && i != 1) {
3521 si->tcp_nodelay = i;
3525 #endif /* TCP_NODELAY */
3531 switch (si->family) {
3533 if (level == IPPROTO_IP) {
3535 if (optname == IP_PKTINFO) {
3536 si->pktinfo = AF_INET;
3538 #endif /* IP_PKTINFO */
3543 if (level == IPPROTO_IPV6) {
3544 #ifdef IPV6_RECVPKTINFO
3545 if (optname == IPV6_RECVPKTINFO) {
3546 si->pktinfo = AF_INET6;
3548 #endif /* IPV6_PKTINFO */
3553 errno = ENOPROTOOPT;
3558 int setsockopt(int s, int level, int optname,
3559 const void *optval, socklen_t optlen)
3561 return swrap_setsockopt(s, level, optname, optval, optlen);
3564 /****************************************************************************
3566 ***************************************************************************/
3568 static int swrap_vioctl(int s, unsigned long int r, va_list va)
3570 struct socket_info *si = find_socket_info(s);
3576 return libc_vioctl(s, r, va);
3581 rc = libc_vioctl(s, r, va);
3585 value = *((int *)va_arg(ap, int *));
3587 if (rc == -1 && errno != EAGAIN && errno != ENOBUFS) {
3588 swrap_pcap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
3589 } else if (value == 0) { /* END OF FILE */
3590 swrap_pcap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
3600 #ifdef HAVE_IOCTL_INT
3601 int ioctl(int s, int r, ...)
3603 int ioctl(int s, unsigned long int r, ...)
3611 rc = swrap_vioctl(s, (unsigned long int) r, va);
3622 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3625 # ifdef _ALIGN /* BSD */
3626 #define CMSG_ALIGN _ALIGN
3628 #define CMSG_ALIGN(len) (((len) + sizeof(size_t) - 1) & ~(sizeof(size_t) - 1))
3629 # endif /* _ALIGN */
3630 #endif /* CMSG_ALIGN */
3633 * @brief Add a cmsghdr to a msghdr.
3635 * This is an function to add any type of cmsghdr. It will operate on the
3636 * msg->msg_control and msg->msg_controllen you pass in by adapting them to
3637 * the buffer position after the added cmsg element. Hence, this function is
3638 * intended to be used with an intermediate msghdr and not on the original
3639 * one handed in by the client.
3641 * @param[in] msg The msghdr to which to add the cmsg.
3643 * @param[in] level The cmsg level to set.
3645 * @param[in] type The cmsg type to set.
3647 * @param[in] data The cmsg data to set.
3649 * @param[in] len the length of the data to set.
3651 static void swrap_msghdr_add_cmsghdr(struct msghdr *msg,
3657 size_t cmlen = CMSG_LEN(len);
3658 size_t cmspace = CMSG_SPACE(len);
3659 uint8_t cmbuf[cmspace];
3660 void *cast_ptr = (void *)cmbuf;
3661 struct cmsghdr *cm = (struct cmsghdr *)cast_ptr;
3664 memset(cmbuf, 0, cmspace);
3666 if (msg->msg_controllen < cmlen) {
3667 cmlen = msg->msg_controllen;
3668 msg->msg_flags |= MSG_CTRUNC;
3671 if (msg->msg_controllen < cmspace) {
3672 cmspace = msg->msg_controllen;
3676 * We copy the full input data into an intermediate cmsghdr first
3677 * in order to more easily cope with truncation.
3679 cm->cmsg_len = cmlen;
3680 cm->cmsg_level = level;
3681 cm->cmsg_type = type;
3682 memcpy(CMSG_DATA(cm), data, len);
3685 * We now copy the possibly truncated buffer.
3686 * We copy cmlen bytes, but consume cmspace bytes,
3687 * leaving the possible padding uninitialiazed.
3689 p = (uint8_t *)msg->msg_control;
3690 memcpy(p, cm, cmlen);
3692 msg->msg_control = p;
3693 msg->msg_controllen -= cmspace;
3698 static int swrap_msghdr_add_pktinfo(struct socket_info *si,
3701 /* Add packet info */
3702 switch (si->pktinfo) {
3703 #if defined(IP_PKTINFO) && (defined(HAVE_STRUCT_IN_PKTINFO) || defined(IP_RECVDSTADDR))
3705 struct sockaddr_in *sin;
3706 #if defined(HAVE_STRUCT_IN_PKTINFO)
3707 struct in_pktinfo pkt;
3708 #elif defined(IP_RECVDSTADDR)
3712 if (si->bindname.sa_socklen == sizeof(struct sockaddr_in)) {
3713 sin = &si->bindname.sa.in;
3715 if (si->myname.sa_socklen != sizeof(struct sockaddr_in)) {
3718 sin = &si->myname.sa.in;
3723 #if defined(HAVE_STRUCT_IN_PKTINFO)
3724 pkt.ipi_ifindex = socket_wrapper_default_iface();
3725 pkt.ipi_addr.s_addr = sin->sin_addr.s_addr;
3726 #elif defined(IP_RECVDSTADDR)
3727 pkt = sin->sin_addr;
3730 swrap_msghdr_add_cmsghdr(msg, IPPROTO_IP, IP_PKTINFO,
3735 #endif /* IP_PKTINFO */
3736 #if defined(HAVE_IPV6)
3738 #if defined(IPV6_PKTINFO) && defined(HAVE_STRUCT_IN6_PKTINFO)
3739 struct sockaddr_in6 *sin6;
3740 struct in6_pktinfo pkt6;
3742 if (si->bindname.sa_socklen == sizeof(struct sockaddr_in6)) {
3743 sin6 = &si->bindname.sa.in6;
3745 if (si->myname.sa_socklen != sizeof(struct sockaddr_in6)) {
3748 sin6 = &si->myname.sa.in6;
3753 pkt6.ipi6_ifindex = socket_wrapper_default_iface();
3754 pkt6.ipi6_addr = sin6->sin6_addr;
3756 swrap_msghdr_add_cmsghdr(msg, IPPROTO_IPV6, IPV6_PKTINFO,
3757 &pkt6, sizeof(pkt6));
3758 #endif /* HAVE_STRUCT_IN6_PKTINFO */
3762 #endif /* IPV6_PKTINFO */
3770 static int swrap_msghdr_add_socket_info(struct socket_info *si,
3771 struct msghdr *omsg)
3775 if (si->pktinfo > 0) {
3776 rc = swrap_msghdr_add_pktinfo(si, omsg);
3782 static int swrap_sendmsg_copy_cmsg(struct cmsghdr *cmsg,
3784 size_t *cm_data_space);
3785 static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr *cmsg,
3787 size_t *cm_data_space);
3789 static int swrap_sendmsg_filter_cmsghdr(struct msghdr *msg,
3791 size_t *cm_data_space) {
3792 struct cmsghdr *cmsg;
3796 if (msg->msg_controllen == 0 || msg->msg_control == NULL) {
3800 for (cmsg = CMSG_FIRSTHDR(msg);
3802 cmsg = CMSG_NXTHDR(msg, cmsg)) {
3803 switch (cmsg->cmsg_level) {
3805 rc = swrap_sendmsg_filter_cmsg_socket(cmsg,
3810 rc = swrap_sendmsg_copy_cmsg(cmsg,
3820 static int swrap_sendmsg_copy_cmsg(struct cmsghdr *cmsg,
3822 size_t *cm_data_space)
3827 cmspace = *cm_data_space + CMSG_ALIGN(cmsg->cmsg_len);
3829 p = realloc((*cm_data), cmspace);
3835 p = (*cm_data) + (*cm_data_space);
3836 *cm_data_space = cmspace;
3838 memcpy(p, cmsg, cmsg->cmsg_len);
3843 static int swrap_sendmsg_filter_cmsg_pktinfo(struct cmsghdr *cmsg,
3845 size_t *cm_data_space);
3848 static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr *cmsg,
3850 size_t *cm_data_space)
3854 switch(cmsg->cmsg_type) {
3857 rc = swrap_sendmsg_filter_cmsg_pktinfo(cmsg,
3864 rc = swrap_sendmsg_filter_cmsg_pktinfo(cmsg,
3876 static int swrap_sendmsg_filter_cmsg_pktinfo(struct cmsghdr *cmsg,
3878 size_t *cm_data_space)
3880 (void)cmsg; /* unused */
3881 (void)cm_data; /* unused */
3882 (void)cm_data_space; /* unused */
3885 * Passing a IP pktinfo to a unix socket might be rejected by the
3886 * Kernel, at least on FreeBSD. So skip this cmsg.
3890 #endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
3892 static ssize_t swrap_sendmsg_before(int fd,
3893 struct socket_info *si,
3895 struct iovec *tmp_iov,
3896 struct sockaddr_un *tmp_un,
3897 const struct sockaddr_un **to_un,
3898 const struct sockaddr **to,
3918 if (!si->connected) {
3923 if (msg->msg_iovlen == 0) {
3927 mtu = socket_wrapper_mtu();
3928 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3930 nlen = len + msg->msg_iov[i].iov_len;
3935 msg->msg_iovlen = i;
3936 if (msg->msg_iovlen == 0) {
3937 *tmp_iov = msg->msg_iov[0];
3938 tmp_iov->iov_len = MIN((size_t)tmp_iov->iov_len,
3940 msg->msg_iov = tmp_iov;
3941 msg->msg_iovlen = 1;
3946 if (si->connected) {
3947 if (msg->msg_name != NULL) {
3949 * We are dealing with unix sockets and if we
3950 * are connected, we should only talk to the
3951 * connected unix path. Using the fd to send
3952 * to another server would be hard to achieve.
3954 msg->msg_name = NULL;
3955 msg->msg_namelen = 0;
3958 const struct sockaddr *msg_name;
3959 msg_name = (const struct sockaddr *)msg->msg_name;
3961 if (msg_name == NULL) {
3967 ret = sockaddr_convert_to_un(si, msg_name, msg->msg_namelen,
3969 if (ret == -1) return -1;
3977 msg->msg_name = tmp_un;
3978 msg->msg_namelen = sizeof(*tmp_un);
3981 if (si->bound == 0) {
3982 ret = swrap_auto_bind(fd, si, si->family);
3984 if (errno == ENOTSOCK) {
3985 swrap_remove_stale(fd);
3988 SWRAP_LOG(SWRAP_LOG_ERROR, "swrap_sendmsg_before failed");
3994 if (!si->defer_connect) {
3998 ret = sockaddr_convert_to_un(si,
4000 si->peername.sa_socklen,
4004 if (ret == -1) return -1;
4006 ret = libc_connect(fd,
4007 (struct sockaddr *)(void *)tmp_un,
4010 /* to give better errors */
4011 if (ret == -1 && errno == ENOENT) {
4012 errno = EHOSTUNREACH;
4019 si->defer_connect = 0;
4022 errno = EHOSTUNREACH;
4026 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4027 if (msg->msg_controllen > 0 && msg->msg_control != NULL) {
4028 uint8_t *cmbuf = NULL;
4031 ret = swrap_sendmsg_filter_cmsghdr(msg, &cmbuf, &cmlen);
4038 msg->msg_controllen = 0;
4039 msg->msg_control = NULL;
4040 } else if (cmlen < msg->msg_controllen && cmbuf != NULL) {
4041 memcpy(msg->msg_control, cmbuf, cmlen);
4042 msg->msg_controllen = cmlen;
4051 static void swrap_sendmsg_after(int fd,
4052 struct socket_info *si,
4054 const struct sockaddr *to,
4057 int saved_errno = errno;
4064 /* to give better errors */
4066 if (saved_errno == ENOENT) {
4067 saved_errno = EHOSTUNREACH;
4068 } else if (saved_errno == ENOTSOCK) {
4069 /* If the fd is not a socket, remove it */
4070 swrap_remove_stale(fd);
4074 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
4075 avail += msg->msg_iov[i].iov_len;
4079 remain = MIN(80, avail);
4084 /* we capture it as one single packet */
4085 buf = (uint8_t *)malloc(remain);
4087 /* we just not capture the packet */
4088 errno = saved_errno;
4092 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
4093 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
4095 msg->msg_iov[i].iov_base,
4098 remain -= this_time;
4105 swrap_pcap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
4106 swrap_pcap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
4108 swrap_pcap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
4113 if (si->connected) {
4114 to = &si->peername.sa.s;
4117 swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
4118 swrap_pcap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);
4120 swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
4126 errno = saved_errno;
4129 static int swrap_recvmsg_before(int fd,
4130 struct socket_info *si,
4132 struct iovec *tmp_iov)
4137 (void)fd; /* unused */
4142 if (!si->connected) {
4147 if (msg->msg_iovlen == 0) {
4151 mtu = socket_wrapper_mtu();
4152 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
4154 nlen = len + msg->msg_iov[i].iov_len;
4159 msg->msg_iovlen = i;
4160 if (msg->msg_iovlen == 0) {
4161 *tmp_iov = msg->msg_iov[0];
4162 tmp_iov->iov_len = MIN((size_t)tmp_iov->iov_len,
4164 msg->msg_iov = tmp_iov;
4165 msg->msg_iovlen = 1;
4170 if (msg->msg_name == NULL) {
4175 if (msg->msg_iovlen == 0) {
4179 if (si->bound == 0) {
4180 ret = swrap_auto_bind(fd, si, si->family);
4183 * When attempting to read or write to a
4184 * descriptor, if an underlying autobind fails
4185 * because it's not a socket, stop intercepting
4186 * uses of that descriptor.
4188 if (errno == ENOTSOCK) {
4189 swrap_remove_stale(fd);
4192 SWRAP_LOG(SWRAP_LOG_ERROR,
4193 "swrap_recvmsg_before failed");
4200 errno = EHOSTUNREACH;
4207 static int swrap_recvmsg_after(int fd,
4208 struct socket_info *si,
4210 const struct sockaddr_un *un_addr,
4211 socklen_t un_addrlen,
4214 int saved_errno = errno;
4216 uint8_t *buf = NULL;
4222 /* to give better errors */
4224 if (saved_errno == ENOENT) {
4225 saved_errno = EHOSTUNREACH;
4226 } else if (saved_errno == ENOTSOCK) {
4227 /* If the fd is not a socket, remove it */
4228 swrap_remove_stale(fd);
4232 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
4233 avail += msg->msg_iov[i].iov_len;
4236 /* Convert the socket address before we leave */
4237 if (si->type == SOCK_DGRAM && un_addr != NULL) {
4238 rc = sockaddr_convert_from_un(si,
4255 remain = MIN(80, avail);
4260 /* we capture it as one single packet */
4261 buf = (uint8_t *)malloc(remain);
4263 /* we just not capture the packet */
4264 errno = saved_errno;
4268 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
4269 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
4271 msg->msg_iov[i].iov_base,
4274 remain -= this_time;
4279 if (ret == -1 && saved_errno != EAGAIN && saved_errno != ENOBUFS) {
4280 swrap_pcap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
4281 } else if (ret == 0) { /* END OF FILE */
4282 swrap_pcap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
4283 } else if (ret > 0) {
4284 swrap_pcap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
4293 if (un_addr != NULL) {
4294 swrap_pcap_dump_packet(si,
4300 swrap_pcap_dump_packet(si,
4313 errno = saved_errno;
4315 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4317 msg->msg_controllen > 0 &&
4318 msg->msg_control != NULL) {
4319 rc = swrap_msghdr_add_socket_info(si, msg);
4329 /****************************************************************************
4331 ***************************************************************************/
4333 static ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags,
4334 struct sockaddr *from, socklen_t *fromlen)
4336 struct swrap_address from_addr = {
4337 .sa_socklen = sizeof(struct sockaddr_un),
4340 struct socket_info *si = find_socket_info(s);
4341 struct swrap_address saddr = {
4342 .sa_socklen = sizeof(struct sockaddr_storage),
4349 return libc_recvfrom(s,
4361 if (from != NULL && fromlen != NULL) {
4362 msg.msg_name = from; /* optional address */
4363 msg.msg_namelen = *fromlen; /* size of address */
4365 msg.msg_name = &saddr.sa.s; /* optional address */
4366 msg.msg_namelen = saddr.sa_socklen; /* size of address */
4368 msg.msg_iov = &tmp; /* scatter/gather array */
4369 msg.msg_iovlen = 1; /* # elements in msg_iov */
4370 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4371 msg.msg_control = NULL; /* ancillary data, see below */
4372 msg.msg_controllen = 0; /* ancillary data buffer len */
4373 msg.msg_flags = 0; /* flags on received message */
4376 tret = swrap_recvmsg_before(s, si, &msg, &tmp);
4381 buf = msg.msg_iov[0].iov_base;
4382 len = msg.msg_iov[0].iov_len;
4384 ret = libc_recvfrom(s,
4389 &from_addr.sa_socklen);
4394 tret = swrap_recvmsg_after(s,
4398 from_addr.sa_socklen,
4404 if (from != NULL && fromlen != NULL) {
4405 *fromlen = msg.msg_namelen;
4411 #ifdef HAVE_ACCEPT_PSOCKLEN_T
4412 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
4413 struct sockaddr *from, Psocklen_t fromlen)
4415 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
4416 struct sockaddr *from, socklen_t *fromlen)
4419 return swrap_recvfrom(s, buf, len, flags, from, (socklen_t *)fromlen);
4422 /****************************************************************************
4424 ***************************************************************************/
4426 static ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags,
4427 const struct sockaddr *to, socklen_t tolen)
4431 struct swrap_address un_addr = {
4432 .sa_socklen = sizeof(struct sockaddr_un),
4434 const struct sockaddr_un *to_un = NULL;
4437 struct socket_info *si = find_socket_info(s);
4441 return libc_sendto(s, buf, len, flags, to, tolen);
4444 tmp.iov_base = discard_const_p(char, buf);
4448 msg.msg_name = discard_const_p(struct sockaddr, to); /* optional address */
4449 msg.msg_namelen = tolen; /* size of address */
4450 msg.msg_iov = &tmp; /* scatter/gather array */
4451 msg.msg_iovlen = 1; /* # elements in msg_iov */
4452 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
4453 msg.msg_control = NULL; /* ancillary data, see below */
4454 msg.msg_controllen = 0; /* ancillary data buffer len */
4455 msg.msg_flags = 0; /* flags on received message */
4458 rc = swrap_sendmsg_before(s,
4470 buf = msg.msg_iov[0].iov_base;
4471 len = msg.msg_iov[0].iov_len;
4476 unsigned int prt = ntohs(((const struct sockaddr_in *)(const void *)to)->sin_port);
4479 type = SOCKET_TYPE_CHAR_UDP;
4481 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
4482 snprintf(un_addr.sa.un.sun_path,
4483 sizeof(un_addr.sa.un.sun_path),
4485 socket_wrapper_dir(), type, iface, prt);
4486 if (stat(un_addr.sa.un.sun_path, &st) != 0) continue;
4488 /* ignore the any errors in broadcast sends */
4494 un_addr.sa_socklen);
4497 swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
4503 * If it is a dgram socket and we are connected, don't include the
4506 if (si->type == SOCK_DGRAM && si->connected) {
4507 ret = libc_sendto(s,
4514 ret = libc_sendto(s,
4518 (struct sockaddr *)msg.msg_name,
4522 swrap_sendmsg_after(s, si, &msg, to, ret);
4527 ssize_t sendto(int s, const void *buf, size_t len, int flags,
4528 const struct sockaddr *to, socklen_t tolen)
4530 return swrap_sendto(s, buf, len, flags, to, tolen);
4533 /****************************************************************************
4535 ***************************************************************************/
4537 static ssize_t swrap_recv(int s, void *buf, size_t len, int flags)
4539 struct socket_info *si;
4541 struct swrap_address saddr = {
4542 .sa_socklen = sizeof(struct sockaddr_storage),
4548 si = find_socket_info(s);
4550 return libc_recv(s, buf, len, flags);
4557 msg.msg_name = &saddr.sa.s; /* optional address */
4558 msg.msg_namelen = saddr.sa_socklen; /* size of address */
4559 msg.msg_iov = &tmp; /* scatter/gather array */
4560 msg.msg_iovlen = 1; /* # elements in msg_iov */
4561 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4562 msg.msg_control = NULL; /* ancillary data, see below */
4563 msg.msg_controllen = 0; /* ancillary data buffer len */
4564 msg.msg_flags = 0; /* flags on received message */
4567 tret = swrap_recvmsg_before(s, si, &msg, &tmp);
4572 buf = msg.msg_iov[0].iov_base;
4573 len = msg.msg_iov[0].iov_len;
4575 ret = libc_recv(s, buf, len, flags);
4577 tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
4585 ssize_t recv(int s, void *buf, size_t len, int flags)
4587 return swrap_recv(s, buf, len, flags);
4590 /****************************************************************************
4592 ***************************************************************************/
4594 static ssize_t swrap_read(int s, void *buf, size_t len)
4596 struct socket_info *si;
4599 struct swrap_address saddr = {
4600 .sa_socklen = sizeof(struct sockaddr_storage),
4605 si = find_socket_info(s);
4607 return libc_read(s, buf, len);
4614 msg.msg_name = &saddr.sa.ss; /* optional address */
4615 msg.msg_namelen = saddr.sa_socklen; /* size of address */
4616 msg.msg_iov = &tmp; /* scatter/gather array */
4617 msg.msg_iovlen = 1; /* # elements in msg_iov */
4618 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4619 msg.msg_control = NULL; /* ancillary data, see below */
4620 msg.msg_controllen = 0; /* ancillary data buffer len */
4621 msg.msg_flags = 0; /* flags on received message */
4624 tret = swrap_recvmsg_before(s, si, &msg, &tmp);
4626 if (tret == -ENOTSOCK) {
4627 return libc_read(s, buf, len);
4632 buf = msg.msg_iov[0].iov_base;
4633 len = msg.msg_iov[0].iov_len;
4635 ret = libc_read(s, buf, len);
4637 tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
4645 ssize_t read(int s, void *buf, size_t len)
4647 return swrap_read(s, buf, len);
4650 /****************************************************************************
4652 ***************************************************************************/
4654 static ssize_t swrap_write(int s, const void *buf, size_t len)
4658 struct sockaddr_un un_addr;
4661 struct socket_info *si;
4663 si = find_socket_info(s);
4665 return libc_write(s, buf, len);
4668 tmp.iov_base = discard_const_p(char, buf);
4672 msg.msg_name = NULL; /* optional address */
4673 msg.msg_namelen = 0; /* size of address */
4674 msg.msg_iov = &tmp; /* scatter/gather array */
4675 msg.msg_iovlen = 1; /* # elements in msg_iov */
4676 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
4677 msg.msg_control = NULL; /* ancillary data, see below */
4678 msg.msg_controllen = 0; /* ancillary data buffer len */
4679 msg.msg_flags = 0; /* flags on received message */
4682 rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
4687 buf = msg.msg_iov[0].iov_base;
4688 len = msg.msg_iov[0].iov_len;
4690 ret = libc_write(s, buf, len);
4692 swrap_sendmsg_after(s, si, &msg, NULL, ret);
4697 ssize_t write(int s, const void *buf, size_t len)
4699 return swrap_write(s, buf, len);
4702 /****************************************************************************
4704 ***************************************************************************/
4706 static ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
4710 struct sockaddr_un un_addr;
4713 struct socket_info *si = find_socket_info(s);
4716 return libc_send(s, buf, len, flags);
4719 tmp.iov_base = discard_const_p(char, buf);
4723 msg.msg_name = NULL; /* optional address */
4724 msg.msg_namelen = 0; /* size of address */
4725 msg.msg_iov = &tmp; /* scatter/gather array */
4726 msg.msg_iovlen = 1; /* # elements in msg_iov */
4727 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
4728 msg.msg_control = NULL; /* ancillary data, see below */
4729 msg.msg_controllen = 0; /* ancillary data buffer len */
4730 msg.msg_flags = 0; /* flags on received message */
4733 rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
4738 buf = msg.msg_iov[0].iov_base;
4739 len = msg.msg_iov[0].iov_len;
4741 ret = libc_send(s, buf, len, flags);
4743 swrap_sendmsg_after(s, si, &msg, NULL, ret);
4748 ssize_t send(int s, const void *buf, size_t len, int flags)
4750 return swrap_send(s, buf, len, flags);
4753 /****************************************************************************
4755 ***************************************************************************/
4757 static ssize_t swrap_recvmsg(int s, struct msghdr *omsg, int flags)
4759 struct swrap_address from_addr = {
4760 .sa_socklen = sizeof(struct sockaddr_un),
4762 struct swrap_address convert_addr = {
4763 .sa_socklen = sizeof(struct sockaddr_storage),
4765 struct socket_info *si;
4768 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4769 size_t msg_ctrllen_filled;
4770 size_t msg_ctrllen_left;
4776 si = find_socket_info(s);
4778 return libc_recvmsg(s, omsg, flags);
4781 tmp.iov_base = NULL;
4785 msg.msg_name = &from_addr.sa; /* optional address */
4786 msg.msg_namelen = from_addr.sa_socklen; /* size of address */
4787 msg.msg_iov = omsg->msg_iov; /* scatter/gather array */
4788 msg.msg_iovlen = omsg->msg_iovlen; /* # elements in msg_iov */
4789 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4790 msg_ctrllen_filled = 0;
4791 msg_ctrllen_left = omsg->msg_controllen;
4793 msg.msg_control = omsg->msg_control; /* ancillary data, see below */
4794 msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
4795 msg.msg_flags = omsg->msg_flags; /* flags on received message */
4798 rc = swrap_recvmsg_before(s, si, &msg, &tmp);
4803 ret = libc_recvmsg(s, &msg, flags);
4805 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4806 msg_ctrllen_filled += msg.msg_controllen;
4807 msg_ctrllen_left -= msg.msg_controllen;
4809 if (omsg->msg_control != NULL) {
4812 p = omsg->msg_control;
4813 p += msg_ctrllen_filled;
4815 msg.msg_control = p;
4816 msg.msg_controllen = msg_ctrllen_left;
4818 msg.msg_control = NULL;
4819 msg.msg_controllen = 0;
4824 * We convert the unix address to a IP address so we need a buffer
4825 * which can store the address in case of SOCK_DGRAM, see below.
4827 msg.msg_name = &convert_addr.sa;
4828 msg.msg_namelen = convert_addr.sa_socklen;
4830 rc = swrap_recvmsg_after(s,
4834 from_addr.sa_socklen,
4840 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4841 if (omsg->msg_control != NULL) {
4842 /* msg.msg_controllen = space left */
4843 msg_ctrllen_left = msg.msg_controllen;
4844 msg_ctrllen_filled = omsg->msg_controllen - msg_ctrllen_left;
4847 /* Update the original message length */
4848 omsg->msg_controllen = msg_ctrllen_filled;
4849 omsg->msg_flags = msg.msg_flags;
4851 omsg->msg_iovlen = msg.msg_iovlen;
4856 * The msg_name field points to a caller-allocated buffer that is
4857 * used to return the source address if the socket is unconnected. The
4858 * caller should set msg_namelen to the size of this buffer before this
4859 * call; upon return from a successful call, msg_name will contain the
4860 * length of the returned address. If the application does not need
4861 * to know the source address, msg_name can be specified as NULL.
4863 if (si->type == SOCK_STREAM) {
4864 omsg->msg_namelen = 0;
4865 } else if (omsg->msg_name != NULL &&
4866 omsg->msg_namelen != 0 &&
4867 omsg->msg_namelen >= msg.msg_namelen) {
4868 memcpy(omsg->msg_name, msg.msg_name, msg.msg_namelen);
4869 omsg->msg_namelen = msg.msg_namelen;
4875 ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)
4877 return swrap_recvmsg(sockfd, msg, flags);
4880 /****************************************************************************
4882 ***************************************************************************/
4884 static ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags)
4888 struct sockaddr_un un_addr;
4889 const struct sockaddr_un *to_un = NULL;
4890 const struct sockaddr *to = NULL;
4893 struct socket_info *si = find_socket_info(s);
4897 return libc_sendmsg(s, omsg, flags);
4900 ZERO_STRUCT(un_addr);
4902 tmp.iov_base = NULL;
4907 if (si->connected == 0) {
4908 msg.msg_name = omsg->msg_name; /* optional address */
4909 msg.msg_namelen = omsg->msg_namelen; /* size of address */
4911 msg.msg_iov = omsg->msg_iov; /* scatter/gather array */
4912 msg.msg_iovlen = omsg->msg_iovlen; /* # elements in msg_iov */
4913 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4914 if (msg.msg_controllen > 0 && msg.msg_control != NULL) {
4915 /* omsg is a const so use a local buffer for modifications */
4916 uint8_t cmbuf[omsg->msg_controllen];
4918 memcpy(cmbuf, omsg->msg_control, omsg->msg_controllen);
4920 msg.msg_control = cmbuf; /* ancillary data, see below */
4921 msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
4923 msg.msg_flags = omsg->msg_flags; /* flags on received message */
4926 rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
4934 unsigned int prt = ntohs(((const struct sockaddr_in *)(const void *)to)->sin_port);
4942 for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
4943 avail += msg.msg_iov[i].iov_len;
4949 /* we capture it as one single packet */
4950 buf = (uint8_t *)malloc(remain);
4955 for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
4956 size_t this_time = MIN(remain, (size_t)msg.msg_iov[i].iov_len);
4958 msg.msg_iov[i].iov_base,
4961 remain -= this_time;
4964 type = SOCKET_TYPE_CHAR_UDP;
4966 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
4967 snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT,
4968 socket_wrapper_dir(), type, iface, prt);
4969 if (stat(un_addr.sun_path, &st) != 0) continue;
4971 msg.msg_name = &un_addr; /* optional address */
4972 msg.msg_namelen = sizeof(un_addr); /* size of address */
4974 /* ignore the any errors in broadcast sends */
4975 libc_sendmsg(s, &msg, flags);
4978 swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
4984 ret = libc_sendmsg(s, &msg, flags);
4986 swrap_sendmsg_after(s, si, &msg, to, ret);
4991 ssize_t sendmsg(int s, const struct msghdr *omsg, int flags)
4993 return swrap_sendmsg(s, omsg, flags);
4996 /****************************************************************************
4998 ***************************************************************************/
5000 static ssize_t swrap_readv(int s, const struct iovec *vector, int count)
5002 struct socket_info *si;
5005 struct swrap_address saddr = {
5006 .sa_socklen = sizeof(struct sockaddr_storage)
5011 si = find_socket_info(s);
5013 return libc_readv(s, vector, count);
5016 tmp.iov_base = NULL;
5020 msg.msg_name = &saddr.sa.s; /* optional address */
5021 msg.msg_namelen = saddr.sa_socklen; /* size of address */
5022 msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
5023 msg.msg_iovlen = count; /* # elements in msg_iov */
5024 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5025 msg.msg_control = NULL; /* ancillary data, see below */
5026 msg.msg_controllen = 0; /* ancillary data buffer len */
5027 msg.msg_flags = 0; /* flags on received message */
5030 rc = swrap_recvmsg_before(s, si, &msg, &tmp);
5032 if (rc == -ENOTSOCK) {
5033 return libc_readv(s, vector, count);
5038 ret = libc_readv(s, msg.msg_iov, msg.msg_iovlen);
5040 rc = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
5048 ssize_t readv(int s, const struct iovec *vector, int count)
5050 return swrap_readv(s, vector, count);
5053 /****************************************************************************
5055 ***************************************************************************/
5057 static ssize_t swrap_writev(int s, const struct iovec *vector, int count)
5061 struct sockaddr_un un_addr;
5064 struct socket_info *si = find_socket_info(s);
5067 return libc_writev(s, vector, count);
5070 tmp.iov_base = NULL;
5074 msg.msg_name = NULL; /* optional address */
5075 msg.msg_namelen = 0; /* size of address */
5076 msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
5077 msg.msg_iovlen = count; /* # elements in msg_iov */
5078 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
5079 msg.msg_control = NULL; /* ancillary data, see below */
5080 msg.msg_controllen = 0; /* ancillary data buffer len */
5081 msg.msg_flags = 0; /* flags on received message */
5084 rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
5086 if (rc == -ENOTSOCK) {
5087 return libc_readv(s, vector, count);
5092 ret = libc_writev(s, msg.msg_iov, msg.msg_iovlen);
5094 swrap_sendmsg_after(s, si, &msg, NULL, ret);
5099 ssize_t writev(int s, const struct iovec *vector, int count)
5101 return swrap_writev(s, vector, count);
5104 /****************************
5106 ***************************/
5108 static int swrap_close(int fd)
5110 struct socket_info_fd *fi = find_socket_info_fd(fd);
5111 struct socket_info *si = NULL;
5115 return libc_close(fd);
5120 SWRAP_DLIST_REMOVE(socket_fds, fi);
5125 if (si->refcount > 0) {
5126 /* there are still references left */
5127 return libc_close(fd);
5130 if (si->myname.sa_socklen > 0 && si->peername.sa_socklen > 0) {
5131 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0);
5134 ret = libc_close(fd);
5136 if (si->myname.sa_socklen > 0 && si->peername.sa_socklen > 0) {
5137 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0);
5138 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0);
5141 if (si->un_addr.sun_path[0] != '\0') {
5142 unlink(si->un_addr.sun_path);
5151 return swrap_close(fd);
5154 /****************************
5156 ***************************/
5158 static int swrap_dup(int fd)
5160 struct socket_info *si;
5161 struct socket_info_fd *src_fi, *fi;
5163 src_fi = find_socket_info_fd(fd);
5164 if (src_fi == NULL) {
5165 return libc_dup(fd);
5170 fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
5176 fi->fd = libc_dup(fd);
5178 int saved_errno = errno;
5180 errno = saved_errno;
5187 /* Make sure we don't have an entry for the fd */
5188 swrap_remove_stale(fi->fd);
5190 SWRAP_DLIST_ADD_AFTER(socket_fds, fi, src_fi);
5196 return swrap_dup(fd);
5199 /****************************
5201 ***************************/
5203 static int swrap_dup2(int fd, int newfd)
5205 struct socket_info *si;
5206 struct socket_info_fd *src_fi, *fi;
5208 src_fi = find_socket_info_fd(fd);
5209 if (src_fi == NULL) {
5210 return libc_dup2(fd, newfd);
5217 * According to the manpage:
5219 * "If oldfd is a valid file descriptor, and newfd has the same
5220 * value as oldfd, then dup2() does nothing, and returns newfd."
5225 if (find_socket_info(newfd)) {
5226 /* dup2() does an implicit close of newfd, which we
5227 * need to emulate */
5231 fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
5237 fi->fd = libc_dup2(fd, newfd);
5239 int saved_errno = errno;
5241 errno = saved_errno;
5248 /* Make sure we don't have an entry for the fd */
5249 swrap_remove_stale(fi->fd);
5251 SWRAP_DLIST_ADD_AFTER(socket_fds, fi, src_fi);
5255 int dup2(int fd, int newfd)
5257 return swrap_dup2(fd, newfd);
5260 /****************************
5262 ***************************/
5264 static int swrap_vfcntl(int fd, int cmd, va_list va)
5266 struct socket_info_fd *fi;
5267 struct socket_info *si;
5270 si = find_socket_info(fd);
5272 rc = libc_vfcntl(fd, cmd, va);
5279 fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
5285 fi->fd = libc_vfcntl(fd, cmd, va);
5287 int saved_errno = errno;
5289 errno = saved_errno;
5296 /* Make sure we don't have an entry for the fd */
5297 swrap_remove_stale(fi->fd);
5299 SWRAP_DLIST_ADD(socket_fds, fi);
5304 rc = libc_vfcntl(fd, cmd, va);
5311 int fcntl(int fd, int cmd, ...)
5318 rc = swrap_vfcntl(fd, cmd, va);
5325 /****************************
5327 ***************************/
5330 static int swrap_eventfd(int count, int flags)
5334 fd = libc_eventfd(count, flags);
5336 swrap_remove_stale(fd);
5342 #ifdef HAVE_EVENTFD_UNSIGNED_INT
5343 int eventfd(unsigned int count, int flags)
5345 int eventfd(int count, int flags)
5348 return swrap_eventfd(count, flags);
5353 int pledge(const char *promises, const char *paths[])
5355 (void)promises; /* unused */
5356 (void)paths; /* unused */
5360 #endif /* HAVE_PLEDGE */
5362 /****************************
5364 ***************************/
5367 * This function is called when the library is unloaded and makes sure that
5368 * sockets get closed and the unix file for the socket are unlinked.
5370 void swrap_destructor(void)
5372 struct socket_info_fd *s = socket_fds;
5379 if (swrap.libc_handle != NULL) {
5380 dlclose(swrap.libc_handle);
5382 if (swrap.libsocket_handle) {
5383 dlclose(swrap.libsocket_handle);