3ac802abe9416a1e8915720251f704ac52a7b083
[socket_wrapper.git] / src / socket_wrapper.c
1 /*
2  * BSD 3-Clause License
3  *
4  * Copyright (c) 2005-2008, Jelmer Vernooij <jelmer@samba.org>
5  * Copyright (c) 2006-2018, Stefan Metzmacher <metze@samba.org>
6  * Copyright (c) 2013-2018, Andreas Schneider <asn@samba.org>
7  * Copyright (c) 2014-2017, Michael Adam <obnox@samba.org>
8  * Copyright (c) 2016-2018, Anoop C S <anoopcs@redhat.com>
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  *
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  *
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  *
22  * 3. Neither the name of the author nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  */
38
39 /*
40    Socket wrapper library. Passes all socket communication over
41    unix domain sockets if the environment variable SOCKET_WRAPPER_DIR
42    is set.
43 */
44
45 #include "config.h"
46
47 #include <sys/types.h>
48 #include <sys/time.h>
49 #include <sys/stat.h>
50 #include <sys/socket.h>
51 #include <sys/ioctl.h>
52 #ifdef HAVE_SYS_FILIO_H
53 #include <sys/filio.h>
54 #endif
55 #ifdef HAVE_SYS_SIGNALFD_H
56 #include <sys/signalfd.h>
57 #endif
58 #ifdef HAVE_SYS_EVENTFD_H
59 #include <sys/eventfd.h>
60 #endif
61 #ifdef HAVE_SYS_TIMERFD_H
62 #include <sys/timerfd.h>
63 #endif
64 #include <sys/uio.h>
65 #include <errno.h>
66 #include <sys/un.h>
67 #include <netinet/in.h>
68 #include <netinet/tcp.h>
69 #ifdef HAVE_NETINET_TCP_FSM_H
70 #include <netinet/tcp_fsm.h>
71 #endif
72 #include <arpa/inet.h>
73 #include <fcntl.h>
74 #include <stdlib.h>
75 #include <string.h>
76 #include <stdio.h>
77 #include <stdint.h>
78 #include <stdarg.h>
79 #include <stdbool.h>
80 #include <unistd.h>
81 #ifdef HAVE_GNU_LIB_NAMES_H
82 #include <gnu/lib-names.h>
83 #endif
84 #ifdef HAVE_RPC_RPC_H
85 #include <rpc/rpc.h>
86 #endif
87 #include <pthread.h>
88
89 enum swrap_dbglvl_e {
90         SWRAP_LOG_ERROR = 0,
91         SWRAP_LOG_WARN,
92         SWRAP_LOG_DEBUG,
93         SWRAP_LOG_TRACE
94 };
95
96 /* GCC have printf type attribute check. */
97 #ifdef HAVE_FUNCTION_ATTRIBUTE_FORMAT
98 #define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
99 #else
100 #define PRINTF_ATTRIBUTE(a,b)
101 #endif /* HAVE_FUNCTION_ATTRIBUTE_FORMAT */
102
103 #ifdef HAVE_CONSTRUCTOR_ATTRIBUTE
104 #define CONSTRUCTOR_ATTRIBUTE __attribute__ ((constructor))
105 #else
106 #define CONSTRUCTOR_ATTRIBUTE
107 #endif /* HAVE_CONSTRUCTOR_ATTRIBUTE */
108
109 #ifdef HAVE_DESTRUCTOR_ATTRIBUTE
110 #define DESTRUCTOR_ATTRIBUTE __attribute__ ((destructor))
111 #else
112 #define DESTRUCTOR_ATTRIBUTE
113 #endif
114
115 #ifndef FALL_THROUGH
116 # ifdef HAVE_FALLTHROUGH_ATTRIBUTE
117 #  define FALL_THROUGH __attribute__ ((fallthrough))
118 # else /* HAVE_FALLTHROUGH_ATTRIBUTE */
119 #  define FALL_THROUGH ((void)0)
120 # endif /* HAVE_FALLTHROUGH_ATTRIBUTE */
121 #endif /* FALL_THROUGH */
122
123 #ifdef HAVE_ADDRESS_SANITIZER_ATTRIBUTE
124 #define DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE __attribute__((no_sanitize_address))
125 #else
126 #define DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
127 #endif
128
129 #ifdef HAVE_GCC_THREAD_LOCAL_STORAGE
130 # define SWRAP_THREAD __thread
131 #else
132 # define SWRAP_THREAD
133 #endif
134
135 #ifndef MIN
136 #define MIN(a,b) ((a)<(b)?(a):(b))
137 #endif
138
139 #ifndef ZERO_STRUCT
140 #define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
141 #endif
142
143 #ifndef ZERO_STRUCTP
144 #define ZERO_STRUCTP(x) do { \
145                 if ((x) != NULL) \
146                         memset((char *)(x), 0, sizeof(*(x))); \
147         } while(0)
148 #endif
149
150 #ifndef SAFE_FREE
151 #define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0)
152 #endif
153
154 #ifndef discard_const
155 #define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
156 #endif
157
158 #ifndef discard_const_p
159 #define discard_const_p(type, ptr) ((type *)discard_const(ptr))
160 #endif
161
162 #define UNUSED(x) (void)(x)
163
164 #ifdef IPV6_PKTINFO
165 # ifndef IPV6_RECVPKTINFO
166 #  define IPV6_RECVPKTINFO IPV6_PKTINFO
167 # endif /* IPV6_RECVPKTINFO */
168 #endif /* IPV6_PKTINFO */
169
170 /*
171  * On BSD IP_PKTINFO has a different name because during
172  * the time when they implemented it, there was no RFC.
173  * The name for IPv6 is the same as on Linux.
174  */
175 #ifndef IP_PKTINFO
176 # ifdef IP_RECVDSTADDR
177 #  define IP_PKTINFO IP_RECVDSTADDR
178 # endif
179 #endif
180
181 #define socket_wrapper_init_mutex(m) \
182         _socket_wrapper_init_mutex(m, #m)
183
184 /* Add new global locks here please */
185 # define SWRAP_REINIT_ALL do { \
186         size_t __i; \
187         int ret; \
188         ret = socket_wrapper_init_mutex(&sockets_mutex); \
189         if (ret != 0) exit(-1); \
190         ret = socket_wrapper_init_mutex(&socket_reset_mutex); \
191         if (ret != 0) exit(-1); \
192         ret = socket_wrapper_init_mutex(&first_free_mutex); \
193         if (ret != 0) exit(-1); \
194         for (__i = 0; (sockets != NULL) && __i < socket_info_max; __i++) { \
195                 ret = socket_wrapper_init_mutex(&sockets[__i].meta.mutex); \
196                 if (ret != 0) exit(-1); \
197         } \
198         ret = socket_wrapper_init_mutex(&autobind_start_mutex); \
199         if (ret != 0) exit(-1); \
200         ret = socket_wrapper_init_mutex(&pcap_dump_mutex); \
201         if (ret != 0) exit(-1); \
202         ret = socket_wrapper_init_mutex(&mtu_update_mutex); \
203         if (ret != 0) exit(-1); \
204 } while(0)
205
206 # define SWRAP_LOCK_ALL do { \
207         size_t __i; \
208         swrap_mutex_lock(&sockets_mutex); \
209         swrap_mutex_lock(&socket_reset_mutex); \
210         swrap_mutex_lock(&first_free_mutex); \
211         for (__i = 0; (sockets != NULL) && __i < socket_info_max; __i++) { \
212                 swrap_mutex_lock(&sockets[__i].meta.mutex); \
213         } \
214         swrap_mutex_lock(&autobind_start_mutex); \
215         swrap_mutex_lock(&pcap_dump_mutex); \
216         swrap_mutex_lock(&mtu_update_mutex); \
217 } while(0)
218
219 # define SWRAP_UNLOCK_ALL do { \
220         size_t __s; \
221         swrap_mutex_unlock(&mtu_update_mutex); \
222         swrap_mutex_unlock(&pcap_dump_mutex); \
223         swrap_mutex_unlock(&autobind_start_mutex); \
224         for (__s = 0; (sockets != NULL) && __s < socket_info_max; __s++) { \
225                 size_t __i = (socket_info_max - 1) - __s; \
226                 swrap_mutex_unlock(&sockets[__i].meta.mutex); \
227         } \
228         swrap_mutex_unlock(&first_free_mutex); \
229         swrap_mutex_unlock(&socket_reset_mutex); \
230         swrap_mutex_unlock(&sockets_mutex); \
231 } while(0)
232
233 #define SOCKET_INFO_CONTAINER(si) \
234         (struct socket_info_container *)(si)
235
236 #define SWRAP_LOCK_SI(si) do { \
237         struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si); \
238         swrap_mutex_lock(&sic->meta.mutex); \
239 } while(0)
240
241 #define SWRAP_UNLOCK_SI(si) do { \
242         struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si); \
243         swrap_mutex_unlock(&sic->meta.mutex); \
244 } while(0)
245
246 #if defined(HAVE_GETTIMEOFDAY_TZ) || defined(HAVE_GETTIMEOFDAY_TZ_VOID)
247 #define swrapGetTimeOfDay(tval) gettimeofday(tval,NULL)
248 #else
249 #define swrapGetTimeOfDay(tval) gettimeofday(tval)
250 #endif
251
252 /* we need to use a very terse format here as IRIX 6.4 silently
253    truncates names to 16 chars, so if we use a longer name then we
254    can't tell which port a packet came from with recvfrom()
255
256    with this format we have 8 chars left for the directory name
257 */
258 #define SOCKET_FORMAT "%c%02X%04X"
259 #define SOCKET_TYPE_CHAR_TCP            'T'
260 #define SOCKET_TYPE_CHAR_UDP            'U'
261 #define SOCKET_TYPE_CHAR_TCP_V6         'X'
262 #define SOCKET_TYPE_CHAR_UDP_V6         'Y'
263
264 /*
265  * Set the packet MTU to 1500 bytes for stream sockets to make it it easier to
266  * format PCAP capture files (as the caller will simply continue from here).
267  */
268 #define SOCKET_WRAPPER_MTU_DEFAULT 1500
269 #define SOCKET_WRAPPER_MTU_MIN     512
270 #define SOCKET_WRAPPER_MTU_MAX     32768
271
272 #define SOCKET_MAX_SOCKETS 1024
273
274 /*
275  * Maximum number of socket_info structures that can
276  * be used. Can be overriden by the environment variable
277  * SOCKET_WRAPPER_MAX_SOCKETS.
278  */
279 #define SOCKET_WRAPPER_MAX_SOCKETS_DEFAULT 65535
280
281 #define SOCKET_WRAPPER_MAX_SOCKETS_LIMIT 262140
282
283 /* This limit is to avoid broadcast sendto() needing to stat too many
284  * files.  It may be raised (with a performance cost) to up to 254
285  * without changing the format above */
286 #define MAX_WRAPPED_INTERFACES 64
287
288 struct swrap_address {
289         socklen_t sa_socklen;
290         union {
291                 struct sockaddr s;
292                 struct sockaddr_in in;
293 #ifdef HAVE_IPV6
294                 struct sockaddr_in6 in6;
295 #endif
296                 struct sockaddr_un un;
297                 struct sockaddr_storage ss;
298         } sa;
299 };
300
301 static int first_free;
302
303 struct socket_info
304 {
305         int family;
306         int type;
307         int protocol;
308         int bound;
309         int bcast;
310         int is_server;
311         int connected;
312         int defer_connect;
313         int pktinfo;
314         int tcp_nodelay;
315         int listening;
316
317         /* The unix path so we can unlink it on close() */
318         struct sockaddr_un un_addr;
319
320         struct swrap_address bindname;
321         struct swrap_address myname;
322         struct swrap_address peername;
323
324         struct {
325                 unsigned long pck_snd;
326                 unsigned long pck_rcv;
327         } io;
328 };
329
330 struct socket_info_meta
331 {
332         unsigned int refcount;
333         int next_free;
334         pthread_mutex_t mutex;
335 };
336
337 struct socket_info_container
338 {
339         struct socket_info info;
340         struct socket_info_meta meta;
341 };
342
343 static struct socket_info_container *sockets;
344
345 static size_t socket_info_max = 0;
346
347 /*
348  * Allocate the socket array always on the limit value. We want it to be
349  * at least bigger than the default so if we reach the limit we can
350  * still deal with duplicate fds pointing to the same socket_info.
351  */
352 static size_t socket_fds_max = SOCKET_WRAPPER_MAX_SOCKETS_LIMIT;
353
354 /* Hash table to map fds to corresponding socket_info index */
355 static int *socket_fds_idx;
356
357 /* Mutex for syncronizing port selection during swrap_auto_bind() */
358 static pthread_mutex_t autobind_start_mutex = PTHREAD_MUTEX_INITIALIZER;
359
360 /* Mutex to guard the initialization of array of socket_info structures */
361 static pthread_mutex_t sockets_mutex = PTHREAD_MUTEX_INITIALIZER;
362
363 /* Mutex to guard the socket reset in swrap_close() and swrap_remove_stale() */
364 static pthread_mutex_t socket_reset_mutex = PTHREAD_MUTEX_INITIALIZER;
365
366 /* Mutex to synchronize access to first free index in socket_info array */
367 static pthread_mutex_t first_free_mutex = PTHREAD_MUTEX_INITIALIZER;
368
369 /* Mutex to synchronize access to packet capture dump file */
370 static pthread_mutex_t pcap_dump_mutex = PTHREAD_MUTEX_INITIALIZER;
371
372 /* Mutex for synchronizing mtu value fetch*/
373 static pthread_mutex_t mtu_update_mutex = PTHREAD_MUTEX_INITIALIZER;
374
375 /* Function prototypes */
376
377 bool socket_wrapper_enabled(void);
378
379 #if ! defined(HAVE_CONSTRUCTOR_ATTRIBUTE) && defined(HAVE_PRAGMA_INIT)
380 /* xlC and other oldschool compilers support (only) this */
381 #pragma init (swrap_constructor)
382 #endif
383 void swrap_constructor(void) CONSTRUCTOR_ATTRIBUTE;
384 #if ! defined(HAVE_DESTRUCTOR_ATTRIBUTE) && defined(HAVE_PRAGMA_FINI)
385 #pragma fini (swrap_destructor)
386 #endif
387 void swrap_destructor(void) DESTRUCTOR_ATTRIBUTE;
388
389 #ifndef HAVE_GETPROGNAME
390 static const char *getprogname(void)
391 {
392 #if defined(HAVE_PROGRAM_INVOCATION_SHORT_NAME)
393         return program_invocation_short_name;
394 #elif defined(HAVE_GETEXECNAME)
395         return getexecname();
396 #else
397         return NULL;
398 #endif /* HAVE_PROGRAM_INVOCATION_SHORT_NAME */
399 }
400 #endif /* HAVE_GETPROGNAME */
401
402 static void swrap_log(enum swrap_dbglvl_e dbglvl, const char *func, const char *format, ...) PRINTF_ATTRIBUTE(3, 4);
403 # define SWRAP_LOG(dbglvl, ...) swrap_log((dbglvl), __func__, __VA_ARGS__)
404
405 static void swrap_log(enum swrap_dbglvl_e dbglvl,
406                       const char *func,
407                       const char *format, ...)
408 {
409         char buffer[1024];
410         va_list va;
411         const char *d;
412         unsigned int lvl = 0;
413         const char *prefix = "SWRAP";
414         const char *progname = getprogname();
415
416         d = getenv("SOCKET_WRAPPER_DEBUGLEVEL");
417         if (d != NULL) {
418                 lvl = atoi(d);
419         }
420
421         if (lvl < dbglvl) {
422                 return;
423         }
424
425         va_start(va, format);
426         vsnprintf(buffer, sizeof(buffer), format, va);
427         va_end(va);
428
429         switch (dbglvl) {
430                 case SWRAP_LOG_ERROR:
431                         prefix = "SWRAP_ERROR";
432                         break;
433                 case SWRAP_LOG_WARN:
434                         prefix = "SWRAP_WARN";
435                         break;
436                 case SWRAP_LOG_DEBUG:
437                         prefix = "SWRAP_DEBUG";
438                         break;
439                 case SWRAP_LOG_TRACE:
440                         prefix = "SWRAP_TRACE";
441                         break;
442         }
443
444         if (progname == NULL) {
445                 progname = "<unknown>";
446         }
447
448         fprintf(stderr,
449                 "%s[%s (%u)] - %s: %s\n",
450                 prefix,
451                 progname,
452                 (unsigned int)getpid(),
453                 func,
454                 buffer);
455 }
456
457 /*********************************************************
458  * SWRAP LOADING LIBC FUNCTIONS
459  *********************************************************/
460
461 #include <dlfcn.h>
462
463 #ifdef HAVE_ACCEPT4
464 typedef int (*__libc_accept4)(int sockfd,
465                               struct sockaddr *addr,
466                               socklen_t *addrlen,
467                               int flags);
468 #else
469 typedef int (*__libc_accept)(int sockfd,
470                              struct sockaddr *addr,
471                              socklen_t *addrlen);
472 #endif
473 typedef int (*__libc_bind)(int sockfd,
474                            const struct sockaddr *addr,
475                            socklen_t addrlen);
476 typedef int (*__libc_close)(int fd);
477 typedef int (*__libc_connect)(int sockfd,
478                               const struct sockaddr *addr,
479                               socklen_t addrlen);
480 typedef int (*__libc_dup)(int fd);
481 typedef int (*__libc_dup2)(int oldfd, int newfd);
482 typedef int (*__libc_fcntl)(int fd, int cmd, ...);
483 typedef FILE *(*__libc_fopen)(const char *name, const char *mode);
484 #ifdef HAVE_FOPEN64
485 typedef FILE *(*__libc_fopen64)(const char *name, const char *mode);
486 #endif
487 #ifdef HAVE_EVENTFD
488 typedef int (*__libc_eventfd)(int count, int flags);
489 #endif
490 typedef int (*__libc_getpeername)(int sockfd,
491                                   struct sockaddr *addr,
492                                   socklen_t *addrlen);
493 typedef int (*__libc_getsockname)(int sockfd,
494                                   struct sockaddr *addr,
495                                   socklen_t *addrlen);
496 typedef int (*__libc_getsockopt)(int sockfd,
497                                int level,
498                                int optname,
499                                void *optval,
500                                socklen_t *optlen);
501 typedef int (*__libc_ioctl)(int d, unsigned long int request, ...);
502 typedef int (*__libc_listen)(int sockfd, int backlog);
503 typedef int (*__libc_open)(const char *pathname, int flags, ...);
504 #ifdef HAVE_OPEN64
505 typedef int (*__libc_open64)(const char *pathname, int flags, ...);
506 #endif /* HAVE_OPEN64 */
507 typedef int (*__libc_openat)(int dirfd, const char *path, int flags, ...);
508 typedef int (*__libc_pipe)(int pipefd[2]);
509 typedef int (*__libc_read)(int fd, void *buf, size_t count);
510 typedef ssize_t (*__libc_readv)(int fd, const struct iovec *iov, int iovcnt);
511 typedef int (*__libc_recv)(int sockfd, void *buf, size_t len, int flags);
512 typedef int (*__libc_recvfrom)(int sockfd,
513                              void *buf,
514                              size_t len,
515                              int flags,
516                              struct sockaddr *src_addr,
517                              socklen_t *addrlen);
518 typedef int (*__libc_recvmsg)(int sockfd, const struct msghdr *msg, int flags);
519 typedef int (*__libc_send)(int sockfd, const void *buf, size_t len, int flags);
520 typedef int (*__libc_sendmsg)(int sockfd, const struct msghdr *msg, int flags);
521 typedef int (*__libc_sendto)(int sockfd,
522                            const void *buf,
523                            size_t len,
524                            int flags,
525                            const  struct sockaddr *dst_addr,
526                            socklen_t addrlen);
527 typedef int (*__libc_setsockopt)(int sockfd,
528                                int level,
529                                int optname,
530                                const void *optval,
531                                socklen_t optlen);
532 #ifdef HAVE_SIGNALFD
533 typedef int (*__libc_signalfd)(int fd, const sigset_t *mask, int flags);
534 #endif
535 typedef int (*__libc_socket)(int domain, int type, int protocol);
536 typedef int (*__libc_socketpair)(int domain, int type, int protocol, int sv[2]);
537 #ifdef HAVE_TIMERFD_CREATE
538 typedef int (*__libc_timerfd_create)(int clockid, int flags);
539 #endif
540 typedef ssize_t (*__libc_write)(int fd, const void *buf, size_t count);
541 typedef ssize_t (*__libc_writev)(int fd, const struct iovec *iov, int iovcnt);
542
543 #define SWRAP_SYMBOL_ENTRY(i) \
544         union { \
545                 __libc_##i f; \
546                 void *obj; \
547         } _libc_##i
548
549 struct swrap_libc_symbols {
550 #ifdef HAVE_ACCEPT4
551         SWRAP_SYMBOL_ENTRY(accept4);
552 #else
553         SWRAP_SYMBOL_ENTRY(accept);
554 #endif
555         SWRAP_SYMBOL_ENTRY(bind);
556         SWRAP_SYMBOL_ENTRY(close);
557         SWRAP_SYMBOL_ENTRY(connect);
558         SWRAP_SYMBOL_ENTRY(dup);
559         SWRAP_SYMBOL_ENTRY(dup2);
560         SWRAP_SYMBOL_ENTRY(fcntl);
561         SWRAP_SYMBOL_ENTRY(fopen);
562 #ifdef HAVE_FOPEN64
563         SWRAP_SYMBOL_ENTRY(fopen64);
564 #endif
565 #ifdef HAVE_EVENTFD
566         SWRAP_SYMBOL_ENTRY(eventfd);
567 #endif
568         SWRAP_SYMBOL_ENTRY(getpeername);
569         SWRAP_SYMBOL_ENTRY(getsockname);
570         SWRAP_SYMBOL_ENTRY(getsockopt);
571         SWRAP_SYMBOL_ENTRY(ioctl);
572         SWRAP_SYMBOL_ENTRY(listen);
573         SWRAP_SYMBOL_ENTRY(open);
574 #ifdef HAVE_OPEN64
575         SWRAP_SYMBOL_ENTRY(open64);
576 #endif
577         SWRAP_SYMBOL_ENTRY(openat);
578         SWRAP_SYMBOL_ENTRY(pipe);
579         SWRAP_SYMBOL_ENTRY(read);
580         SWRAP_SYMBOL_ENTRY(readv);
581         SWRAP_SYMBOL_ENTRY(recv);
582         SWRAP_SYMBOL_ENTRY(recvfrom);
583         SWRAP_SYMBOL_ENTRY(recvmsg);
584         SWRAP_SYMBOL_ENTRY(send);
585         SWRAP_SYMBOL_ENTRY(sendmsg);
586         SWRAP_SYMBOL_ENTRY(sendto);
587         SWRAP_SYMBOL_ENTRY(setsockopt);
588 #ifdef HAVE_SIGNALFD
589         SWRAP_SYMBOL_ENTRY(signalfd);
590 #endif
591         SWRAP_SYMBOL_ENTRY(socket);
592         SWRAP_SYMBOL_ENTRY(socketpair);
593 #ifdef HAVE_TIMERFD_CREATE
594         SWRAP_SYMBOL_ENTRY(timerfd_create);
595 #endif
596         SWRAP_SYMBOL_ENTRY(write);
597         SWRAP_SYMBOL_ENTRY(writev);
598 };
599
600 struct swrap {
601         struct {
602                 void *handle;
603                 void *socket_handle;
604                 struct swrap_libc_symbols symbols;
605         } libc;
606 };
607
608 static struct swrap swrap;
609
610 /* prototypes */
611 static char *socket_wrapper_dir(void);
612
613 #define LIBC_NAME "libc.so"
614
615 enum swrap_lib {
616     SWRAP_LIBC,
617     SWRAP_LIBSOCKET,
618 };
619
620 static const char *swrap_str_lib(enum swrap_lib lib)
621 {
622         switch (lib) {
623         case SWRAP_LIBC:
624                 return "libc";
625         case SWRAP_LIBSOCKET:
626                 return "libsocket";
627         }
628
629         /* Compiler would warn us about unhandled enum value if we get here */
630         return "unknown";
631 }
632
633 static void *swrap_load_lib_handle(enum swrap_lib lib)
634 {
635         int flags = RTLD_LAZY;
636         void *handle = NULL;
637         int i;
638
639 #ifdef RTLD_DEEPBIND
640         const char *env_preload = getenv("LD_PRELOAD");
641         const char *env_deepbind = getenv("SOCKET_WRAPPER_DISABLE_DEEPBIND");
642         bool enable_deepbind = true;
643
644         /* Don't do a deepbind if we run with libasan */
645         if (env_preload != NULL && strlen(env_preload) < 1024) {
646                 const char *p = strstr(env_preload, "libasan.so");
647                 if (p != NULL) {
648                         enable_deepbind = false;
649                 }
650         }
651
652         if (env_deepbind != NULL && strlen(env_deepbind) >= 1) {
653                 enable_deepbind = false;
654         }
655
656         if (enable_deepbind) {
657                 flags |= RTLD_DEEPBIND;
658         }
659 #endif
660
661         switch (lib) {
662         case SWRAP_LIBSOCKET:
663 #ifdef HAVE_LIBSOCKET
664                 handle = swrap.libc.socket_handle;
665                 if (handle == NULL) {
666                         for (i = 10; i >= 0; i--) {
667                                 char soname[256] = {0};
668
669                                 snprintf(soname, sizeof(soname), "libsocket.so.%d", i);
670                                 handle = dlopen(soname, flags);
671                                 if (handle != NULL) {
672                                         break;
673                                 }
674                         }
675
676                         swrap.libc.socket_handle = handle;
677                 }
678                 break;
679 #endif
680         case SWRAP_LIBC:
681                 handle = swrap.libc.handle;
682 #ifdef LIBC_SO
683                 if (handle == NULL) {
684                         handle = dlopen(LIBC_SO, flags);
685
686                         swrap.libc.handle = handle;
687                 }
688 #endif
689                 if (handle == NULL) {
690                         for (i = 10; i >= 0; i--) {
691                                 char soname[256] = {0};
692
693                                 snprintf(soname, sizeof(soname), "libc.so.%d", i);
694                                 handle = dlopen(soname, flags);
695                                 if (handle != NULL) {
696                                         break;
697                                 }
698                         }
699
700                         swrap.libc.handle = handle;
701                 }
702                 break;
703         }
704
705         if (handle == NULL) {
706 #ifdef RTLD_NEXT
707                 handle = swrap.libc.handle = swrap.libc.socket_handle = RTLD_NEXT;
708 #else
709                 SWRAP_LOG(SWRAP_LOG_ERROR,
710                           "Failed to dlopen library: %s",
711                           dlerror());
712                 exit(-1);
713 #endif
714         }
715
716         return handle;
717 }
718
719 static void *_swrap_bind_symbol(enum swrap_lib lib, const char *fn_name)
720 {
721         void *handle;
722         void *func;
723
724         handle = swrap_load_lib_handle(lib);
725
726         func = dlsym(handle, fn_name);
727         if (func == NULL) {
728                 SWRAP_LOG(SWRAP_LOG_ERROR,
729                           "Failed to find %s: %s",
730                           fn_name,
731                           dlerror());
732                 exit(-1);
733         }
734
735         SWRAP_LOG(SWRAP_LOG_TRACE,
736                   "Loaded %s from %s",
737                   fn_name,
738                   swrap_str_lib(lib));
739
740         return func;
741 }
742
743 #define swrap_mutex_lock(m) _swrap_mutex_lock(m, #m, __func__, __LINE__)
744 static void _swrap_mutex_lock(pthread_mutex_t *mutex, const char *name, const char *caller, unsigned line)
745 {
746         int ret;
747
748         ret = pthread_mutex_lock(mutex);
749         if (ret != 0) {
750                 SWRAP_LOG(SWRAP_LOG_ERROR, "PID(%d):PPID(%d): %s(%u): Couldn't lock pthread mutex(%s) - %s",
751                           getpid(), getppid(), caller, line, name, strerror(ret));
752         }
753 }
754
755 #define swrap_mutex_unlock(m) _swrap_mutex_unlock(m, #m, __func__, __LINE__)
756 static void _swrap_mutex_unlock(pthread_mutex_t *mutex, const char *name, const char *caller, unsigned line)
757 {
758         int ret;
759
760         ret = pthread_mutex_unlock(mutex);
761         if (ret != 0) {
762                 SWRAP_LOG(SWRAP_LOG_ERROR, "PID(%d):PPID(%d): %s(%u): Couldn't unlock pthread mutex(%s) - %s",
763                           getpid(), getppid(), caller, line, name, strerror(ret));
764         }
765 }
766
767 /*
768  * These macros have a thread race condition on purpose!
769  *
770  * This is an optimization to avoid locking each time we check if the symbol is
771  * bound.
772  */
773 #define _swrap_bind_symbol_generic(lib, sym_name) do { \
774         swrap.libc.symbols._libc_##sym_name.obj = \
775                 _swrap_bind_symbol(lib, #sym_name); \
776 } while(0);
777
778 #define swrap_bind_symbol_libc(sym_name) \
779         _swrap_bind_symbol_generic(SWRAP_LIBC, sym_name)
780
781 #define swrap_bind_symbol_libsocket(sym_name) \
782         _swrap_bind_symbol_generic(SWRAP_LIBSOCKET, sym_name)
783
784 static void swrap_bind_symbol_all(void);
785
786 /****************************************************************************
787  *                               IMPORTANT
788  ****************************************************************************
789  *
790  * Functions especially from libc need to be loaded individually, you can't
791  * load all at once or gdb will segfault at startup. The same applies to
792  * valgrind and has probably something todo with with the linker.  So we need
793  * load each function at the point it is called the first time.
794  *
795  ****************************************************************************/
796
797 #ifdef HAVE_ACCEPT4
798 static int libc_accept4(int sockfd,
799                         struct sockaddr *addr,
800                         socklen_t *addrlen,
801                         int flags)
802 {
803         swrap_bind_symbol_all();
804
805         return swrap.libc.symbols._libc_accept4.f(sockfd, addr, addrlen, flags);
806 }
807
808 #else /* HAVE_ACCEPT4 */
809
810 static int libc_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
811 {
812         swrap_bind_symbol_all();
813
814         return swrap.libc.symbols._libc_accept.f(sockfd, addr, addrlen);
815 }
816 #endif /* HAVE_ACCEPT4 */
817
818 static int libc_bind(int sockfd,
819                      const struct sockaddr *addr,
820                      socklen_t addrlen)
821 {
822         swrap_bind_symbol_all();
823
824         return swrap.libc.symbols._libc_bind.f(sockfd, addr, addrlen);
825 }
826
827 static int libc_close(int fd)
828 {
829         swrap_bind_symbol_all();
830
831         return swrap.libc.symbols._libc_close.f(fd);
832 }
833
834 static int libc_connect(int sockfd,
835                         const struct sockaddr *addr,
836                         socklen_t addrlen)
837 {
838         swrap_bind_symbol_all();
839
840         return swrap.libc.symbols._libc_connect.f(sockfd, addr, addrlen);
841 }
842
843 static int libc_dup(int fd)
844 {
845         swrap_bind_symbol_all();
846
847         return swrap.libc.symbols._libc_dup.f(fd);
848 }
849
850 static int libc_dup2(int oldfd, int newfd)
851 {
852         swrap_bind_symbol_all();
853
854         return swrap.libc.symbols._libc_dup2.f(oldfd, newfd);
855 }
856
857 #ifdef HAVE_EVENTFD
858 static int libc_eventfd(int count, int flags)
859 {
860         swrap_bind_symbol_all();
861
862         return swrap.libc.symbols._libc_eventfd.f(count, flags);
863 }
864 #endif
865
866 DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
867 static int libc_vfcntl(int fd, int cmd, va_list ap)
868 {
869         void *arg;
870         int rc;
871
872         swrap_bind_symbol_all();
873
874         arg = va_arg(ap, void *);
875
876         rc = swrap.libc.symbols._libc_fcntl.f(fd, cmd, arg);
877
878         return rc;
879 }
880
881 static int libc_getpeername(int sockfd,
882                             struct sockaddr *addr,
883                             socklen_t *addrlen)
884 {
885         swrap_bind_symbol_all();
886
887         return swrap.libc.symbols._libc_getpeername.f(sockfd, addr, addrlen);
888 }
889
890 static int libc_getsockname(int sockfd,
891                             struct sockaddr *addr,
892                             socklen_t *addrlen)
893 {
894         swrap_bind_symbol_all();
895
896         return swrap.libc.symbols._libc_getsockname.f(sockfd, addr, addrlen);
897 }
898
899 static int libc_getsockopt(int sockfd,
900                            int level,
901                            int optname,
902                            void *optval,
903                            socklen_t *optlen)
904 {
905         swrap_bind_symbol_all();
906
907         return swrap.libc.symbols._libc_getsockopt.f(sockfd,
908                                                      level,
909                                                      optname,
910                                                      optval,
911                                                      optlen);
912 }
913
914 DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
915 static int libc_vioctl(int d, unsigned long int request, va_list ap)
916 {
917         void *arg;
918         int rc;
919
920         swrap_bind_symbol_all();
921
922         arg = va_arg(ap, void *);
923
924         rc = swrap.libc.symbols._libc_ioctl.f(d, request, arg);
925
926         return rc;
927 }
928
929 static int libc_listen(int sockfd, int backlog)
930 {
931         swrap_bind_symbol_all();
932
933         return swrap.libc.symbols._libc_listen.f(sockfd, backlog);
934 }
935
936 static FILE *libc_fopen(const char *name, const char *mode)
937 {
938         swrap_bind_symbol_all();
939
940         return swrap.libc.symbols._libc_fopen.f(name, mode);
941 }
942
943 #ifdef HAVE_FOPEN64
944 static FILE *libc_fopen64(const char *name, const char *mode)
945 {
946         swrap_bind_symbol_all();
947
948         return swrap.libc.symbols._libc_fopen64.f(name, mode);
949 }
950 #endif /* HAVE_FOPEN64 */
951
952 static int libc_vopen(const char *pathname, int flags, va_list ap)
953 {
954         int mode = 0;
955         int fd;
956
957         swrap_bind_symbol_all();
958
959         if (flags & O_CREAT) {
960                 mode = va_arg(ap, int);
961         }
962         fd = swrap.libc.symbols._libc_open.f(pathname, flags, (mode_t)mode);
963
964         return fd;
965 }
966
967 static int libc_open(const char *pathname, int flags, ...)
968 {
969         va_list ap;
970         int fd;
971
972         va_start(ap, flags);
973         fd = libc_vopen(pathname, flags, ap);
974         va_end(ap);
975
976         return fd;
977 }
978
979 #ifdef HAVE_OPEN64
980 static int libc_vopen64(const char *pathname, int flags, va_list ap)
981 {
982         int mode = 0;
983         int fd;
984
985         swrap_bind_symbol_all();
986
987         if (flags & O_CREAT) {
988                 mode = va_arg(ap, int);
989         }
990         fd = swrap.libc.symbols._libc_open64.f(pathname, flags, (mode_t)mode);
991
992         return fd;
993 }
994 #endif /* HAVE_OPEN64 */
995
996 static int libc_vopenat(int dirfd, const char *path, int flags, va_list ap)
997 {
998         int mode = 0;
999         int fd;
1000
1001         swrap_bind_symbol_all();
1002
1003         if (flags & O_CREAT) {
1004                 mode = va_arg(ap, int);
1005         }
1006         fd = swrap.libc.symbols._libc_openat.f(dirfd,
1007                                                path,
1008                                                flags,
1009                                                (mode_t)mode);
1010
1011         return fd;
1012 }
1013
1014 #if 0
1015 static int libc_openat(int dirfd, const char *path, int flags, ...)
1016 {
1017         va_list ap;
1018         int fd;
1019
1020         va_start(ap, flags);
1021         fd = libc_vopenat(dirfd, path, flags, ap);
1022         va_end(ap);
1023
1024         return fd;
1025 }
1026 #endif
1027
1028 static int libc_pipe(int pipefd[2])
1029 {
1030         swrap_bind_symbol_all();
1031
1032         return swrap.libc.symbols._libc_pipe.f(pipefd);
1033 }
1034
1035 static int libc_read(int fd, void *buf, size_t count)
1036 {
1037         swrap_bind_symbol_all();
1038
1039         return swrap.libc.symbols._libc_read.f(fd, buf, count);
1040 }
1041
1042 static ssize_t libc_readv(int fd, const struct iovec *iov, int iovcnt)
1043 {
1044         swrap_bind_symbol_all();
1045
1046         return swrap.libc.symbols._libc_readv.f(fd, iov, iovcnt);
1047 }
1048
1049 static int libc_recv(int sockfd, void *buf, size_t len, int flags)
1050 {
1051         swrap_bind_symbol_all();
1052
1053         return swrap.libc.symbols._libc_recv.f(sockfd, buf, len, flags);
1054 }
1055
1056 static int libc_recvfrom(int sockfd,
1057                          void *buf,
1058                          size_t len,
1059                          int flags,
1060                          struct sockaddr *src_addr,
1061                          socklen_t *addrlen)
1062 {
1063         swrap_bind_symbol_all();
1064
1065         return swrap.libc.symbols._libc_recvfrom.f(sockfd,
1066                                                    buf,
1067                                                    len,
1068                                                    flags,
1069                                                    src_addr,
1070                                                    addrlen);
1071 }
1072
1073 static int libc_recvmsg(int sockfd, struct msghdr *msg, int flags)
1074 {
1075         swrap_bind_symbol_all();
1076
1077         return swrap.libc.symbols._libc_recvmsg.f(sockfd, msg, flags);
1078 }
1079
1080 static int libc_send(int sockfd, const void *buf, size_t len, int flags)
1081 {
1082         swrap_bind_symbol_all();
1083
1084         return swrap.libc.symbols._libc_send.f(sockfd, buf, len, flags);
1085 }
1086
1087 static int libc_sendmsg(int sockfd, const struct msghdr *msg, int flags)
1088 {
1089         swrap_bind_symbol_all();
1090
1091         return swrap.libc.symbols._libc_sendmsg.f(sockfd, msg, flags);
1092 }
1093
1094 static int libc_sendto(int sockfd,
1095                        const void *buf,
1096                        size_t len,
1097                        int flags,
1098                        const  struct sockaddr *dst_addr,
1099                        socklen_t addrlen)
1100 {
1101         swrap_bind_symbol_all();
1102
1103         return swrap.libc.symbols._libc_sendto.f(sockfd,
1104                                                  buf,
1105                                                  len,
1106                                                  flags,
1107                                                  dst_addr,
1108                                                  addrlen);
1109 }
1110
1111 static int libc_setsockopt(int sockfd,
1112                            int level,
1113                            int optname,
1114                            const void *optval,
1115                            socklen_t optlen)
1116 {
1117         swrap_bind_symbol_all();
1118
1119         return swrap.libc.symbols._libc_setsockopt.f(sockfd,
1120                                                      level,
1121                                                      optname,
1122                                                      optval,
1123                                                      optlen);
1124 }
1125
1126 #ifdef HAVE_SIGNALFD
1127 static int libc_signalfd(int fd, const sigset_t *mask, int flags)
1128 {
1129         swrap_bind_symbol_all();
1130
1131         return swrap.libc.symbols._libc_signalfd.f(fd, mask, flags);
1132 }
1133 #endif
1134
1135 static int libc_socket(int domain, int type, int protocol)
1136 {
1137         swrap_bind_symbol_all();
1138
1139         return swrap.libc.symbols._libc_socket.f(domain, type, protocol);
1140 }
1141
1142 static int libc_socketpair(int domain, int type, int protocol, int sv[2])
1143 {
1144         swrap_bind_symbol_all();
1145
1146         return swrap.libc.symbols._libc_socketpair.f(domain, type, protocol, sv);
1147 }
1148
1149 #ifdef HAVE_TIMERFD_CREATE
1150 static int libc_timerfd_create(int clockid, int flags)
1151 {
1152         swrap_bind_symbol_all();
1153
1154         return swrap.libc.symbols._libc_timerfd_create.f(clockid, flags);
1155 }
1156 #endif
1157
1158 static ssize_t libc_write(int fd, const void *buf, size_t count)
1159 {
1160         swrap_bind_symbol_all();
1161
1162         return swrap.libc.symbols._libc_write.f(fd, buf, count);
1163 }
1164
1165 static ssize_t libc_writev(int fd, const struct iovec *iov, int iovcnt)
1166 {
1167         swrap_bind_symbol_all();
1168
1169         return swrap.libc.symbols._libc_writev.f(fd, iov, iovcnt);
1170 }
1171
1172 /* DO NOT call this function during library initialization! */
1173 static void __swrap_bind_symbol_all_once(void)
1174 {
1175 #ifdef HAVE_ACCEPT4
1176         swrap_bind_symbol_libsocket(accept4);
1177 #else
1178         swrap_bind_symbol_libsocket(accept);
1179 #endif
1180         swrap_bind_symbol_libsocket(bind);
1181         swrap_bind_symbol_libc(close);
1182         swrap_bind_symbol_libsocket(connect);
1183         swrap_bind_symbol_libc(dup);
1184         swrap_bind_symbol_libc(dup2);
1185         swrap_bind_symbol_libc(fcntl);
1186         swrap_bind_symbol_libc(fopen);
1187 #ifdef HAVE_FOPEN64
1188         swrap_bind_symbol_libc(fopen64);
1189 #endif
1190 #ifdef HAVE_EVENTFD
1191         swrap_bind_symbol_libc(eventfd);
1192 #endif
1193         swrap_bind_symbol_libsocket(getpeername);
1194         swrap_bind_symbol_libsocket(getsockname);
1195         swrap_bind_symbol_libsocket(getsockopt);
1196         swrap_bind_symbol_libc(ioctl);
1197         swrap_bind_symbol_libsocket(listen);
1198         swrap_bind_symbol_libc(open);
1199 #ifdef HAVE_OPEN64
1200         swrap_bind_symbol_libc(open64);
1201 #endif
1202         swrap_bind_symbol_libc(openat);
1203         swrap_bind_symbol_libsocket(pipe);
1204         swrap_bind_symbol_libc(read);
1205         swrap_bind_symbol_libsocket(readv);
1206         swrap_bind_symbol_libsocket(recv);
1207         swrap_bind_symbol_libsocket(recvfrom);
1208         swrap_bind_symbol_libsocket(recvmsg);
1209         swrap_bind_symbol_libsocket(send);
1210         swrap_bind_symbol_libsocket(sendmsg);
1211         swrap_bind_symbol_libsocket(sendto);
1212         swrap_bind_symbol_libsocket(setsockopt);
1213 #ifdef HAVE_SIGNALFD
1214         swrap_bind_symbol_libsocket(signalfd);
1215 #endif
1216         swrap_bind_symbol_libsocket(socket);
1217         swrap_bind_symbol_libsocket(socketpair);
1218 #ifdef HAVE_TIMERFD_CREATE
1219         swrap_bind_symbol_libc(timerfd_create);
1220 #endif
1221         swrap_bind_symbol_libc(write);
1222         swrap_bind_symbol_libsocket(writev);
1223 }
1224
1225 static void swrap_bind_symbol_all(void)
1226 {
1227         static pthread_once_t all_symbol_binding_once = PTHREAD_ONCE_INIT;
1228
1229         pthread_once(&all_symbol_binding_once, __swrap_bind_symbol_all_once);
1230 }
1231
1232 /*********************************************************
1233  * SWRAP HELPER FUNCTIONS
1234  *********************************************************/
1235
1236 /*
1237  * We return 127.0.0.0 (default) or 10.53.57.0.
1238  *
1239  * This can be controlled by:
1240  * SOCKET_WRAPPER_IPV4_NETWORK=127.0.0.0 (default)
1241  * or
1242  * SOCKET_WRAPPER_IPV4_NETWORK=10.53.57.0
1243  */
1244 static in_addr_t swrap_ipv4_net(void)
1245 {
1246         static int initialized;
1247         static in_addr_t hv;
1248         const char *net_str = NULL;
1249         struct in_addr nv;
1250         int ret;
1251
1252         if (initialized) {
1253                 return hv;
1254         }
1255         initialized = 1;
1256
1257         net_str = getenv("SOCKET_WRAPPER_IPV4_NETWORK");
1258         if (net_str == NULL) {
1259                 net_str = "127.0.0.0";
1260         }
1261
1262         ret = inet_pton(AF_INET, net_str, &nv);
1263         if (ret <= 0) {
1264                 SWRAP_LOG(SWRAP_LOG_ERROR,
1265                           "INVALID IPv4 Network [%s]",
1266                           net_str);
1267                 abort();
1268         }
1269
1270         hv = ntohl(nv.s_addr);
1271
1272         switch (hv) {
1273         case 0x7f000000:
1274                 /* 127.0.0.0 */
1275                 break;
1276         case 0x0a353900:
1277                 /* 10.53.57.0 */
1278                 break;
1279         default:
1280                 SWRAP_LOG(SWRAP_LOG_ERROR,
1281                           "INVALID IPv4 Network [%s][0x%x] should be "
1282                           "127.0.0.0 or 10.53.57.0",
1283                           net_str, (unsigned)hv);
1284                 abort();
1285         }
1286
1287         return hv;
1288 }
1289
1290 /*
1291  * This returns 127.255.255.255 or 10.255.255.255
1292  */
1293 static in_addr_t swrap_ipv4_bcast(void)
1294 {
1295         in_addr_t hv;
1296
1297         hv = swrap_ipv4_net();
1298         hv |= IN_CLASSA_HOST;
1299
1300         return hv;
1301 }
1302
1303 /*
1304  * This returns 127.0.0.${iface} or 10.53.57.${iface}
1305  */
1306 static in_addr_t swrap_ipv4_iface(unsigned int iface)
1307 {
1308         in_addr_t hv;
1309
1310         if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
1311                 SWRAP_LOG(SWRAP_LOG_ERROR,
1312                           "swrap_ipv4_iface(%u) invalid!",
1313                           iface);
1314                 abort();
1315                 return -1;
1316         }
1317
1318         hv = swrap_ipv4_net();
1319         hv |= iface;
1320
1321         return hv;
1322 }
1323
1324 #ifdef HAVE_IPV6
1325 /*
1326  * FD00::5357:5FXX
1327  */
1328 static const struct in6_addr *swrap_ipv6(void)
1329 {
1330         static struct in6_addr v;
1331         static int initialized;
1332         int ret;
1333
1334         if (initialized) {
1335                 return &v;
1336         }
1337         initialized = 1;
1338
1339         ret = inet_pton(AF_INET6, "FD00::5357:5F00", &v);
1340         if (ret <= 0) {
1341                 abort();
1342         }
1343
1344         return &v;
1345 }
1346 #endif
1347
1348 static void set_port(int family, int prt, struct swrap_address *addr)
1349 {
1350         switch (family) {
1351         case AF_INET:
1352                 addr->sa.in.sin_port = htons(prt);
1353                 break;
1354 #ifdef HAVE_IPV6
1355         case AF_INET6:
1356                 addr->sa.in6.sin6_port = htons(prt);
1357                 break;
1358 #endif
1359         }
1360 }
1361
1362 static size_t socket_length(int family)
1363 {
1364         switch (family) {
1365         case AF_INET:
1366                 return sizeof(struct sockaddr_in);
1367 #ifdef HAVE_IPV6
1368         case AF_INET6:
1369                 return sizeof(struct sockaddr_in6);
1370 #endif
1371         }
1372         return 0;
1373 }
1374
1375 static struct socket_info *swrap_get_socket_info(int si_index)
1376 {
1377         return (struct socket_info *)(&(sockets[si_index].info));
1378 }
1379
1380 static int swrap_get_refcount(struct socket_info *si)
1381 {
1382         struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si);
1383         return sic->meta.refcount;
1384 }
1385
1386 static void swrap_inc_refcount(struct socket_info *si)
1387 {
1388         struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si);
1389
1390         sic->meta.refcount += 1;
1391 }
1392
1393 static void swrap_dec_refcount(struct socket_info *si)
1394 {
1395         struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si);
1396
1397         sic->meta.refcount -= 1;
1398 }
1399
1400 static int swrap_get_next_free(struct socket_info *si)
1401 {
1402         struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si);
1403
1404         return sic->meta.next_free;
1405 }
1406
1407 static void swrap_set_next_free(struct socket_info *si, int next_free)
1408 {
1409         struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si);
1410
1411         sic->meta.next_free = next_free;
1412 }
1413
1414 static int swrap_un_path(struct sockaddr_un *un,
1415                          const char *swrap_dir,
1416                          char type,
1417                          unsigned int iface,
1418                          unsigned int prt)
1419 {
1420         int ret;
1421
1422         ret = snprintf(un->sun_path,
1423                        sizeof(un->sun_path),
1424                        "%s/"SOCKET_FORMAT,
1425                        swrap_dir,
1426                        type,
1427                        iface,
1428                        prt);
1429         if ((size_t)ret >= sizeof(un->sun_path)) {
1430                 return ENAMETOOLONG;
1431         }
1432
1433         return 0;
1434 }
1435
1436 static int swrap_un_path_EINVAL(struct sockaddr_un *un,
1437                                 const char *swrap_dir)
1438 {
1439         int ret;
1440
1441         ret = snprintf(un->sun_path,
1442                        sizeof(un->sun_path),
1443                        "%s/EINVAL",
1444                        swrap_dir);
1445
1446         if ((size_t)ret >= sizeof(un->sun_path)) {
1447                 return ENAMETOOLONG;
1448         }
1449
1450         return 0;
1451 }
1452
1453 static bool swrap_dir_usable(const char *swrap_dir)
1454 {
1455         struct sockaddr_un un;
1456         int ret;
1457
1458         ret = swrap_un_path(&un, swrap_dir, SOCKET_TYPE_CHAR_TCP, 0, 0);
1459         if (ret == 0) {
1460                 return true;
1461         }
1462
1463         ret = swrap_un_path_EINVAL(&un, swrap_dir);
1464         if (ret == 0) {
1465                 return true;
1466         }
1467
1468         return false;
1469 }
1470
1471 static char *socket_wrapper_dir(void)
1472 {
1473         char *swrap_dir = NULL;
1474         char *s = getenv("SOCKET_WRAPPER_DIR");
1475         char *t;
1476         bool ok;
1477
1478         if (s == NULL || s[0] == '\0') {
1479                 SWRAP_LOG(SWRAP_LOG_WARN, "SOCKET_WRAPPER_DIR not set");
1480                 return NULL;
1481         }
1482
1483         swrap_dir = realpath(s, NULL);
1484         if (swrap_dir == NULL) {
1485                 SWRAP_LOG(SWRAP_LOG_ERROR,
1486                           "Unable to resolve socket_wrapper dir path: %s - %s",
1487                           s,
1488                           strerror(errno));
1489                 abort();
1490         }
1491
1492         ok = swrap_dir_usable(swrap_dir);
1493         if (ok) {
1494                 goto done;
1495         }
1496
1497         free(swrap_dir);
1498
1499         ok = swrap_dir_usable(s);
1500         if (!ok) {
1501                 SWRAP_LOG(SWRAP_LOG_ERROR, "SOCKET_WRAPPER_DIR is too long");
1502                 abort();
1503         }
1504
1505         t = getenv("SOCKET_WRAPPER_DIR_ALLOW_ORIG");
1506         if (t == NULL) {
1507                 SWRAP_LOG(SWRAP_LOG_ERROR,
1508                           "realpath(SOCKET_WRAPPER_DIR) too long and "
1509                           "SOCKET_WRAPPER_DIR_ALLOW_ORIG not set");
1510                 abort();
1511
1512         }
1513
1514         swrap_dir = strdup(s);
1515         if (swrap_dir == NULL) {
1516                 SWRAP_LOG(SWRAP_LOG_ERROR,
1517                           "Unable to duplicate socket_wrapper dir path");
1518                 abort();
1519         }
1520
1521         SWRAP_LOG(SWRAP_LOG_WARN,
1522                   "realpath(SOCKET_WRAPPER_DIR) too long, "
1523                   "using original SOCKET_WRAPPER_DIR\n");
1524
1525 done:
1526         SWRAP_LOG(SWRAP_LOG_TRACE, "socket_wrapper_dir: %s", swrap_dir);
1527         return swrap_dir;
1528 }
1529
1530 static unsigned int socket_wrapper_mtu(void)
1531 {
1532         static unsigned int max_mtu = 0;
1533         unsigned int tmp;
1534         const char *s;
1535         char *endp;
1536
1537         swrap_mutex_lock(&mtu_update_mutex);
1538
1539         if (max_mtu != 0) {
1540                 goto done;
1541         }
1542
1543         max_mtu = SOCKET_WRAPPER_MTU_DEFAULT;
1544
1545         s = getenv("SOCKET_WRAPPER_MTU");
1546         if (s == NULL) {
1547                 goto done;
1548         }
1549
1550         tmp = strtol(s, &endp, 10);
1551         if (s == endp) {
1552                 goto done;
1553         }
1554
1555         if (tmp < SOCKET_WRAPPER_MTU_MIN || tmp > SOCKET_WRAPPER_MTU_MAX) {
1556                 goto done;
1557         }
1558         max_mtu = tmp;
1559
1560 done:
1561         swrap_mutex_unlock(&mtu_update_mutex);
1562         return max_mtu;
1563 }
1564
1565 static int _socket_wrapper_init_mutex(pthread_mutex_t *m, const char *name)
1566 {
1567         pthread_mutexattr_t ma;
1568         bool need_destroy = false;
1569         int ret = 0;
1570
1571 #define __CHECK(cmd) do { \
1572         ret = cmd; \
1573         if (ret != 0) { \
1574                 SWRAP_LOG(SWRAP_LOG_ERROR, \
1575                           "%s: %s - failed %d", \
1576                           name, #cmd, ret); \
1577                 goto done; \
1578         } \
1579 } while(0)
1580
1581         *m = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;
1582         __CHECK(pthread_mutexattr_init(&ma));
1583         need_destroy = true;
1584         __CHECK(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK));
1585         __CHECK(pthread_mutex_init(m, &ma));
1586 done:
1587         if (need_destroy) {
1588                 pthread_mutexattr_destroy(&ma);
1589         }
1590         return ret;
1591 }
1592
1593 static size_t socket_wrapper_max_sockets(void)
1594 {
1595         const char *s;
1596         size_t tmp;
1597         char *endp;
1598
1599         if (socket_info_max != 0) {
1600                 return socket_info_max;
1601         }
1602
1603         socket_info_max = SOCKET_WRAPPER_MAX_SOCKETS_DEFAULT;
1604
1605         s = getenv("SOCKET_WRAPPER_MAX_SOCKETS");
1606         if (s == NULL || s[0] == '\0') {
1607                 goto done;
1608         }
1609
1610         tmp = strtoul(s, &endp, 10);
1611         if (s == endp) {
1612                 goto done;
1613         }
1614         if (tmp == 0) {
1615                 tmp = SOCKET_WRAPPER_MAX_SOCKETS_DEFAULT;
1616                 SWRAP_LOG(SWRAP_LOG_ERROR,
1617                           "Invalid number of sockets specified, "
1618                           "using default (%zu)",
1619                           tmp);
1620         }
1621
1622         if (tmp > SOCKET_WRAPPER_MAX_SOCKETS_LIMIT) {
1623                 tmp = SOCKET_WRAPPER_MAX_SOCKETS_LIMIT;
1624                 SWRAP_LOG(SWRAP_LOG_ERROR,
1625                           "Invalid number of sockets specified, "
1626                           "using maximum (%zu).",
1627                           tmp);
1628         }
1629
1630         socket_info_max = tmp;
1631
1632 done:
1633         return socket_info_max;
1634 }
1635
1636 static void socket_wrapper_init_fds_idx(void)
1637 {
1638         int *tmp = NULL;
1639         size_t i;
1640
1641         if (socket_fds_idx != NULL) {
1642                 return;
1643         }
1644
1645         tmp = (int *)calloc(socket_fds_max, sizeof(int));
1646         if (tmp == NULL) {
1647                 SWRAP_LOG(SWRAP_LOG_ERROR,
1648                           "Failed to allocate socket fds index array: %s",
1649                           strerror(errno));
1650                 exit(-1);
1651         }
1652
1653         for (i = 0; i < socket_fds_max; i++) {
1654                 tmp[i] = -1;
1655         }
1656
1657         socket_fds_idx = tmp;
1658 }
1659
1660 static void socket_wrapper_init_sockets(void)
1661 {
1662         size_t max_sockets;
1663         size_t i;
1664         int ret = 0;
1665
1666         swrap_bind_symbol_all();
1667
1668         swrap_mutex_lock(&sockets_mutex);
1669
1670         if (sockets != NULL) {
1671                 swrap_mutex_unlock(&sockets_mutex);
1672                 return;
1673         }
1674
1675         SWRAP_LOG(SWRAP_LOG_DEBUG,
1676                   "SOCKET_WRAPPER_PACKAGE[%s] SOCKET_WRAPPER_VERSION[%s]",
1677                   SOCKET_WRAPPER_PACKAGE, SOCKET_WRAPPER_VERSION);
1678
1679         /*
1680          * Intialize the static cache early before
1681          * any thread is able to start.
1682          */
1683         (void)swrap_ipv4_net();
1684
1685         socket_wrapper_init_fds_idx();
1686
1687         /* Needs to be called inside the sockets_mutex lock here. */
1688         max_sockets = socket_wrapper_max_sockets();
1689
1690         sockets = (struct socket_info_container *)calloc(max_sockets,
1691                                         sizeof(struct socket_info_container));
1692
1693         if (sockets == NULL) {
1694                 SWRAP_LOG(SWRAP_LOG_ERROR,
1695                           "Failed to allocate sockets array: %s",
1696                           strerror(errno));
1697                 swrap_mutex_unlock(&sockets_mutex);
1698                 exit(-1);
1699         }
1700
1701         swrap_mutex_lock(&first_free_mutex);
1702
1703         first_free = 0;
1704
1705         for (i = 0; i < max_sockets; i++) {
1706                 swrap_set_next_free(&sockets[i].info, i+1);
1707                 sockets[i].meta.mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;
1708         }
1709
1710         for (i = 0; i < max_sockets; i++) {
1711                 ret = socket_wrapper_init_mutex(&sockets[i].meta.mutex);
1712                 if (ret != 0) {
1713                         SWRAP_LOG(SWRAP_LOG_ERROR,
1714                                   "Failed to initialize pthread mutex i=%zu", i);
1715                         goto done;
1716                 }
1717         }
1718
1719         /* mark the end of the free list */
1720         swrap_set_next_free(&sockets[max_sockets-1].info, -1);
1721
1722 done:
1723         swrap_mutex_unlock(&first_free_mutex);
1724         swrap_mutex_unlock(&sockets_mutex);
1725         if (ret != 0) {
1726                 exit(-1);
1727         }
1728 }
1729
1730 bool socket_wrapper_enabled(void)
1731 {
1732         char *s = socket_wrapper_dir();
1733
1734         if (s == NULL) {
1735                 return false;
1736         }
1737
1738         SAFE_FREE(s);
1739
1740         socket_wrapper_init_sockets();
1741
1742         return true;
1743 }
1744
1745 static unsigned int socket_wrapper_default_iface(void)
1746 {
1747         const char *s = getenv("SOCKET_WRAPPER_DEFAULT_IFACE");
1748         if (s) {
1749                 unsigned int iface;
1750                 if (sscanf(s, "%u", &iface) == 1) {
1751                         if (iface >= 1 && iface <= MAX_WRAPPED_INTERFACES) {
1752                                 return iface;
1753                         }
1754                 }
1755         }
1756
1757         return 1;/* 127.0.0.1 */
1758 }
1759
1760 static void set_socket_info_index(int fd, int idx)
1761 {
1762         SWRAP_LOG(SWRAP_LOG_TRACE,
1763                   "fd=%d idx=%d",
1764                   fd, idx);
1765         socket_fds_idx[fd] = idx;
1766         /* This builtin issues a full memory barrier. */
1767         __sync_synchronize();
1768 }
1769
1770 static void reset_socket_info_index(int fd)
1771 {
1772         SWRAP_LOG(SWRAP_LOG_TRACE,
1773                   "fd=%d idx=%d",
1774                   fd, -1);
1775         set_socket_info_index(fd, -1);
1776 }
1777
1778 static int find_socket_info_index(int fd)
1779 {
1780         if (fd < 0) {
1781                 return -1;
1782         }
1783
1784         if (socket_fds_idx == NULL) {
1785                 return -1;
1786         }
1787
1788         if ((size_t)fd >= socket_fds_max) {
1789                 /*
1790                  * Do not add a log here as some applications do stupid things
1791                  * like:
1792                  *
1793                  *     for (fd = 0; fd <= getdtablesize(); fd++) {
1794                  *         close(fd)
1795                  *     };
1796                  *
1797                  * This would produce millions of lines of debug messages.
1798                  */
1799 #if 0
1800                 SWRAP_LOG(SWRAP_LOG_ERROR,
1801                           "Looking for a socket info for the fd %d is over the "
1802                           "max socket index limit of %zu.",
1803                           fd,
1804                           socket_fds_max);
1805 #endif
1806                 return -1;
1807         }
1808
1809         /* This builtin issues a full memory barrier. */
1810         __sync_synchronize();
1811         return socket_fds_idx[fd];
1812 }
1813
1814 static int swrap_add_socket_info(const struct socket_info *si_input)
1815 {
1816         struct socket_info *si = NULL;
1817         int si_index = -1;
1818
1819         if (si_input == NULL) {
1820                 errno = EINVAL;
1821                 return -1;
1822         }
1823
1824         swrap_mutex_lock(&first_free_mutex);
1825         if (first_free == -1) {
1826                 errno = ENFILE;
1827                 goto out;
1828         }
1829
1830         si_index = first_free;
1831         si = swrap_get_socket_info(si_index);
1832
1833         SWRAP_LOCK_SI(si);
1834
1835         first_free = swrap_get_next_free(si);
1836         *si = *si_input;
1837         swrap_inc_refcount(si);
1838
1839         SWRAP_UNLOCK_SI(si);
1840
1841 out:
1842         swrap_mutex_unlock(&first_free_mutex);
1843
1844         return si_index;
1845 }
1846
1847 static int swrap_create_socket(struct socket_info *si, int fd)
1848 {
1849         int idx;
1850
1851         if ((size_t)fd >= socket_fds_max) {
1852                 SWRAP_LOG(SWRAP_LOG_ERROR,
1853                           "The max socket index limit of %zu has been reached, "
1854                           "trying to add %d",
1855                           socket_fds_max,
1856                           fd);
1857                 errno = EMFILE;
1858                 return -1;
1859         }
1860
1861         idx = swrap_add_socket_info(si);
1862         if (idx == -1) {
1863                 return -1;
1864         }
1865
1866         set_socket_info_index(fd, idx);
1867
1868         return idx;
1869 }
1870
1871 static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, socklen_t *len)
1872 {
1873         unsigned int iface;
1874         unsigned int prt;
1875         const char *p;
1876         char type;
1877
1878         p = strrchr(un->sun_path, '/');
1879         if (p) p++; else p = un->sun_path;
1880
1881         if (sscanf(p, SOCKET_FORMAT, &type, &iface, &prt) != 3) {
1882                 errno = EINVAL;
1883                 return -1;
1884         }
1885
1886         SWRAP_LOG(SWRAP_LOG_TRACE, "type %c iface %u port %u",
1887                         type, iface, prt);
1888
1889         if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
1890                 errno = EINVAL;
1891                 return -1;
1892         }
1893
1894         if (prt > 0xFFFF) {
1895                 errno = EINVAL;
1896                 return -1;
1897         }
1898
1899         switch(type) {
1900         case SOCKET_TYPE_CHAR_TCP:
1901         case SOCKET_TYPE_CHAR_UDP: {
1902                 struct sockaddr_in *in2 = (struct sockaddr_in *)(void *)in;
1903
1904                 if ((*len) < sizeof(*in2)) {
1905                     errno = EINVAL;
1906                     return -1;
1907                 }
1908
1909                 memset(in2, 0, sizeof(*in2));
1910                 in2->sin_family = AF_INET;
1911                 in2->sin_addr.s_addr = htonl(swrap_ipv4_iface(iface));
1912                 in2->sin_port = htons(prt);
1913
1914                 *len = sizeof(*in2);
1915                 break;
1916         }
1917 #ifdef HAVE_IPV6
1918         case SOCKET_TYPE_CHAR_TCP_V6:
1919         case SOCKET_TYPE_CHAR_UDP_V6: {
1920                 struct sockaddr_in6 *in2 = (struct sockaddr_in6 *)(void *)in;
1921
1922                 if ((*len) < sizeof(*in2)) {
1923                         errno = EINVAL;
1924                         return -1;
1925                 }
1926
1927                 memset(in2, 0, sizeof(*in2));
1928                 in2->sin6_family = AF_INET6;
1929                 in2->sin6_addr = *swrap_ipv6();
1930                 in2->sin6_addr.s6_addr[15] = iface;
1931                 in2->sin6_port = htons(prt);
1932
1933                 *len = sizeof(*in2);
1934                 break;
1935         }
1936 #endif
1937         default:
1938                 errno = EINVAL;
1939                 return -1;
1940         }
1941
1942         return 0;
1943 }
1944
1945 static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un,
1946                                 int *bcast)
1947 {
1948         char type = '\0';
1949         unsigned int prt;
1950         unsigned int iface;
1951         int is_bcast = 0;
1952         char *swrap_dir = NULL;
1953
1954         if (bcast) *bcast = 0;
1955
1956         switch (inaddr->sa_family) {
1957         case AF_INET: {
1958                 const struct sockaddr_in *in =
1959                     (const struct sockaddr_in *)(const void *)inaddr;
1960                 unsigned int addr = ntohl(in->sin_addr.s_addr);
1961                 char u_type = '\0';
1962                 char b_type = '\0';
1963                 char a_type = '\0';
1964                 const unsigned int sw_net_addr = swrap_ipv4_net();
1965                 const unsigned int sw_bcast_addr = swrap_ipv4_bcast();
1966
1967                 switch (si->type) {
1968                 case SOCK_STREAM:
1969                         u_type = SOCKET_TYPE_CHAR_TCP;
1970                         break;
1971                 case SOCK_DGRAM:
1972                         u_type = SOCKET_TYPE_CHAR_UDP;
1973                         a_type = SOCKET_TYPE_CHAR_UDP;
1974                         b_type = SOCKET_TYPE_CHAR_UDP;
1975                         break;
1976                 default:
1977                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!");
1978                         errno = ESOCKTNOSUPPORT;
1979                         return -1;
1980                 }
1981
1982                 prt = ntohs(in->sin_port);
1983                 if (a_type && addr == 0xFFFFFFFF) {
1984                         /* 255.255.255.255 only udp */
1985                         is_bcast = 2;
1986                         type = a_type;
1987                         iface = socket_wrapper_default_iface();
1988                 } else if (b_type && addr == sw_bcast_addr) {
1989                         /*
1990                          * 127.255.255.255
1991                          * or
1992                          * 10.255.255.255
1993                          * only udp
1994                          */
1995                         is_bcast = 1;
1996                         type = b_type;
1997                         iface = socket_wrapper_default_iface();
1998                 } else if ((addr & 0xFFFFFF00) == sw_net_addr) {
1999                         /* 127.0.0.X or 10.53.57.X */
2000                         is_bcast = 0;
2001                         type = u_type;
2002                         iface = (addr & 0x000000FF);
2003                 } else {
2004                         errno = ENETUNREACH;
2005                         return -1;
2006                 }
2007                 if (bcast) *bcast = is_bcast;
2008                 break;
2009         }
2010 #ifdef HAVE_IPV6
2011         case AF_INET6: {
2012                 const struct sockaddr_in6 *in =
2013                     (const struct sockaddr_in6 *)(const void *)inaddr;
2014                 struct in6_addr cmp1, cmp2;
2015
2016                 switch (si->type) {
2017                 case SOCK_STREAM:
2018                         type = SOCKET_TYPE_CHAR_TCP_V6;
2019                         break;
2020                 case SOCK_DGRAM:
2021                         type = SOCKET_TYPE_CHAR_UDP_V6;
2022                         break;
2023                 default:
2024                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!");
2025                         errno = ESOCKTNOSUPPORT;
2026                         return -1;
2027                 }
2028
2029                 /* XXX no multicast/broadcast */
2030
2031                 prt = ntohs(in->sin6_port);
2032
2033                 cmp1 = *swrap_ipv6();
2034                 cmp2 = in->sin6_addr;
2035                 cmp2.s6_addr[15] = 0;
2036                 if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
2037                         iface = in->sin6_addr.s6_addr[15];
2038                 } else {
2039                         errno = ENETUNREACH;
2040                         return -1;
2041                 }
2042
2043                 break;
2044         }
2045 #endif
2046         default:
2047                 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family!");
2048                 errno = ENETUNREACH;
2049                 return -1;
2050         }
2051
2052         if (prt == 0) {
2053                 SWRAP_LOG(SWRAP_LOG_WARN, "Port not set");
2054                 errno = EINVAL;
2055                 return -1;
2056         }
2057
2058         swrap_dir = socket_wrapper_dir();
2059         if (swrap_dir == NULL) {
2060                 errno = EINVAL;
2061                 return -1;
2062         }
2063
2064         if (is_bcast) {
2065                 swrap_un_path_EINVAL(un, swrap_dir);
2066                 SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
2067                 SAFE_FREE(swrap_dir);
2068                 /* the caller need to do more processing */
2069                 return 0;
2070         }
2071
2072         swrap_un_path(un, swrap_dir, type, iface, prt);
2073         SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
2074
2075         SAFE_FREE(swrap_dir);
2076
2077         return 0;
2078 }
2079
2080 static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un,
2081                                int *bcast)
2082 {
2083         char type = '\0';
2084         unsigned int prt;
2085         unsigned int iface;
2086         struct stat st;
2087         int is_bcast = 0;
2088         char *swrap_dir = NULL;
2089
2090         if (bcast) *bcast = 0;
2091
2092         switch (si->family) {
2093         case AF_INET: {
2094                 const struct sockaddr_in *in =
2095                     (const struct sockaddr_in *)(const void *)inaddr;
2096                 unsigned int addr = ntohl(in->sin_addr.s_addr);
2097                 char u_type = '\0';
2098                 char d_type = '\0';
2099                 char b_type = '\0';
2100                 char a_type = '\0';
2101                 const unsigned int sw_net_addr = swrap_ipv4_net();
2102                 const unsigned int sw_bcast_addr = swrap_ipv4_bcast();
2103
2104                 prt = ntohs(in->sin_port);
2105
2106                 switch (si->type) {
2107                 case SOCK_STREAM:
2108                         u_type = SOCKET_TYPE_CHAR_TCP;
2109                         d_type = SOCKET_TYPE_CHAR_TCP;
2110                         break;
2111                 case SOCK_DGRAM:
2112                         u_type = SOCKET_TYPE_CHAR_UDP;
2113                         d_type = SOCKET_TYPE_CHAR_UDP;
2114                         a_type = SOCKET_TYPE_CHAR_UDP;
2115                         b_type = SOCKET_TYPE_CHAR_UDP;
2116                         break;
2117                 default:
2118                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!");
2119                         errno = ESOCKTNOSUPPORT;
2120                         return -1;
2121                 }
2122
2123                 if (addr == 0) {
2124                         /* 0.0.0.0 */
2125                         is_bcast = 0;
2126                         type = d_type;
2127                         iface = socket_wrapper_default_iface();
2128                 } else if (a_type && addr == 0xFFFFFFFF) {
2129                         /* 255.255.255.255 only udp */
2130                         is_bcast = 2;
2131                         type = a_type;
2132                         iface = socket_wrapper_default_iface();
2133                 } else if (b_type && addr == sw_bcast_addr) {
2134                         /* 127.255.255.255 only udp */
2135                         is_bcast = 1;
2136                         type = b_type;
2137                         iface = socket_wrapper_default_iface();
2138                 } else if ((addr & 0xFFFFFF00) == sw_net_addr) {
2139                         /* 127.0.0.X */
2140                         is_bcast = 0;
2141                         type = u_type;
2142                         iface = (addr & 0x000000FF);
2143                 } else {
2144                         errno = EADDRNOTAVAIL;
2145                         return -1;
2146                 }
2147
2148                 /* Store the bind address for connect() */
2149                 if (si->bindname.sa_socklen == 0) {
2150                         struct sockaddr_in bind_in;
2151                         socklen_t blen = sizeof(struct sockaddr_in);
2152
2153                         ZERO_STRUCT(bind_in);
2154                         bind_in.sin_family = in->sin_family;
2155                         bind_in.sin_port = in->sin_port;
2156                         bind_in.sin_addr.s_addr = htonl(swrap_ipv4_iface(iface));
2157                         si->bindname.sa_socklen = blen;
2158                         memcpy(&si->bindname.sa.in, &bind_in, blen);
2159                 }
2160
2161                 break;
2162         }
2163 #ifdef HAVE_IPV6
2164         case AF_INET6: {
2165                 const struct sockaddr_in6 *in =
2166                     (const struct sockaddr_in6 *)(const void *)inaddr;
2167                 struct in6_addr cmp1, cmp2;
2168
2169                 switch (si->type) {
2170                 case SOCK_STREAM:
2171                         type = SOCKET_TYPE_CHAR_TCP_V6;
2172                         break;
2173                 case SOCK_DGRAM:
2174                         type = SOCKET_TYPE_CHAR_UDP_V6;
2175                         break;
2176                 default:
2177                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!");
2178                         errno = ESOCKTNOSUPPORT;
2179                         return -1;
2180                 }
2181
2182                 /* XXX no multicast/broadcast */
2183
2184                 prt = ntohs(in->sin6_port);
2185
2186                 cmp1 = *swrap_ipv6();
2187                 cmp2 = in->sin6_addr;
2188                 cmp2.s6_addr[15] = 0;
2189                 if (IN6_IS_ADDR_UNSPECIFIED(&in->sin6_addr)) {
2190                         iface = socket_wrapper_default_iface();
2191                 } else if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
2192                         iface = in->sin6_addr.s6_addr[15];
2193                 } else {
2194                         errno = EADDRNOTAVAIL;
2195                         return -1;
2196                 }
2197
2198                 /* Store the bind address for connect() */
2199                 if (si->bindname.sa_socklen == 0) {
2200                         struct sockaddr_in6 bind_in;
2201                         socklen_t blen = sizeof(struct sockaddr_in6);
2202
2203                         ZERO_STRUCT(bind_in);
2204                         bind_in.sin6_family = in->sin6_family;
2205                         bind_in.sin6_port = in->sin6_port;
2206
2207                         bind_in.sin6_addr = *swrap_ipv6();
2208                         bind_in.sin6_addr.s6_addr[15] = iface;
2209
2210                         memcpy(&si->bindname.sa.in6, &bind_in, blen);
2211                         si->bindname.sa_socklen = blen;
2212                 }
2213
2214                 break;
2215         }
2216 #endif
2217         default:
2218                 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family");
2219                 errno = EADDRNOTAVAIL;
2220                 return -1;
2221         }
2222
2223
2224         if (bcast) *bcast = is_bcast;
2225
2226         if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
2227                 errno = EINVAL;
2228                 return -1;
2229         }
2230
2231         swrap_dir = socket_wrapper_dir();
2232         if (swrap_dir == NULL) {
2233                 errno = EINVAL;
2234                 return -1;
2235         }
2236
2237         if (prt == 0) {
2238                 /* handle auto-allocation of ephemeral ports */
2239                 for (prt = 5001; prt < 10000; prt++) {
2240                         swrap_un_path(un, swrap_dir, type, iface, prt);
2241                         if (stat(un->sun_path, &st) == 0) continue;
2242
2243                         set_port(si->family, prt, &si->myname);
2244                         set_port(si->family, prt, &si->bindname);
2245
2246                         break;
2247                 }
2248
2249                 if (prt == 10000) {
2250                         errno = ENFILE;
2251                         SAFE_FREE(swrap_dir);
2252                         return -1;
2253                 }
2254         }
2255
2256         swrap_un_path(un, swrap_dir, type, iface, prt);
2257         SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
2258
2259         SAFE_FREE(swrap_dir);
2260
2261         return 0;
2262 }
2263
2264 static struct socket_info *find_socket_info(int fd)
2265 {
2266         int idx = find_socket_info_index(fd);
2267
2268         if (idx == -1) {
2269                 return NULL;
2270         }
2271
2272         return swrap_get_socket_info(idx);
2273 }
2274
2275 #if 0 /* FIXME */
2276 static bool check_addr_port_in_use(const struct sockaddr *sa, socklen_t len)
2277 {
2278         struct socket_info_fd *f;
2279         const struct socket_info *last_s = NULL;
2280
2281         /* first catch invalid input */
2282         switch (sa->sa_family) {
2283         case AF_INET:
2284                 if (len < sizeof(struct sockaddr_in)) {
2285                         return false;
2286                 }
2287                 break;
2288 #ifdef HAVE_IPV6
2289         case AF_INET6:
2290                 if (len < sizeof(struct sockaddr_in6)) {
2291                         return false;
2292                 }
2293                 break;
2294 #endif
2295         default:
2296                 return false;
2297                 break;
2298         }
2299
2300         for (f = socket_fds; f; f = f->next) {
2301                 struct socket_info *s = swrap_get_socket_info(f->si_index);
2302
2303                 if (s == last_s) {
2304                         continue;
2305                 }
2306                 last_s = s;
2307
2308                 if (s->myname == NULL) {
2309                         continue;
2310                 }
2311                 if (s->myname->sa_family != sa->sa_family) {
2312                         continue;
2313                 }
2314                 switch (s->myname->sa_family) {
2315                 case AF_INET: {
2316                         struct sockaddr_in *sin1, *sin2;
2317
2318                         sin1 = (struct sockaddr_in *)s->myname;
2319                         sin2 = (struct sockaddr_in *)sa;
2320
2321                         if (sin1->sin_addr.s_addr == htonl(INADDR_ANY)) {
2322                                 continue;
2323                         }
2324                         if (sin1->sin_port != sin2->sin_port) {
2325                                 continue;
2326                         }
2327                         if (sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) {
2328                                 continue;
2329                         }
2330
2331                         /* found */
2332                         return true;
2333                         break;
2334                 }
2335 #ifdef HAVE_IPV6
2336                 case AF_INET6: {
2337                         struct sockaddr_in6 *sin1, *sin2;
2338
2339                         sin1 = (struct sockaddr_in6 *)s->myname;
2340                         sin2 = (struct sockaddr_in6 *)sa;
2341
2342                         if (sin1->sin6_port != sin2->sin6_port) {
2343                                 continue;
2344                         }
2345                         if (!IN6_ARE_ADDR_EQUAL(&sin1->sin6_addr,
2346                                                 &sin2->sin6_addr))
2347                         {
2348                                 continue;
2349                         }
2350
2351                         /* found */
2352                         return true;
2353                         break;
2354                 }
2355 #endif
2356                 default:
2357                         continue;
2358                         break;
2359
2360                 }
2361         }
2362
2363         return false;
2364 }
2365 #endif
2366
2367 static void swrap_remove_stale(int fd)
2368 {
2369         struct socket_info *si;
2370         int si_index;
2371
2372         SWRAP_LOG(SWRAP_LOG_TRACE, "remove stale wrapper for %d", fd);
2373
2374         swrap_mutex_lock(&socket_reset_mutex);
2375
2376         si_index = find_socket_info_index(fd);
2377         if (si_index == -1) {
2378                 swrap_mutex_unlock(&socket_reset_mutex);
2379                 return;
2380         }
2381
2382         reset_socket_info_index(fd);
2383
2384         si = swrap_get_socket_info(si_index);
2385
2386         swrap_mutex_lock(&first_free_mutex);
2387         SWRAP_LOCK_SI(si);
2388
2389         swrap_dec_refcount(si);
2390
2391         if (swrap_get_refcount(si) > 0) {
2392                 goto out;
2393         }
2394
2395         if (si->un_addr.sun_path[0] != '\0') {
2396                 unlink(si->un_addr.sun_path);
2397         }
2398
2399         swrap_set_next_free(si, first_free);
2400         first_free = si_index;
2401
2402 out:
2403         SWRAP_UNLOCK_SI(si);
2404         swrap_mutex_unlock(&first_free_mutex);
2405         swrap_mutex_unlock(&socket_reset_mutex);
2406 }
2407
2408 static int sockaddr_convert_to_un(struct socket_info *si,
2409                                   const struct sockaddr *in_addr,
2410                                   socklen_t in_len,
2411                                   struct sockaddr_un *out_addr,
2412                                   int alloc_sock,
2413                                   int *bcast)
2414 {
2415         struct sockaddr *out = (struct sockaddr *)(void *)out_addr;
2416
2417         (void) in_len; /* unused */
2418
2419         if (out_addr == NULL) {
2420                 return 0;
2421         }
2422
2423         out->sa_family = AF_UNIX;
2424 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
2425         out->sa_len = sizeof(*out_addr);
2426 #endif
2427
2428         switch (in_addr->sa_family) {
2429         case AF_UNSPEC: {
2430                 const struct sockaddr_in *sin;
2431                 if (si->family != AF_INET) {
2432                         break;
2433                 }
2434                 if (in_len < sizeof(struct sockaddr_in)) {
2435                         break;
2436                 }
2437                 sin = (const struct sockaddr_in *)(const void *)in_addr;
2438                 if(sin->sin_addr.s_addr != htonl(INADDR_ANY)) {
2439                         break;
2440                 }
2441
2442                 /*
2443                  * Note: in the special case of AF_UNSPEC and INADDR_ANY,
2444                  * AF_UNSPEC is mapped to AF_INET and must be treated here.
2445                  */
2446
2447                 FALL_THROUGH;
2448         }
2449         case AF_INET:
2450 #ifdef HAVE_IPV6
2451         case AF_INET6:
2452 #endif
2453                 switch (si->type) {
2454                 case SOCK_STREAM:
2455                 case SOCK_DGRAM:
2456                         break;
2457                 default:
2458                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!");
2459                         errno = ESOCKTNOSUPPORT;
2460                         return -1;
2461                 }
2462                 if (alloc_sock) {
2463                         return convert_in_un_alloc(si, in_addr, out_addr, bcast);
2464                 } else {
2465                         return convert_in_un_remote(si, in_addr, out_addr, bcast);
2466                 }
2467         default:
2468                 break;
2469         }
2470
2471         errno = EAFNOSUPPORT;
2472         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family");
2473         return -1;
2474 }
2475
2476 static int sockaddr_convert_from_un(const struct socket_info *si,
2477                                     const struct sockaddr_un *in_addr,
2478                                     socklen_t un_addrlen,
2479                                     int family,
2480                                     struct sockaddr *out_addr,
2481                                     socklen_t *out_addrlen)
2482 {
2483         int ret;
2484
2485         if (out_addr == NULL || out_addrlen == NULL)
2486                 return 0;
2487
2488         if (un_addrlen == 0) {
2489                 *out_addrlen = 0;
2490                 return 0;
2491         }
2492
2493         switch (family) {
2494         case AF_INET:
2495 #ifdef HAVE_IPV6
2496         case AF_INET6:
2497 #endif
2498                 switch (si->type) {
2499                 case SOCK_STREAM:
2500                 case SOCK_DGRAM:
2501                         break;
2502                 default:
2503                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!");
2504                         errno = ESOCKTNOSUPPORT;
2505                         return -1;
2506                 }
2507                 ret = convert_un_in(in_addr, out_addr, out_addrlen);
2508 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
2509                 out_addr->sa_len = *out_addrlen;
2510 #endif
2511                 return ret;
2512         default:
2513                 break;
2514         }
2515
2516         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family");
2517         errno = EAFNOSUPPORT;
2518         return -1;
2519 }
2520
2521 enum swrap_packet_type {
2522         SWRAP_CONNECT_SEND,
2523         SWRAP_CONNECT_UNREACH,
2524         SWRAP_CONNECT_RECV,
2525         SWRAP_CONNECT_ACK,
2526         SWRAP_ACCEPT_SEND,
2527         SWRAP_ACCEPT_RECV,
2528         SWRAP_ACCEPT_ACK,
2529         SWRAP_RECVFROM,
2530         SWRAP_SENDTO,
2531         SWRAP_SENDTO_UNREACH,
2532         SWRAP_PENDING_RST,
2533         SWRAP_RECV,
2534         SWRAP_RECV_RST,
2535         SWRAP_SEND,
2536         SWRAP_SEND_RST,
2537         SWRAP_CLOSE_SEND,
2538         SWRAP_CLOSE_RECV,
2539         SWRAP_CLOSE_ACK,
2540 };
2541
2542 struct swrap_file_hdr {
2543         uint32_t        magic;
2544         uint16_t        version_major;
2545         uint16_t        version_minor;
2546         int32_t         timezone;
2547         uint32_t        sigfigs;
2548         uint32_t        frame_max_len;
2549 #define SWRAP_FRAME_LENGTH_MAX 0xFFFF
2550         uint32_t        link_type;
2551 };
2552 #define SWRAP_FILE_HDR_SIZE 24
2553
2554 struct swrap_packet_frame {
2555         uint32_t seconds;
2556         uint32_t micro_seconds;
2557         uint32_t recorded_length;
2558         uint32_t full_length;
2559 };
2560 #define SWRAP_PACKET_FRAME_SIZE 16
2561
2562 union swrap_packet_ip {
2563         struct {
2564                 uint8_t         ver_hdrlen;
2565                 uint8_t         tos;
2566                 uint16_t        packet_length;
2567                 uint16_t        identification;
2568                 uint8_t         flags;
2569                 uint8_t         fragment;
2570                 uint8_t         ttl;
2571                 uint8_t         protocol;
2572                 uint16_t        hdr_checksum;
2573                 uint32_t        src_addr;
2574                 uint32_t        dest_addr;
2575         } v4;
2576 #define SWRAP_PACKET_IP_V4_SIZE 20
2577         struct {
2578                 uint8_t         ver_prio;
2579                 uint8_t         flow_label_high;
2580                 uint16_t        flow_label_low;
2581                 uint16_t        payload_length;
2582                 uint8_t         next_header;
2583                 uint8_t         hop_limit;
2584                 uint8_t         src_addr[16];
2585                 uint8_t         dest_addr[16];
2586         } v6;
2587 #define SWRAP_PACKET_IP_V6_SIZE 40
2588 };
2589 #define SWRAP_PACKET_IP_SIZE 40
2590
2591 union swrap_packet_payload {
2592         struct {
2593                 uint16_t        source_port;
2594                 uint16_t        dest_port;
2595                 uint32_t        seq_num;
2596                 uint32_t        ack_num;
2597                 uint8_t         hdr_length;
2598                 uint8_t         control;
2599                 uint16_t        window;
2600                 uint16_t        checksum;
2601                 uint16_t        urg;
2602         } tcp;
2603 #define SWRAP_PACKET_PAYLOAD_TCP_SIZE 20
2604         struct {
2605                 uint16_t        source_port;
2606                 uint16_t        dest_port;
2607                 uint16_t        length;
2608                 uint16_t        checksum;
2609         } udp;
2610 #define SWRAP_PACKET_PAYLOAD_UDP_SIZE 8
2611         struct {
2612                 uint8_t         type;
2613                 uint8_t         code;
2614                 uint16_t        checksum;
2615                 uint32_t        unused;
2616         } icmp4;
2617 #define SWRAP_PACKET_PAYLOAD_ICMP4_SIZE 8
2618         struct {
2619                 uint8_t         type;
2620                 uint8_t         code;
2621                 uint16_t        checksum;
2622                 uint32_t        unused;
2623         } icmp6;
2624 #define SWRAP_PACKET_PAYLOAD_ICMP6_SIZE 8
2625 };
2626 #define SWRAP_PACKET_PAYLOAD_SIZE 20
2627
2628 #define SWRAP_PACKET_MIN_ALLOC \
2629         (SWRAP_PACKET_FRAME_SIZE + \
2630          SWRAP_PACKET_IP_SIZE + \
2631          SWRAP_PACKET_PAYLOAD_SIZE)
2632
2633 static const char *swrap_pcap_init_file(void)
2634 {
2635         static int initialized = 0;
2636         static const char *s = NULL;
2637         static const struct swrap_file_hdr h;
2638         static const struct swrap_packet_frame f;
2639         static const union swrap_packet_ip i;
2640         static const union swrap_packet_payload p;
2641
2642         if (initialized == 1) {
2643                 return s;
2644         }
2645         initialized = 1;
2646
2647         /*
2648          * TODO: don't use the structs use plain buffer offsets
2649          *       and PUSH_U8(), PUSH_U16() and PUSH_U32()
2650          *
2651          * for now make sure we disable PCAP support
2652          * if the struct has alignment!
2653          */
2654         if (sizeof(h) != SWRAP_FILE_HDR_SIZE) {
2655                 return NULL;
2656         }
2657         if (sizeof(f) != SWRAP_PACKET_FRAME_SIZE) {
2658                 return NULL;
2659         }
2660         if (sizeof(i) != SWRAP_PACKET_IP_SIZE) {
2661                 return NULL;
2662         }
2663         if (sizeof(i.v4) != SWRAP_PACKET_IP_V4_SIZE) {
2664                 return NULL;
2665         }
2666         if (sizeof(i.v6) != SWRAP_PACKET_IP_V6_SIZE) {
2667                 return NULL;
2668         }
2669         if (sizeof(p) != SWRAP_PACKET_PAYLOAD_SIZE) {
2670                 return NULL;
2671         }
2672         if (sizeof(p.tcp) != SWRAP_PACKET_PAYLOAD_TCP_SIZE) {
2673                 return NULL;
2674         }
2675         if (sizeof(p.udp) != SWRAP_PACKET_PAYLOAD_UDP_SIZE) {
2676                 return NULL;
2677         }
2678         if (sizeof(p.icmp4) != SWRAP_PACKET_PAYLOAD_ICMP4_SIZE) {
2679                 return NULL;
2680         }
2681         if (sizeof(p.icmp6) != SWRAP_PACKET_PAYLOAD_ICMP6_SIZE) {
2682                 return NULL;
2683         }
2684
2685         s = getenv("SOCKET_WRAPPER_PCAP_FILE");
2686         if (s == NULL) {
2687                 return NULL;
2688         }
2689         if (strncmp(s, "./", 2) == 0) {
2690                 s += 2;
2691         }
2692         SWRAP_LOG(SWRAP_LOG_TRACE, "SOCKET_WRAPPER_PCAP_FILE: %s", s);
2693         return s;
2694 }
2695
2696 static uint8_t *swrap_pcap_packet_init(struct timeval *tval,
2697                                        const struct sockaddr *src,
2698                                        const struct sockaddr *dest,
2699                                        int socket_type,
2700                                        const uint8_t *payload,
2701                                        size_t payload_len,
2702                                        unsigned long tcp_seqno,
2703                                        unsigned long tcp_ack,
2704                                        unsigned char tcp_ctl,
2705                                        int unreachable,
2706                                        size_t *_packet_len)
2707 {
2708         uint8_t *base = NULL;
2709         uint8_t *buf = NULL;
2710         union {
2711                 uint8_t *ptr;
2712                 struct swrap_packet_frame *frame;
2713         } f;
2714         union {
2715                 uint8_t *ptr;
2716                 union swrap_packet_ip *ip;
2717         } i;
2718         union swrap_packet_payload *pay;
2719         size_t packet_len;
2720         size_t alloc_len;
2721         size_t nonwire_len = sizeof(struct swrap_packet_frame);
2722         size_t wire_hdr_len = 0;
2723         size_t wire_len = 0;
2724         size_t ip_hdr_len = 0;
2725         size_t icmp_hdr_len = 0;
2726         size_t icmp_truncate_len = 0;
2727         uint8_t protocol = 0, icmp_protocol = 0;
2728         const struct sockaddr_in *src_in = NULL;
2729         const struct sockaddr_in *dest_in = NULL;
2730 #ifdef HAVE_IPV6
2731         const struct sockaddr_in6 *src_in6 = NULL;
2732         const struct sockaddr_in6 *dest_in6 = NULL;
2733 #endif
2734         uint16_t src_port;
2735         uint16_t dest_port;
2736
2737         switch (src->sa_family) {
2738         case AF_INET:
2739                 src_in = (const struct sockaddr_in *)(const void *)src;
2740                 dest_in = (const struct sockaddr_in *)(const void *)dest;
2741                 src_port = src_in->sin_port;
2742                 dest_port = dest_in->sin_port;
2743                 ip_hdr_len = sizeof(i.ip->v4);
2744                 break;
2745 #ifdef HAVE_IPV6
2746         case AF_INET6:
2747                 src_in6 = (const struct sockaddr_in6 *)(const void *)src;
2748                 dest_in6 = (const struct sockaddr_in6 *)(const void *)dest;
2749                 src_port = src_in6->sin6_port;
2750                 dest_port = dest_in6->sin6_port;
2751                 ip_hdr_len = sizeof(i.ip->v6);
2752                 break;
2753 #endif
2754         default:
2755                 return NULL;
2756         }
2757
2758         switch (socket_type) {
2759         case SOCK_STREAM:
2760                 protocol = 0x06; /* TCP */
2761                 wire_hdr_len = ip_hdr_len + sizeof(pay->tcp);
2762                 wire_len = wire_hdr_len + payload_len;
2763                 break;
2764
2765         case SOCK_DGRAM:
2766                 protocol = 0x11; /* UDP */
2767                 wire_hdr_len = ip_hdr_len + sizeof(pay->udp);
2768                 wire_len = wire_hdr_len + payload_len;
2769                 break;
2770
2771         default:
2772                 return NULL;
2773         }
2774
2775         if (unreachable) {
2776                 icmp_protocol = protocol;
2777                 switch (src->sa_family) {
2778                 case AF_INET:
2779                         protocol = 0x01; /* ICMPv4 */
2780                         icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp4);
2781                         break;
2782 #ifdef HAVE_IPV6
2783                 case AF_INET6:
2784                         protocol = 0x3A; /* ICMPv6 */
2785                         icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp6);
2786                         break;
2787 #endif
2788                 }
2789                 if (wire_len > 64 ) {
2790                         icmp_truncate_len = wire_len - 64;
2791                 }
2792                 wire_len += icmp_hdr_len;
2793         }
2794
2795         packet_len = nonwire_len + wire_len;
2796         alloc_len = packet_len;
2797         if (alloc_len < SWRAP_PACKET_MIN_ALLOC) {
2798                 alloc_len = SWRAP_PACKET_MIN_ALLOC;
2799         }
2800
2801         base = (uint8_t *)calloc(1, alloc_len);
2802         if (base == NULL) {
2803                 return NULL;
2804         }
2805
2806         buf = base;
2807         f.ptr = buf;
2808
2809         f.frame->seconds                = tval->tv_sec;
2810         f.frame->micro_seconds  = tval->tv_usec;
2811         f.frame->recorded_length        = wire_len - icmp_truncate_len;
2812         f.frame->full_length    = wire_len - icmp_truncate_len;
2813
2814         buf += SWRAP_PACKET_FRAME_SIZE;
2815
2816         i.ptr = buf;
2817         switch (src->sa_family) {
2818         case AF_INET:
2819                 if (src_in == NULL || dest_in == NULL) {
2820                         SAFE_FREE(base);
2821                         return NULL;
2822                 }
2823
2824                 i.ip->v4.ver_hdrlen     = 0x45; /* version 4 and 5 * 32 bit words */
2825                 i.ip->v4.tos            = 0x00;
2826                 i.ip->v4.packet_length  = htons(wire_len - icmp_truncate_len);
2827                 i.ip->v4.identification = htons(0xFFFF);
2828                 i.ip->v4.flags          = 0x40; /* BIT 1 set - means don't fragment */
2829                 i.ip->v4.fragment       = htons(0x0000);
2830                 i.ip->v4.ttl            = 0xFF;
2831                 i.ip->v4.protocol       = protocol;
2832                 i.ip->v4.hdr_checksum   = htons(0x0000);
2833                 i.ip->v4.src_addr       = src_in->sin_addr.s_addr;
2834                 i.ip->v4.dest_addr      = dest_in->sin_addr.s_addr;
2835                 buf += SWRAP_PACKET_IP_V4_SIZE;
2836                 break;
2837 #ifdef HAVE_IPV6
2838         case AF_INET6:
2839                 if (src_in6 == NULL || dest_in6 == NULL) {
2840                         SAFE_FREE(base);
2841                         return NULL;
2842                 }
2843
2844                 i.ip->v6.ver_prio               = 0x60; /* version 4 and 5 * 32 bit words */
2845                 i.ip->v6.flow_label_high        = 0x00;
2846                 i.ip->v6.flow_label_low = 0x0000;
2847                 i.ip->v6.payload_length = htons(wire_len - icmp_truncate_len); /* TODO */
2848                 i.ip->v6.next_header    = protocol;
2849                 memcpy(i.ip->v6.src_addr, src_in6->sin6_addr.s6_addr, 16);
2850                 memcpy(i.ip->v6.dest_addr, dest_in6->sin6_addr.s6_addr, 16);
2851                 buf += SWRAP_PACKET_IP_V6_SIZE;
2852                 break;
2853 #endif
2854         }
2855
2856         if (unreachable) {
2857                 pay = (union swrap_packet_payload *)(void *)buf;
2858                 switch (src->sa_family) {
2859                 case AF_INET:
2860                         pay->icmp4.type         = 0x03; /* destination unreachable */
2861                         pay->icmp4.code         = 0x01; /* host unreachable */
2862                         pay->icmp4.checksum     = htons(0x0000);
2863                         pay->icmp4.unused       = htonl(0x00000000);
2864
2865                         buf += SWRAP_PACKET_PAYLOAD_ICMP4_SIZE;
2866
2867                         /* set the ip header in the ICMP payload */
2868                         i.ptr = buf;
2869                         i.ip->v4.ver_hdrlen     = 0x45; /* version 4 and 5 * 32 bit words */
2870                         i.ip->v4.tos            = 0x00;
2871                         i.ip->v4.packet_length  = htons(wire_len - icmp_hdr_len);
2872                         i.ip->v4.identification = htons(0xFFFF);
2873                         i.ip->v4.flags          = 0x40; /* BIT 1 set - means don't fragment */
2874                         i.ip->v4.fragment       = htons(0x0000);
2875                         i.ip->v4.ttl            = 0xFF;
2876                         i.ip->v4.protocol       = icmp_protocol;
2877                         i.ip->v4.hdr_checksum   = htons(0x0000);
2878                         i.ip->v4.src_addr       = dest_in->sin_addr.s_addr;
2879                         i.ip->v4.dest_addr      = src_in->sin_addr.s_addr;
2880
2881                         buf += SWRAP_PACKET_IP_V4_SIZE;
2882
2883                         src_port = dest_in->sin_port;
2884                         dest_port = src_in->sin_port;
2885                         break;
2886 #ifdef HAVE_IPV6
2887                 case AF_INET6:
2888                         pay->icmp6.type         = 0x01; /* destination unreachable */
2889                         pay->icmp6.code         = 0x03; /* address unreachable */
2890                         pay->icmp6.checksum     = htons(0x0000);
2891                         pay->icmp6.unused       = htonl(0x00000000);
2892                         buf += SWRAP_PACKET_PAYLOAD_ICMP6_SIZE;
2893
2894                         /* set the ip header in the ICMP payload */
2895                         i.ptr = buf;
2896                         i.ip->v6.ver_prio               = 0x60; /* version 4 and 5 * 32 bit words */
2897                         i.ip->v6.flow_label_high        = 0x00;
2898                         i.ip->v6.flow_label_low = 0x0000;
2899                         i.ip->v6.payload_length = htons(wire_len - icmp_truncate_len); /* TODO */
2900                         i.ip->v6.next_header    = protocol;
2901                         memcpy(i.ip->v6.src_addr, dest_in6->sin6_addr.s6_addr, 16);
2902                         memcpy(i.ip->v6.dest_addr, src_in6->sin6_addr.s6_addr, 16);
2903
2904                         buf += SWRAP_PACKET_IP_V6_SIZE;
2905
2906                         src_port = dest_in6->sin6_port;
2907                         dest_port = src_in6->sin6_port;
2908                         break;
2909 #endif
2910                 }
2911         }
2912
2913         pay = (union swrap_packet_payload *)(void *)buf;
2914
2915         switch (socket_type) {
2916         case SOCK_STREAM:
2917                 pay->tcp.source_port    = src_port;
2918                 pay->tcp.dest_port      = dest_port;
2919                 pay->tcp.seq_num        = htonl(tcp_seqno);
2920                 pay->tcp.ack_num        = htonl(tcp_ack);
2921                 pay->tcp.hdr_length     = 0x50; /* 5 * 32 bit words */
2922                 pay->tcp.control        = tcp_ctl;
2923                 pay->tcp.window         = htons(0x7FFF);
2924                 pay->tcp.checksum       = htons(0x0000);
2925                 pay->tcp.urg            = htons(0x0000);
2926                 buf += SWRAP_PACKET_PAYLOAD_TCP_SIZE;
2927
2928                 break;
2929
2930         case SOCK_DGRAM:
2931                 pay->udp.source_port    = src_port;
2932                 pay->udp.dest_port      = dest_port;
2933                 pay->udp.length         = htons(8 + payload_len);
2934                 pay->udp.checksum       = htons(0x0000);
2935                 buf += SWRAP_PACKET_PAYLOAD_UDP_SIZE;
2936
2937                 break;
2938         }
2939
2940         if (payload && payload_len > 0) {
2941                 memcpy(buf, payload, payload_len);
2942         }
2943
2944         *_packet_len = packet_len - icmp_truncate_len;
2945         return base;
2946 }
2947
2948 static int swrap_pcap_get_fd(const char *fname)
2949 {
2950         static int fd = -1;
2951
2952         if (fd != -1) {
2953                 return fd;
2954         }
2955
2956         fd = libc_open(fname, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0644);
2957         if (fd != -1) {
2958                 struct swrap_file_hdr file_hdr;
2959                 file_hdr.magic          = 0xA1B2C3D4;
2960                 file_hdr.version_major  = 0x0002;
2961                 file_hdr.version_minor  = 0x0004;
2962                 file_hdr.timezone       = 0x00000000;
2963                 file_hdr.sigfigs        = 0x00000000;
2964                 file_hdr.frame_max_len  = SWRAP_FRAME_LENGTH_MAX;
2965                 file_hdr.link_type      = 0x0065; /* 101 RAW IP */
2966
2967                 if (write(fd, &file_hdr, sizeof(file_hdr)) != sizeof(file_hdr)) {
2968                         libc_close(fd);
2969                         fd = -1;
2970                 }
2971                 return fd;
2972         }
2973
2974         fd = libc_open(fname, O_WRONLY|O_APPEND, 0644);
2975
2976         return fd;
2977 }
2978
2979 static uint8_t *swrap_pcap_marshall_packet(struct socket_info *si,
2980                                            const struct sockaddr *addr,
2981                                            enum swrap_packet_type type,
2982                                            const void *buf, size_t len,
2983                                            size_t *packet_len)
2984 {
2985         const struct sockaddr *src_addr;
2986         const struct sockaddr *dest_addr;
2987         unsigned long tcp_seqno = 0;
2988         unsigned long tcp_ack = 0;
2989         unsigned char tcp_ctl = 0;
2990         int unreachable = 0;
2991
2992         struct timeval tv;
2993
2994         switch (si->family) {
2995         case AF_INET:
2996                 break;
2997 #ifdef HAVE_IPV6
2998         case AF_INET6:
2999                 break;
3000 #endif
3001         default:
3002                 return NULL;
3003         }
3004
3005         switch (type) {
3006         case SWRAP_CONNECT_SEND:
3007                 if (si->type != SOCK_STREAM) {
3008                         return NULL;
3009                 }
3010
3011                 src_addr  = &si->myname.sa.s;
3012                 dest_addr = addr;
3013
3014                 tcp_seqno = si->io.pck_snd;
3015                 tcp_ack = si->io.pck_rcv;
3016                 tcp_ctl = 0x02; /* SYN */
3017
3018                 si->io.pck_snd += 1;
3019
3020                 break;
3021
3022         case SWRAP_CONNECT_RECV:
3023                 if (si->type != SOCK_STREAM) {
3024                         return NULL;
3025                 }
3026
3027                 dest_addr = &si->myname.sa.s;
3028                 src_addr = addr;
3029
3030                 tcp_seqno = si->io.pck_rcv;
3031                 tcp_ack = si->io.pck_snd;
3032                 tcp_ctl = 0x12; /** SYN,ACK */
3033
3034                 si->io.pck_rcv += 1;
3035
3036                 break;
3037
3038         case SWRAP_CONNECT_UNREACH:
3039                 if (si->type != SOCK_STREAM) {
3040                         return NULL;
3041                 }
3042
3043                 dest_addr = &si->myname.sa.s;
3044                 src_addr  = addr;
3045
3046                 /* Unreachable: resend the data of SWRAP_CONNECT_SEND */
3047                 tcp_seqno = si->io.pck_snd - 1;
3048                 tcp_ack = si->io.pck_rcv;
3049                 tcp_ctl = 0x02; /* SYN */
3050                 unreachable = 1;
3051
3052                 break;
3053
3054         case SWRAP_CONNECT_ACK:
3055                 if (si->type != SOCK_STREAM) {
3056                         return NULL;
3057                 }
3058
3059                 src_addr  = &si->myname.sa.s;
3060                 dest_addr = addr;
3061
3062                 tcp_seqno = si->io.pck_snd;
3063                 tcp_ack = si->io.pck_rcv;
3064                 tcp_ctl = 0x10; /* ACK */
3065
3066                 break;
3067
3068         case SWRAP_ACCEPT_SEND:
3069                 if (si->type != SOCK_STREAM) {
3070                         return NULL;
3071                 }
3072
3073                 dest_addr = &si->myname.sa.s;
3074                 src_addr = addr;
3075
3076                 tcp_seqno = si->io.pck_rcv;
3077                 tcp_ack = si->io.pck_snd;
3078                 tcp_ctl = 0x02; /* SYN */
3079
3080                 si->io.pck_rcv += 1;
3081
3082                 break;
3083
3084         case SWRAP_ACCEPT_RECV:
3085                 if (si->type != SOCK_STREAM) {
3086                         return NULL;
3087                 }
3088
3089                 src_addr = &si->myname.sa.s;
3090                 dest_addr = addr;
3091
3092                 tcp_seqno = si->io.pck_snd;
3093                 tcp_ack = si->io.pck_rcv;
3094                 tcp_ctl = 0x12; /* SYN,ACK */
3095
3096                 si->io.pck_snd += 1;
3097
3098                 break;
3099
3100         case SWRAP_ACCEPT_ACK:
3101                 if (si->type != SOCK_STREAM) {
3102                         return NULL;
3103                 }
3104
3105                 dest_addr = &si->myname.sa.s;
3106                 src_addr = addr;
3107
3108                 tcp_seqno = si->io.pck_rcv;
3109                 tcp_ack = si->io.pck_snd;
3110                 tcp_ctl = 0x10; /* ACK */
3111
3112                 break;
3113
3114         case SWRAP_SEND:
3115                 src_addr  = &si->myname.sa.s;
3116                 dest_addr = &si->peername.sa.s;
3117
3118                 tcp_seqno = si->io.pck_snd;
3119                 tcp_ack = si->io.pck_rcv;
3120                 tcp_ctl = 0x18; /* PSH,ACK */
3121
3122                 si->io.pck_snd += len;
3123
3124                 break;
3125
3126         case SWRAP_SEND_RST:
3127                 dest_addr = &si->myname.sa.s;
3128                 src_addr  = &si->peername.sa.s;
3129
3130                 if (si->type == SOCK_DGRAM) {
3131                         return swrap_pcap_marshall_packet(si,
3132                                                           &si->peername.sa.s,
3133                                                           SWRAP_SENDTO_UNREACH,
3134                                                           buf,
3135                                                           len,
3136                                                           packet_len);
3137                 }
3138
3139                 tcp_seqno = si->io.pck_rcv;
3140                 tcp_ack = si->io.pck_snd;
3141                 tcp_ctl = 0x14; /** RST,ACK */
3142
3143                 break;
3144
3145         case SWRAP_PENDING_RST:
3146                 dest_addr = &si->myname.sa.s;
3147                 src_addr  = &si->peername.sa.s;
3148
3149                 if (si->type == SOCK_DGRAM) {
3150                         return NULL;
3151                 }
3152
3153                 tcp_seqno = si->io.pck_rcv;
3154                 tcp_ack = si->io.pck_snd;
3155                 tcp_ctl = 0x14; /* RST,ACK */
3156
3157                 break;
3158
3159         case SWRAP_RECV:
3160                 dest_addr = &si->myname.sa.s;
3161                 src_addr  = &si->peername.sa.s;
3162
3163                 tcp_seqno = si->io.pck_rcv;
3164                 tcp_ack = si->io.pck_snd;
3165                 tcp_ctl = 0x18; /* PSH,ACK */
3166
3167                 si->io.pck_rcv += len;
3168
3169                 break;
3170
3171         case SWRAP_RECV_RST:
3172                 dest_addr = &si->myname.sa.s;
3173                 src_addr  = &si->peername.sa.s;
3174
3175                 if (si->type == SOCK_DGRAM) {
3176                         return NULL;
3177                 }
3178
3179                 tcp_seqno = si->io.pck_rcv;
3180                 tcp_ack = si->io.pck_snd;
3181                 tcp_ctl = 0x14; /* RST,ACK */
3182
3183                 break;
3184
3185         case SWRAP_SENDTO:
3186                 src_addr = &si->myname.sa.s;
3187                 dest_addr = addr;
3188
3189                 si->io.pck_snd += len;
3190
3191                 break;
3192
3193         case SWRAP_SENDTO_UNREACH:
3194                 dest_addr = &si->myname.sa.s;
3195                 src_addr = addr;
3196
3197                 unreachable = 1;
3198
3199                 break;
3200
3201         case SWRAP_RECVFROM:
3202                 dest_addr = &si->myname.sa.s;
3203                 src_addr = addr;
3204
3205                 si->io.pck_rcv += len;
3206
3207                 break;
3208
3209         case SWRAP_CLOSE_SEND:
3210                 if (si->type != SOCK_STREAM) {
3211                         return NULL;
3212                 }
3213
3214                 src_addr  = &si->myname.sa.s;
3215                 dest_addr = &si->peername.sa.s;
3216
3217                 tcp_seqno = si->io.pck_snd;
3218                 tcp_ack = si->io.pck_rcv;
3219                 tcp_ctl = 0x11; /* FIN, ACK */
3220
3221                 si->io.pck_snd += 1;
3222
3223                 break;
3224
3225         case SWRAP_CLOSE_RECV:
3226                 if (si->type != SOCK_STREAM) {
3227                         return NULL;
3228                 }
3229
3230                 dest_addr = &si->myname.sa.s;
3231                 src_addr  = &si->peername.sa.s;
3232
3233                 tcp_seqno = si->io.pck_rcv;
3234                 tcp_ack = si->io.pck_snd;
3235                 tcp_ctl = 0x11; /* FIN,ACK */
3236
3237                 si->io.pck_rcv += 1;
3238
3239                 break;
3240
3241         case SWRAP_CLOSE_ACK:
3242                 if (si->type != SOCK_STREAM) {
3243                         return NULL;
3244                 }
3245
3246                 src_addr  = &si->myname.sa.s;
3247                 dest_addr = &si->peername.sa.s;
3248
3249                 tcp_seqno = si->io.pck_snd;
3250                 tcp_ack = si->io.pck_rcv;
3251                 tcp_ctl = 0x10; /* ACK */
3252
3253                 break;
3254         default:
3255                 return NULL;
3256         }
3257
3258         swrapGetTimeOfDay(&tv);
3259
3260         return swrap_pcap_packet_init(&tv,
3261                                       src_addr,
3262                                       dest_addr,
3263                                       si->type,
3264                                       (const uint8_t *)buf,
3265                                       len,
3266                                       tcp_seqno,
3267                                       tcp_ack,
3268                                       tcp_ctl,
3269                                       unreachable,
3270                                       packet_len);
3271 }
3272
3273 static void swrap_pcap_dump_packet(struct socket_info *si,
3274                                    const struct sockaddr *addr,
3275                                    enum swrap_packet_type type,
3276                                    const void *buf, size_t len)
3277 {
3278         const char *file_name;
3279         uint8_t *packet;
3280         size_t packet_len = 0;
3281         int fd;
3282
3283         swrap_mutex_lock(&pcap_dump_mutex);
3284
3285         file_name = swrap_pcap_init_file();
3286         if (!file_name) {
3287                 goto done;
3288         }
3289
3290         packet = swrap_pcap_marshall_packet(si,
3291                                             addr,
3292                                             type,
3293                                             buf,
3294                                             len,
3295                                             &packet_len);
3296         if (packet == NULL) {
3297                 goto done;
3298         }
3299
3300         fd = swrap_pcap_get_fd(file_name);
3301         if (fd != -1) {
3302                 if (write(fd, packet, packet_len) != (ssize_t)packet_len) {
3303                         free(packet);
3304                         goto done;
3305                 }
3306         }
3307
3308         free(packet);
3309
3310 done:
3311         swrap_mutex_unlock(&pcap_dump_mutex);
3312 }
3313
3314 /****************************************************************************
3315  *   SIGNALFD
3316  ***************************************************************************/
3317
3318 #ifdef HAVE_SIGNALFD
3319 static int swrap_signalfd(int fd, const sigset_t *mask, int flags)
3320 {
3321         int rc;
3322
3323         rc = libc_signalfd(fd, mask, flags);
3324         if (rc != -1) {
3325                 swrap_remove_stale(fd);
3326         }
3327
3328         return rc;
3329 }
3330
3331 int signalfd(int fd, const sigset_t *mask, int flags)
3332 {
3333         return swrap_signalfd(fd, mask, flags);
3334 }
3335 #endif
3336
3337 /****************************************************************************
3338  *   SOCKET
3339  ***************************************************************************/
3340
3341 static int swrap_socket(int family, int type, int protocol)
3342 {
3343         struct socket_info *si = NULL;
3344         struct socket_info _si = { 0 };
3345         int fd;
3346         int ret;
3347         int real_type = type;
3348
3349         /*
3350          * Remove possible addition flags passed to socket() so
3351          * do not fail checking the type.
3352          * See https://lwn.net/Articles/281965/
3353          */
3354 #ifdef SOCK_CLOEXEC
3355         real_type &= ~SOCK_CLOEXEC;
3356 #endif
3357 #ifdef SOCK_NONBLOCK
3358         real_type &= ~SOCK_NONBLOCK;
3359 #endif
3360
3361         if (!socket_wrapper_enabled()) {
3362                 return libc_socket(family, type, protocol);
3363         }
3364
3365         switch (family) {
3366         case AF_INET:
3367 #ifdef HAVE_IPV6
3368         case AF_INET6:
3369 #endif
3370                 break;
3371 #ifdef AF_NETLINK
3372         case AF_NETLINK:
3373 #endif /* AF_NETLINK */
3374 #ifdef AF_PACKET
3375         case AF_PACKET:
3376 #endif /* AF_PACKET */
3377         case AF_UNIX:
3378                 fd = libc_socket(family, type, protocol);
3379                 if (fd != -1) {
3380                         /* Check if we have a stale fd and remove it */
3381                         swrap_remove_stale(fd);
3382                         SWRAP_LOG(SWRAP_LOG_TRACE,
3383                                   "Unix socket fd=%d",
3384                                   fd);
3385                 }
3386                 return fd;
3387         default:
3388                 errno = EAFNOSUPPORT;
3389                 return -1;
3390         }
3391
3392         switch (real_type) {
3393         case SOCK_STREAM:
3394                 break;
3395         case SOCK_DGRAM:
3396                 break;
3397         default:
3398                 errno = EPROTONOSUPPORT;
3399                 return -1;
3400         }
3401
3402         switch (protocol) {
3403         case 0:
3404                 break;
3405         case 6:
3406                 if (real_type == SOCK_STREAM) {
3407                         break;
3408                 }
3409                 FALL_THROUGH;
3410         case 17:
3411                 if (real_type == SOCK_DGRAM) {
3412                         break;
3413                 }
3414                 FALL_THROUGH;
3415         default:
3416                 errno = EPROTONOSUPPORT;
3417                 return -1;
3418         }
3419
3420         /*
3421          * We must call libc_socket with type, from the caller, not the version
3422          * we removed SOCK_CLOEXEC and SOCK_NONBLOCK from
3423          */
3424         fd = libc_socket(AF_UNIX, type, 0);
3425
3426         if (fd == -1) {
3427                 return -1;
3428         }
3429
3430         /* Check if we have a stale fd and remove it */
3431         swrap_remove_stale(fd);
3432
3433         si = &_si;
3434         si->family = family;
3435
3436         /* however, the rest of the socket_wrapper code expects just
3437          * the type, not the flags */
3438         si->type = real_type;
3439         si->protocol = protocol;
3440
3441         /*
3442          * Setup myname so getsockname() can succeed to find out the socket
3443          * type.
3444          */
3445         switch(si->family) {
3446         case AF_INET: {
3447                 struct sockaddr_in sin = {
3448                         .sin_family = AF_INET,
3449                 };
3450
3451                 si->myname.sa_socklen = sizeof(struct sockaddr_in);
3452                 memcpy(&si->myname.sa.in, &sin, si->myname.sa_socklen);
3453                 break;
3454         }
3455 #ifdef HAVE_IPV6
3456         case AF_INET6: {
3457                 struct sockaddr_in6 sin6 = {
3458                         .sin6_family = AF_INET6,
3459                 };
3460
3461                 si->myname.sa_socklen = sizeof(struct sockaddr_in6);
3462                 memcpy(&si->myname.sa.in6, &sin6, si->myname.sa_socklen);
3463                 break;
3464         }
3465 #endif
3466         default:
3467                 errno = EINVAL;
3468                 return -1;
3469         }
3470
3471         ret = swrap_create_socket(si, fd);
3472         if (ret == -1) {
3473                 int saved_errno = errno;
3474                 libc_close(fd);
3475                 errno = saved_errno;
3476                 return -1;
3477         }
3478
3479         SWRAP_LOG(SWRAP_LOG_TRACE,
3480                   "Created %s socket for protocol %s, fd=%d",
3481                   family == AF_INET ? "IPv4" : "IPv6",
3482                   real_type == SOCK_DGRAM ? "UDP" : "TCP",
3483                   fd);
3484
3485         return fd;
3486 }
3487
3488 int socket(int family, int type, int protocol)
3489 {
3490         return swrap_socket(family, type, protocol);
3491 }
3492
3493 /****************************************************************************
3494  *   SOCKETPAIR
3495  ***************************************************************************/
3496
3497 static int swrap_socketpair(int family, int type, int protocol, int sv[2])
3498 {
3499         int rc;
3500
3501         rc = libc_socketpair(family, type, protocol, sv);
3502         if (rc != -1) {
3503                 swrap_remove_stale(sv[0]);
3504                 swrap_remove_stale(sv[1]);
3505         }
3506
3507         return rc;
3508 }
3509
3510 int socketpair(int family, int type, int protocol, int sv[2])
3511 {
3512         return swrap_socketpair(family, type, protocol, sv);
3513 }
3514
3515 /****************************************************************************
3516  *   SOCKETPAIR
3517  ***************************************************************************/
3518
3519 #ifdef HAVE_TIMERFD_CREATE
3520 static int swrap_timerfd_create(int clockid, int flags)
3521 {
3522         int fd;
3523
3524         fd = libc_timerfd_create(clockid, flags);
3525         if (fd != -1) {
3526                 swrap_remove_stale(fd);
3527         }
3528
3529         return fd;
3530 }
3531
3532 int timerfd_create(int clockid, int flags)
3533 {
3534         return swrap_timerfd_create(clockid, flags);
3535 }
3536 #endif
3537
3538 /****************************************************************************
3539  *   PIPE
3540  ***************************************************************************/
3541
3542 static int swrap_pipe(int pipefd[2])
3543 {
3544         int rc;
3545
3546         rc = libc_pipe(pipefd);
3547         if (rc != -1) {
3548                 swrap_remove_stale(pipefd[0]);
3549                 swrap_remove_stale(pipefd[1]);
3550         }
3551
3552         return rc;
3553 }
3554
3555 int pipe(int pipefd[2])
3556 {
3557         return swrap_pipe(pipefd);
3558 }
3559
3560 /****************************************************************************
3561  *   ACCEPT
3562  ***************************************************************************/
3563
3564 static int swrap_accept(int s,
3565                         struct sockaddr *addr,
3566                         socklen_t *addrlen,
3567                         int flags)
3568 {
3569         struct socket_info *parent_si, *child_si;
3570         struct socket_info new_si = { 0 };
3571         int fd;
3572         int idx;
3573         struct swrap_address un_addr = {
3574                 .sa_socklen = sizeof(struct sockaddr_un),
3575         };
3576         struct swrap_address un_my_addr = {
3577                 .sa_socklen = sizeof(struct sockaddr_un),
3578         };
3579         struct swrap_address in_addr = {
3580                 .sa_socklen = sizeof(struct sockaddr_storage),
3581         };
3582         struct swrap_address in_my_addr = {
3583                 .sa_socklen = sizeof(struct sockaddr_storage),
3584         };
3585         int ret;
3586
3587         parent_si = find_socket_info(s);
3588         if (!parent_si) {
3589 #ifdef HAVE_ACCEPT4
3590                 return libc_accept4(s, addr, addrlen, flags);
3591 #else
3592                 UNUSED(flags);
3593                 return libc_accept(s, addr, addrlen);
3594 #endif
3595         }
3596
3597
3598         /*
3599          * prevent parent_si from being altered / closed
3600          * while we read it
3601          */
3602         SWRAP_LOCK_SI(parent_si);
3603
3604         /*
3605          * assume out sockaddr have the same size as the in parent
3606          * socket family
3607          */
3608         in_addr.sa_socklen = socket_length(parent_si->family);
3609         if (in_addr.sa_socklen <= 0) {
3610                 SWRAP_UNLOCK_SI(parent_si);
3611                 errno = EINVAL;
3612                 return -1;
3613         }
3614
3615         SWRAP_UNLOCK_SI(parent_si);
3616
3617 #ifdef HAVE_ACCEPT4
3618         ret = libc_accept4(s, &un_addr.sa.s, &un_addr.sa_socklen, flags);
3619 #else
3620         UNUSED(flags);
3621         ret = libc_accept(s, &un_addr.sa.s, &un_addr.sa_socklen);
3622 #endif
3623         if (ret == -1) {
3624                 if (errno == ENOTSOCK) {
3625                         /* Remove stale fds */
3626                         swrap_remove_stale(s);
3627                 }
3628                 return ret;
3629         }
3630
3631         fd = ret;
3632
3633         /* Check if we have a stale fd and remove it */
3634         swrap_remove_stale(fd);
3635
3636         SWRAP_LOCK_SI(parent_si);
3637
3638         ret = sockaddr_convert_from_un(parent_si,
3639                                        &un_addr.sa.un,
3640                                        un_addr.sa_socklen,
3641                                        parent_si->family,
3642                                        &in_addr.sa.s,
3643                                        &in_addr.sa_socklen);
3644         if (ret == -1) {
3645                 SWRAP_UNLOCK_SI(parent_si);
3646                 libc_close(fd);
3647                 return ret;
3648         }
3649
3650         child_si = &new_si;
3651
3652         child_si->family = parent_si->family;
3653         child_si->type = parent_si->type;
3654         child_si->protocol = parent_si->protocol;
3655         child_si->bound = 1;
3656         child_si->is_server = 1;
3657         child_si->connected = 1;
3658
3659         SWRAP_UNLOCK_SI(parent_si);
3660
3661         child_si->peername = (struct swrap_address) {
3662                 .sa_socklen = in_addr.sa_socklen,
3663         };
3664         memcpy(&child_si->peername.sa.ss, &in_addr.sa.ss, in_addr.sa_socklen);
3665
3666         if (addr != NULL && addrlen != NULL) {
3667                 size_t copy_len = MIN(*addrlen, in_addr.sa_socklen);
3668                 if (copy_len > 0) {
3669                         memcpy(addr, &in_addr.sa.ss, copy_len);
3670                 }
3671                 *addrlen = in_addr.sa_socklen;
3672         }
3673
3674         ret = libc_getsockname(fd,
3675                                &un_my_addr.sa.s,
3676                                &un_my_addr.sa_socklen);
3677         if (ret == -1) {
3678                 libc_close(fd);
3679                 return ret;
3680         }
3681
3682         ret = sockaddr_convert_from_un(child_si,
3683                                        &un_my_addr.sa.un,
3684                                        un_my_addr.sa_socklen,
3685                                        child_si->family,
3686                                        &in_my_addr.sa.s,
3687                                        &in_my_addr.sa_socklen);
3688         if (ret == -1) {
3689                 libc_close(fd);
3690                 return ret;
3691         }
3692
3693         SWRAP_LOG(SWRAP_LOG_TRACE,
3694                   "accept() path=%s, fd=%d",
3695                   un_my_addr.sa.un.sun_path, s);
3696
3697         child_si->myname = (struct swrap_address) {
3698                 .sa_socklen = in_my_addr.sa_socklen,
3699         };
3700         memcpy(&child_si->myname.sa.ss, &in_my_addr.sa.ss, in_my_addr.sa_socklen);
3701
3702         idx = swrap_create_socket(&new_si, fd);
3703         if (idx == -1) {
3704                 int saved_errno = errno;
3705                 libc_close(fd);
3706                 errno = saved_errno;
3707                 return -1;
3708         }
3709
3710         if (addr != NULL) {
3711                 struct socket_info *si = swrap_get_socket_info(idx);
3712
3713                 SWRAP_LOCK_SI(si);
3714                 swrap_pcap_dump_packet(si, addr, SWRAP_ACCEPT_SEND, NULL, 0);
3715                 swrap_pcap_dump_packet(si, addr, SWRAP_ACCEPT_RECV, NULL, 0);
3716                 swrap_pcap_dump_packet(si, addr, SWRAP_ACCEPT_ACK, NULL, 0);
3717                 SWRAP_UNLOCK_SI(si);
3718         }
3719
3720         return fd;
3721 }
3722
3723 #ifdef HAVE_ACCEPT4
3724 int accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags)
3725 {
3726         return swrap_accept(s, addr, (socklen_t *)addrlen, flags);
3727 }
3728 #endif
3729
3730 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3731 int accept(int s, struct sockaddr *addr, Psocklen_t addrlen)
3732 #else
3733 int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
3734 #endif
3735 {
3736         return swrap_accept(s, addr, (socklen_t *)addrlen, 0);
3737 }
3738
3739 static int autobind_start_init;
3740 static int autobind_start;
3741
3742 /* using sendto() or connect() on an unbound socket would give the
3743    recipient no way to reply, as unlike UDP and TCP, a unix domain
3744    socket can't auto-assign ephemeral port numbers, so we need to
3745    assign it here.
3746    Note: this might change the family from ipv6 to ipv4
3747 */
3748 static int swrap_auto_bind(int fd, struct socket_info *si, int family)
3749 {
3750         struct swrap_address un_addr = {
3751                 .sa_socklen = sizeof(struct sockaddr_un),
3752         };
3753         int i;
3754         char type;
3755         int ret;
3756         int port;
3757         struct stat st;
3758         char *swrap_dir = NULL;
3759
3760         swrap_mutex_lock(&autobind_start_mutex);
3761
3762         if (autobind_start_init != 1) {
3763                 autobind_start_init = 1;
3764                 autobind_start = getpid();
3765                 autobind_start %= 50000;
3766                 autobind_start += 10000;
3767         }
3768
3769         un_addr.sa.un.sun_family = AF_UNIX;
3770
3771         switch (family) {
3772         case AF_INET: {
3773                 struct sockaddr_in in;
3774
3775                 switch (si->type) {
3776                 case SOCK_STREAM:
3777                         type = SOCKET_TYPE_CHAR_TCP;
3778                         break;
3779                 case SOCK_DGRAM:
3780                         type = SOCKET_TYPE_CHAR_UDP;
3781                         break;
3782                 default:
3783                         errno = ESOCKTNOSUPPORT;
3784                         ret = -1;
3785                         goto done;
3786                 }
3787
3788                 memset(&in, 0, sizeof(in));
3789                 in.sin_family = AF_INET;
3790                 in.sin_addr.s_addr = htonl(swrap_ipv4_iface(
3791                                            socket_wrapper_default_iface()));
3792
3793                 si->myname = (struct swrap_address) {
3794                         .sa_socklen = sizeof(in),
3795                 };
3796                 memcpy(&si->myname.sa.in, &in, si->myname.sa_socklen);
3797                 break;
3798         }
3799 #ifdef HAVE_IPV6
3800         case AF_INET6: {
3801                 struct sockaddr_in6 in6;
3802
3803                 if (si->family != family) {
3804                         errno = ENETUNREACH;
3805                         ret = -1;
3806                         goto done;
3807                 }
3808
3809                 switch (si->type) {
3810                 case SOCK_STREAM:
3811                         type = SOCKET_TYPE_CHAR_TCP_V6;
3812                         break;
3813                 case SOCK_DGRAM:
3814                         type = SOCKET_TYPE_CHAR_UDP_V6;
3815                         break;
3816                 default:
3817                         errno = ESOCKTNOSUPPORT;
3818                         ret = -1;
3819                         goto done;
3820                 }
3821
3822                 memset(&in6, 0, sizeof(in6));
3823                 in6.sin6_family = AF_INET6;
3824                 in6.sin6_addr = *swrap_ipv6();
3825                 in6.sin6_addr.s6_addr[15] = socket_wrapper_default_iface();
3826
3827                 si->myname = (struct swrap_address) {
3828                         .sa_socklen = sizeof(in6),
3829                 };
3830                 memcpy(&si->myname.sa.in6, &in6, si->myname.sa_socklen);
3831                 break;
3832         }
3833 #endif
3834         default:
3835                 errno = ESOCKTNOSUPPORT;
3836                 ret = -1;
3837                 goto done;
3838         }
3839
3840         if (autobind_start > 60000) {
3841                 autobind_start = 10000;
3842         }
3843
3844         swrap_dir = socket_wrapper_dir();
3845         if (swrap_dir == NULL) {
3846                 errno = EINVAL;
3847                 ret = -1;
3848                 goto done;
3849         }
3850
3851         for (i = 0; i < SOCKET_MAX_SOCKETS; i++) {
3852                 port = autobind_start + i;
3853                 swrap_un_path(&un_addr.sa.un,
3854                               swrap_dir,
3855                               type,
3856                               socket_wrapper_default_iface(),
3857                               port);
3858                 if (stat(un_addr.sa.un.sun_path, &st) == 0) continue;
3859
3860                 ret = libc_bind(fd, &un_addr.sa.s, un_addr.sa_socklen);
3861                 if (ret == -1) {
3862                         goto done;
3863                 }
3864
3865                 si->un_addr = un_addr.sa.un;
3866
3867                 si->bound = 1;
3868                 autobind_start = port + 1;
3869                 break;
3870         }
3871         if (i == SOCKET_MAX_SOCKETS) {
3872                 SWRAP_LOG(SWRAP_LOG_ERROR, "Too many open unix sockets (%u) for "
3873                                            "interface "SOCKET_FORMAT,
3874                                            SOCKET_MAX_SOCKETS,
3875                                            type,
3876                                            socket_wrapper_default_iface(),
3877                                            0);
3878                 errno = ENFILE;
3879                 ret = -1;
3880                 goto done;
3881         }
3882
3883         si->family = family;
3884         set_port(si->family, port, &si->myname);
3885
3886         ret = 0;
3887
3888 done:
3889         SAFE_FREE(swrap_dir);
3890         swrap_mutex_unlock(&autobind_start_mutex);
3891         return ret;
3892 }
3893
3894 /****************************************************************************
3895  *   CONNECT
3896  ***************************************************************************/
3897
3898 static int swrap_connect(int s, const struct sockaddr *serv_addr,
3899                          socklen_t addrlen)
3900 {
3901         int ret;
3902         struct swrap_address un_addr = {
3903                 .sa_socklen = sizeof(struct sockaddr_un),
3904         };
3905         struct socket_info *si = find_socket_info(s);
3906         int bcast = 0;
3907
3908         if (!si) {
3909                 return libc_connect(s, serv_addr, addrlen);
3910         }
3911
3912         SWRAP_LOCK_SI(si);
3913
3914         if (si->bound == 0) {
3915                 ret = swrap_auto_bind(s, si, serv_addr->sa_family);
3916                 if (ret == -1) {
3917                         goto done;
3918                 }
3919         }
3920
3921         if (si->family != serv_addr->sa_family) {
3922                 SWRAP_LOG(SWRAP_LOG_ERROR,
3923                           "called for fd=%d (family=%d) called with invalid family=%d",
3924                           s, si->family, serv_addr->sa_family);
3925                 errno = EINVAL;
3926                 ret = -1;
3927                 goto done;
3928         }
3929
3930         ret = sockaddr_convert_to_un(si, serv_addr,
3931                                      addrlen, &un_addr.sa.un, 0, &bcast);
3932         if (ret == -1) {
3933                 goto done;
3934         }
3935
3936         if (bcast) {
3937                 errno = ENETUNREACH;
3938                 ret = -1;
3939                 goto done;
3940         }
3941
3942         if (si->type == SOCK_DGRAM) {
3943                 si->defer_connect = 1;
3944                 ret = 0;
3945         } else {
3946                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0);
3947
3948                 ret = libc_connect(s,
3949                                    &un_addr.sa.s,
3950                                    un_addr.sa_socklen);
3951         }
3952
3953         SWRAP_LOG(SWRAP_LOG_TRACE,
3954                   "connect() path=%s, fd=%d",
3955                   un_addr.sa.un.sun_path, s);
3956
3957
3958         /* to give better errors */
3959         if (ret == -1 && errno == ENOENT) {
3960                 errno = EHOSTUNREACH;
3961         }
3962
3963         if (ret == 0) {
3964                 si->peername = (struct swrap_address) {
3965                         .sa_socklen = addrlen,
3966                 };
3967
3968                 memcpy(&si->peername.sa.ss, serv_addr, addrlen);
3969                 si->connected = 1;
3970
3971                 /*
3972                  * When we connect() on a socket than we have to bind the
3973                  * outgoing connection on the interface we use for the
3974                  * transport. We already bound it on the right interface
3975                  * but here we have to update the name so getsockname()
3976                  * returns correct information.
3977                  */
3978                 if (si->bindname.sa_socklen > 0) {
3979                         si->myname = (struct swrap_address) {
3980                                 .sa_socklen = si->bindname.sa_socklen,
3981                         };
3982
3983                         memcpy(&si->myname.sa.ss,
3984                                &si->bindname.sa.ss,
3985                                si->bindname.sa_socklen);
3986
3987                         /* Cleanup bindname */
3988                         si->bindname = (struct swrap_address) {
3989                                 .sa_socklen = 0,
3990                         };
3991                 }
3992
3993                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0);
3994                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0);
3995         } else {
3996                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0);
3997         }
3998
3999 done:
4000         SWRAP_UNLOCK_SI(si);
4001         return ret;
4002 }
4003
4004 int connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen)
4005 {
4006         return swrap_connect(s, serv_addr, addrlen);
4007 }
4008
4009 /****************************************************************************
4010  *   BIND
4011  ***************************************************************************/
4012
4013 static int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
4014 {
4015         int ret;
4016         struct swrap_address un_addr = {
4017                 .sa_socklen = sizeof(struct sockaddr_un),
4018         };
4019         struct socket_info *si = find_socket_info(s);
4020         int bind_error = 0;
4021 #if 0 /* FIXME */
4022         bool in_use;
4023 #endif
4024
4025         if (!si) {
4026                 return libc_bind(s, myaddr, addrlen);
4027         }
4028
4029         SWRAP_LOCK_SI(si);
4030
4031         switch (si->family) {
4032         case AF_INET: {
4033                 const struct sockaddr_in *sin;
4034                 if (addrlen < sizeof(struct sockaddr_in)) {
4035                         bind_error = EINVAL;
4036                         break;
4037                 }
4038
4039                 sin = (const struct sockaddr_in *)(const void *)myaddr;
4040
4041                 if (sin->sin_family != AF_INET) {
4042                         bind_error = EAFNOSUPPORT;
4043                 }
4044
4045                 /* special case for AF_UNSPEC */
4046                 if (sin->sin_family == AF_UNSPEC &&
4047                     (sin->sin_addr.s_addr == htonl(INADDR_ANY)))
4048                 {
4049                         bind_error = 0;
4050                 }
4051
4052                 break;
4053         }
4054 #ifdef HAVE_IPV6
4055         case AF_INET6: {
4056                 const struct sockaddr_in6 *sin6;
4057                 if (addrlen < sizeof(struct sockaddr_in6)) {
4058                         bind_error = EINVAL;
4059                         break;
4060                 }
4061
4062                 sin6 = (const struct sockaddr_in6 *)(const void *)myaddr;
4063
4064                 if (sin6->sin6_family != AF_INET6) {
4065                         bind_error = EAFNOSUPPORT;
4066                 }
4067
4068                 break;
4069         }
4070 #endif
4071         default:
4072                 bind_error = EINVAL;
4073                 break;
4074         }
4075
4076         if (bind_error != 0) {
4077                 errno = bind_error;
4078                 ret = -1;
4079                 goto out;
4080         }
4081
4082 #if 0 /* FIXME */
4083         in_use = check_addr_port_in_use(myaddr, addrlen);
4084         if (in_use) {
4085                 errno = EADDRINUSE;
4086                 ret = -1;
4087                 goto out;
4088         }
4089 #endif
4090
4091         si->myname.sa_socklen = addrlen;
4092         memcpy(&si->myname.sa.ss, myaddr, addrlen);
4093
4094         ret = sockaddr_convert_to_un(si,
4095                                      myaddr,
4096                                      addrlen,
4097                                      &un_addr.sa.un,
4098                                      1,
4099                                      &si->bcast);
4100         if (ret == -1) {
4101                 goto out;
4102         }
4103
4104         unlink(un_addr.sa.un.sun_path);
4105
4106         ret = libc_bind(s, &un_addr.sa.s, un_addr.sa_socklen);
4107
4108         SWRAP_LOG(SWRAP_LOG_TRACE,
4109                   "bind() path=%s, fd=%d",
4110                   un_addr.sa.un.sun_path, s);
4111
4112         if (ret == 0) {
4113                 si->bound = 1;
4114         }
4115
4116 out:
4117         SWRAP_UNLOCK_SI(si);
4118
4119         return ret;
4120 }
4121
4122 int bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
4123 {
4124         return swrap_bind(s, myaddr, addrlen);
4125 }
4126
4127 /****************************************************************************
4128  *   BINDRESVPORT
4129  ***************************************************************************/
4130
4131 #ifdef HAVE_BINDRESVPORT
4132 static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen);
4133
4134 static int swrap_bindresvport_sa(int sd, struct sockaddr *sa)
4135 {
4136         struct swrap_address myaddr = {
4137                 .sa_socklen = sizeof(struct sockaddr_storage),
4138         };
4139         socklen_t salen;
4140         static uint16_t port;
4141         uint16_t i;
4142         int rc = -1;
4143         int af;
4144
4145 #define SWRAP_STARTPORT 600
4146 #define SWRAP_ENDPORT (IPPORT_RESERVED - 1)
4147 #define SWRAP_NPORTS (SWRAP_ENDPORT - SWRAP_STARTPORT + 1)
4148
4149         if (port == 0) {
4150                 port = (getpid() % SWRAP_NPORTS) + SWRAP_STARTPORT;
4151         }
4152
4153         if (sa == NULL) {
4154                 salen = myaddr.sa_socklen;
4155                 sa = &myaddr.sa.s;
4156
4157                 rc = swrap_getsockname(sd, &myaddr.sa.s, &salen);
4158                 if (rc < 0) {
4159                         return -1;
4160                 }
4161
4162                 af = sa->sa_family;
4163                 memset(&myaddr.sa.ss, 0, salen);
4164         } else {
4165                 af = sa->sa_family;
4166         }
4167
4168         for (i = 0; i < SWRAP_NPORTS; i++, port++) {
4169                 switch(af) {
4170                 case AF_INET: {
4171                         struct sockaddr_in *sinp = (struct sockaddr_in *)(void *)sa;
4172
4173                         salen = sizeof(struct sockaddr_in);
4174                         sinp->sin_port = htons(port);
4175                         break;
4176                 }
4177                 case AF_INET6: {
4178                         struct sockaddr_in6 *sin6p = (struct sockaddr_in6 *)(void *)sa;
4179
4180                         salen = sizeof(struct sockaddr_in6);
4181                         sin6p->sin6_port = htons(port);
4182                         break;
4183                 }
4184                 default:
4185                         errno = EAFNOSUPPORT;
4186                         return -1;
4187                 }
4188                 sa->sa_family = af;
4189
4190                 if (port > SWRAP_ENDPORT) {
4191                         port = SWRAP_STARTPORT;
4192                 }
4193
4194                 rc = swrap_bind(sd, (struct sockaddr *)sa, salen);
4195                 if (rc == 0 || errno != EADDRINUSE) {
4196                         break;
4197                 }
4198         }
4199
4200         return rc;
4201 }
4202
4203 int bindresvport(int sockfd, struct sockaddr_in *sinp)
4204 {
4205         return swrap_bindresvport_sa(sockfd, (struct sockaddr *)sinp);
4206 }
4207 #endif
4208
4209 /****************************************************************************
4210  *   LISTEN
4211  ***************************************************************************/
4212
4213 static int swrap_listen(int s, int backlog)
4214 {
4215         int ret;
4216         struct socket_info *si = find_socket_info(s);
4217
4218         if (!si) {
4219                 return libc_listen(s, backlog);
4220         }
4221
4222         SWRAP_LOCK_SI(si);
4223
4224         if (si->bound == 0) {
4225                 ret = swrap_auto_bind(s, si, si->family);
4226                 if (ret == -1) {
4227                         errno = EADDRINUSE;
4228                         goto out;
4229                 }
4230         }
4231
4232         ret = libc_listen(s, backlog);
4233         if (ret == 0) {
4234                 si->listening = 1;
4235         }
4236
4237 out:
4238         SWRAP_UNLOCK_SI(si);
4239
4240         return ret;
4241 }
4242
4243 int listen(int s, int backlog)
4244 {
4245         return swrap_listen(s, backlog);
4246 }
4247
4248 /****************************************************************************
4249  *   FOPEN
4250  ***************************************************************************/
4251
4252 static FILE *swrap_fopen(const char *name, const char *mode)
4253 {
4254         FILE *fp;
4255
4256         fp = libc_fopen(name, mode);
4257         if (fp != NULL) {
4258                 int fd = fileno(fp);
4259
4260                 swrap_remove_stale(fd);
4261         }
4262
4263         return fp;
4264 }
4265
4266 FILE *fopen(const char *name, const char *mode)
4267 {
4268         return swrap_fopen(name, mode);
4269 }
4270
4271 /****************************************************************************
4272  *   FOPEN64
4273  ***************************************************************************/
4274
4275 #ifdef HAVE_FOPEN64
4276 static FILE *swrap_fopen64(const char *name, const char *mode)
4277 {
4278         FILE *fp;
4279
4280         fp = libc_fopen64(name, mode);
4281         if (fp != NULL) {
4282                 int fd = fileno(fp);
4283
4284                 swrap_remove_stale(fd);
4285         }
4286
4287         return fp;
4288 }
4289
4290 FILE *fopen64(const char *name, const char *mode)
4291 {
4292         return swrap_fopen64(name, mode);
4293 }
4294 #endif /* HAVE_FOPEN64 */
4295
4296 /****************************************************************************
4297  *   OPEN
4298  ***************************************************************************/
4299
4300 static int swrap_vopen(const char *pathname, int flags, va_list ap)
4301 {
4302         int ret;
4303
4304         ret = libc_vopen(pathname, flags, ap);
4305         if (ret != -1) {
4306                 /*
4307                  * There are methods for closing descriptors (libc-internal code
4308                  * paths, direct syscalls) which close descriptors in ways that
4309                  * we can't intercept, so try to recover when we notice that
4310                  * that's happened
4311                  */
4312                 swrap_remove_stale(ret);
4313         }
4314         return ret;
4315 }
4316
4317 int open(const char *pathname, int flags, ...)
4318 {
4319         va_list ap;
4320         int fd;
4321
4322         va_start(ap, flags);
4323         fd = swrap_vopen(pathname, flags, ap);
4324         va_end(ap);
4325
4326         return fd;
4327 }
4328
4329 /****************************************************************************
4330  *   OPEN64
4331  ***************************************************************************/
4332
4333 #ifdef HAVE_OPEN64
4334 static int swrap_vopen64(const char *pathname, int flags, va_list ap)
4335 {
4336         int ret;
4337
4338         ret = libc_vopen64(pathname, flags, ap);
4339         if (ret != -1) {
4340                 /*
4341                  * There are methods for closing descriptors (libc-internal code
4342                  * paths, direct syscalls) which close descriptors in ways that
4343                  * we can't intercept, so try to recover when we notice that
4344                  * that's happened
4345                  */
4346                 swrap_remove_stale(ret);
4347         }
4348         return ret;
4349 }
4350
4351 int open64(const char *pathname, int flags, ...)
4352 {
4353         va_list ap;
4354         int fd;
4355
4356         va_start(ap, flags);
4357         fd = swrap_vopen64(pathname, flags, ap);
4358         va_end(ap);
4359
4360         return fd;
4361 }
4362 #endif /* HAVE_OPEN64 */
4363
4364 /****************************************************************************
4365  *   OPENAT
4366  ***************************************************************************/
4367
4368 static int swrap_vopenat(int dirfd, const char *path, int flags, va_list ap)
4369 {
4370         int ret;
4371
4372         ret = libc_vopenat(dirfd, path, flags, ap);
4373         if (ret != -1) {
4374                 /*
4375                  * There are methods for closing descriptors (libc-internal code
4376                  * paths, direct syscalls) which close descriptors in ways that
4377                  * we can't intercept, so try to recover when we notice that
4378                  * that's happened
4379                  */
4380                 swrap_remove_stale(ret);
4381         }
4382
4383         return ret;
4384 }
4385
4386 int openat(int dirfd, const char *path, int flags, ...)
4387 {
4388         va_list ap;
4389         int fd;
4390
4391         va_start(ap, flags);
4392         fd = swrap_vopenat(dirfd, path, flags, ap);
4393         va_end(ap);
4394
4395         return fd;
4396 }
4397
4398 /****************************************************************************
4399  *   GETPEERNAME
4400  ***************************************************************************/
4401
4402 static int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
4403 {
4404         struct socket_info *si = find_socket_info(s);
4405         socklen_t len;
4406         int ret = -1;
4407
4408         if (!si) {
4409                 return libc_getpeername(s, name, addrlen);
4410         }
4411
4412         SWRAP_LOCK_SI(si);
4413
4414         if (si->peername.sa_socklen == 0)
4415         {
4416                 errno = ENOTCONN;
4417                 goto out;
4418         }
4419
4420         len = MIN(*addrlen, si->peername.sa_socklen);
4421         if (len == 0) {
4422                 ret = 0;
4423                 goto out;
4424         }
4425
4426         memcpy(name, &si->peername.sa.ss, len);
4427         *addrlen = si->peername.sa_socklen;
4428
4429         ret = 0;
4430 out:
4431         SWRAP_UNLOCK_SI(si);
4432
4433         return ret;
4434 }
4435
4436 #ifdef HAVE_ACCEPT_PSOCKLEN_T
4437 int getpeername(int s, struct sockaddr *name, Psocklen_t addrlen)
4438 #else
4439 int getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
4440 #endif
4441 {
4442         return swrap_getpeername(s, name, (socklen_t *)addrlen);
4443 }
4444
4445 /****************************************************************************
4446  *   GETSOCKNAME
4447  ***************************************************************************/
4448
4449 static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
4450 {
4451         struct socket_info *si = find_socket_info(s);
4452         socklen_t len;
4453         int ret = -1;
4454
4455         if (!si) {
4456                 return libc_getsockname(s, name, addrlen);
4457         }
4458
4459         SWRAP_LOCK_SI(si);
4460
4461         len = MIN(*addrlen, si->myname.sa_socklen);
4462         if (len == 0) {
4463                 ret = 0;
4464                 goto out;
4465         }
4466
4467         memcpy(name, &si->myname.sa.ss, len);
4468         *addrlen = si->myname.sa_socklen;
4469
4470         ret = 0;
4471 out:
4472         SWRAP_UNLOCK_SI(si);
4473
4474         return ret;
4475 }
4476
4477 #ifdef HAVE_ACCEPT_PSOCKLEN_T
4478 int getsockname(int s, struct sockaddr *name, Psocklen_t addrlen)
4479 #else
4480 int getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
4481 #endif
4482 {
4483         return swrap_getsockname(s, name, (socklen_t *)addrlen);
4484 }
4485
4486 /****************************************************************************
4487  *   GETSOCKOPT
4488  ***************************************************************************/
4489
4490 #ifndef SO_PROTOCOL
4491 # ifdef SO_PROTOTYPE /* The Solaris name */
4492 #  define SO_PROTOCOL SO_PROTOTYPE
4493 # endif /* SO_PROTOTYPE */
4494 #endif /* SO_PROTOCOL */
4495
4496 static int swrap_getsockopt(int s, int level, int optname,
4497                             void *optval, socklen_t *optlen)
4498 {
4499         struct socket_info *si = find_socket_info(s);
4500         int ret;
4501
4502         if (!si) {
4503                 return libc_getsockopt(s,
4504                                        level,
4505                                        optname,
4506                                        optval,
4507                                        optlen);
4508         }
4509
4510         SWRAP_LOCK_SI(si);
4511
4512         if (level == SOL_SOCKET) {
4513                 switch (optname) {
4514 #ifdef SO_DOMAIN
4515                 case SO_DOMAIN:
4516                         if (optval == NULL || optlen == NULL ||
4517                             *optlen < (socklen_t)sizeof(int)) {
4518                                 errno = EINVAL;
4519                                 ret = -1;
4520                                 goto done;
4521                         }
4522
4523                         *optlen = sizeof(int);
4524                         *(int *)optval = si->family;
4525                         ret = 0;
4526                         goto done;
4527 #endif /* SO_DOMAIN */
4528
4529 #ifdef SO_PROTOCOL
4530                 case SO_PROTOCOL:
4531                         if (optval == NULL || optlen == NULL ||
4532                             *optlen < (socklen_t)sizeof(int)) {
4533                                 errno = EINVAL;
4534                                 ret = -1;
4535                                 goto done;
4536                         }
4537
4538                         *optlen = sizeof(int);
4539                         *(int *)optval = si->protocol;
4540                         ret = 0;
4541                         goto done;
4542 #endif /* SO_PROTOCOL */
4543                 case SO_TYPE:
4544                         if (optval == NULL || optlen == NULL ||
4545                             *optlen < (socklen_t)sizeof(int)) {
4546                                 errno = EINVAL;
4547                                 ret = -1;
4548                                 goto done;
4549                         }
4550
4551                         *optlen = sizeof(int);
4552                         *(int *)optval = si->type;
4553                         ret = 0;
4554                         goto done;
4555                 default:
4556                         ret = libc_getsockopt(s,
4557                                               level,
4558                                               optname,
4559                                               optval,
4560                                               optlen);
4561                         goto done;
4562                 }
4563         } else if (level == IPPROTO_TCP) {
4564                 switch (optname) {
4565 #ifdef TCP_NODELAY
4566                 case TCP_NODELAY:
4567                         /*
4568                          * This enables sending packets directly out over TCP.
4569                          * As a unix socket is doing that any way, report it as
4570                          * enabled.
4571                          */
4572                         if (optval == NULL || optlen == NULL ||
4573                             *optlen < (socklen_t)sizeof(int)) {
4574                                 errno = EINVAL;
4575                                 ret = -1;
4576                                 goto done;
4577                         }
4578
4579                         *optlen = sizeof(int);
4580                         *(int *)optval = si->tcp_nodelay;
4581
4582                         ret = 0;
4583                         goto done;
4584 #endif /* TCP_NODELAY */
4585 #ifdef TCP_INFO
4586                 case TCP_INFO: {
4587                         struct tcp_info info;
4588                         socklen_t ilen = sizeof(info);
4589
4590 #ifdef HAVE_NETINET_TCP_FSM_H
4591 /* This is FreeBSD */
4592 # define __TCP_LISTEN TCPS_LISTEN
4593 # define __TCP_ESTABLISHED TCPS_ESTABLISHED
4594 # define __TCP_CLOSE TCPS_CLOSED
4595 #else
4596 /* This is Linux */
4597 # define __TCP_LISTEN TCP_LISTEN
4598 # define __TCP_ESTABLISHED TCP_ESTABLISHED
4599 # define __TCP_CLOSE TCP_CLOSE
4600 #endif
4601
4602                         ZERO_STRUCT(info);
4603                         if (si->listening) {
4604                                 info.tcpi_state = __TCP_LISTEN;
4605                         } else if (si->connected) {
4606                                 /*
4607                                  * For now we just fake a few values
4608                                  * supported both by FreeBSD and Linux
4609                                  */
4610                                 info.tcpi_state = __TCP_ESTABLISHED;
4611                                 info.tcpi_rto = 200000;  /* 200 msec */
4612                                 info.tcpi_rtt = 5000;    /* 5 msec */
4613                                 info.tcpi_rttvar = 5000; /* 5 msec */
4614                         } else {
4615                                 info.tcpi_state = __TCP_CLOSE;
4616                                 info.tcpi_rto = 1000000;  /* 1 sec */
4617                                 info.tcpi_rtt = 0;
4618                                 info.tcpi_rttvar = 250000; /* 250 msec */
4619                         }
4620
4621                         if (optval == NULL || optlen == NULL ||
4622                             *optlen < (socklen_t)ilen) {
4623                                 errno = EINVAL;
4624                                 ret = -1;
4625                                 goto done;
4626                         }
4627
4628                         *optlen = ilen;
4629                         memcpy(optval, &info, ilen);
4630
4631                         ret = 0;
4632                         goto done;
4633                 }
4634 #endif /* TCP_INFO */
4635                 default:
4636                         break;
4637                 }
4638         }
4639
4640         errno = ENOPROTOOPT;
4641         ret = -1;
4642
4643 done:
4644         SWRAP_UNLOCK_SI(si);
4645         return ret;
4646 }
4647
4648 #ifdef HAVE_ACCEPT_PSOCKLEN_T
4649 int getsockopt(int s, int level, int optname, void *optval, Psocklen_t optlen)
4650 #else
4651 int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
4652 #endif
4653 {
4654         return swrap_getsockopt(s, level, optname, optval, (socklen_t *)optlen);
4655 }
4656
4657 /****************************************************************************
4658  *   SETSOCKOPT
4659  ***************************************************************************/
4660
4661 static int swrap_setsockopt(int s, int level, int optname,
4662                             const void *optval, socklen_t optlen)
4663 {
4664         struct socket_info *si = find_socket_info(s);
4665         int ret;
4666
4667         if (!si) {
4668                 return libc_setsockopt(s,
4669                                        level,
4670                                        optname,
4671                                        optval,
4672                                        optlen);
4673         }
4674
4675         if (level == SOL_SOCKET) {
4676                 return libc_setsockopt(s,
4677                                        level,
4678                                        optname,
4679                                        optval,
4680                                        optlen);
4681         }
4682
4683         SWRAP_LOCK_SI(si);
4684
4685         if (level == IPPROTO_TCP) {
4686                 switch (optname) {
4687 #ifdef TCP_NODELAY
4688                 case TCP_NODELAY: {
4689                         int i;
4690
4691                         /*
4692                          * This enables sending packets directly out over TCP.
4693                          * A unix socket is doing that any way.
4694                          */
4695                         if (optval == NULL || optlen == 0 ||
4696                             optlen < (socklen_t)sizeof(int)) {
4697                                 errno = EINVAL;
4698                                 ret = -1;
4699                                 goto done;
4700                         }
4701
4702                         i = *discard_const_p(int, optval);
4703                         if (i != 0 && i != 1) {
4704                                 errno = EINVAL;
4705                                 ret = -1;
4706                                 goto done;
4707                         }
4708                         si->tcp_nodelay = i;
4709
4710                         ret = 0;
4711                         goto done;
4712                 }
4713 #endif /* TCP_NODELAY */
4714                 default:
4715                         break;
4716                 }
4717         }
4718
4719         switch (si->family) {
4720         case AF_INET:
4721                 if (level == IPPROTO_IP) {
4722 #ifdef IP_PKTINFO
4723                         if (optname == IP_PKTINFO) {
4724                                 si->pktinfo = AF_INET;
4725                         }
4726 #endif /* IP_PKTINFO */
4727                 }
4728                 ret = 0;
4729                 goto done;
4730 #ifdef HAVE_IPV6
4731         case AF_INET6:
4732                 if (level == IPPROTO_IPV6) {
4733 #ifdef IPV6_RECVPKTINFO
4734                         if (optname == IPV6_RECVPKTINFO) {
4735                                 si->pktinfo = AF_INET6;
4736                         }
4737 #endif /* IPV6_PKTINFO */
4738                 }
4739                 ret = 0;
4740                 goto done;
4741 #endif
4742         default:
4743                 errno = ENOPROTOOPT;
4744                 ret = -1;
4745                 goto done;
4746         }
4747
4748 done:
4749         SWRAP_UNLOCK_SI(si);
4750         return ret;
4751 }
4752
4753 int setsockopt(int s, int level, int optname,
4754                const void *optval, socklen_t optlen)
4755 {
4756         return swrap_setsockopt(s, level, optname, optval, optlen);
4757 }
4758
4759 /****************************************************************************
4760  *   IOCTL
4761  ***************************************************************************/
4762
4763 static int swrap_vioctl(int s, unsigned long int r, va_list va)
4764 {
4765         struct socket_info *si = find_socket_info(s);
4766         va_list ap;
4767         int *value_ptr = NULL;
4768         int rc;
4769
4770         if (!si) {
4771                 return libc_vioctl(s, r, va);
4772         }
4773
4774         SWRAP_LOCK_SI(si);
4775
4776         va_copy(ap, va);
4777
4778         rc = libc_vioctl(s, r, va);
4779
4780         switch (r) {
4781         case FIONREAD:
4782                 if (rc == 0) {
4783                         value_ptr = ((int *)va_arg(ap, int *));
4784                 }
4785
4786                 if (rc == -1 && errno != EAGAIN && errno != ENOBUFS) {
4787                         swrap_pcap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
4788                 } else if (value_ptr != NULL && *value_ptr == 0) { /* END OF FILE */
4789                         swrap_pcap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
4790                 }
4791                 break;
4792 #ifdef FIONWRITE
4793         case FIONWRITE:
4794                 /* this is FreeBSD */
4795                 FALL_THROUGH; /* to TIOCOUTQ */
4796 #endif /* FIONWRITE */
4797         case TIOCOUTQ: /* same as SIOCOUTQ on Linux */
4798                 /*
4799                  * This may return more bytes then the application
4800                  * sent into the socket, for tcp it should
4801                  * return the number of unacked bytes.
4802                  *
4803                  * On AF_UNIX, all bytes are immediately acked!
4804                  */
4805                 if (rc == 0) {
4806                         value_ptr = ((int *)va_arg(ap, int *));
4807                         *value_ptr = 0;
4808                 }
4809                 break;
4810         }
4811
4812         va_end(ap);
4813
4814         SWRAP_UNLOCK_SI(si);
4815         return rc;
4816 }
4817
4818 #ifdef HAVE_IOCTL_INT
4819 int ioctl(int s, int r, ...)
4820 #else
4821 int ioctl(int s, unsigned long int r, ...)
4822 #endif
4823 {
4824         va_list va;
4825         int rc;
4826
4827         va_start(va, r);
4828
4829         rc = swrap_vioctl(s, (unsigned long int) r, va);
4830
4831         va_end(va);
4832
4833         return rc;
4834 }
4835
4836 /*****************
4837  * CMSG
4838  *****************/
4839
4840 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4841
4842 #ifndef CMSG_ALIGN
4843 # ifdef _ALIGN /* BSD */
4844 #define CMSG_ALIGN _ALIGN
4845 # else
4846 #define CMSG_ALIGN(len) (((len) + sizeof(size_t) - 1) & ~(sizeof(size_t) - 1))
4847 # endif /* _ALIGN */
4848 #endif /* CMSG_ALIGN */
4849
4850 /**
4851  * @brief Add a cmsghdr to a msghdr.
4852  *
4853  * This is an function to add any type of cmsghdr. It will operate on the
4854  * msg->msg_control and msg->msg_controllen you pass in by adapting them to
4855  * the buffer position after the added cmsg element. Hence, this function is
4856  * intended to be used with an intermediate msghdr and not on the original
4857  * one handed in by the client.
4858  *
4859  * @param[in]  msg      The msghdr to which to add the cmsg.
4860  *
4861  * @param[in]  level    The cmsg level to set.
4862  *
4863  * @param[in]  type     The cmsg type to set.
4864  *
4865  * @param[in]  data     The cmsg data to set.
4866  *
4867  * @param[in]  len      the length of the data to set.
4868  */
4869 static void swrap_msghdr_add_cmsghdr(struct msghdr *msg,
4870                                      int level,
4871                                      int type,
4872                                      const void *data,
4873                                      size_t len)
4874 {
4875         size_t cmlen = CMSG_LEN(len);
4876         size_t cmspace = CMSG_SPACE(len);
4877         uint8_t cmbuf[cmspace];
4878         void *cast_ptr = (void *)cmbuf;
4879         struct cmsghdr *cm = (struct cmsghdr *)cast_ptr;
4880         uint8_t *p;
4881
4882         memset(cmbuf, 0, cmspace);
4883
4884         if (msg->msg_controllen < cmlen) {
4885                 cmlen = msg->msg_controllen;
4886                 msg->msg_flags |= MSG_CTRUNC;
4887         }
4888
4889         if (msg->msg_controllen < cmspace) {
4890                 cmspace = msg->msg_controllen;
4891         }
4892
4893         /*
4894          * We copy the full input data into an intermediate cmsghdr first
4895          * in order to more easily cope with truncation.
4896          */
4897         cm->cmsg_len = cmlen;
4898         cm->cmsg_level = level;
4899         cm->cmsg_type = type;
4900         memcpy(CMSG_DATA(cm), data, len);
4901
4902         /*
4903          * We now copy the possibly truncated buffer.
4904          * We copy cmlen bytes, but consume cmspace bytes,
4905          * leaving the possible padding uninitialiazed.
4906          */
4907         p = (uint8_t *)msg->msg_control;
4908         memcpy(p, cm, cmlen);
4909         p += cmspace;
4910         msg->msg_control = p;
4911         msg->msg_controllen -= cmspace;
4912
4913         return;
4914 }
4915
4916 static int swrap_msghdr_add_pktinfo(struct socket_info *si,
4917                                     struct msghdr *msg)
4918 {
4919         /* Add packet info */
4920         switch (si->pktinfo) {
4921 #if defined(IP_PKTINFO) && (defined(HAVE_STRUCT_IN_PKTINFO) || defined(IP_RECVDSTADDR))
4922         case AF_INET: {
4923                 struct sockaddr_in *sin;
4924 #if defined(HAVE_STRUCT_IN_PKTINFO)
4925                 struct in_pktinfo pkt;
4926 #elif defined(IP_RECVDSTADDR)
4927                 struct in_addr pkt;
4928 #endif
4929
4930                 if (si->bindname.sa_socklen == sizeof(struct sockaddr_in)) {
4931                         sin = &si->bindname.sa.in;
4932                 } else {
4933                         if (si->myname.sa_socklen != sizeof(struct sockaddr_in)) {
4934                                 return 0;
4935                         }
4936                         sin = &si->myname.sa.in;
4937                 }
4938
4939                 ZERO_STRUCT(pkt);
4940
4941 #if defined(HAVE_STRUCT_IN_PKTINFO)
4942                 pkt.ipi_ifindex = socket_wrapper_default_iface();
4943                 pkt.ipi_addr.s_addr = sin->sin_addr.s_addr;
4944 #elif defined(IP_RECVDSTADDR)
4945                 pkt = sin->sin_addr;
4946 #endif
4947
4948                 swrap_msghdr_add_cmsghdr(msg, IPPROTO_IP, IP_PKTINFO,
4949                                          &pkt, sizeof(pkt));
4950
4951                 break;
4952         }
4953 #endif /* IP_PKTINFO */
4954 #if defined(HAVE_IPV6)
4955         case AF_INET6: {
4956 #if defined(IPV6_PKTINFO) && defined(HAVE_STRUCT_IN6_PKTINFO)
4957                 struct sockaddr_in6 *sin6;
4958                 struct in6_pktinfo pkt6;
4959
4960                 if (si->bindname.sa_socklen == sizeof(struct sockaddr_in6)) {
4961                         sin6 = &si->bindname.sa.in6;
4962                 } else {
4963                         if (si->myname.sa_socklen != sizeof(struct sockaddr_in6)) {
4964                                 return 0;
4965                         }
4966                         sin6 = &si->myname.sa.in6;
4967                 }
4968
4969                 ZERO_STRUCT(pkt6);
4970
4971                 pkt6.ipi6_ifindex = socket_wrapper_default_iface();
4972                 pkt6.ipi6_addr = sin6->sin6_addr;
4973
4974                 swrap_msghdr_add_cmsghdr(msg, IPPROTO_IPV6, IPV6_PKTINFO,
4975                                         &pkt6, sizeof(pkt6));
4976 #endif /* HAVE_STRUCT_IN6_PKTINFO */
4977
4978                 break;
4979         }
4980 #endif /* IPV6_PKTINFO */
4981         default:
4982                 return -1;
4983         }
4984
4985         return 0;
4986 }
4987
4988 static int swrap_msghdr_add_socket_info(struct socket_info *si,
4989                                         struct msghdr *omsg)
4990 {
4991         int rc = 0;
4992
4993         if (si->pktinfo > 0) {
4994                 rc = swrap_msghdr_add_pktinfo(si, omsg);
4995         }
4996
4997         return rc;
4998 }
4999
5000 static int swrap_sendmsg_copy_cmsg(const struct cmsghdr *cmsg,
5001                                    uint8_t **cm_data,
5002                                    size_t *cm_data_space);
5003 static int swrap_sendmsg_filter_cmsg_ipproto_ip(const struct cmsghdr *cmsg,
5004                                                 uint8_t **cm_data,
5005                                                 size_t *cm_data_space);
5006 static int swrap_sendmsg_filter_cmsg_sol_socket(const struct cmsghdr *cmsg,
5007                                                 uint8_t **cm_data,
5008                                                 size_t *cm_data_space);
5009
5010 static int swrap_sendmsg_filter_cmsghdr(const struct msghdr *_msg,
5011                                         uint8_t **cm_data,
5012                                         size_t *cm_data_space)
5013 {
5014         struct msghdr *msg = discard_const_p(struct msghdr, _msg);
5015         struct cmsghdr *cmsg;
5016         int rc = -1;
5017
5018         /* Nothing to do */
5019         if (msg->msg_controllen == 0 || msg->msg_control == NULL) {
5020                 return 0;
5021         }
5022
5023         for (cmsg = CMSG_FIRSTHDR(msg);
5024              cmsg != NULL;
5025              cmsg = CMSG_NXTHDR(msg, cmsg)) {
5026                 switch (cmsg->cmsg_level) {
5027                 case IPPROTO_IP:
5028                         rc = swrap_sendmsg_filter_cmsg_ipproto_ip(cmsg,
5029                                                                   cm_data,
5030                                                                   cm_data_space);
5031                         break;
5032                 case SOL_SOCKET:
5033                         rc = swrap_sendmsg_filter_cmsg_sol_socket(cmsg,
5034                                                                   cm_data,
5035                                                                   cm_data_space);
5036                         break;
5037                 default:
5038                         rc = swrap_sendmsg_copy_cmsg(cmsg,
5039                                                      cm_data,
5040                                                      cm_data_space);
5041                         break;
5042                 }
5043                 if (rc < 0) {
5044                         int saved_errno = errno;
5045                         SAFE_FREE(*cm_data);
5046                         *cm_data_space = 0;
5047                         errno = saved_errno;
5048                         return rc;
5049                 }
5050         }
5051
5052         return rc;
5053 }
5054
5055 static int swrap_sendmsg_copy_cmsg(const struct cmsghdr *cmsg,
5056                                    uint8_t **cm_data,
5057                                    size_t *cm_data_space)
5058 {
5059         size_t cmspace;
5060         uint8_t *p;
5061
5062         cmspace = *cm_data_space + CMSG_ALIGN(cmsg->cmsg_len);
5063
5064         p = realloc((*cm_data), cmspace);
5065         if (p == NULL) {
5066                 return -1;
5067         }
5068         (*cm_data) = p;
5069
5070         p = (*cm_data) + (*cm_data_space);
5071         *cm_data_space = cmspace;
5072
5073         memcpy(p, cmsg, cmsg->cmsg_len);
5074
5075         return 0;
5076 }
5077
5078 static int swrap_sendmsg_filter_cmsg_pktinfo(const struct cmsghdr *cmsg,
5079                                             uint8_t **cm_data,
5080                                             size_t *cm_data_space);
5081
5082
5083 static int swrap_sendmsg_filter_cmsg_ipproto_ip(const struct cmsghdr *cmsg,
5084                                                 uint8_t **cm_data,
5085                                                 size_t *cm_data_space)
5086 {
5087         int rc = -1;
5088
5089         switch(cmsg->cmsg_type) {
5090 #ifdef IP_PKTINFO
5091         case IP_PKTINFO:
5092                 rc = swrap_sendmsg_filter_cmsg_pktinfo(cmsg,
5093                                                        cm_data,
5094                                                        cm_data_space);
5095                 break;
5096 #endif
5097 #ifdef IPV6_PKTINFO
5098         case IPV6_PKTINFO:
5099                 rc = swrap_sendmsg_filter_cmsg_pktinfo(cmsg,
5100                                                        cm_data,
5101                                                        cm_data_space);
5102                 break;
5103 #endif
5104         default:
5105                 break;
5106         }
5107
5108         return rc;
5109 }
5110
5111 static int swrap_sendmsg_filter_cmsg_pktinfo(const struct cmsghdr *cmsg,
5112                                              uint8_t **cm_data,
5113                                              size_t *cm_data_space)
5114 {
5115         (void)cmsg; /* unused */
5116         (void)cm_data; /* unused */
5117         (void)cm_data_space; /* unused */
5118
5119         /*
5120          * Passing a IP pktinfo to a unix socket might be rejected by the
5121          * Kernel, at least on FreeBSD. So skip this cmsg.
5122          */
5123         return 0;
5124 }
5125
5126 static int swrap_sendmsg_filter_cmsg_sol_socket(const struct cmsghdr *cmsg,
5127                                                 uint8_t **cm_data,
5128                                                 size_t *cm_data_space)
5129 {
5130         int rc = -1;
5131
5132         switch (cmsg->cmsg_type) {
5133         case SCM_RIGHTS:
5134                 SWRAP_LOG(SWRAP_LOG_TRACE,
5135                           "Ignoring SCM_RIGHTS on inet socket!");
5136                 rc = 0;
5137                 break;
5138 #ifdef SCM_CREDENTIALS
5139         case SCM_CREDENTIALS:
5140                 SWRAP_LOG(SWRAP_LOG_TRACE,
5141                           "Ignoring SCM_CREDENTIALS on inet socket!");
5142                 rc = 0;
5143                 break;
5144 #endif /* SCM_CREDENTIALS */
5145         default:
5146                 rc = swrap_sendmsg_copy_cmsg(cmsg,
5147                                              cm_data,
5148                                              cm_data_space);
5149                 break;
5150         }
5151
5152         return rc;
5153 }
5154
5155 #endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
5156
5157 static int swrap_sendmsg_before_unix(const struct msghdr *_msg_in,
5158                                      struct msghdr *msg_tmp)
5159 {
5160 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5161         struct msghdr *msg_in = discard_const_p(struct msghdr, _msg_in);
5162         struct cmsghdr *cmsg = NULL;
5163         uint8_t *cm_data = NULL;
5164         size_t cm_data_space = 0;
5165         int rc = -1;
5166
5167         *msg_tmp = *msg_in;
5168
5169         /* Nothing to do */
5170         if (msg_in->msg_controllen == 0 || msg_in->msg_control == NULL) {
5171                 return 0;
5172         }
5173
5174         for (cmsg = CMSG_FIRSTHDR(msg_in);
5175              cmsg != NULL;
5176              cmsg = CMSG_NXTHDR(msg_in, cmsg)) {
5177                 switch (cmsg->cmsg_level) {
5178                 default:
5179                         rc = swrap_sendmsg_copy_cmsg(cmsg,
5180                                                      &cm_data,
5181                                                      &cm_data_space);
5182                         break;
5183                 }
5184                 if (rc < 0) {
5185                         int saved_errno = errno;
5186                         SAFE_FREE(cm_data);
5187                         errno = saved_errno;
5188                         return rc;
5189                 }
5190         }
5191
5192         msg_tmp->msg_controllen = cm_data_space;
5193         msg_tmp->msg_control = cm_data;
5194
5195         return 0;
5196 #else /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
5197         *msg_tmp = *_msg_in;
5198         return 0;
5199 #endif /* ! HAVE_STRUCT_MSGHDR_MSG_CONTROL */
5200 }
5201
5202 static ssize_t swrap_sendmsg_after_unix(struct msghdr *msg_tmp,
5203                                         ssize_t ret)
5204 {
5205 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5206         int saved_errno = errno;
5207         SAFE_FREE(msg_tmp->msg_control);
5208         errno = saved_errno;
5209 #endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
5210         return ret;
5211 }
5212
5213 static int swrap_recvmsg_before_unix(struct msghdr *msg_in,
5214                                      struct msghdr *msg_tmp)
5215 {
5216         *msg_tmp = *msg_in;
5217         return 0;
5218 }
5219
5220 static ssize_t swrap_recvmsg_after_unix(struct msghdr *msg_tmp,
5221                                         struct msghdr *msg_out,
5222                                         ssize_t ret)
5223 {
5224         *msg_out = *msg_tmp;
5225         return ret;
5226 }
5227
5228 static ssize_t swrap_sendmsg_before(int fd,
5229                                     struct socket_info *si,
5230                                     struct msghdr *msg,
5231                                     struct iovec *tmp_iov,
5232                                     struct sockaddr_un *tmp_un,
5233                                     const struct sockaddr_un **to_un,
5234                                     const struct sockaddr **to,
5235                                     int *bcast)
5236 {
5237         size_t i, len = 0;
5238         ssize_t ret = -1;
5239
5240         if (to_un) {
5241                 *to_un = NULL;
5242         }
5243         if (to) {
5244                 *to = NULL;
5245         }
5246         if (bcast) {
5247                 *bcast = 0;
5248         }
5249
5250         SWRAP_LOCK_SI(si);
5251
5252         switch (si->type) {
5253         case SOCK_STREAM: {
5254                 unsigned long mtu;
5255
5256                 if (!si->connected) {
5257                         errno = ENOTCONN;
5258                         goto out;
5259                 }
5260
5261                 if (msg->msg_iovlen == 0) {
5262                         break;
5263                 }
5264
5265                 mtu = socket_wrapper_mtu();
5266                 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
5267                         size_t nlen;
5268                         nlen = len + msg->msg_iov[i].iov_len;
5269                         if (nlen < len) {
5270                                 /* overflow */
5271                                 errno = EMSGSIZE;
5272                                 goto out;
5273                         }
5274                         if (nlen > mtu) {
5275                                 break;
5276                         }
5277                 }
5278                 msg->msg_iovlen = i;
5279                 if (msg->msg_iovlen == 0) {
5280                         *tmp_iov = msg->msg_iov[0];
5281                         tmp_iov->iov_len = MIN((size_t)tmp_iov->iov_len,
5282                                                (size_t)mtu);
5283                         msg->msg_iov = tmp_iov;
5284                         msg->msg_iovlen = 1;
5285                 }
5286                 break;
5287         }
5288         case SOCK_DGRAM:
5289                 if (si->connected) {
5290                         if (msg->msg_name != NULL) {
5291                                 /*
5292                                  * We are dealing with unix sockets and if we
5293                                  * are connected, we should only talk to the
5294                                  * connected unix path. Using the fd to send
5295                                  * to another server would be hard to achieve.
5296                                  */
5297                                 msg->msg_name = NULL;
5298                                 msg->msg_namelen = 0;
5299                         }
5300                 } else {
5301                         const struct sockaddr *msg_name;
5302                         msg_name = (const struct sockaddr *)msg->msg_name;
5303
5304                         if (msg_name == NULL) {
5305                                 errno = ENOTCONN;
5306                                 goto out;
5307                         }
5308
5309
5310                         ret = sockaddr_convert_to_un(si, msg_name, msg->msg_namelen,
5311                                                      tmp_un, 0, bcast);
5312                         if (ret == -1) {
5313                                 goto out;
5314                         }
5315
5316                         if (to_un) {
5317                                 *to_un = tmp_un;
5318                         }
5319                         if (to) {
5320                                 *to = msg_name;
5321                         }
5322                         msg->msg_name = tmp_un;
5323                         msg->msg_namelen = sizeof(*tmp_un);
5324                 }
5325
5326                 if (si->bound == 0) {
5327                         ret = swrap_auto_bind(fd, si, si->family);
5328                         if (ret == -1) {
5329                                 SWRAP_UNLOCK_SI(si);
5330                                 if (errno == ENOTSOCK) {
5331                                         swrap_remove_stale(fd);
5332                                         ret = -ENOTSOCK;
5333                                 } else {
5334                                         SWRAP_LOG(SWRAP_LOG_ERROR, "swrap_sendmsg_before failed");
5335                                 }
5336                                 return ret;
5337                         }
5338                 }
5339
5340                 if (!si->defer_connect) {
5341                         break;
5342                 }
5343
5344                 ret = sockaddr_convert_to_un(si,
5345                                              &si->peername.sa.s,
5346                                              si->peername.sa_socklen,
5347                                              tmp_un,
5348                                              0,
5349                                              NULL);
5350                 if (ret == -1) {
5351                         goto out;
5352                 }
5353
5354                 ret = libc_connect(fd,
5355                                    (struct sockaddr *)(void *)tmp_un,
5356                                    sizeof(*tmp_un));
5357
5358                 /* to give better errors */
5359                 if (ret == -1 && errno == ENOENT) {
5360                         errno = EHOSTUNREACH;
5361                 }
5362
5363                 if (ret == -1) {
5364                         goto out;
5365                 }
5366
5367                 si->defer_connect = 0;
5368                 break;
5369         default:
5370                 errno = EHOSTUNREACH;
5371                 goto out;
5372         }
5373
5374         ret = 0;
5375 out:
5376         SWRAP_UNLOCK_SI(si);
5377
5378         return ret;
5379 }
5380
5381 static void swrap_sendmsg_after(int fd,
5382                                 struct socket_info *si,
5383                                 struct msghdr *msg,
5384                                 const struct sockaddr *to,
5385                                 ssize_t ret)
5386 {
5387         int saved_errno = errno;
5388         size_t i, len = 0;
5389         uint8_t *buf;
5390         off_t ofs = 0;
5391         size_t avail = 0;
5392         size_t remain;
5393
5394         /* to give better errors */
5395         if (ret == -1) {
5396                 if (saved_errno == ENOENT) {
5397                         saved_errno = EHOSTUNREACH;
5398                 } else if (saved_errno == ENOTSOCK) {
5399                         /* If the fd is not a socket, remove it */
5400                         swrap_remove_stale(fd);
5401                 }
5402         }
5403
5404         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
5405                 avail += msg->msg_iov[i].iov_len;
5406         }
5407
5408         if (ret == -1) {
5409                 remain = MIN(80, avail);
5410         } else {
5411                 remain = ret;
5412         }
5413
5414         /* we capture it as one single packet */
5415         buf = (uint8_t *)malloc(remain);
5416         if (!buf) {
5417                 /* we just not capture the packet */
5418                 errno = saved_errno;
5419                 return;
5420         }
5421
5422         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
5423                 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
5424                 memcpy(buf + ofs,
5425                        msg->msg_iov[i].iov_base,
5426                        this_time);
5427                 ofs += this_time;
5428                 remain -= this_time;
5429         }
5430         len = ofs;
5431
5432         SWRAP_LOCK_SI(si);
5433
5434         switch (si->type) {
5435         case SOCK_STREAM:
5436                 if (ret == -1) {
5437                         swrap_pcap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
5438                         swrap_pcap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
5439                 } else {
5440                         swrap_pcap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
5441                 }
5442                 break;
5443
5444         case SOCK_DGRAM:
5445                 if (si->connected) {
5446                         to = &si->peername.sa.s;
5447                 }
5448                 if (ret == -1) {
5449                         swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
5450                         swrap_pcap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);
5451                 } else {
5452                         swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
5453                 }
5454                 break;
5455         }
5456
5457         SWRAP_UNLOCK_SI(si);
5458
5459         free(buf);
5460         errno = saved_errno;
5461 }
5462
5463 static int swrap_recvmsg_before(int fd,
5464                                 struct socket_info *si,
5465                                 struct msghdr *msg,
5466                                 struct iovec *tmp_iov)
5467 {
5468         size_t i, len = 0;
5469         int ret = -1;
5470
5471         SWRAP_LOCK_SI(si);
5472
5473         (void)fd; /* unused */
5474
5475         switch (si->type) {
5476         case SOCK_STREAM: {
5477                 unsigned int mtu;
5478                 if (!si->connected) {
5479                         errno = ENOTCONN;
5480                         goto out;
5481                 }
5482
5483                 if (msg->msg_iovlen == 0) {
5484                         break;
5485                 }
5486
5487                 mtu = socket_wrapper_mtu();
5488                 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
5489                         size_t nlen;
5490                         nlen = len + msg->msg_iov[i].iov_len;
5491                         if (nlen > mtu) {
5492                                 break;
5493                         }
5494                 }
5495                 msg->msg_iovlen = i;
5496                 if (msg->msg_iovlen == 0) {
5497                         *tmp_iov = msg->msg_iov[0];
5498                         tmp_iov->iov_len = MIN((size_t)tmp_iov->iov_len,
5499                                                (size_t)mtu);
5500                         msg->msg_iov = tmp_iov;
5501                         msg->msg_iovlen = 1;
5502                 }
5503                 break;
5504         }
5505         case SOCK_DGRAM:
5506                 if (msg->msg_name == NULL) {
5507                         errno = EINVAL;
5508                         goto out;
5509                 }
5510
5511                 if (msg->msg_iovlen == 0) {
5512                         break;
5513                 }
5514
5515                 if (si->bound == 0) {
5516                         ret = swrap_auto_bind(fd, si, si->family);
5517                         if (ret == -1) {
5518                                 SWRAP_UNLOCK_SI(si);
5519                                 /*
5520                                  * When attempting to read or write to a
5521                                  * descriptor, if an underlying autobind fails
5522                                  * because it's not a socket, stop intercepting
5523                                  * uses of that descriptor.
5524                                  */
5525                                 if (errno == ENOTSOCK) {
5526                                         swrap_remove_stale(fd);
5527                                         ret = -ENOTSOCK;
5528                                 } else {
5529                                         SWRAP_LOG(SWRAP_LOG_ERROR,
5530                                                   "swrap_recvmsg_before failed");
5531                                 }
5532                                 return ret;
5533                         }
5534                 }
5535                 break;
5536         default:
5537                 errno = EHOSTUNREACH;
5538                 goto out;
5539         }
5540
5541         ret = 0;
5542 out:
5543         SWRAP_UNLOCK_SI(si);
5544
5545         return ret;
5546 }
5547
5548 static int swrap_recvmsg_after(int fd,
5549                                struct socket_info *si,
5550                                struct msghdr *msg,
5551                                const struct sockaddr_un *un_addr,
5552                                socklen_t un_addrlen,
5553                                ssize_t ret)
5554 {
5555         int saved_errno = errno;
5556         size_t i;
5557         uint8_t *buf = NULL;
5558         off_t ofs = 0;
5559         size_t avail = 0;
5560         size_t remain;
5561         int rc;
5562
5563         /* to give better errors */
5564         if (ret == -1) {
5565                 if (saved_errno == ENOENT) {
5566                         saved_errno = EHOSTUNREACH;
5567                 } else if (saved_errno == ENOTSOCK) {
5568                         /* If the fd is not a socket, remove it */
5569                         swrap_remove_stale(fd);
5570                 }
5571         }
5572
5573         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
5574                 avail += msg->msg_iov[i].iov_len;
5575         }
5576
5577         SWRAP_LOCK_SI(si);
5578
5579         /* Convert the socket address before we leave */
5580         if (si->type == SOCK_DGRAM && un_addr != NULL) {
5581                 rc = sockaddr_convert_from_un(si,
5582                                               un_addr,
5583                                               un_addrlen,
5584                                               si->family,
5585                                               msg->msg_name,
5586                                               &msg->msg_namelen);
5587                 if (rc == -1) {
5588                         goto done;
5589                 }
5590         }
5591
5592         if (avail == 0) {
5593                 rc = 0;
5594                 goto done;
5595         }
5596
5597         if (ret == -1) {
5598                 remain = MIN(80, avail);
5599         } else {
5600                 remain = ret;
5601         }
5602
5603         /* we capture it as one single packet */
5604         buf = (uint8_t *)malloc(remain);
5605         if (buf == NULL) {
5606                 /* we just not capture the packet */
5607                 SWRAP_UNLOCK_SI(si);
5608                 errno = saved_errno;
5609                 return -1;
5610         }
5611
5612         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
5613                 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
5614                 memcpy(buf + ofs,
5615                        msg->msg_iov[i].iov_base,
5616                        this_time);
5617                 ofs += this_time;
5618                 remain -= this_time;
5619         }
5620
5621         switch (si->type) {
5622         case SOCK_STREAM:
5623                 if (ret == -1 && saved_errno != EAGAIN && saved_errno != ENOBUFS) {
5624                         swrap_pcap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
5625                 } else if (ret == 0) { /* END OF FILE */
5626                         swrap_pcap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
5627                 } else if (ret > 0) {
5628                         swrap_pcap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
5629                 }
5630                 break;
5631
5632         case SOCK_DGRAM:
5633                 if (ret == -1) {
5634                         break;
5635                 }
5636
5637                 if (un_addr != NULL) {
5638                         swrap_pcap_dump_packet(si,
5639                                           msg->msg_name,
5640                                           SWRAP_RECVFROM,
5641                                           buf,
5642                                           ret);
5643                 } else {
5644                         swrap_pcap_dump_packet(si,
5645                                           msg->msg_name,
5646                                           SWRAP_RECV,
5647                                           buf,
5648                                           ret);
5649                 }
5650
5651                 break;
5652         }
5653
5654         rc = 0;
5655 done:
5656         free(buf);
5657         errno = saved_errno;
5658
5659 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5660         if (rc == 0 &&
5661             msg->msg_controllen > 0 &&
5662             msg->msg_control != NULL) {
5663                 rc = swrap_msghdr_add_socket_info(si, msg);
5664                 if (rc < 0) {
5665                         SWRAP_UNLOCK_SI(si);
5666                         return -1;
5667                 }
5668         }
5669 #endif
5670
5671         SWRAP_UNLOCK_SI(si);
5672         return rc;
5673 }
5674
5675 /****************************************************************************
5676  *   RECVFROM
5677  ***************************************************************************/
5678
5679 static ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags,
5680                               struct sockaddr *from, socklen_t *fromlen)
5681 {
5682         struct swrap_address from_addr = {
5683                 .sa_socklen = sizeof(struct sockaddr_un),
5684         };
5685         ssize_t ret;
5686         struct socket_info *si = find_socket_info(s);
5687         struct swrap_address saddr = {
5688                 .sa_socklen = sizeof(struct sockaddr_storage),
5689         };
5690         struct msghdr msg;
5691         struct iovec tmp;
5692         int tret;
5693
5694         if (!si) {
5695                 return libc_recvfrom(s,
5696                                      buf,
5697                                      len,
5698                                      flags,
5699                                      from,
5700                                      fromlen);
5701         }
5702
5703         tmp.iov_base = buf;
5704         tmp.iov_len = len;
5705
5706         ZERO_STRUCT(msg);
5707         if (from != NULL && fromlen != NULL) {
5708                 msg.msg_name = from;   /* optional address */
5709                 msg.msg_namelen = *fromlen; /* size of address */
5710         } else {
5711                 msg.msg_name = &saddr.sa.s; /* optional address */
5712                 msg.msg_namelen = saddr.sa_socklen; /* size of address */
5713         }
5714         msg.msg_iov = &tmp;            /* scatter/gather array */
5715         msg.msg_iovlen = 1;            /* # elements in msg_iov */
5716 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5717         msg.msg_control = NULL;        /* ancillary data, see below */
5718         msg.msg_controllen = 0;        /* ancillary data buffer len */
5719         msg.msg_flags = 0;             /* flags on received message */
5720 #endif
5721
5722         tret = swrap_recvmsg_before(s, si, &msg, &tmp);
5723         if (tret < 0) {
5724                 return -1;
5725         }
5726
5727         buf = msg.msg_iov[0].iov_base;
5728         len = msg.msg_iov[0].iov_len;
5729
5730         ret = libc_recvfrom(s,
5731                             buf,
5732                             len,
5733                             flags,
5734                             &from_addr.sa.s,
5735                             &from_addr.sa_socklen);
5736         if (ret == -1) {
5737                 return ret;
5738         }
5739
5740         tret = swrap_recvmsg_after(s,
5741                                    si,
5742                                    &msg,
5743                                    &from_addr.sa.un,
5744                                    from_addr.sa_socklen,
5745                                    ret);
5746         if (tret != 0) {
5747                 return tret;
5748         }
5749
5750         if (from != NULL && fromlen != NULL) {
5751                 *fromlen = msg.msg_namelen;
5752         }
5753
5754         return ret;
5755 }
5756
5757 #ifdef HAVE_ACCEPT_PSOCKLEN_T
5758 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
5759                  struct sockaddr *from, Psocklen_t fromlen)
5760 #else
5761 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
5762                  struct sockaddr *from, socklen_t *fromlen)
5763 #endif
5764 {
5765         return swrap_recvfrom(s, buf, len, flags, from, (socklen_t *)fromlen);
5766 }
5767
5768 /****************************************************************************
5769  *   SENDTO
5770  ***************************************************************************/
5771
5772 static ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags,
5773                             const struct sockaddr *to, socklen_t tolen)
5774 {
5775         struct msghdr msg;
5776         struct iovec tmp;
5777         struct swrap_address un_addr = {
5778                 .sa_socklen = sizeof(struct sockaddr_un),
5779         };
5780         const struct sockaddr_un *to_un = NULL;
5781         ssize_t ret;
5782         int rc;
5783         struct socket_info *si = find_socket_info(s);
5784         int bcast = 0;
5785
5786         if (!si) {
5787                 return libc_sendto(s, buf, len, flags, to, tolen);
5788         }
5789
5790         tmp.iov_base = discard_const_p(char, buf);
5791         tmp.iov_len = len;
5792
5793         ZERO_STRUCT(msg);
5794         msg.msg_name = discard_const_p(struct sockaddr, to); /* optional address */
5795         msg.msg_namelen = tolen;       /* size of address */
5796         msg.msg_iov = &tmp;            /* scatter/gather array */
5797         msg.msg_iovlen = 1;            /* # elements in msg_iov */
5798 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5799         msg.msg_control = NULL;        /* ancillary data, see below */
5800         msg.msg_controllen = 0;        /* ancillary data buffer len */
5801         msg.msg_flags = 0;             /* flags on received message */
5802 #endif
5803
5804         rc = swrap_sendmsg_before(s,
5805                                   si,
5806                                   &msg,
5807                                   &tmp,
5808                                   &un_addr.sa.un,
5809                                   &to_un,
5810                                   &to,
5811                                   &bcast);
5812         if (rc < 0) {
5813                 return -1;
5814         }
5815
5816         buf = msg.msg_iov[0].iov_base;
5817         len = msg.msg_iov[0].iov_len;
5818
5819         if (bcast) {
5820                 struct stat st;
5821                 unsigned int iface;
5822                 unsigned int prt = ntohs(((const struct sockaddr_in *)(const void *)to)->sin_port);
5823                 char type;
5824                 char *swrap_dir = NULL;
5825
5826                 type = SOCKET_TYPE_CHAR_UDP;
5827
5828                 swrap_dir = socket_wrapper_dir();
5829                 if (swrap_dir == NULL) {
5830                         return -1;
5831                 }
5832
5833                 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
5834                         swrap_un_path(&un_addr.sa.un,
5835                                       swrap_dir,
5836                                       type,
5837                                       iface,
5838                                       prt);
5839                         if (stat(un_addr.sa.un.sun_path, &st) != 0) continue;
5840
5841                         /* ignore the any errors in broadcast sends */
5842                         libc_sendto(s,
5843                                     buf,
5844                                     len,
5845                                     flags,
5846                                     &un_addr.sa.s,
5847                                     un_addr.sa_socklen);
5848                 }
5849
5850                 SAFE_FREE(swrap_dir);
5851
5852                 SWRAP_LOCK_SI(si);
5853
5854                 swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
5855
5856                 SWRAP_UNLOCK_SI(si);
5857
5858                 return len;
5859         }
5860
5861         SWRAP_LOCK_SI(si);
5862         /*
5863          * If it is a dgram socket and we are connected, don't include the
5864          * 'to' address.
5865          */
5866         if (si->type == SOCK_DGRAM && si->connected) {
5867                 ret = libc_sendto(s,
5868                                   buf,
5869                                   len,
5870                                   flags,
5871                                   NULL,
5872                                   0);
5873         } else {
5874                 ret = libc_sendto(s,
5875                                   buf,
5876                                   len,
5877                                   flags,
5878                                   (struct sockaddr *)msg.msg_name,
5879                                   msg.msg_namelen);
5880         }
5881
5882         SWRAP_UNLOCK_SI(si);
5883
5884         swrap_sendmsg_after(s, si, &msg, to, ret);
5885
5886         return ret;
5887 }
5888
5889 ssize_t sendto(int s, const void *buf, size_t len, int flags,
5890                const struct sockaddr *to, socklen_t tolen)
5891 {
5892         return swrap_sendto(s, buf, len, flags, to, tolen);
5893 }
5894
5895 /****************************************************************************
5896  *   READV
5897  ***************************************************************************/
5898
5899 static ssize_t swrap_recv(int s, void *buf, size_t len, int flags)
5900 {
5901         struct socket_info *si;
5902         struct msghdr msg;
5903         struct swrap_address saddr = {
5904                 .sa_socklen = sizeof(struct sockaddr_storage),
5905         };
5906         struct iovec tmp;
5907         ssize_t ret;
5908         int tret;
5909
5910         si = find_socket_info(s);
5911         if (si == NULL) {
5912                 return libc_recv(s, buf, len, flags);
5913         }
5914
5915         tmp.iov_base = buf;
5916         tmp.iov_len = len;
5917
5918         ZERO_STRUCT(msg);
5919         msg.msg_name = &saddr.sa.s;    /* optional address */
5920         msg.msg_namelen = saddr.sa_socklen; /* size of address */
5921         msg.msg_iov = &tmp;            /* scatter/gather array */
5922         msg.msg_iovlen = 1;            /* # elements in msg_iov */
5923 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5924         msg.msg_control = NULL;        /* ancillary data, see below */
5925         msg.msg_controllen = 0;        /* ancillary data buffer len */
5926         msg.msg_flags = 0;             /* flags on received message */
5927 #endif
5928
5929         tret = swrap_recvmsg_before(s, si, &msg, &tmp);
5930         if (tret < 0) {
5931                 return -1;
5932         }
5933
5934         buf = msg.msg_iov[0].iov_base;
5935         len = msg.msg_iov[0].iov_len;
5936
5937         ret = libc_recv(s, buf, len, flags);
5938
5939         tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
5940         if (tret != 0) {
5941                 return tret;
5942         }
5943
5944         return ret;
5945 }
5946
5947 ssize_t recv(int s, void *buf, size_t len, int flags)
5948 {
5949         return swrap_recv(s, buf, len, flags);
5950 }
5951
5952 /****************************************************************************
5953  *   READ
5954  ***************************************************************************/
5955
5956 static ssize_t swrap_read(int s, void *buf, size_t len)
5957 {
5958         struct socket_info *si;
5959         struct msghdr msg;
5960         struct iovec tmp;
5961         struct swrap_address saddr = {
5962                 .sa_socklen = sizeof(struct sockaddr_storage),
5963         };
5964         ssize_t ret;
5965         int tret;
5966
5967         si = find_socket_info(s);
5968         if (si == NULL) {
5969                 return libc_read(s, buf, len);
5970         }
5971
5972         tmp.iov_base = buf;
5973         tmp.iov_len = len;
5974
5975         ZERO_STRUCT(msg);
5976         msg.msg_name = &saddr.sa.ss;   /* optional address */
5977         msg.msg_namelen = saddr.sa_socklen; /* size of address */
5978         msg.msg_iov = &tmp;            /* scatter/gather array */
5979         msg.msg_iovlen = 1;            /* # elements in msg_iov */
5980 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5981         msg.msg_control = NULL;        /* ancillary data, see below */
5982         msg.msg_controllen = 0;        /* ancillary data buffer len */
5983         msg.msg_flags = 0;             /* flags on received message */
5984 #endif
5985
5986         tret = swrap_recvmsg_before(s, si, &msg, &tmp);
5987         if (tret < 0) {
5988                 if (tret == -ENOTSOCK) {
5989                         return libc_read(s, buf, len);
5990                 }
5991                 return -1;
5992         }
5993
5994         buf = msg.msg_iov[0].iov_base;
5995         len = msg.msg_iov[0].iov_len;
5996
5997         ret = libc_read(s, buf, len);
5998
5999         tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
6000         if (tret != 0) {
6001                 return tret;
6002         }
6003
6004         return ret;
6005 }
6006
6007 ssize_t read(int s, void *buf, size_t len)
6008 {
6009         return swrap_read(s, buf, len);
6010 }
6011
6012 /****************************************************************************
6013  *   WRITE
6014  ***************************************************************************/
6015
6016 static ssize_t swrap_write(int s, const void *buf, size_t len)
6017 {
6018         struct msghdr msg;
6019         struct iovec tmp;
6020         struct sockaddr_un un_addr;
6021         ssize_t ret;
6022         int rc;
6023         struct socket_info *si;
6024
6025         si = find_socket_info(s);
6026         if (si == NULL) {
6027                 return libc_write(s, buf, len);
6028         }
6029
6030         tmp.iov_base = discard_const_p(char, buf);
6031         tmp.iov_len = len;
6032
6033         ZERO_STRUCT(msg);
6034         msg.msg_name = NULL;           /* optional address */
6035         msg.msg_namelen = 0;           /* size of address */
6036         msg.msg_iov = &tmp;            /* scatter/gather array */
6037         msg.msg_iovlen = 1;            /* # elements in msg_iov */
6038 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6039         msg.msg_control = NULL;        /* ancillary data, see below */
6040         msg.msg_controllen = 0;        /* ancillary data buffer len */
6041         msg.msg_flags = 0;             /* flags on received message */
6042 #endif
6043
6044         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
6045         if (rc < 0) {
6046                 return -1;
6047         }
6048
6049         buf = msg.msg_iov[0].iov_base;
6050         len = msg.msg_iov[0].iov_len;
6051
6052         ret = libc_write(s, buf, len);
6053
6054         swrap_sendmsg_after(s, si, &msg, NULL, ret);
6055
6056         return ret;
6057 }
6058
6059 ssize_t write(int s, const void *buf, size_t len)
6060 {
6061         return swrap_write(s, buf, len);
6062 }
6063
6064 /****************************************************************************
6065  *   SEND
6066  ***************************************************************************/
6067
6068 static ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
6069 {
6070         struct msghdr msg;
6071         struct iovec tmp;
6072         struct sockaddr_un un_addr;
6073         ssize_t ret;
6074         int rc;
6075         struct socket_info *si = find_socket_info(s);
6076
6077         if (!si) {
6078                 return libc_send(s, buf, len, flags);
6079         }
6080
6081         tmp.iov_base = discard_const_p(char, buf);
6082         tmp.iov_len = len;
6083
6084         ZERO_STRUCT(msg);
6085         msg.msg_name = NULL;           /* optional address */
6086         msg.msg_namelen = 0;           /* size of address */
6087         msg.msg_iov = &tmp;            /* scatter/gather array */
6088         msg.msg_iovlen = 1;            /* # elements in msg_iov */
6089 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6090         msg.msg_control = NULL;        /* ancillary data, see below */
6091         msg.msg_controllen = 0;        /* ancillary data buffer len */
6092         msg.msg_flags = 0;             /* flags on received message */
6093 #endif
6094
6095         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
6096         if (rc < 0) {
6097                 return -1;
6098         }
6099
6100         buf = msg.msg_iov[0].iov_base;
6101         len = msg.msg_iov[0].iov_len;
6102
6103         ret = libc_send(s, buf, len, flags);
6104
6105         swrap_sendmsg_after(s, si, &msg, NULL, ret);
6106
6107         return ret;
6108 }
6109
6110 ssize_t send(int s, const void *buf, size_t len, int flags)
6111 {
6112         return swrap_send(s, buf, len, flags);
6113 }
6114
6115 /****************************************************************************
6116  *   RECVMSG
6117  ***************************************************************************/
6118
6119 static ssize_t swrap_recvmsg(int s, struct msghdr *omsg, int flags)
6120 {
6121         struct swrap_address from_addr = {
6122                 .sa_socklen = sizeof(struct sockaddr_un),
6123         };
6124         struct swrap_address convert_addr = {
6125                 .sa_socklen = sizeof(struct sockaddr_storage),
6126         };
6127         struct socket_info *si;
6128         struct msghdr msg;
6129         struct iovec tmp;
6130 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6131         size_t msg_ctrllen_filled;
6132         size_t msg_ctrllen_left;
6133 #endif
6134
6135         ssize_t ret;
6136         int rc;
6137
6138         si = find_socket_info(s);
6139         if (si == NULL) {
6140                 rc = swrap_recvmsg_before_unix(omsg, &msg);
6141                 if (rc < 0) {
6142                         return rc;
6143                 }
6144                 ret = libc_recvmsg(s, &msg, flags);
6145                 return swrap_recvmsg_after_unix(&msg, omsg, ret);
6146         }
6147
6148         tmp.iov_base = NULL;
6149         tmp.iov_len = 0;
6150
6151         ZERO_STRUCT(msg);
6152         msg.msg_name = &from_addr.sa;              /* optional address */
6153         msg.msg_namelen = from_addr.sa_socklen;    /* size of address */
6154         msg.msg_iov = omsg->msg_iov;               /* scatter/gather array */
6155         msg.msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
6156 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6157         msg_ctrllen_filled = 0;
6158         msg_ctrllen_left = omsg->msg_controllen;
6159
6160         msg.msg_control = omsg->msg_control;       /* ancillary data, see below */
6161         msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
6162         msg.msg_flags = omsg->msg_flags;           /* flags on received message */
6163 #endif
6164
6165         rc = swrap_recvmsg_before(s, si, &msg, &tmp);
6166         if (rc < 0) {
6167                 return -1;
6168         }
6169
6170         ret = libc_recvmsg(s, &msg, flags);
6171
6172 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6173         msg_ctrllen_filled += msg.msg_controllen;
6174         msg_ctrllen_left -= msg.msg_controllen;
6175
6176         if (omsg->msg_control != NULL) {
6177                 uint8_t *p;
6178
6179                 p = omsg->msg_control;
6180                 p += msg_ctrllen_filled;
6181
6182                 msg.msg_control = p;
6183                 msg.msg_controllen = msg_ctrllen_left;
6184         } else {
6185                 msg.msg_control = NULL;
6186                 msg.msg_controllen = 0;
6187         }
6188 #endif
6189
6190         /*
6191          * We convert the unix address to a IP address so we need a buffer
6192          * which can store the address in case of SOCK_DGRAM, see below.
6193          */
6194         msg.msg_name = &convert_addr.sa;
6195         msg.msg_namelen = convert_addr.sa_socklen;
6196
6197         rc = swrap_recvmsg_after(s,
6198                                  si,
6199                                  &msg,
6200                                  &from_addr.sa.un,
6201                                  from_addr.sa_socklen,
6202                                  ret);
6203         if (rc != 0) {
6204                 return rc;
6205         }
6206
6207 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6208         if (omsg->msg_control != NULL) {
6209                 /* msg.msg_controllen = space left */
6210                 msg_ctrllen_left = msg.msg_controllen;
6211                 msg_ctrllen_filled = omsg->msg_controllen - msg_ctrllen_left;
6212         }
6213
6214         /* Update the original message length */
6215         omsg->msg_controllen = msg_ctrllen_filled;
6216         omsg->msg_flags = msg.msg_flags;
6217 #endif
6218         omsg->msg_iovlen = msg.msg_iovlen;
6219
6220         SWRAP_LOCK_SI(si);
6221
6222         /*
6223          * From the manpage:
6224          *
6225          * The  msg_name  field  points  to a caller-allocated buffer that is
6226          * used to return the source address if the socket is unconnected.  The
6227          * caller should set msg_namelen to the size of this buffer before this
6228          * call; upon return from a successful call, msg_name will contain the
6229          * length of the returned address.  If the application  does  not  need
6230          * to know the source address, msg_name can be specified as NULL.
6231          */
6232         if (si->type == SOCK_STREAM) {
6233                 omsg->msg_namelen = 0;
6234         } else if (omsg->msg_name != NULL &&
6235                    omsg->msg_namelen != 0 &&
6236                    omsg->msg_namelen >= msg.msg_namelen) {
6237                 memcpy(omsg->msg_name, msg.msg_name, msg.msg_namelen);
6238                 omsg->msg_namelen = msg.msg_namelen;
6239         }
6240
6241         SWRAP_UNLOCK_SI(si);
6242
6243         return ret;
6244 }
6245
6246 ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)
6247 {
6248         return swrap_recvmsg(sockfd, msg, flags);
6249 }
6250
6251 /****************************************************************************
6252  *   SENDMSG
6253  ***************************************************************************/
6254
6255 static ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags)
6256 {
6257         struct msghdr msg;
6258         struct iovec tmp;
6259         struct sockaddr_un un_addr;
6260         const struct sockaddr_un *to_un = NULL;
6261         const struct sockaddr *to = NULL;
6262         ssize_t ret;
6263         int rc;
6264         struct socket_info *si = find_socket_info(s);
6265         int bcast = 0;
6266
6267         if (!si) {
6268                 rc = swrap_sendmsg_before_unix(omsg, &msg);
6269                 if (rc < 0) {
6270                         return rc;
6271                 }
6272                 ret = libc_sendmsg(s, &msg, flags);
6273                 return swrap_sendmsg_after_unix(&msg, ret);
6274         }
6275
6276         ZERO_STRUCT(un_addr);
6277
6278         tmp.iov_base = NULL;
6279         tmp.iov_len = 0;
6280
6281         ZERO_STRUCT(msg);
6282
6283         SWRAP_LOCK_SI(si);
6284
6285         if (si->connected == 0) {
6286                 msg.msg_name = omsg->msg_name;             /* optional address */
6287                 msg.msg_namelen = omsg->msg_namelen;       /* size of address */
6288         }
6289         msg.msg_iov = omsg->msg_iov;               /* scatter/gather array */
6290         msg.msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
6291
6292         SWRAP_UNLOCK_SI(si);
6293
6294 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6295         if (omsg != NULL && omsg->msg_controllen > 0 && omsg->msg_control != NULL) {
6296                 uint8_t *cmbuf = NULL;
6297                 size_t cmlen = 0;
6298
6299                 rc = swrap_sendmsg_filter_cmsghdr(omsg, &cmbuf, &cmlen);
6300                 if (rc < 0) {
6301                         return rc;
6302                 }
6303
6304                 if (cmlen == 0) {
6305                         msg.msg_controllen = 0;
6306                         msg.msg_control = NULL;
6307                 } else {
6308                         msg.msg_control = cmbuf;
6309                         msg.msg_controllen = cmlen;
6310                 }
6311         }
6312         msg.msg_flags = omsg->msg_flags;           /* flags on received message */
6313 #endif
6314         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
6315         if (rc < 0) {
6316                 int saved_errno = errno;
6317 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6318                 SAFE_FREE(msg.msg_control);
6319 #endif
6320                 errno = saved_errno;
6321                 return -1;
6322         }
6323
6324         if (bcast) {
6325                 struct stat st;
6326                 unsigned int iface;
6327                 unsigned int prt = ntohs(((const struct sockaddr_in *)(const void *)to)->sin_port);
6328                 char type;
6329                 size_t i, len = 0;
6330                 uint8_t *buf;
6331                 off_t ofs = 0;
6332                 size_t avail = 0;
6333                 size_t remain;
6334                 char *swrap_dir = NULL;
6335
6336                 for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
6337                         avail += msg.msg_iov[i].iov_len;
6338                 }
6339
6340                 len = avail;
6341                 remain = avail;
6342
6343                 /* we capture it as one single packet */
6344                 buf = (uint8_t *)malloc(remain);
6345                 if (!buf) {
6346                         int saved_errno = errno;
6347 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6348                         SAFE_FREE(msg.msg_control);
6349 #endif
6350                         errno = saved_errno;
6351                         return -1;
6352                 }
6353
6354                 for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
6355                         size_t this_time = MIN(remain, (size_t)msg.msg_iov[i].iov_len);
6356                         memcpy(buf + ofs,
6357                                msg.msg_iov[i].iov_base,
6358                                this_time);
6359                         ofs += this_time;
6360                         remain -= this_time;
6361                 }
6362
6363                 type = SOCKET_TYPE_CHAR_UDP;
6364
6365                 swrap_dir = socket_wrapper_dir();
6366                 if (swrap_dir == NULL) {
6367                         int saved_errno = errno;
6368 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6369                         SAFE_FREE(msg.msg_control);
6370 #endif
6371                         SAFE_FREE(buf);
6372                         errno = saved_errno;
6373                         return -1;
6374                 }
6375
6376                 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
6377                         swrap_un_path(&un_addr, swrap_dir, type, iface, prt);
6378                         if (stat(un_addr.sun_path, &st) != 0) continue;
6379
6380                         msg.msg_name = &un_addr;           /* optional address */
6381                         msg.msg_namelen = sizeof(un_addr); /* size of address */
6382
6383                         /* ignore the any errors in broadcast sends */
6384                         libc_sendmsg(s, &msg, flags);
6385                 }
6386
6387                 SAFE_FREE(swrap_dir);
6388
6389                 SWRAP_LOCK_SI(si);
6390
6391                 swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
6392                 free(buf);
6393
6394                 SWRAP_UNLOCK_SI(si);
6395
6396                 return len;
6397         }
6398
6399         ret = libc_sendmsg(s, &msg, flags);
6400
6401         swrap_sendmsg_after(s, si, &msg, to, ret);
6402
6403 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6404         {
6405                 int saved_errno = errno;
6406                 SAFE_FREE(msg.msg_control);
6407                 errno = saved_errno;
6408         }
6409 #endif
6410
6411         return ret;
6412 }
6413
6414 ssize_t sendmsg(int s, const struct msghdr *omsg, int flags)
6415 {
6416         return swrap_sendmsg(s, omsg, flags);
6417 }
6418
6419 /****************************************************************************
6420  *   READV
6421  ***************************************************************************/
6422
6423 static ssize_t swrap_readv(int s, const struct iovec *vector, int count)
6424 {
6425         struct socket_info *si;
6426         struct msghdr msg;
6427         struct iovec tmp;
6428         struct swrap_address saddr = {
6429                 .sa_socklen = sizeof(struct sockaddr_storage)
6430         };
6431         ssize_t ret;
6432         int rc;
6433
6434         si = find_socket_info(s);
6435         if (si == NULL) {
6436                 return libc_readv(s, vector, count);
6437         }
6438
6439         tmp.iov_base = NULL;
6440         tmp.iov_len = 0;
6441
6442         ZERO_STRUCT(msg);
6443         msg.msg_name = &saddr.sa.s; /* optional address */
6444         msg.msg_namelen = saddr.sa_socklen;      /* size of address */
6445         msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
6446         msg.msg_iovlen = count;        /* # elements in msg_iov */
6447 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6448         msg.msg_control = NULL;        /* ancillary data, see below */
6449         msg.msg_controllen = 0;        /* ancillary data buffer len */
6450         msg.msg_flags = 0;             /* flags on received message */
6451 #endif
6452
6453         rc = swrap_recvmsg_before(s, si, &msg, &tmp);
6454         if (rc < 0) {
6455                 if (rc == -ENOTSOCK) {
6456                         return libc_readv(s, vector, count);
6457                 }
6458                 return -1;
6459         }
6460
6461         ret = libc_readv(s, msg.msg_iov, msg.msg_iovlen);
6462
6463         rc = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
6464         if (rc != 0) {
6465                 return rc;
6466         }
6467
6468         return ret;
6469 }
6470
6471 ssize_t readv(int s, const struct iovec *vector, int count)
6472 {
6473         return swrap_readv(s, vector, count);
6474 }
6475
6476 /****************************************************************************
6477  *   WRITEV
6478  ***************************************************************************/
6479
6480 static ssize_t swrap_writev(int s, const struct iovec *vector, int count)
6481 {
6482         struct msghdr msg;
6483         struct iovec tmp;
6484         struct sockaddr_un un_addr;
6485         ssize_t ret;
6486         int rc;
6487         struct socket_info *si = find_socket_info(s);
6488
6489         if (!si) {
6490                 return libc_writev(s, vector, count);
6491         }
6492
6493         tmp.iov_base = NULL;
6494         tmp.iov_len = 0;
6495
6496         ZERO_STRUCT(msg);
6497         msg.msg_name = NULL;           /* optional address */
6498         msg.msg_namelen = 0;           /* size of address */
6499         msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
6500         msg.msg_iovlen = count;        /* # elements in msg_iov */
6501 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6502         msg.msg_control = NULL;        /* ancillary data, see below */
6503         msg.msg_controllen = 0;        /* ancillary data buffer len */
6504         msg.msg_flags = 0;             /* flags on received message */
6505 #endif
6506
6507         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
6508         if (rc < 0) {
6509                 if (rc == -ENOTSOCK) {
6510                         return libc_readv(s, vector, count);
6511                 }
6512                 return -1;
6513         }
6514
6515         ret = libc_writev(s, msg.msg_iov, msg.msg_iovlen);
6516
6517         swrap_sendmsg_after(s, si, &msg, NULL, ret);
6518
6519         return ret;
6520 }
6521
6522 ssize_t writev(int s, const struct iovec *vector, int count)
6523 {
6524         return swrap_writev(s, vector, count);
6525 }
6526
6527 /****************************
6528  * CLOSE
6529  ***************************/
6530
6531 static int swrap_close(int fd)
6532 {
6533         struct socket_info *si = NULL;
6534         int si_index;
6535         int ret;
6536
6537         swrap_mutex_lock(&socket_reset_mutex);
6538
6539         si_index = find_socket_info_index(fd);
6540         if (si_index == -1) {
6541                 swrap_mutex_unlock(&socket_reset_mutex);
6542                 return libc_close(fd);
6543         }
6544
6545         SWRAP_LOG(SWRAP_LOG_TRACE, "Close wrapper for fd=%d", fd);
6546         reset_socket_info_index(fd);
6547
6548         si = swrap_get_socket_info(si_index);
6549
6550         swrap_mutex_lock(&first_free_mutex);
6551         SWRAP_LOCK_SI(si);
6552
6553         ret = libc_close(fd);
6554
6555         swrap_dec_refcount(si);
6556
6557         if (swrap_get_refcount(si) > 0) {
6558                 /* there are still references left */
6559                 goto out;
6560         }
6561
6562         if (si->myname.sa_socklen > 0 && si->peername.sa_socklen > 0) {
6563                 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0);
6564         }
6565
6566         if (si->myname.sa_socklen > 0 && si->peername.sa_socklen > 0) {
6567                 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0);
6568                 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0);
6569         }
6570
6571         if (si->un_addr.sun_path[0] != '\0') {
6572                 unlink(si->un_addr.sun_path);
6573         }
6574
6575         swrap_set_next_free(si, first_free);
6576         first_free = si_index;
6577
6578 out:
6579         SWRAP_UNLOCK_SI(si);
6580         swrap_mutex_unlock(&first_free_mutex);
6581         swrap_mutex_unlock(&socket_reset_mutex);
6582
6583         return ret;
6584 }
6585
6586 int close(int fd)
6587 {
6588         return swrap_close(fd);
6589 }
6590
6591 /****************************
6592  * DUP
6593  ***************************/
6594
6595 static int swrap_dup(int fd)
6596 {
6597         struct socket_info *si;
6598         int dup_fd, idx;
6599
6600         idx = find_socket_info_index(fd);
6601         if (idx == -1) {
6602                 return libc_dup(fd);
6603         }
6604
6605         si = swrap_get_socket_info(idx);
6606
6607         dup_fd = libc_dup(fd);
6608         if (dup_fd == -1) {
6609                 int saved_errno = errno;
6610                 errno = saved_errno;
6611                 return -1;
6612         }
6613
6614         if ((size_t)dup_fd >= socket_fds_max) {
6615                 SWRAP_LOG(SWRAP_LOG_ERROR,
6616                           "The max socket index limit of %zu has been reached, "
6617                           "trying to add %d",
6618                           socket_fds_max,
6619                           dup_fd);
6620                 libc_close(dup_fd);
6621                 errno = EMFILE;
6622                 return -1;
6623         }
6624
6625         SWRAP_LOCK_SI(si);
6626
6627         swrap_inc_refcount(si);
6628
6629         SWRAP_UNLOCK_SI(si);
6630
6631         /* Make sure we don't have an entry for the fd */
6632         swrap_remove_stale(dup_fd);
6633
6634         set_socket_info_index(dup_fd, idx);
6635
6636         return dup_fd;
6637 }
6638
6639 int dup(int fd)
6640 {
6641         return swrap_dup(fd);
6642 }
6643
6644 /****************************
6645  * DUP2
6646  ***************************/
6647
6648 static int swrap_dup2(int fd, int newfd)
6649 {
6650         struct socket_info *si;
6651         int dup_fd, idx;
6652
6653         idx = find_socket_info_index(fd);
6654         if (idx == -1) {
6655                 return libc_dup2(fd, newfd);
6656         }
6657
6658         si = swrap_get_socket_info(idx);
6659
6660         if (fd == newfd) {
6661                 /*
6662                  * According to the manpage:
6663                  *
6664                  * "If oldfd is a valid file descriptor, and newfd has the same
6665                  * value as oldfd, then dup2() does nothing, and returns newfd."
6666                  */
6667                 return newfd;
6668         }
6669
6670         if ((size_t)newfd >= socket_fds_max) {
6671                 SWRAP_LOG(SWRAP_LOG_ERROR,
6672                           "The max socket index limit of %zu has been reached, "
6673                           "trying to add %d",
6674                           socket_fds_max,
6675                           newfd);
6676                 errno = EMFILE;
6677                 return -1;
6678         }
6679
6680         if (find_socket_info(newfd)) {
6681                 /* dup2() does an implicit close of newfd, which we
6682                  * need to emulate */
6683                 swrap_close(newfd);
6684         }
6685
6686         dup_fd = libc_dup2(fd, newfd);
6687         if (dup_fd == -1) {
6688                 int saved_errno = errno;
6689                 errno = saved_errno;
6690                 return -1;
6691         }
6692
6693         SWRAP_LOCK_SI(si);
6694
6695         swrap_inc_refcount(si);
6696
6697         SWRAP_UNLOCK_SI(si);
6698
6699         /* Make sure we don't have an entry for the fd */
6700         swrap_remove_stale(dup_fd);
6701
6702         set_socket_info_index(dup_fd, idx);
6703
6704         return dup_fd;
6705 }
6706
6707 int dup2(int fd, int newfd)
6708 {
6709         return swrap_dup2(fd, newfd);
6710 }
6711
6712 /****************************
6713  * FCNTL
6714  ***************************/
6715
6716 static int swrap_vfcntl(int fd, int cmd, va_list va)
6717 {
6718         struct socket_info *si;
6719         int rc, dup_fd, idx;
6720
6721         idx = find_socket_info_index(fd);
6722         if (idx == -1) {
6723                 return libc_vfcntl(fd, cmd, va);
6724         }
6725
6726         si = swrap_get_socket_info(idx);
6727
6728         switch (cmd) {
6729         case F_DUPFD:
6730                 dup_fd = libc_vfcntl(fd, cmd, va);
6731                 if (dup_fd == -1) {
6732                         int saved_errno = errno;
6733                         errno = saved_errno;
6734                         return -1;
6735                 }
6736
6737                 /* Make sure we don't have an entry for the fd */
6738                 swrap_remove_stale(dup_fd);
6739
6740                 if ((size_t)dup_fd >= socket_fds_max) {
6741                         SWRAP_LOG(SWRAP_LOG_ERROR,
6742                           "The max socket index limit of %zu has been reached, "
6743                           "trying to add %d",
6744                           socket_fds_max,
6745                           dup_fd);
6746                         libc_close(dup_fd);
6747                         errno = EMFILE;
6748                         return -1;
6749                 }
6750
6751                 SWRAP_LOCK_SI(si);
6752
6753                 swrap_inc_refcount(si);
6754
6755                 SWRAP_UNLOCK_SI(si);
6756
6757
6758                 set_socket_info_index(dup_fd, idx);
6759
6760                 rc = dup_fd;
6761                 break;
6762         default:
6763                 rc = libc_vfcntl(fd, cmd, va);
6764                 break;
6765         }
6766
6767         return rc;
6768 }
6769
6770 int fcntl(int fd, int cmd, ...)
6771 {
6772         va_list va;
6773         int rc;
6774
6775         va_start(va, cmd);
6776
6777         rc = swrap_vfcntl(fd, cmd, va);
6778
6779         va_end(va);
6780
6781         return rc;
6782 }
6783
6784 /****************************
6785  * EVENTFD
6786  ***************************/
6787
6788 #ifdef HAVE_EVENTFD
6789 static int swrap_eventfd(int count, int flags)
6790 {
6791         int fd;
6792
6793         fd = libc_eventfd(count, flags);
6794         if (fd != -1) {
6795                 swrap_remove_stale(fd);
6796         }
6797
6798         return fd;
6799 }
6800
6801 #ifdef HAVE_EVENTFD_UNSIGNED_INT
6802 int eventfd(unsigned int count, int flags)
6803 #else
6804 int eventfd(int count, int flags)
6805 #endif
6806 {
6807         return swrap_eventfd(count, flags);
6808 }
6809 #endif
6810
6811 #ifdef HAVE_PLEDGE
6812 int pledge(const char *promises, const char *paths[])
6813 {
6814         (void)promises; /* unused */
6815         (void)paths; /* unused */
6816
6817         return 0;
6818 }
6819 #endif /* HAVE_PLEDGE */
6820
6821 static void swrap_thread_prepare(void)
6822 {
6823         /*
6824          * This function should only be called here!!
6825          *
6826          * We bind all symobls to avoid deadlocks of the fork is
6827          * interrupted by a signal handler using a symbol of this
6828          * library.
6829          */
6830         swrap_bind_symbol_all();
6831
6832         SWRAP_LOCK_ALL;
6833 }
6834
6835 static void swrap_thread_parent(void)
6836 {
6837         SWRAP_UNLOCK_ALL;
6838 }
6839
6840 static void swrap_thread_child(void)
6841 {
6842         SWRAP_REINIT_ALL;
6843 }
6844
6845 /****************************
6846  * CONSTRUCTOR
6847  ***************************/
6848 void swrap_constructor(void)
6849 {
6850         SWRAP_REINIT_ALL;
6851
6852         /*
6853         * If we hold a lock and the application forks, then the child
6854         * is not able to unlock the mutex and we are in a deadlock.
6855         * This should prevent such deadlocks.
6856         */
6857         pthread_atfork(&swrap_thread_prepare,
6858                        &swrap_thread_parent,
6859                        &swrap_thread_child);
6860 }
6861
6862 /****************************
6863  * DESTRUCTOR
6864  ***************************/
6865
6866 /*
6867  * This function is called when the library is unloaded and makes sure that
6868  * sockets get closed and the unix file for the socket are unlinked.
6869  */
6870 void swrap_destructor(void)
6871 {
6872         size_t i;
6873
6874         if (socket_fds_idx != NULL) {
6875                 for (i = 0; i < socket_fds_max; ++i) {
6876                         if (socket_fds_idx[i] != -1) {
6877                                 swrap_close(i);
6878                         }
6879                 }
6880                 SAFE_FREE(socket_fds_idx);
6881         }
6882
6883         SAFE_FREE(sockets);
6884
6885         if (swrap.libc.handle != NULL) {
6886                 dlclose(swrap.libc.handle);
6887         }
6888         if (swrap.libc.socket_handle) {
6889                 dlclose(swrap.libc.socket_handle);
6890         }
6891 }
6892
6893 #if defined(HAVE__SOCKET) && defined(HAVE__CLOSE)
6894 /*
6895  * On FreeBSD 12 (and maybe other platforms)
6896  * system libraries like libresolv prefix there
6897  * syscalls with '_' in order to always use
6898  * the symbols from libc.
6899  *
6900  * In the interaction with resolv_wrapper,
6901  * we need to inject socket wrapper into libresolv,
6902  * which means we need to private all socket
6903  * related syscalls also with the '_' prefix.
6904  *
6905  * This is tested in Samba's 'make test',
6906  * there we noticed that providing '_read'
6907  * and '_open' would cause errors, which
6908  * means we skip '_read', '_write' and
6909  * all non socket related calls without
6910  * further analyzing the problem.
6911  */
6912 #define SWRAP_SYMBOL_ALIAS(__sym, __aliassym) \
6913         extern typeof(__sym) __aliassym __attribute__ ((alias(#__sym)))
6914
6915 #ifdef HAVE_ACCEPT4
6916 SWRAP_SYMBOL_ALIAS(accept4, _accept4);
6917 #endif
6918 SWRAP_SYMBOL_ALIAS(accept, _accept);
6919 SWRAP_SYMBOL_ALIAS(bind, _bind);
6920 SWRAP_SYMBOL_ALIAS(close, _close);
6921 SWRAP_SYMBOL_ALIAS(connect, _connect);
6922 SWRAP_SYMBOL_ALIAS(dup, _dup);
6923 SWRAP_SYMBOL_ALIAS(dup2, _dup2);
6924 SWRAP_SYMBOL_ALIAS(fcntl, _fcntl);
6925 SWRAP_SYMBOL_ALIAS(getpeername, _getpeername);
6926 SWRAP_SYMBOL_ALIAS(getsockname, _getsockname);
6927 SWRAP_SYMBOL_ALIAS(getsockopt, _getsockopt);
6928 SWRAP_SYMBOL_ALIAS(ioctl, _ioctl);
6929 SWRAP_SYMBOL_ALIAS(listen, _listen);
6930 SWRAP_SYMBOL_ALIAS(readv, _readv);
6931 SWRAP_SYMBOL_ALIAS(recv, _recv);
6932 SWRAP_SYMBOL_ALIAS(recvfrom, _recvfrom);
6933 SWRAP_SYMBOL_ALIAS(recvmsg, _recvmsg);
6934 SWRAP_SYMBOL_ALIAS(send, _send);
6935 SWRAP_SYMBOL_ALIAS(sendmsg, _sendmsg);
6936 SWRAP_SYMBOL_ALIAS(sendto, _sendto);
6937 SWRAP_SYMBOL_ALIAS(setsockopt, _setsockopt);
6938 SWRAP_SYMBOL_ALIAS(socket, _socket);
6939 SWRAP_SYMBOL_ALIAS(socketpair, _socketpair);
6940 SWRAP_SYMBOL_ALIAS(writev, _writev);
6941
6942 #endif /* SOCKET_WRAPPER_EXPORT_UNDERSCORE_SYMBOLS */