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