swrap: export a public socket_wrapper_indicate_no_inet_fd() helper function
[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-2021, Stefan Metzmacher <metze@samba.org>
6  * Copyright (c) 2013-2021, 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 #include "socket_wrapper.h"
90
91 enum swrap_dbglvl_e {
92         SWRAP_LOG_ERROR = 0,
93         SWRAP_LOG_WARN,
94         SWRAP_LOG_DEBUG,
95         SWRAP_LOG_TRACE
96 };
97
98 /* GCC have printf type attribute check. */
99 #ifdef HAVE_FUNCTION_ATTRIBUTE_FORMAT
100 #define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
101 #else
102 #define PRINTF_ATTRIBUTE(a,b)
103 #endif /* HAVE_FUNCTION_ATTRIBUTE_FORMAT */
104
105 #ifdef HAVE_CONSTRUCTOR_ATTRIBUTE
106 #define CONSTRUCTOR_ATTRIBUTE __attribute__ ((constructor))
107 #else
108 #define CONSTRUCTOR_ATTRIBUTE
109 #endif /* HAVE_CONSTRUCTOR_ATTRIBUTE */
110
111 #ifdef HAVE_DESTRUCTOR_ATTRIBUTE
112 #define DESTRUCTOR_ATTRIBUTE __attribute__ ((destructor))
113 #else
114 #define DESTRUCTOR_ATTRIBUTE
115 #endif
116
117 #ifndef FALL_THROUGH
118 # ifdef HAVE_FALLTHROUGH_ATTRIBUTE
119 #  define FALL_THROUGH __attribute__ ((fallthrough))
120 # else /* HAVE_FALLTHROUGH_ATTRIBUTE */
121 #  define FALL_THROUGH ((void)0)
122 # endif /* HAVE_FALLTHROUGH_ATTRIBUTE */
123 #endif /* FALL_THROUGH */
124
125 #ifdef HAVE_ADDRESS_SANITIZER_ATTRIBUTE
126 #define DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE __attribute__((no_sanitize_address))
127 #else
128 #define DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
129 #endif
130
131 #ifdef HAVE_GCC_THREAD_LOCAL_STORAGE
132 # define SWRAP_THREAD __thread
133 #else
134 # define SWRAP_THREAD
135 #endif
136
137 #ifndef MIN
138 #define MIN(a,b) ((a)<(b)?(a):(b))
139 #endif
140
141 #ifndef ZERO_STRUCT
142 #define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
143 #endif
144
145 #ifndef ZERO_STRUCTP
146 #define ZERO_STRUCTP(x) do { \
147                 if ((x) != NULL) \
148                         memset((char *)(x), 0, sizeof(*(x))); \
149         } while(0)
150 #endif
151
152 #ifndef SAFE_FREE
153 #define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0)
154 #endif
155
156 #ifndef discard_const
157 #define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
158 #endif
159
160 #ifndef discard_const_p
161 #define discard_const_p(type, ptr) ((type *)discard_const(ptr))
162 #endif
163
164 #define UNUSED(x) (void)(x)
165
166 #ifdef IPV6_PKTINFO
167 # ifndef IPV6_RECVPKTINFO
168 #  define IPV6_RECVPKTINFO IPV6_PKTINFO
169 # endif /* IPV6_RECVPKTINFO */
170 #endif /* IPV6_PKTINFO */
171
172 /*
173  * On BSD IP_PKTINFO has a different name because during
174  * the time when they implemented it, there was no RFC.
175  * The name for IPv6 is the same as on Linux.
176  */
177 #ifndef IP_PKTINFO
178 # ifdef IP_RECVDSTADDR
179 #  define IP_PKTINFO IP_RECVDSTADDR
180 # endif
181 #endif
182
183 #define socket_wrapper_init_mutex(m) \
184         _socket_wrapper_init_mutex(m, #m)
185
186 /* Add new global locks here please */
187 # define SWRAP_REINIT_ALL do { \
188         int ret; \
189         ret = socket_wrapper_init_mutex(&sockets_mutex); \
190         if (ret != 0) exit(-1); \
191         ret = socket_wrapper_init_mutex(&socket_reset_mutex); \
192         if (ret != 0) exit(-1); \
193         ret = socket_wrapper_init_mutex(&first_free_mutex); \
194         if (ret != 0) exit(-1); \
195         ret = socket_wrapper_init_mutex(&sockets_si_global); \
196         if (ret != 0) exit(-1); \
197         ret = socket_wrapper_init_mutex(&autobind_start_mutex); \
198         if (ret != 0) exit(-1); \
199         ret = socket_wrapper_init_mutex(&pcap_dump_mutex); \
200         if (ret != 0) exit(-1); \
201         ret = socket_wrapper_init_mutex(&mtu_update_mutex); \
202         if (ret != 0) exit(-1); \
203 } while(0)
204
205 # define SWRAP_LOCK_ALL do { \
206         swrap_mutex_lock(&sockets_mutex); \
207         swrap_mutex_lock(&socket_reset_mutex); \
208         swrap_mutex_lock(&first_free_mutex); \
209         swrap_mutex_lock(&sockets_si_global); \
210         swrap_mutex_lock(&autobind_start_mutex); \
211         swrap_mutex_lock(&pcap_dump_mutex); \
212         swrap_mutex_lock(&mtu_update_mutex); \
213 } while(0)
214
215 # define SWRAP_UNLOCK_ALL do { \
216         swrap_mutex_unlock(&mtu_update_mutex); \
217         swrap_mutex_unlock(&pcap_dump_mutex); \
218         swrap_mutex_unlock(&autobind_start_mutex); \
219         swrap_mutex_unlock(&sockets_si_global); \
220         swrap_mutex_unlock(&first_free_mutex); \
221         swrap_mutex_unlock(&socket_reset_mutex); \
222         swrap_mutex_unlock(&sockets_mutex); \
223 } while(0)
224
225 #define SOCKET_INFO_CONTAINER(si) \
226         (struct socket_info_container *)(si)
227
228 #define SWRAP_LOCK_SI(si) do { \
229         struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si); \
230         if (sic != NULL) { \
231                 swrap_mutex_lock(&sockets_si_global); \
232         } else { \
233                 abort(); \
234         } \
235 } while(0)
236
237 #define SWRAP_UNLOCK_SI(si) do { \
238         struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si); \
239         if (sic != NULL) { \
240                 swrap_mutex_unlock(&sockets_si_global); \
241         } else { \
242                 abort(); \
243         } \
244 } while(0)
245
246 #if defined(HAVE_GETTIMEOFDAY_TZ) || defined(HAVE_GETTIMEOFDAY_TZ_VOID)
247 #define swrapGetTimeOfDay(tval) gettimeofday(tval,NULL)
248 #else
249 #define swrapGetTimeOfDay(tval) gettimeofday(tval)
250 #endif
251
252 /* we need to use a very terse format here as IRIX 6.4 silently
253    truncates names to 16 chars, so if we use a longer name then we
254    can't tell which port a packet came from with recvfrom()
255
256    with this format we have 8 chars left for the directory name
257 */
258 #define SOCKET_FORMAT "%c%02X%04X"
259 #define SOCKET_TYPE_CHAR_TCP            'T'
260 #define SOCKET_TYPE_CHAR_UDP            'U'
261 #define SOCKET_TYPE_CHAR_TCP_V6         'X'
262 #define SOCKET_TYPE_CHAR_UDP_V6         'Y'
263
264 /*
265  * Set the packet MTU to 1500 bytes for stream sockets to make it it easier to
266  * format PCAP capture files (as the caller will simply continue from here).
267  */
268 #define SOCKET_WRAPPER_MTU_DEFAULT 1500
269 #define SOCKET_WRAPPER_MTU_MIN     512
270 #define SOCKET_WRAPPER_MTU_MAX     32768
271
272 #define SOCKET_MAX_SOCKETS 1024
273
274 /*
275  * Maximum number of socket_info structures that can
276  * be used. Can be overriden by the environment variable
277  * SOCKET_WRAPPER_MAX_SOCKETS.
278  */
279 #define SOCKET_WRAPPER_MAX_SOCKETS_DEFAULT 65535
280
281 #define SOCKET_WRAPPER_MAX_SOCKETS_LIMIT 262140
282
283 /* This limit is to avoid broadcast sendto() needing to stat too many
284  * files.  It may be raised (with a performance cost) to up to 254
285  * without changing the format above */
286 #define MAX_WRAPPED_INTERFACES 64
287
288 struct swrap_address {
289         socklen_t sa_socklen;
290         union {
291                 struct sockaddr s;
292                 struct sockaddr_in in;
293 #ifdef HAVE_IPV6
294                 struct sockaddr_in6 in6;
295 #endif
296                 struct sockaddr_un un;
297                 struct sockaddr_storage ss;
298         } sa;
299 };
300
301 static int first_free;
302
303 struct socket_info
304 {
305         /*
306          * Remember to update swrap_unix_scm_right_magic
307          * on any change.
308          */
309
310         int family;
311         int type;
312         int protocol;
313         int bound;
314         int bcast;
315         int is_server;
316         int connected;
317         int defer_connect;
318         int pktinfo;
319         int tcp_nodelay;
320         int listening;
321         int fd_passed;
322
323         /* The unix path so we can unlink it on close() */
324         struct sockaddr_un un_addr;
325
326         struct swrap_address bindname;
327         struct swrap_address myname;
328         struct swrap_address peername;
329
330         struct {
331                 unsigned long pck_snd;
332                 unsigned long pck_rcv;
333         } io;
334 };
335
336 struct socket_info_meta
337 {
338         unsigned int refcount;
339         int next_free;
340         /*
341          * As long as we don't use shared memory
342          * for the sockets array, we use
343          * sockets_si_global as a single mutex.
344          *
345          * pthread_mutex_t mutex;
346          */
347 };
348
349 struct socket_info_container
350 {
351         struct socket_info info;
352         struct socket_info_meta meta;
353 };
354
355 static struct socket_info_container *sockets;
356
357 static size_t socket_info_max = 0;
358
359 /*
360  * Allocate the socket array always on the limit value. We want it to be
361  * at least bigger than the default so if we reach the limit we can
362  * still deal with duplicate fds pointing to the same socket_info.
363  */
364 static size_t socket_fds_max = SOCKET_WRAPPER_MAX_SOCKETS_LIMIT;
365
366 /* Hash table to map fds to corresponding socket_info index */
367 static int *socket_fds_idx;
368
369 /* Mutex for syncronizing port selection during swrap_auto_bind() */
370 static pthread_mutex_t autobind_start_mutex = PTHREAD_MUTEX_INITIALIZER;
371
372 /* Mutex to guard the initialization of array of socket_info structures */
373 static pthread_mutex_t sockets_mutex = PTHREAD_MUTEX_INITIALIZER;
374
375 /* Mutex to guard the socket reset in swrap_remove_wrapper() */
376 static pthread_mutex_t socket_reset_mutex = PTHREAD_MUTEX_INITIALIZER;
377
378 /* Mutex to synchronize access to first free index in socket_info array */
379 static pthread_mutex_t first_free_mutex = PTHREAD_MUTEX_INITIALIZER;
380
381 /*
382  * Mutex to synchronize access to to socket_info structures
383  * We use a single global mutex in order to avoid leaking
384  * ~ 38M copy on write memory per fork.
385  * max_sockets=65535 * sizeof(struct socket_info_container)=592 = 38796720
386  */
387 static pthread_mutex_t sockets_si_global = PTHREAD_MUTEX_INITIALIZER;
388
389 /* Mutex to synchronize access to packet capture dump file */
390 static pthread_mutex_t pcap_dump_mutex = PTHREAD_MUTEX_INITIALIZER;
391
392 /* Mutex for synchronizing mtu value fetch*/
393 static pthread_mutex_t mtu_update_mutex = PTHREAD_MUTEX_INITIALIZER;
394
395 /* Function prototypes */
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 static int sockaddr_convert_to_un(struct socket_info *si,
2410                                   const struct sockaddr *in_addr,
2411                                   socklen_t in_len,
2412                                   struct sockaddr_un *out_addr,
2413                                   int alloc_sock,
2414                                   int *bcast)
2415 {
2416         struct sockaddr *out = (struct sockaddr *)(void *)out_addr;
2417
2418         (void) in_len; /* unused */
2419
2420         if (out_addr == NULL) {
2421                 return 0;
2422         }
2423
2424         out->sa_family = AF_UNIX;
2425 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
2426         out->sa_len = sizeof(*out_addr);
2427 #endif
2428
2429         switch (in_addr->sa_family) {
2430         case AF_UNSPEC: {
2431                 const struct sockaddr_in *sin;
2432                 if (si->family != AF_INET) {
2433                         break;
2434                 }
2435                 if (in_len < sizeof(struct sockaddr_in)) {
2436                         break;
2437                 }
2438                 sin = (const struct sockaddr_in *)(const void *)in_addr;
2439                 if(sin->sin_addr.s_addr != htonl(INADDR_ANY)) {
2440                         break;
2441                 }
2442
2443                 /*
2444                  * Note: in the special case of AF_UNSPEC and INADDR_ANY,
2445                  * AF_UNSPEC is mapped to AF_INET and must be treated here.
2446                  */
2447
2448                 FALL_THROUGH;
2449         }
2450         case AF_INET:
2451 #ifdef HAVE_IPV6
2452         case AF_INET6:
2453 #endif
2454                 switch (si->type) {
2455                 case SOCK_STREAM:
2456                 case SOCK_DGRAM:
2457                         break;
2458                 default:
2459                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!");
2460                         errno = ESOCKTNOSUPPORT;
2461                         return -1;
2462                 }
2463                 if (alloc_sock) {
2464                         return convert_in_un_alloc(si, in_addr, out_addr, bcast);
2465                 } else {
2466                         return convert_in_un_remote(si, in_addr, out_addr, bcast);
2467                 }
2468         default:
2469                 break;
2470         }
2471
2472         errno = EAFNOSUPPORT;
2473         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family");
2474         return -1;
2475 }
2476
2477 static int sockaddr_convert_from_un(const struct socket_info *si,
2478                                     const struct sockaddr_un *in_addr,
2479                                     socklen_t un_addrlen,
2480                                     int family,
2481                                     struct sockaddr *out_addr,
2482                                     socklen_t *out_addrlen)
2483 {
2484         int ret;
2485
2486         if (out_addr == NULL || out_addrlen == NULL)
2487                 return 0;
2488
2489         if (un_addrlen == 0) {
2490                 *out_addrlen = 0;
2491                 return 0;
2492         }
2493
2494         switch (family) {
2495         case AF_INET:
2496 #ifdef HAVE_IPV6
2497         case AF_INET6:
2498 #endif
2499                 switch (si->type) {
2500                 case SOCK_STREAM:
2501                 case SOCK_DGRAM:
2502                         break;
2503                 default:
2504                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!");
2505                         errno = ESOCKTNOSUPPORT;
2506                         return -1;
2507                 }
2508                 ret = convert_un_in(in_addr, out_addr, out_addrlen);
2509 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
2510                 out_addr->sa_len = *out_addrlen;
2511 #endif
2512                 return ret;
2513         default:
2514                 break;
2515         }
2516
2517         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family");
2518         errno = EAFNOSUPPORT;
2519         return -1;
2520 }
2521
2522 enum swrap_packet_type {
2523         SWRAP_CONNECT_SEND,
2524         SWRAP_CONNECT_UNREACH,
2525         SWRAP_CONNECT_RECV,
2526         SWRAP_CONNECT_ACK,
2527         SWRAP_ACCEPT_SEND,
2528         SWRAP_ACCEPT_RECV,
2529         SWRAP_ACCEPT_ACK,
2530         SWRAP_RECVFROM,
2531         SWRAP_SENDTO,
2532         SWRAP_SENDTO_UNREACH,
2533         SWRAP_PENDING_RST,
2534         SWRAP_RECV,
2535         SWRAP_RECV_RST,
2536         SWRAP_SEND,
2537         SWRAP_SEND_RST,
2538         SWRAP_CLOSE_SEND,
2539         SWRAP_CLOSE_RECV,
2540         SWRAP_CLOSE_ACK,
2541 };
2542
2543 struct swrap_file_hdr {
2544         uint32_t        magic;
2545         uint16_t        version_major;
2546         uint16_t        version_minor;
2547         int32_t         timezone;
2548         uint32_t        sigfigs;
2549         uint32_t        frame_max_len;
2550 #define SWRAP_FRAME_LENGTH_MAX 0xFFFF
2551         uint32_t        link_type;
2552 };
2553 #define SWRAP_FILE_HDR_SIZE 24
2554
2555 struct swrap_packet_frame {
2556         uint32_t seconds;
2557         uint32_t micro_seconds;
2558         uint32_t recorded_length;
2559         uint32_t full_length;
2560 };
2561 #define SWRAP_PACKET_FRAME_SIZE 16
2562
2563 union swrap_packet_ip {
2564         struct {
2565                 uint8_t         ver_hdrlen;
2566                 uint8_t         tos;
2567                 uint16_t        packet_length;
2568                 uint16_t        identification;
2569                 uint8_t         flags;
2570                 uint8_t         fragment;
2571                 uint8_t         ttl;
2572                 uint8_t         protocol;
2573                 uint16_t        hdr_checksum;
2574                 uint32_t        src_addr;
2575                 uint32_t        dest_addr;
2576         } v4;
2577 #define SWRAP_PACKET_IP_V4_SIZE 20
2578         struct {
2579                 uint8_t         ver_prio;
2580                 uint8_t         flow_label_high;
2581                 uint16_t        flow_label_low;
2582                 uint16_t        payload_length;
2583                 uint8_t         next_header;
2584                 uint8_t         hop_limit;
2585                 uint8_t         src_addr[16];
2586                 uint8_t         dest_addr[16];
2587         } v6;
2588 #define SWRAP_PACKET_IP_V6_SIZE 40
2589 };
2590 #define SWRAP_PACKET_IP_SIZE 40
2591
2592 union swrap_packet_payload {
2593         struct {
2594                 uint16_t        source_port;
2595                 uint16_t        dest_port;
2596                 uint32_t        seq_num;
2597                 uint32_t        ack_num;
2598                 uint8_t         hdr_length;
2599                 uint8_t         control;
2600                 uint16_t        window;
2601                 uint16_t        checksum;
2602                 uint16_t        urg;
2603         } tcp;
2604 #define SWRAP_PACKET_PAYLOAD_TCP_SIZE 20
2605         struct {
2606                 uint16_t        source_port;
2607                 uint16_t        dest_port;
2608                 uint16_t        length;
2609                 uint16_t        checksum;
2610         } udp;
2611 #define SWRAP_PACKET_PAYLOAD_UDP_SIZE 8
2612         struct {
2613                 uint8_t         type;
2614                 uint8_t         code;
2615                 uint16_t        checksum;
2616                 uint32_t        unused;
2617         } icmp4;
2618 #define SWRAP_PACKET_PAYLOAD_ICMP4_SIZE 8
2619         struct {
2620                 uint8_t         type;
2621                 uint8_t         code;
2622                 uint16_t        checksum;
2623                 uint32_t        unused;
2624         } icmp6;
2625 #define SWRAP_PACKET_PAYLOAD_ICMP6_SIZE 8
2626 };
2627 #define SWRAP_PACKET_PAYLOAD_SIZE 20
2628
2629 #define SWRAP_PACKET_MIN_ALLOC \
2630         (SWRAP_PACKET_FRAME_SIZE + \
2631          SWRAP_PACKET_IP_SIZE + \
2632          SWRAP_PACKET_PAYLOAD_SIZE)
2633
2634 static const char *swrap_pcap_init_file(void)
2635 {
2636         static int initialized = 0;
2637         static const char *s = NULL;
2638         static const struct swrap_file_hdr h;
2639         static const struct swrap_packet_frame f;
2640         static const union swrap_packet_ip i;
2641         static const union swrap_packet_payload p;
2642
2643         if (initialized == 1) {
2644                 return s;
2645         }
2646         initialized = 1;
2647
2648         /*
2649          * TODO: don't use the structs use plain buffer offsets
2650          *       and PUSH_U8(), PUSH_U16() and PUSH_U32()
2651          *
2652          * for now make sure we disable PCAP support
2653          * if the struct has alignment!
2654          */
2655         if (sizeof(h) != SWRAP_FILE_HDR_SIZE) {
2656                 return NULL;
2657         }
2658         if (sizeof(f) != SWRAP_PACKET_FRAME_SIZE) {
2659                 return NULL;
2660         }
2661         if (sizeof(i) != SWRAP_PACKET_IP_SIZE) {
2662                 return NULL;
2663         }
2664         if (sizeof(i.v4) != SWRAP_PACKET_IP_V4_SIZE) {
2665                 return NULL;
2666         }
2667         if (sizeof(i.v6) != SWRAP_PACKET_IP_V6_SIZE) {
2668                 return NULL;
2669         }
2670         if (sizeof(p) != SWRAP_PACKET_PAYLOAD_SIZE) {
2671                 return NULL;
2672         }
2673         if (sizeof(p.tcp) != SWRAP_PACKET_PAYLOAD_TCP_SIZE) {
2674                 return NULL;
2675         }
2676         if (sizeof(p.udp) != SWRAP_PACKET_PAYLOAD_UDP_SIZE) {
2677                 return NULL;
2678         }
2679         if (sizeof(p.icmp4) != SWRAP_PACKET_PAYLOAD_ICMP4_SIZE) {
2680                 return NULL;
2681         }
2682         if (sizeof(p.icmp6) != SWRAP_PACKET_PAYLOAD_ICMP6_SIZE) {
2683                 return NULL;
2684         }
2685
2686         s = getenv("SOCKET_WRAPPER_PCAP_FILE");
2687         if (s == NULL) {
2688                 return NULL;
2689         }
2690         if (strncmp(s, "./", 2) == 0) {
2691                 s += 2;
2692         }
2693         SWRAP_LOG(SWRAP_LOG_TRACE, "SOCKET_WRAPPER_PCAP_FILE: %s", s);
2694         return s;
2695 }
2696
2697 static uint8_t *swrap_pcap_packet_init(struct timeval *tval,
2698                                        const struct sockaddr *src,
2699                                        const struct sockaddr *dest,
2700                                        int socket_type,
2701                                        const uint8_t *payload,
2702                                        size_t payload_len,
2703                                        unsigned long tcp_seqno,
2704                                        unsigned long tcp_ack,
2705                                        unsigned char tcp_ctl,
2706                                        int unreachable,
2707                                        size_t *_packet_len)
2708 {
2709         uint8_t *base = NULL;
2710         uint8_t *buf = NULL;
2711         union {
2712                 uint8_t *ptr;
2713                 struct swrap_packet_frame *frame;
2714         } f;
2715         union {
2716                 uint8_t *ptr;
2717                 union swrap_packet_ip *ip;
2718         } i;
2719         union swrap_packet_payload *pay;
2720         size_t packet_len;
2721         size_t alloc_len;
2722         size_t nonwire_len = sizeof(struct swrap_packet_frame);
2723         size_t wire_hdr_len = 0;
2724         size_t wire_len = 0;
2725         size_t ip_hdr_len = 0;
2726         size_t icmp_hdr_len = 0;
2727         size_t icmp_truncate_len = 0;
2728         uint8_t protocol = 0, icmp_protocol = 0;
2729         const struct sockaddr_in *src_in = NULL;
2730         const struct sockaddr_in *dest_in = NULL;
2731 #ifdef HAVE_IPV6
2732         const struct sockaddr_in6 *src_in6 = NULL;
2733         const struct sockaddr_in6 *dest_in6 = NULL;
2734 #endif
2735         uint16_t src_port;
2736         uint16_t dest_port;
2737
2738         switch (src->sa_family) {
2739         case AF_INET:
2740                 src_in = (const struct sockaddr_in *)(const void *)src;
2741                 dest_in = (const struct sockaddr_in *)(const void *)dest;
2742                 src_port = src_in->sin_port;
2743                 dest_port = dest_in->sin_port;
2744                 ip_hdr_len = sizeof(i.ip->v4);
2745                 break;
2746 #ifdef HAVE_IPV6
2747         case AF_INET6:
2748                 src_in6 = (const struct sockaddr_in6 *)(const void *)src;
2749                 dest_in6 = (const struct sockaddr_in6 *)(const void *)dest;
2750                 src_port = src_in6->sin6_port;
2751                 dest_port = dest_in6->sin6_port;
2752                 ip_hdr_len = sizeof(i.ip->v6);
2753                 break;
2754 #endif
2755         default:
2756                 return NULL;
2757         }
2758
2759         switch (socket_type) {
2760         case SOCK_STREAM:
2761                 protocol = 0x06; /* TCP */
2762                 wire_hdr_len = ip_hdr_len + sizeof(pay->tcp);
2763                 wire_len = wire_hdr_len + payload_len;
2764                 break;
2765
2766         case SOCK_DGRAM:
2767                 protocol = 0x11; /* UDP */
2768                 wire_hdr_len = ip_hdr_len + sizeof(pay->udp);
2769                 wire_len = wire_hdr_len + payload_len;
2770                 break;
2771
2772         default:
2773                 return NULL;
2774         }
2775
2776         if (unreachable) {
2777                 icmp_protocol = protocol;
2778                 switch (src->sa_family) {
2779                 case AF_INET:
2780                         protocol = 0x01; /* ICMPv4 */
2781                         icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp4);
2782                         break;
2783 #ifdef HAVE_IPV6
2784                 case AF_INET6:
2785                         protocol = 0x3A; /* ICMPv6 */
2786                         icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp6);
2787                         break;
2788 #endif
2789                 }
2790                 if (wire_len > 64 ) {
2791                         icmp_truncate_len = wire_len - 64;
2792                 }
2793                 wire_len += icmp_hdr_len;
2794         }
2795
2796         packet_len = nonwire_len + wire_len;
2797         alloc_len = packet_len;
2798         if (alloc_len < SWRAP_PACKET_MIN_ALLOC) {
2799                 alloc_len = SWRAP_PACKET_MIN_ALLOC;
2800         }
2801
2802         base = (uint8_t *)calloc(1, alloc_len);
2803         if (base == NULL) {
2804                 return NULL;
2805         }
2806
2807         buf = base;
2808         f.ptr = buf;
2809
2810         f.frame->seconds                = tval->tv_sec;
2811         f.frame->micro_seconds  = tval->tv_usec;
2812         f.frame->recorded_length        = wire_len - icmp_truncate_len;
2813         f.frame->full_length    = wire_len - icmp_truncate_len;
2814
2815         buf += SWRAP_PACKET_FRAME_SIZE;
2816
2817         i.ptr = buf;
2818         switch (src->sa_family) {
2819         case AF_INET:
2820                 if (src_in == NULL || dest_in == NULL) {
2821                         SAFE_FREE(base);
2822                         return NULL;
2823                 }
2824
2825                 i.ip->v4.ver_hdrlen     = 0x45; /* version 4 and 5 * 32 bit words */
2826                 i.ip->v4.tos            = 0x00;
2827                 i.ip->v4.packet_length  = htons(wire_len - icmp_truncate_len);
2828                 i.ip->v4.identification = htons(0xFFFF);
2829                 i.ip->v4.flags          = 0x40; /* BIT 1 set - means don't fragment */
2830                 i.ip->v4.fragment       = htons(0x0000);
2831                 i.ip->v4.ttl            = 0xFF;
2832                 i.ip->v4.protocol       = protocol;
2833                 i.ip->v4.hdr_checksum   = htons(0x0000);
2834                 i.ip->v4.src_addr       = src_in->sin_addr.s_addr;
2835                 i.ip->v4.dest_addr      = dest_in->sin_addr.s_addr;
2836                 buf += SWRAP_PACKET_IP_V4_SIZE;
2837                 break;
2838 #ifdef HAVE_IPV6
2839         case AF_INET6:
2840                 if (src_in6 == NULL || dest_in6 == NULL) {
2841                         SAFE_FREE(base);
2842                         return NULL;
2843                 }
2844
2845                 i.ip->v6.ver_prio               = 0x60; /* version 4 and 5 * 32 bit words */
2846                 i.ip->v6.flow_label_high        = 0x00;
2847                 i.ip->v6.flow_label_low = 0x0000;
2848                 i.ip->v6.payload_length = htons(wire_len - icmp_truncate_len); /* TODO */
2849                 i.ip->v6.next_header    = protocol;
2850                 memcpy(i.ip->v6.src_addr, src_in6->sin6_addr.s6_addr, 16);
2851                 memcpy(i.ip->v6.dest_addr, dest_in6->sin6_addr.s6_addr, 16);
2852                 buf += SWRAP_PACKET_IP_V6_SIZE;
2853                 break;
2854 #endif
2855         }
2856
2857         if (unreachable) {
2858                 pay = (union swrap_packet_payload *)(void *)buf;
2859                 switch (src->sa_family) {
2860                 case AF_INET:
2861                         pay->icmp4.type         = 0x03; /* destination unreachable */
2862                         pay->icmp4.code         = 0x01; /* host unreachable */
2863                         pay->icmp4.checksum     = htons(0x0000);
2864                         pay->icmp4.unused       = htonl(0x00000000);
2865
2866                         buf += SWRAP_PACKET_PAYLOAD_ICMP4_SIZE;
2867
2868                         /* set the ip header in the ICMP payload */
2869                         i.ptr = buf;
2870                         i.ip->v4.ver_hdrlen     = 0x45; /* version 4 and 5 * 32 bit words */
2871                         i.ip->v4.tos            = 0x00;
2872                         i.ip->v4.packet_length  = htons(wire_len - icmp_hdr_len);
2873                         i.ip->v4.identification = htons(0xFFFF);
2874                         i.ip->v4.flags          = 0x40; /* BIT 1 set - means don't fragment */
2875                         i.ip->v4.fragment       = htons(0x0000);
2876                         i.ip->v4.ttl            = 0xFF;
2877                         i.ip->v4.protocol       = icmp_protocol;
2878                         i.ip->v4.hdr_checksum   = htons(0x0000);
2879                         i.ip->v4.src_addr       = dest_in->sin_addr.s_addr;
2880                         i.ip->v4.dest_addr      = src_in->sin_addr.s_addr;
2881
2882                         buf += SWRAP_PACKET_IP_V4_SIZE;
2883
2884                         src_port = dest_in->sin_port;
2885                         dest_port = src_in->sin_port;
2886                         break;
2887 #ifdef HAVE_IPV6
2888                 case AF_INET6:
2889                         pay->icmp6.type         = 0x01; /* destination unreachable */
2890                         pay->icmp6.code         = 0x03; /* address unreachable */
2891                         pay->icmp6.checksum     = htons(0x0000);
2892                         pay->icmp6.unused       = htonl(0x00000000);
2893                         buf += SWRAP_PACKET_PAYLOAD_ICMP6_SIZE;
2894
2895                         /* set the ip header in the ICMP payload */
2896                         i.ptr = buf;
2897                         i.ip->v6.ver_prio               = 0x60; /* version 4 and 5 * 32 bit words */
2898                         i.ip->v6.flow_label_high        = 0x00;
2899                         i.ip->v6.flow_label_low = 0x0000;
2900                         i.ip->v6.payload_length = htons(wire_len - icmp_truncate_len); /* TODO */
2901                         i.ip->v6.next_header    = protocol;
2902                         memcpy(i.ip->v6.src_addr, dest_in6->sin6_addr.s6_addr, 16);
2903                         memcpy(i.ip->v6.dest_addr, src_in6->sin6_addr.s6_addr, 16);
2904
2905                         buf += SWRAP_PACKET_IP_V6_SIZE;
2906
2907                         src_port = dest_in6->sin6_port;
2908                         dest_port = src_in6->sin6_port;
2909                         break;
2910 #endif
2911                 }
2912         }
2913
2914         pay = (union swrap_packet_payload *)(void *)buf;
2915
2916         switch (socket_type) {
2917         case SOCK_STREAM:
2918                 pay->tcp.source_port    = src_port;
2919                 pay->tcp.dest_port      = dest_port;
2920                 pay->tcp.seq_num        = htonl(tcp_seqno);
2921                 pay->tcp.ack_num        = htonl(tcp_ack);
2922                 pay->tcp.hdr_length     = 0x50; /* 5 * 32 bit words */
2923                 pay->tcp.control        = tcp_ctl;
2924                 pay->tcp.window         = htons(0x7FFF);
2925                 pay->tcp.checksum       = htons(0x0000);
2926                 pay->tcp.urg            = htons(0x0000);
2927                 buf += SWRAP_PACKET_PAYLOAD_TCP_SIZE;
2928
2929                 break;
2930
2931         case SOCK_DGRAM:
2932                 pay->udp.source_port    = src_port;
2933                 pay->udp.dest_port      = dest_port;
2934                 pay->udp.length         = htons(8 + payload_len);
2935                 pay->udp.checksum       = htons(0x0000);
2936                 buf += SWRAP_PACKET_PAYLOAD_UDP_SIZE;
2937
2938                 break;
2939         }
2940
2941         if (payload && payload_len > 0) {
2942                 memcpy(buf, payload, payload_len);
2943         }
2944
2945         *_packet_len = packet_len - icmp_truncate_len;
2946         return base;
2947 }
2948
2949 static int swrap_pcap_get_fd(const char *fname)
2950 {
2951         static int fd = -1;
2952
2953         if (fd != -1) {
2954                 return fd;
2955         }
2956
2957         fd = libc_open(fname, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0644);
2958         if (fd != -1) {
2959                 struct swrap_file_hdr file_hdr;
2960                 file_hdr.magic          = 0xA1B2C3D4;
2961                 file_hdr.version_major  = 0x0002;
2962                 file_hdr.version_minor  = 0x0004;
2963                 file_hdr.timezone       = 0x00000000;
2964                 file_hdr.sigfigs        = 0x00000000;
2965                 file_hdr.frame_max_len  = SWRAP_FRAME_LENGTH_MAX;
2966                 file_hdr.link_type      = 0x0065; /* 101 RAW IP */
2967
2968                 if (libc_write(fd, &file_hdr, sizeof(file_hdr)) != sizeof(file_hdr)) {
2969                         libc_close(fd);
2970                         fd = -1;
2971                 }
2972                 return fd;
2973         }
2974
2975         fd = libc_open(fname, O_WRONLY|O_APPEND, 0644);
2976
2977         return fd;
2978 }
2979
2980 static uint8_t *swrap_pcap_marshall_packet(struct socket_info *si,
2981                                            const struct sockaddr *addr,
2982                                            enum swrap_packet_type type,
2983                                            const void *buf, size_t len,
2984                                            size_t *packet_len)
2985 {
2986         const struct sockaddr *src_addr;
2987         const struct sockaddr *dest_addr;
2988         unsigned long tcp_seqno = 0;
2989         unsigned long tcp_ack = 0;
2990         unsigned char tcp_ctl = 0;
2991         int unreachable = 0;
2992
2993         struct timeval tv;
2994
2995         switch (si->family) {
2996         case AF_INET:
2997                 break;
2998 #ifdef HAVE_IPV6
2999         case AF_INET6:
3000                 break;
3001 #endif
3002         default:
3003                 return NULL;
3004         }
3005
3006         switch (type) {
3007         case SWRAP_CONNECT_SEND:
3008                 if (si->type != SOCK_STREAM) {
3009                         return NULL;
3010                 }
3011
3012                 src_addr  = &si->myname.sa.s;
3013                 dest_addr = addr;
3014
3015                 tcp_seqno = si->io.pck_snd;
3016                 tcp_ack = si->io.pck_rcv;
3017                 tcp_ctl = 0x02; /* SYN */
3018
3019                 si->io.pck_snd += 1;
3020
3021                 break;
3022
3023         case SWRAP_CONNECT_RECV:
3024                 if (si->type != SOCK_STREAM) {
3025                         return NULL;
3026                 }
3027
3028                 dest_addr = &si->myname.sa.s;
3029                 src_addr = addr;
3030
3031                 tcp_seqno = si->io.pck_rcv;
3032                 tcp_ack = si->io.pck_snd;
3033                 tcp_ctl = 0x12; /** SYN,ACK */
3034
3035                 si->io.pck_rcv += 1;
3036
3037                 break;
3038
3039         case SWRAP_CONNECT_UNREACH:
3040                 if (si->type != SOCK_STREAM) {
3041                         return NULL;
3042                 }
3043
3044                 dest_addr = &si->myname.sa.s;
3045                 src_addr  = addr;
3046
3047                 /* Unreachable: resend the data of SWRAP_CONNECT_SEND */
3048                 tcp_seqno = si->io.pck_snd - 1;
3049                 tcp_ack = si->io.pck_rcv;
3050                 tcp_ctl = 0x02; /* SYN */
3051                 unreachable = 1;
3052
3053                 break;
3054
3055         case SWRAP_CONNECT_ACK:
3056                 if (si->type != SOCK_STREAM) {
3057                         return NULL;
3058                 }
3059
3060                 src_addr  = &si->myname.sa.s;
3061                 dest_addr = addr;
3062
3063                 tcp_seqno = si->io.pck_snd;
3064                 tcp_ack = si->io.pck_rcv;
3065                 tcp_ctl = 0x10; /* ACK */
3066
3067                 break;
3068
3069         case SWRAP_ACCEPT_SEND:
3070                 if (si->type != SOCK_STREAM) {
3071                         return NULL;
3072                 }
3073
3074                 dest_addr = &si->myname.sa.s;
3075                 src_addr = addr;
3076
3077                 tcp_seqno = si->io.pck_rcv;
3078                 tcp_ack = si->io.pck_snd;
3079                 tcp_ctl = 0x02; /* SYN */
3080
3081                 si->io.pck_rcv += 1;
3082
3083                 break;
3084
3085         case SWRAP_ACCEPT_RECV:
3086                 if (si->type != SOCK_STREAM) {
3087                         return NULL;
3088                 }
3089
3090                 src_addr = &si->myname.sa.s;
3091                 dest_addr = addr;
3092
3093                 tcp_seqno = si->io.pck_snd;
3094                 tcp_ack = si->io.pck_rcv;
3095                 tcp_ctl = 0x12; /* SYN,ACK */
3096
3097                 si->io.pck_snd += 1;
3098
3099                 break;
3100
3101         case SWRAP_ACCEPT_ACK:
3102                 if (si->type != SOCK_STREAM) {
3103                         return NULL;
3104                 }
3105
3106                 dest_addr = &si->myname.sa.s;
3107                 src_addr = addr;
3108
3109                 tcp_seqno = si->io.pck_rcv;
3110                 tcp_ack = si->io.pck_snd;
3111                 tcp_ctl = 0x10; /* ACK */
3112
3113                 break;
3114
3115         case SWRAP_SEND:
3116                 src_addr  = &si->myname.sa.s;
3117                 dest_addr = &si->peername.sa.s;
3118
3119                 tcp_seqno = si->io.pck_snd;
3120                 tcp_ack = si->io.pck_rcv;
3121                 tcp_ctl = 0x18; /* PSH,ACK */
3122
3123                 si->io.pck_snd += len;
3124
3125                 break;
3126
3127         case SWRAP_SEND_RST:
3128                 dest_addr = &si->myname.sa.s;
3129                 src_addr  = &si->peername.sa.s;
3130
3131                 if (si->type == SOCK_DGRAM) {
3132                         return swrap_pcap_marshall_packet(si,
3133                                                           &si->peername.sa.s,
3134                                                           SWRAP_SENDTO_UNREACH,
3135                                                           buf,
3136                                                           len,
3137                                                           packet_len);
3138                 }
3139
3140                 tcp_seqno = si->io.pck_rcv;
3141                 tcp_ack = si->io.pck_snd;
3142                 tcp_ctl = 0x14; /** RST,ACK */
3143
3144                 break;
3145
3146         case SWRAP_PENDING_RST:
3147                 dest_addr = &si->myname.sa.s;
3148                 src_addr  = &si->peername.sa.s;
3149
3150                 if (si->type == SOCK_DGRAM) {
3151                         return NULL;
3152                 }
3153
3154                 tcp_seqno = si->io.pck_rcv;
3155                 tcp_ack = si->io.pck_snd;
3156                 tcp_ctl = 0x14; /* RST,ACK */
3157
3158                 break;
3159
3160         case SWRAP_RECV:
3161                 dest_addr = &si->myname.sa.s;
3162                 src_addr  = &si->peername.sa.s;
3163
3164                 tcp_seqno = si->io.pck_rcv;
3165                 tcp_ack = si->io.pck_snd;
3166                 tcp_ctl = 0x18; /* PSH,ACK */
3167
3168                 si->io.pck_rcv += len;
3169
3170                 break;
3171
3172         case SWRAP_RECV_RST:
3173                 dest_addr = &si->myname.sa.s;
3174                 src_addr  = &si->peername.sa.s;
3175
3176                 if (si->type == SOCK_DGRAM) {
3177                         return NULL;
3178                 }
3179
3180                 tcp_seqno = si->io.pck_rcv;
3181                 tcp_ack = si->io.pck_snd;
3182                 tcp_ctl = 0x14; /* RST,ACK */
3183
3184                 break;
3185
3186         case SWRAP_SENDTO:
3187                 src_addr = &si->myname.sa.s;
3188                 dest_addr = addr;
3189
3190                 si->io.pck_snd += len;
3191
3192                 break;
3193
3194         case SWRAP_SENDTO_UNREACH:
3195                 dest_addr = &si->myname.sa.s;
3196                 src_addr = addr;
3197
3198                 unreachable = 1;
3199
3200                 break;
3201
3202         case SWRAP_RECVFROM:
3203                 dest_addr = &si->myname.sa.s;
3204                 src_addr = addr;
3205
3206                 si->io.pck_rcv += len;
3207
3208                 break;
3209
3210         case SWRAP_CLOSE_SEND:
3211                 if (si->type != SOCK_STREAM) {
3212                         return NULL;
3213                 }
3214
3215                 src_addr  = &si->myname.sa.s;
3216                 dest_addr = &si->peername.sa.s;
3217
3218                 tcp_seqno = si->io.pck_snd;
3219                 tcp_ack = si->io.pck_rcv;
3220                 tcp_ctl = 0x11; /* FIN, ACK */
3221
3222                 si->io.pck_snd += 1;
3223
3224                 break;
3225
3226         case SWRAP_CLOSE_RECV:
3227                 if (si->type != SOCK_STREAM) {
3228                         return NULL;
3229                 }
3230
3231                 dest_addr = &si->myname.sa.s;
3232                 src_addr  = &si->peername.sa.s;
3233
3234                 tcp_seqno = si->io.pck_rcv;
3235                 tcp_ack = si->io.pck_snd;
3236                 tcp_ctl = 0x11; /* FIN,ACK */
3237
3238                 si->io.pck_rcv += 1;
3239
3240                 break;
3241
3242         case SWRAP_CLOSE_ACK:
3243                 if (si->type != SOCK_STREAM) {
3244                         return NULL;
3245                 }
3246
3247                 src_addr  = &si->myname.sa.s;
3248                 dest_addr = &si->peername.sa.s;
3249
3250                 tcp_seqno = si->io.pck_snd;
3251                 tcp_ack = si->io.pck_rcv;
3252                 tcp_ctl = 0x10; /* ACK */
3253
3254                 break;
3255         default:
3256                 return NULL;
3257         }
3258
3259         swrapGetTimeOfDay(&tv);
3260
3261         return swrap_pcap_packet_init(&tv,
3262                                       src_addr,
3263                                       dest_addr,
3264                                       si->type,
3265                                       (const uint8_t *)buf,
3266                                       len,
3267                                       tcp_seqno,
3268                                       tcp_ack,
3269                                       tcp_ctl,
3270                                       unreachable,
3271                                       packet_len);
3272 }
3273
3274 static void swrap_pcap_dump_packet(struct socket_info *si,
3275                                    const struct sockaddr *addr,
3276                                    enum swrap_packet_type type,
3277                                    const void *buf, size_t len)
3278 {
3279         const char *file_name;
3280         uint8_t *packet;
3281         size_t packet_len = 0;
3282         int fd;
3283
3284         swrap_mutex_lock(&pcap_dump_mutex);
3285
3286         file_name = swrap_pcap_init_file();
3287         if (!file_name) {
3288                 goto done;
3289         }
3290
3291         packet = swrap_pcap_marshall_packet(si,
3292                                             addr,
3293                                             type,
3294                                             buf,
3295                                             len,
3296                                             &packet_len);
3297         if (packet == NULL) {
3298                 goto done;
3299         }
3300
3301         fd = swrap_pcap_get_fd(file_name);
3302         if (fd != -1) {
3303                 if (libc_write(fd, packet, packet_len) != (ssize_t)packet_len) {
3304                         free(packet);
3305                         goto done;
3306                 }
3307         }
3308
3309         free(packet);
3310
3311 done:
3312         swrap_mutex_unlock(&pcap_dump_mutex);
3313 }
3314
3315 /****************************************************************************
3316  *   SIGNALFD
3317  ***************************************************************************/
3318
3319 #ifdef HAVE_SIGNALFD
3320 static int swrap_signalfd(int fd, const sigset_t *mask, int flags)
3321 {
3322         int rc;
3323
3324         rc = libc_signalfd(fd, mask, flags);
3325         if (rc != -1) {
3326                 swrap_remove_stale(fd);
3327         }
3328
3329         return rc;
3330 }
3331
3332 int signalfd(int fd, const sigset_t *mask, int flags)
3333 {
3334         return swrap_signalfd(fd, mask, flags);
3335 }
3336 #endif
3337
3338 /****************************************************************************
3339  *   SOCKET
3340  ***************************************************************************/
3341
3342 static int swrap_socket(int family, int type, int protocol)
3343 {
3344         struct socket_info *si = NULL;
3345         struct socket_info _si = { 0 };
3346         int fd;
3347         int ret;
3348         int real_type = type;
3349
3350         /*
3351          * Remove possible addition flags passed to socket() so
3352          * do not fail checking the type.
3353          * See https://lwn.net/Articles/281965/
3354          */
3355 #ifdef SOCK_CLOEXEC
3356         real_type &= ~SOCK_CLOEXEC;
3357 #endif
3358 #ifdef SOCK_NONBLOCK
3359         real_type &= ~SOCK_NONBLOCK;
3360 #endif
3361
3362         if (!socket_wrapper_enabled()) {
3363                 return libc_socket(family, type, protocol);
3364         }
3365
3366         switch (family) {
3367         case AF_INET:
3368 #ifdef HAVE_IPV6
3369         case AF_INET6:
3370 #endif
3371                 break;
3372 #ifdef AF_NETLINK
3373         case AF_NETLINK:
3374 #endif /* AF_NETLINK */
3375 #ifdef AF_PACKET
3376         case AF_PACKET:
3377 #endif /* AF_PACKET */
3378         case AF_UNIX:
3379                 fd = libc_socket(family, type, protocol);
3380                 if (fd != -1) {
3381                         /* Check if we have a stale fd and remove it */
3382                         swrap_remove_stale(fd);
3383                         SWRAP_LOG(SWRAP_LOG_TRACE,
3384                                   "Unix socket fd=%d",
3385                                   fd);
3386                 }
3387                 return fd;
3388         default:
3389                 errno = EAFNOSUPPORT;
3390                 return -1;
3391         }
3392
3393         switch (real_type) {
3394         case SOCK_STREAM:
3395                 break;
3396         case SOCK_DGRAM:
3397                 break;
3398         default:
3399                 errno = EPROTONOSUPPORT;
3400                 return -1;
3401         }
3402
3403         switch (protocol) {
3404         case 0:
3405                 break;
3406         case 6:
3407                 if (real_type == SOCK_STREAM) {
3408                         break;
3409                 }
3410                 FALL_THROUGH;
3411         case 17:
3412                 if (real_type == SOCK_DGRAM) {
3413                         break;
3414                 }
3415                 FALL_THROUGH;
3416         default:
3417                 errno = EPROTONOSUPPORT;
3418                 return -1;
3419         }
3420
3421         /*
3422          * We must call libc_socket with type, from the caller, not the version
3423          * we removed SOCK_CLOEXEC and SOCK_NONBLOCK from
3424          */
3425         fd = libc_socket(AF_UNIX, type, 0);
3426
3427         if (fd == -1) {
3428                 return -1;
3429         }
3430
3431         /* Check if we have a stale fd and remove it */
3432         swrap_remove_stale(fd);
3433
3434         si = &_si;
3435         si->family = family;
3436
3437         /* however, the rest of the socket_wrapper code expects just
3438          * the type, not the flags */
3439         si->type = real_type;
3440         si->protocol = protocol;
3441
3442         /*
3443          * Setup myname so getsockname() can succeed to find out the socket
3444          * type.
3445          */
3446         switch(si->family) {
3447         case AF_INET: {
3448                 struct sockaddr_in sin = {
3449                         .sin_family = AF_INET,
3450                 };
3451
3452                 si->myname.sa_socklen = sizeof(struct sockaddr_in);
3453                 memcpy(&si->myname.sa.in, &sin, si->myname.sa_socklen);
3454                 break;
3455         }
3456 #ifdef HAVE_IPV6
3457         case AF_INET6: {
3458                 struct sockaddr_in6 sin6 = {
3459                         .sin6_family = AF_INET6,
3460                 };
3461
3462                 si->myname.sa_socklen = sizeof(struct sockaddr_in6);
3463                 memcpy(&si->myname.sa.in6, &sin6, si->myname.sa_socklen);
3464                 break;
3465         }
3466 #endif
3467         default:
3468                 errno = EINVAL;
3469                 return -1;
3470         }
3471
3472         ret = swrap_create_socket(si, fd);
3473         if (ret == -1) {
3474                 int saved_errno = errno;
3475                 libc_close(fd);
3476                 errno = saved_errno;
3477                 return -1;
3478         }
3479
3480         SWRAP_LOG(SWRAP_LOG_TRACE,
3481                   "Created %s socket for protocol %s, fd=%d",
3482                   family == AF_INET ? "IPv4" : "IPv6",
3483                   real_type == SOCK_DGRAM ? "UDP" : "TCP",
3484                   fd);
3485
3486         return fd;
3487 }
3488
3489 int socket(int family, int type, int protocol)
3490 {
3491         return swrap_socket(family, type, protocol);
3492 }
3493
3494 /****************************************************************************
3495  *   SOCKETPAIR
3496  ***************************************************************************/
3497
3498 static int swrap_socketpair(int family, int type, int protocol, int sv[2])
3499 {
3500         int rc;
3501
3502         rc = libc_socketpair(family, type, protocol, sv);
3503         if (rc != -1) {
3504                 swrap_remove_stale(sv[0]);
3505                 swrap_remove_stale(sv[1]);
3506         }
3507
3508         return rc;
3509 }
3510
3511 int socketpair(int family, int type, int protocol, int sv[2])
3512 {
3513         return swrap_socketpair(family, type, protocol, sv);
3514 }
3515
3516 /****************************************************************************
3517  *   SOCKETPAIR
3518  ***************************************************************************/
3519
3520 #ifdef HAVE_TIMERFD_CREATE
3521 static int swrap_timerfd_create(int clockid, int flags)
3522 {
3523         int fd;
3524
3525         fd = libc_timerfd_create(clockid, flags);
3526         if (fd != -1) {
3527                 swrap_remove_stale(fd);
3528         }
3529
3530         return fd;
3531 }
3532
3533 int timerfd_create(int clockid, int flags)
3534 {
3535         return swrap_timerfd_create(clockid, flags);
3536 }
3537 #endif
3538
3539 /****************************************************************************
3540  *   PIPE
3541  ***************************************************************************/
3542
3543 static int swrap_pipe(int pipefd[2])
3544 {
3545         int rc;
3546
3547         rc = libc_pipe(pipefd);
3548         if (rc != -1) {
3549                 swrap_remove_stale(pipefd[0]);
3550                 swrap_remove_stale(pipefd[1]);
3551         }
3552
3553         return rc;
3554 }
3555
3556 int pipe(int pipefd[2])
3557 {
3558         return swrap_pipe(pipefd);
3559 }
3560
3561 /****************************************************************************
3562  *   ACCEPT
3563  ***************************************************************************/
3564
3565 static int swrap_accept(int s,
3566                         struct sockaddr *addr,
3567                         socklen_t *addrlen,
3568                         int flags)
3569 {
3570         struct socket_info *parent_si, *child_si;
3571         struct socket_info new_si = { 0 };
3572         int fd;
3573         int idx;
3574         struct swrap_address un_addr = {
3575                 .sa_socklen = sizeof(struct sockaddr_un),
3576         };
3577         struct swrap_address un_my_addr = {
3578                 .sa_socklen = sizeof(struct sockaddr_un),
3579         };
3580         struct swrap_address in_addr = {
3581                 .sa_socklen = sizeof(struct sockaddr_storage),
3582         };
3583         struct swrap_address in_my_addr = {
3584                 .sa_socklen = sizeof(struct sockaddr_storage),
3585         };
3586         int ret;
3587
3588         parent_si = find_socket_info(s);
3589         if (!parent_si) {
3590 #ifdef HAVE_ACCEPT4
3591                 return libc_accept4(s, addr, addrlen, flags);
3592 #else
3593                 UNUSED(flags);
3594                 return libc_accept(s, addr, addrlen);
3595 #endif
3596         }
3597
3598
3599         /*
3600          * prevent parent_si from being altered / closed
3601          * while we read it
3602          */
3603         SWRAP_LOCK_SI(parent_si);
3604
3605         /*
3606          * assume out sockaddr have the same size as the in parent
3607          * socket family
3608          */
3609         in_addr.sa_socklen = socket_length(parent_si->family);
3610         if (in_addr.sa_socklen <= 0) {
3611                 SWRAP_UNLOCK_SI(parent_si);
3612                 errno = EINVAL;
3613                 return -1;
3614         }
3615
3616         SWRAP_UNLOCK_SI(parent_si);
3617
3618 #ifdef HAVE_ACCEPT4
3619         ret = libc_accept4(s, &un_addr.sa.s, &un_addr.sa_socklen, flags);
3620 #else
3621         UNUSED(flags);
3622         ret = libc_accept(s, &un_addr.sa.s, &un_addr.sa_socklen);
3623 #endif
3624         if (ret == -1) {
3625                 int saved_errno = errno;
3626                 if (saved_errno == ENOTSOCK) {
3627                         /* Remove stale fds */
3628                         swrap_remove_stale(s);
3629                 }
3630                 errno = saved_errno;
3631                 return ret;
3632         }
3633
3634         fd = ret;
3635
3636         /* Check if we have a stale fd and remove it */
3637         swrap_remove_stale(fd);
3638
3639         if (un_addr.sa.un.sun_path[0] == '\0') {
3640                 /*
3641                  * FreeBSD seems to have a problem where
3642                  * accept4() on the unix socket doesn't
3643                  * ECONNABORTED for already disconnected connections.
3644                  *
3645                  * Let's try libc_getpeername() to get the peer address
3646                  * as a fallback, but it'll likely return ENOTCONN,
3647                  * which we have to map to ECONNABORTED.
3648                  */
3649                 un_addr.sa_socklen = sizeof(struct sockaddr_un),
3650                 ret = libc_getpeername(fd, &un_addr.sa.s, &un_addr.sa_socklen);
3651                 if (ret == -1) {
3652                         int saved_errno = errno;
3653                         libc_close(fd);
3654                         if (saved_errno == ENOTCONN) {
3655                                 /*
3656                                  * If the connection is already disconnected
3657                                  * we should return ECONNABORTED.
3658                                  */
3659                                 saved_errno = ECONNABORTED;
3660                         }
3661                         errno = saved_errno;
3662                         return ret;
3663                 }
3664         }
3665
3666         ret = libc_getsockname(fd,
3667                                &un_my_addr.sa.s,
3668                                &un_my_addr.sa_socklen);
3669         if (ret == -1) {
3670                 int saved_errno = errno;
3671                 libc_close(fd);
3672                 if (saved_errno == ENOTCONN) {
3673                         /*
3674                          * If the connection is already disconnected
3675                          * we should return ECONNABORTED.
3676                          */
3677                         saved_errno = ECONNABORTED;
3678                 }
3679                 errno = saved_errno;
3680                 return ret;
3681         }
3682
3683         SWRAP_LOCK_SI(parent_si);
3684
3685         ret = sockaddr_convert_from_un(parent_si,
3686                                        &un_addr.sa.un,
3687                                        un_addr.sa_socklen,
3688                                        parent_si->family,
3689                                        &in_addr.sa.s,
3690                                        &in_addr.sa_socklen);
3691         if (ret == -1) {
3692                 int saved_errno = errno;
3693                 SWRAP_UNLOCK_SI(parent_si);
3694                 libc_close(fd);
3695                 errno = saved_errno;
3696                 return ret;
3697         }
3698
3699         child_si = &new_si;
3700
3701         child_si->family = parent_si->family;
3702         child_si->type = parent_si->type;
3703         child_si->protocol = parent_si->protocol;
3704         child_si->bound = 1;
3705         child_si->is_server = 1;
3706         child_si->connected = 1;
3707
3708         SWRAP_UNLOCK_SI(parent_si);
3709
3710         child_si->peername = (struct swrap_address) {
3711                 .sa_socklen = in_addr.sa_socklen,
3712         };
3713         memcpy(&child_si->peername.sa.ss, &in_addr.sa.ss, in_addr.sa_socklen);
3714
3715         if (addr != NULL && addrlen != NULL) {
3716                 size_t copy_len = MIN(*addrlen, in_addr.sa_socklen);
3717                 if (copy_len > 0) {
3718                         memcpy(addr, &in_addr.sa.ss, copy_len);
3719                 }
3720                 *addrlen = in_addr.sa_socklen;
3721         }
3722
3723         ret = sockaddr_convert_from_un(child_si,
3724                                        &un_my_addr.sa.un,
3725                                        un_my_addr.sa_socklen,
3726                                        child_si->family,
3727                                        &in_my_addr.sa.s,
3728                                        &in_my_addr.sa_socklen);
3729         if (ret == -1) {
3730                 int saved_errno = errno;
3731                 libc_close(fd);
3732                 errno = saved_errno;
3733                 return ret;
3734         }
3735
3736         SWRAP_LOG(SWRAP_LOG_TRACE,
3737                   "accept() path=%s, fd=%d",
3738                   un_my_addr.sa.un.sun_path, s);
3739
3740         child_si->myname = (struct swrap_address) {
3741                 .sa_socklen = in_my_addr.sa_socklen,
3742         };
3743         memcpy(&child_si->myname.sa.ss, &in_my_addr.sa.ss, in_my_addr.sa_socklen);
3744
3745         idx = swrap_create_socket(&new_si, fd);
3746         if (idx == -1) {
3747                 int saved_errno = errno;
3748                 libc_close(fd);
3749                 errno = saved_errno;
3750                 return -1;
3751         }
3752
3753         if (addr != NULL) {
3754                 struct socket_info *si = swrap_get_socket_info(idx);
3755
3756                 SWRAP_LOCK_SI(si);
3757                 swrap_pcap_dump_packet(si, addr, SWRAP_ACCEPT_SEND, NULL, 0);
3758                 swrap_pcap_dump_packet(si, addr, SWRAP_ACCEPT_RECV, NULL, 0);
3759                 swrap_pcap_dump_packet(si, addr, SWRAP_ACCEPT_ACK, NULL, 0);
3760                 SWRAP_UNLOCK_SI(si);
3761         }
3762
3763         return fd;
3764 }
3765
3766 #ifdef HAVE_ACCEPT4
3767 int accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags)
3768 {
3769         return swrap_accept(s, addr, (socklen_t *)addrlen, flags);
3770 }
3771 #endif
3772
3773 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3774 int accept(int s, struct sockaddr *addr, Psocklen_t addrlen)
3775 #else
3776 int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
3777 #endif
3778 {
3779         return swrap_accept(s, addr, (socklen_t *)addrlen, 0);
3780 }
3781
3782 static int autobind_start_init;
3783 static int autobind_start;
3784
3785 /* using sendto() or connect() on an unbound socket would give the
3786    recipient no way to reply, as unlike UDP and TCP, a unix domain
3787    socket can't auto-assign ephemeral port numbers, so we need to
3788    assign it here.
3789    Note: this might change the family from ipv6 to ipv4
3790 */
3791 static int swrap_auto_bind(int fd, struct socket_info *si, int family)
3792 {
3793         struct swrap_address un_addr = {
3794                 .sa_socklen = sizeof(struct sockaddr_un),
3795         };
3796         int i;
3797         char type;
3798         int ret;
3799         int port;
3800         struct stat st;
3801         char *swrap_dir = NULL;
3802
3803         swrap_mutex_lock(&autobind_start_mutex);
3804
3805         if (autobind_start_init != 1) {
3806                 autobind_start_init = 1;
3807                 autobind_start = getpid();
3808                 autobind_start %= 50000;
3809                 autobind_start += 10000;
3810         }
3811
3812         un_addr.sa.un.sun_family = AF_UNIX;
3813
3814         switch (family) {
3815         case AF_INET: {
3816                 struct sockaddr_in in;
3817
3818                 switch (si->type) {
3819                 case SOCK_STREAM:
3820                         type = SOCKET_TYPE_CHAR_TCP;
3821                         break;
3822                 case SOCK_DGRAM:
3823                         type = SOCKET_TYPE_CHAR_UDP;
3824                         break;
3825                 default:
3826                         errno = ESOCKTNOSUPPORT;
3827                         ret = -1;
3828                         goto done;
3829                 }
3830
3831                 memset(&in, 0, sizeof(in));
3832                 in.sin_family = AF_INET;
3833                 in.sin_addr.s_addr = htonl(swrap_ipv4_iface(
3834                                            socket_wrapper_default_iface()));
3835
3836                 si->myname = (struct swrap_address) {
3837                         .sa_socklen = sizeof(in),
3838                 };
3839                 memcpy(&si->myname.sa.in, &in, si->myname.sa_socklen);
3840                 break;
3841         }
3842 #ifdef HAVE_IPV6
3843         case AF_INET6: {
3844                 struct sockaddr_in6 in6;
3845
3846                 if (si->family != family) {
3847                         errno = ENETUNREACH;
3848                         ret = -1;
3849                         goto done;
3850                 }
3851
3852                 switch (si->type) {
3853                 case SOCK_STREAM:
3854                         type = SOCKET_TYPE_CHAR_TCP_V6;
3855                         break;
3856                 case SOCK_DGRAM:
3857                         type = SOCKET_TYPE_CHAR_UDP_V6;
3858                         break;
3859                 default:
3860                         errno = ESOCKTNOSUPPORT;
3861                         ret = -1;
3862                         goto done;
3863                 }
3864
3865                 memset(&in6, 0, sizeof(in6));
3866                 in6.sin6_family = AF_INET6;
3867                 in6.sin6_addr = *swrap_ipv6();
3868                 in6.sin6_addr.s6_addr[15] = socket_wrapper_default_iface();
3869
3870                 si->myname = (struct swrap_address) {
3871                         .sa_socklen = sizeof(in6),
3872                 };
3873                 memcpy(&si->myname.sa.in6, &in6, si->myname.sa_socklen);
3874                 break;
3875         }
3876 #endif
3877         default:
3878                 errno = ESOCKTNOSUPPORT;
3879                 ret = -1;
3880                 goto done;
3881         }
3882
3883         if (autobind_start > 60000) {
3884                 autobind_start = 10000;
3885         }
3886
3887         swrap_dir = socket_wrapper_dir();
3888         if (swrap_dir == NULL) {
3889                 errno = EINVAL;
3890                 ret = -1;
3891                 goto done;
3892         }
3893
3894         for (i = 0; i < SOCKET_MAX_SOCKETS; i++) {
3895                 port = autobind_start + i;
3896                 swrap_un_path(&un_addr.sa.un,
3897                               swrap_dir,
3898                               type,
3899                               socket_wrapper_default_iface(),
3900                               port);
3901                 if (stat(un_addr.sa.un.sun_path, &st) == 0) continue;
3902
3903                 ret = libc_bind(fd, &un_addr.sa.s, un_addr.sa_socklen);
3904                 if (ret == -1) {
3905                         goto done;
3906                 }
3907
3908                 si->un_addr = un_addr.sa.un;
3909
3910                 si->bound = 1;
3911                 autobind_start = port + 1;
3912                 break;
3913         }
3914         if (i == SOCKET_MAX_SOCKETS) {
3915                 SWRAP_LOG(SWRAP_LOG_ERROR, "Too many open unix sockets (%u) for "
3916                                            "interface "SOCKET_FORMAT,
3917                                            SOCKET_MAX_SOCKETS,
3918                                            type,
3919                                            socket_wrapper_default_iface(),
3920                                            0);
3921                 errno = ENFILE;
3922                 ret = -1;
3923                 goto done;
3924         }
3925
3926         si->family = family;
3927         set_port(si->family, port, &si->myname);
3928
3929         ret = 0;
3930
3931 done:
3932         SAFE_FREE(swrap_dir);
3933         swrap_mutex_unlock(&autobind_start_mutex);
3934         return ret;
3935 }
3936
3937 /****************************************************************************
3938  *   CONNECT
3939  ***************************************************************************/
3940
3941 static int swrap_connect(int s, const struct sockaddr *serv_addr,
3942                          socklen_t addrlen)
3943 {
3944         int ret;
3945         struct swrap_address un_addr = {
3946                 .sa_socklen = sizeof(struct sockaddr_un),
3947         };
3948         struct socket_info *si = find_socket_info(s);
3949         int bcast = 0;
3950
3951         if (!si) {
3952                 return libc_connect(s, serv_addr, addrlen);
3953         }
3954
3955         SWRAP_LOCK_SI(si);
3956
3957         if (si->bound == 0) {
3958                 ret = swrap_auto_bind(s, si, serv_addr->sa_family);
3959                 if (ret == -1) {
3960                         goto done;
3961                 }
3962         }
3963
3964         if (si->family != serv_addr->sa_family) {
3965                 SWRAP_LOG(SWRAP_LOG_ERROR,
3966                           "called for fd=%d (family=%d) called with invalid family=%d",
3967                           s, si->family, serv_addr->sa_family);
3968                 errno = EINVAL;
3969                 ret = -1;
3970                 goto done;
3971         }
3972
3973         ret = sockaddr_convert_to_un(si, serv_addr,
3974                                      addrlen, &un_addr.sa.un, 0, &bcast);
3975         if (ret == -1) {
3976                 goto done;
3977         }
3978
3979         if (bcast) {
3980                 errno = ENETUNREACH;
3981                 ret = -1;
3982                 goto done;
3983         }
3984
3985         if (si->type == SOCK_DGRAM) {
3986                 si->defer_connect = 1;
3987                 ret = 0;
3988         } else {
3989                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0);
3990
3991                 ret = libc_connect(s,
3992                                    &un_addr.sa.s,
3993                                    un_addr.sa_socklen);
3994         }
3995
3996         SWRAP_LOG(SWRAP_LOG_TRACE,
3997                   "connect() path=%s, fd=%d",
3998                   un_addr.sa.un.sun_path, s);
3999
4000
4001         /* to give better errors */
4002         if (ret == -1 && errno == ENOENT) {
4003                 errno = EHOSTUNREACH;
4004         }
4005
4006         if (ret == 0) {
4007                 si->peername = (struct swrap_address) {
4008                         .sa_socklen = addrlen,
4009                 };
4010
4011                 memcpy(&si->peername.sa.ss, serv_addr, addrlen);
4012                 si->connected = 1;
4013
4014                 /*
4015                  * When we connect() on a socket than we have to bind the
4016                  * outgoing connection on the interface we use for the
4017                  * transport. We already bound it on the right interface
4018                  * but here we have to update the name so getsockname()
4019                  * returns correct information.
4020                  */
4021                 if (si->bindname.sa_socklen > 0) {
4022                         si->myname = (struct swrap_address) {
4023                                 .sa_socklen = si->bindname.sa_socklen,
4024                         };
4025
4026                         memcpy(&si->myname.sa.ss,
4027                                &si->bindname.sa.ss,
4028                                si->bindname.sa_socklen);
4029
4030                         /* Cleanup bindname */
4031                         si->bindname = (struct swrap_address) {
4032                                 .sa_socklen = 0,
4033                         };
4034                 }
4035
4036                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0);
4037                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0);
4038         } else {
4039                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0);
4040         }
4041
4042 done:
4043         SWRAP_UNLOCK_SI(si);
4044         return ret;
4045 }
4046
4047 int connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen)
4048 {
4049         return swrap_connect(s, serv_addr, addrlen);
4050 }
4051
4052 /****************************************************************************
4053  *   BIND
4054  ***************************************************************************/
4055
4056 static int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
4057 {
4058         int ret;
4059         struct swrap_address un_addr = {
4060                 .sa_socklen = sizeof(struct sockaddr_un),
4061         };
4062         struct socket_info *si = find_socket_info(s);
4063         int bind_error = 0;
4064 #if 0 /* FIXME */
4065         bool in_use;
4066 #endif
4067
4068         if (!si) {
4069                 return libc_bind(s, myaddr, addrlen);
4070         }
4071
4072         SWRAP_LOCK_SI(si);
4073
4074         switch (si->family) {
4075         case AF_INET: {
4076                 const struct sockaddr_in *sin;
4077                 if (addrlen < sizeof(struct sockaddr_in)) {
4078                         bind_error = EINVAL;
4079                         break;
4080                 }
4081
4082                 sin = (const struct sockaddr_in *)(const void *)myaddr;
4083
4084                 if (sin->sin_family != AF_INET) {
4085                         bind_error = EAFNOSUPPORT;
4086                 }
4087
4088                 /* special case for AF_UNSPEC */
4089                 if (sin->sin_family == AF_UNSPEC &&
4090                     (sin->sin_addr.s_addr == htonl(INADDR_ANY)))
4091                 {
4092                         bind_error = 0;
4093                 }
4094
4095                 break;
4096         }
4097 #ifdef HAVE_IPV6
4098         case AF_INET6: {
4099                 const struct sockaddr_in6 *sin6;
4100                 if (addrlen < sizeof(struct sockaddr_in6)) {
4101                         bind_error = EINVAL;
4102                         break;
4103                 }
4104
4105                 sin6 = (const struct sockaddr_in6 *)(const void *)myaddr;
4106
4107                 if (sin6->sin6_family != AF_INET6) {
4108                         bind_error = EAFNOSUPPORT;
4109                 }
4110
4111                 break;
4112         }
4113 #endif
4114         default:
4115                 bind_error = EINVAL;
4116                 break;
4117         }
4118
4119         if (bind_error != 0) {
4120                 errno = bind_error;
4121                 ret = -1;
4122                 goto out;
4123         }
4124
4125 #if 0 /* FIXME */
4126         in_use = check_addr_port_in_use(myaddr, addrlen);
4127         if (in_use) {
4128                 errno = EADDRINUSE;
4129                 ret = -1;
4130                 goto out;
4131         }
4132 #endif
4133
4134         si->myname.sa_socklen = addrlen;
4135         memcpy(&si->myname.sa.ss, myaddr, addrlen);
4136
4137         ret = sockaddr_convert_to_un(si,
4138                                      myaddr,
4139                                      addrlen,
4140                                      &un_addr.sa.un,
4141                                      1,
4142                                      &si->bcast);
4143         if (ret == -1) {
4144                 goto out;
4145         }
4146
4147         unlink(un_addr.sa.un.sun_path);
4148
4149         ret = libc_bind(s, &un_addr.sa.s, un_addr.sa_socklen);
4150
4151         SWRAP_LOG(SWRAP_LOG_TRACE,
4152                   "bind() path=%s, fd=%d",
4153                   un_addr.sa.un.sun_path, s);
4154
4155         if (ret == 0) {
4156                 si->bound = 1;
4157         }
4158
4159 out:
4160         SWRAP_UNLOCK_SI(si);
4161
4162         return ret;
4163 }
4164
4165 int bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
4166 {
4167         return swrap_bind(s, myaddr, addrlen);
4168 }
4169
4170 /****************************************************************************
4171  *   BINDRESVPORT
4172  ***************************************************************************/
4173
4174 #ifdef HAVE_BINDRESVPORT
4175 static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen);
4176
4177 static int swrap_bindresvport_sa(int sd, struct sockaddr *sa)
4178 {
4179         struct swrap_address myaddr = {
4180                 .sa_socklen = sizeof(struct sockaddr_storage),
4181         };
4182         socklen_t salen;
4183         static uint16_t port;
4184         uint16_t i;
4185         int rc = -1;
4186         int af;
4187
4188 #define SWRAP_STARTPORT 600
4189 #define SWRAP_ENDPORT (IPPORT_RESERVED - 1)
4190 #define SWRAP_NPORTS (SWRAP_ENDPORT - SWRAP_STARTPORT + 1)
4191
4192         if (port == 0) {
4193                 port = (getpid() % SWRAP_NPORTS) + SWRAP_STARTPORT;
4194         }
4195
4196         if (sa == NULL) {
4197                 salen = myaddr.sa_socklen;
4198                 sa = &myaddr.sa.s;
4199
4200                 rc = swrap_getsockname(sd, &myaddr.sa.s, &salen);
4201                 if (rc < 0) {
4202                         return -1;
4203                 }
4204
4205                 af = sa->sa_family;
4206                 memset(&myaddr.sa.ss, 0, salen);
4207         } else {
4208                 af = sa->sa_family;
4209         }
4210
4211         for (i = 0; i < SWRAP_NPORTS; i++, port++) {
4212                 switch(af) {
4213                 case AF_INET: {
4214                         struct sockaddr_in *sinp = (struct sockaddr_in *)(void *)sa;
4215
4216                         salen = sizeof(struct sockaddr_in);
4217                         sinp->sin_port = htons(port);
4218                         break;
4219                 }
4220                 case AF_INET6: {
4221                         struct sockaddr_in6 *sin6p = (struct sockaddr_in6 *)(void *)sa;
4222
4223                         salen = sizeof(struct sockaddr_in6);
4224                         sin6p->sin6_port = htons(port);
4225                         break;
4226                 }
4227                 default:
4228                         errno = EAFNOSUPPORT;
4229                         return -1;
4230                 }
4231                 sa->sa_family = af;
4232
4233                 if (port > SWRAP_ENDPORT) {
4234                         port = SWRAP_STARTPORT;
4235                 }
4236
4237                 rc = swrap_bind(sd, (struct sockaddr *)sa, salen);
4238                 if (rc == 0 || errno != EADDRINUSE) {
4239                         break;
4240                 }
4241         }
4242
4243         return rc;
4244 }
4245
4246 int bindresvport(int sockfd, struct sockaddr_in *sinp)
4247 {
4248         return swrap_bindresvport_sa(sockfd, (struct sockaddr *)sinp);
4249 }
4250 #endif
4251
4252 /****************************************************************************
4253  *   LISTEN
4254  ***************************************************************************/
4255
4256 static int swrap_listen(int s, int backlog)
4257 {
4258         int ret;
4259         struct socket_info *si = find_socket_info(s);
4260
4261         if (!si) {
4262                 return libc_listen(s, backlog);
4263         }
4264
4265         SWRAP_LOCK_SI(si);
4266
4267         if (si->bound == 0) {
4268                 ret = swrap_auto_bind(s, si, si->family);
4269                 if (ret == -1) {
4270                         errno = EADDRINUSE;
4271                         goto out;
4272                 }
4273         }
4274
4275         ret = libc_listen(s, backlog);
4276         if (ret == 0) {
4277                 si->listening = 1;
4278         }
4279
4280 out:
4281         SWRAP_UNLOCK_SI(si);
4282
4283         return ret;
4284 }
4285
4286 int listen(int s, int backlog)
4287 {
4288         return swrap_listen(s, backlog);
4289 }
4290
4291 /****************************************************************************
4292  *   FOPEN
4293  ***************************************************************************/
4294
4295 static FILE *swrap_fopen(const char *name, const char *mode)
4296 {
4297         FILE *fp;
4298
4299         fp = libc_fopen(name, mode);
4300         if (fp != NULL) {
4301                 int fd = fileno(fp);
4302
4303                 swrap_remove_stale(fd);
4304         }
4305
4306         return fp;
4307 }
4308
4309 FILE *fopen(const char *name, const char *mode)
4310 {
4311         return swrap_fopen(name, mode);
4312 }
4313
4314 /****************************************************************************
4315  *   FOPEN64
4316  ***************************************************************************/
4317
4318 #ifdef HAVE_FOPEN64
4319 static FILE *swrap_fopen64(const char *name, const char *mode)
4320 {
4321         FILE *fp;
4322
4323         fp = libc_fopen64(name, mode);
4324         if (fp != NULL) {
4325                 int fd = fileno(fp);
4326
4327                 swrap_remove_stale(fd);
4328         }
4329
4330         return fp;
4331 }
4332
4333 FILE *fopen64(const char *name, const char *mode)
4334 {
4335         return swrap_fopen64(name, mode);
4336 }
4337 #endif /* HAVE_FOPEN64 */
4338
4339 /****************************************************************************
4340  *   OPEN
4341  ***************************************************************************/
4342
4343 static int swrap_vopen(const char *pathname, int flags, va_list ap)
4344 {
4345         int ret;
4346
4347         ret = libc_vopen(pathname, flags, ap);
4348         if (ret != -1) {
4349                 /*
4350                  * There are methods for closing descriptors (libc-internal code
4351                  * paths, direct syscalls) which close descriptors in ways that
4352                  * we can't intercept, so try to recover when we notice that
4353                  * that's happened
4354                  */
4355                 swrap_remove_stale(ret);
4356         }
4357         return ret;
4358 }
4359
4360 int open(const char *pathname, int flags, ...)
4361 {
4362         va_list ap;
4363         int fd;
4364
4365         va_start(ap, flags);
4366         fd = swrap_vopen(pathname, flags, ap);
4367         va_end(ap);
4368
4369         return fd;
4370 }
4371
4372 /****************************************************************************
4373  *   OPEN64
4374  ***************************************************************************/
4375
4376 #ifdef HAVE_OPEN64
4377 static int swrap_vopen64(const char *pathname, int flags, va_list ap)
4378 {
4379         int ret;
4380
4381         ret = libc_vopen64(pathname, flags, ap);
4382         if (ret != -1) {
4383                 /*
4384                  * There are methods for closing descriptors (libc-internal code
4385                  * paths, direct syscalls) which close descriptors in ways that
4386                  * we can't intercept, so try to recover when we notice that
4387                  * that's happened
4388                  */
4389                 swrap_remove_stale(ret);
4390         }
4391         return ret;
4392 }
4393
4394 int open64(const char *pathname, int flags, ...)
4395 {
4396         va_list ap;
4397         int fd;
4398
4399         va_start(ap, flags);
4400         fd = swrap_vopen64(pathname, flags, ap);
4401         va_end(ap);
4402
4403         return fd;
4404 }
4405 #endif /* HAVE_OPEN64 */
4406
4407 /****************************************************************************
4408  *   OPENAT
4409  ***************************************************************************/
4410
4411 static int swrap_vopenat(int dirfd, const char *path, int flags, va_list ap)
4412 {
4413         int ret;
4414
4415         ret = libc_vopenat(dirfd, path, flags, ap);
4416         if (ret != -1) {
4417                 /*
4418                  * There are methods for closing descriptors (libc-internal code
4419                  * paths, direct syscalls) which close descriptors in ways that
4420                  * we can't intercept, so try to recover when we notice that
4421                  * that's happened
4422                  */
4423                 swrap_remove_stale(ret);
4424         }
4425
4426         return ret;
4427 }
4428
4429 int openat(int dirfd, const char *path, int flags, ...)
4430 {
4431         va_list ap;
4432         int fd;
4433
4434         va_start(ap, flags);
4435         fd = swrap_vopenat(dirfd, path, flags, ap);
4436         va_end(ap);
4437
4438         return fd;
4439 }
4440
4441 /****************************************************************************
4442  *   GETPEERNAME
4443  ***************************************************************************/
4444
4445 static int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
4446 {
4447         struct socket_info *si = find_socket_info(s);
4448         socklen_t len;
4449         int ret = -1;
4450
4451         if (!si) {
4452                 return libc_getpeername(s, name, addrlen);
4453         }
4454
4455         SWRAP_LOCK_SI(si);
4456
4457         if (si->peername.sa_socklen == 0)
4458         {
4459                 errno = ENOTCONN;
4460                 goto out;
4461         }
4462
4463         len = MIN(*addrlen, si->peername.sa_socklen);
4464         if (len == 0) {
4465                 ret = 0;
4466                 goto out;
4467         }
4468
4469         memcpy(name, &si->peername.sa.ss, len);
4470         *addrlen = si->peername.sa_socklen;
4471
4472         ret = 0;
4473 out:
4474         SWRAP_UNLOCK_SI(si);
4475
4476         return ret;
4477 }
4478
4479 #ifdef HAVE_ACCEPT_PSOCKLEN_T
4480 int getpeername(int s, struct sockaddr *name, Psocklen_t addrlen)
4481 #else
4482 int getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
4483 #endif
4484 {
4485         return swrap_getpeername(s, name, (socklen_t *)addrlen);
4486 }
4487
4488 /****************************************************************************
4489  *   GETSOCKNAME
4490  ***************************************************************************/
4491
4492 static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
4493 {
4494         struct socket_info *si = find_socket_info(s);
4495         socklen_t len;
4496         int ret = -1;
4497
4498         if (!si) {
4499                 return libc_getsockname(s, name, addrlen);
4500         }
4501
4502         SWRAP_LOCK_SI(si);
4503
4504         len = MIN(*addrlen, si->myname.sa_socklen);
4505         if (len == 0) {
4506                 ret = 0;
4507                 goto out;
4508         }
4509
4510         memcpy(name, &si->myname.sa.ss, len);
4511         *addrlen = si->myname.sa_socklen;
4512
4513         ret = 0;
4514 out:
4515         SWRAP_UNLOCK_SI(si);
4516
4517         return ret;
4518 }
4519
4520 #ifdef HAVE_ACCEPT_PSOCKLEN_T
4521 int getsockname(int s, struct sockaddr *name, Psocklen_t addrlen)
4522 #else
4523 int getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
4524 #endif
4525 {
4526         return swrap_getsockname(s, name, (socklen_t *)addrlen);
4527 }
4528
4529 /****************************************************************************
4530  *   GETSOCKOPT
4531  ***************************************************************************/
4532
4533 #ifndef SO_PROTOCOL
4534 # ifdef SO_PROTOTYPE /* The Solaris name */
4535 #  define SO_PROTOCOL SO_PROTOTYPE
4536 # endif /* SO_PROTOTYPE */
4537 #endif /* SO_PROTOCOL */
4538
4539 static int swrap_getsockopt(int s, int level, int optname,
4540                             void *optval, socklen_t *optlen)
4541 {
4542         struct socket_info *si = find_socket_info(s);
4543         int ret;
4544
4545         if (!si) {
4546                 return libc_getsockopt(s,
4547                                        level,
4548                                        optname,
4549                                        optval,
4550                                        optlen);
4551         }
4552
4553         SWRAP_LOCK_SI(si);
4554
4555         if (level == SOL_SOCKET) {
4556                 switch (optname) {
4557 #ifdef SO_DOMAIN
4558                 case SO_DOMAIN:
4559                         if (optval == NULL || optlen == NULL ||
4560                             *optlen < (socklen_t)sizeof(int)) {
4561                                 errno = EINVAL;
4562                                 ret = -1;
4563                                 goto done;
4564                         }
4565
4566                         *optlen = sizeof(int);
4567                         *(int *)optval = si->family;
4568                         ret = 0;
4569                         goto done;
4570 #endif /* SO_DOMAIN */
4571
4572 #ifdef SO_PROTOCOL
4573                 case SO_PROTOCOL:
4574                         if (optval == NULL || optlen == NULL ||
4575                             *optlen < (socklen_t)sizeof(int)) {
4576                                 errno = EINVAL;
4577                                 ret = -1;
4578                                 goto done;
4579                         }
4580
4581                         *optlen = sizeof(int);
4582                         *(int *)optval = si->protocol;
4583                         ret = 0;
4584                         goto done;
4585 #endif /* SO_PROTOCOL */
4586                 case SO_TYPE:
4587                         if (optval == NULL || optlen == NULL ||
4588                             *optlen < (socklen_t)sizeof(int)) {
4589                                 errno = EINVAL;
4590                                 ret = -1;
4591                                 goto done;
4592                         }
4593
4594                         *optlen = sizeof(int);
4595                         *(int *)optval = si->type;
4596                         ret = 0;
4597                         goto done;
4598                 default:
4599                         ret = libc_getsockopt(s,
4600                                               level,
4601                                               optname,
4602                                               optval,
4603                                               optlen);
4604                         goto done;
4605                 }
4606         } else if (level == IPPROTO_TCP) {
4607                 switch (optname) {
4608 #ifdef TCP_NODELAY
4609                 case TCP_NODELAY:
4610                         /*
4611                          * This enables sending packets directly out over TCP.
4612                          * As a unix socket is doing that any way, report it as
4613                          * enabled.
4614                          */
4615                         if (optval == NULL || optlen == NULL ||
4616                             *optlen < (socklen_t)sizeof(int)) {
4617                                 errno = EINVAL;
4618                                 ret = -1;
4619                                 goto done;
4620                         }
4621
4622                         *optlen = sizeof(int);
4623                         *(int *)optval = si->tcp_nodelay;
4624
4625                         ret = 0;
4626                         goto done;
4627 #endif /* TCP_NODELAY */
4628 #ifdef TCP_INFO
4629                 case TCP_INFO: {
4630                         struct tcp_info info;
4631                         socklen_t ilen = sizeof(info);
4632
4633 #ifdef HAVE_NETINET_TCP_FSM_H
4634 /* This is FreeBSD */
4635 # define __TCP_LISTEN TCPS_LISTEN
4636 # define __TCP_ESTABLISHED TCPS_ESTABLISHED
4637 # define __TCP_CLOSE TCPS_CLOSED
4638 #else
4639 /* This is Linux */
4640 # define __TCP_LISTEN TCP_LISTEN
4641 # define __TCP_ESTABLISHED TCP_ESTABLISHED
4642 # define __TCP_CLOSE TCP_CLOSE
4643 #endif
4644
4645                         ZERO_STRUCT(info);
4646                         if (si->listening) {
4647                                 info.tcpi_state = __TCP_LISTEN;
4648                         } else if (si->connected) {
4649                                 /*
4650                                  * For now we just fake a few values
4651                                  * supported both by FreeBSD and Linux
4652                                  */
4653                                 info.tcpi_state = __TCP_ESTABLISHED;
4654                                 info.tcpi_rto = 200000;  /* 200 msec */
4655                                 info.tcpi_rtt = 5000;    /* 5 msec */
4656                                 info.tcpi_rttvar = 5000; /* 5 msec */
4657                         } else {
4658                                 info.tcpi_state = __TCP_CLOSE;
4659                                 info.tcpi_rto = 1000000;  /* 1 sec */
4660                                 info.tcpi_rtt = 0;
4661                                 info.tcpi_rttvar = 250000; /* 250 msec */
4662                         }
4663
4664                         if (optval == NULL || optlen == NULL ||
4665                             *optlen < (socklen_t)ilen) {
4666                                 errno = EINVAL;
4667                                 ret = -1;
4668                                 goto done;
4669                         }
4670
4671                         *optlen = ilen;
4672                         memcpy(optval, &info, ilen);
4673
4674                         ret = 0;
4675                         goto done;
4676                 }
4677 #endif /* TCP_INFO */
4678                 default:
4679                         break;
4680                 }
4681         }
4682
4683         errno = ENOPROTOOPT;
4684         ret = -1;
4685
4686 done:
4687         SWRAP_UNLOCK_SI(si);
4688         return ret;
4689 }
4690
4691 #ifdef HAVE_ACCEPT_PSOCKLEN_T
4692 int getsockopt(int s, int level, int optname, void *optval, Psocklen_t optlen)
4693 #else
4694 int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
4695 #endif
4696 {
4697         return swrap_getsockopt(s, level, optname, optval, (socklen_t *)optlen);
4698 }
4699
4700 /****************************************************************************
4701  *   SETSOCKOPT
4702  ***************************************************************************/
4703
4704 static int swrap_setsockopt(int s, int level, int optname,
4705                             const void *optval, socklen_t optlen)
4706 {
4707         struct socket_info *si = find_socket_info(s);
4708         int ret;
4709
4710         if (!si) {
4711                 return libc_setsockopt(s,
4712                                        level,
4713                                        optname,
4714                                        optval,
4715                                        optlen);
4716         }
4717
4718         if (level == SOL_SOCKET) {
4719                 return libc_setsockopt(s,
4720                                        level,
4721                                        optname,
4722                                        optval,
4723                                        optlen);
4724         }
4725
4726         SWRAP_LOCK_SI(si);
4727
4728         if (level == IPPROTO_TCP) {
4729                 switch (optname) {
4730 #ifdef TCP_NODELAY
4731                 case TCP_NODELAY: {
4732                         int i;
4733
4734                         /*
4735                          * This enables sending packets directly out over TCP.
4736                          * A unix socket is doing that any way.
4737                          */
4738                         if (optval == NULL || optlen == 0 ||
4739                             optlen < (socklen_t)sizeof(int)) {
4740                                 errno = EINVAL;
4741                                 ret = -1;
4742                                 goto done;
4743                         }
4744
4745                         i = *discard_const_p(int, optval);
4746                         if (i != 0 && i != 1) {
4747                                 errno = EINVAL;
4748                                 ret = -1;
4749                                 goto done;
4750                         }
4751                         si->tcp_nodelay = i;
4752
4753                         ret = 0;
4754                         goto done;
4755                 }
4756 #endif /* TCP_NODELAY */
4757                 default:
4758                         break;
4759                 }
4760         }
4761
4762         switch (si->family) {
4763         case AF_INET:
4764                 if (level == IPPROTO_IP) {
4765 #ifdef IP_PKTINFO
4766                         if (optname == IP_PKTINFO) {
4767                                 si->pktinfo = AF_INET;
4768                         }
4769 #endif /* IP_PKTINFO */
4770                 }
4771                 ret = 0;
4772                 goto done;
4773 #ifdef HAVE_IPV6
4774         case AF_INET6:
4775                 if (level == IPPROTO_IPV6) {
4776 #ifdef IPV6_RECVPKTINFO
4777                         if (optname == IPV6_RECVPKTINFO) {
4778                                 si->pktinfo = AF_INET6;
4779                         }
4780 #endif /* IPV6_PKTINFO */
4781                 }
4782                 ret = 0;
4783                 goto done;
4784 #endif
4785         default:
4786                 errno = ENOPROTOOPT;
4787                 ret = -1;
4788                 goto done;
4789         }
4790
4791 done:
4792         SWRAP_UNLOCK_SI(si);
4793         return ret;
4794 }
4795
4796 int setsockopt(int s, int level, int optname,
4797                const void *optval, socklen_t optlen)
4798 {
4799         return swrap_setsockopt(s, level, optname, optval, optlen);
4800 }
4801
4802 /****************************************************************************
4803  *   IOCTL
4804  ***************************************************************************/
4805
4806 static int swrap_vioctl(int s, unsigned long int r, va_list va)
4807 {
4808         struct socket_info *si = find_socket_info(s);
4809         va_list ap;
4810         int *value_ptr = NULL;
4811         int rc;
4812
4813         if (!si) {
4814                 return libc_vioctl(s, r, va);
4815         }
4816
4817         SWRAP_LOCK_SI(si);
4818
4819         va_copy(ap, va);
4820
4821         rc = libc_vioctl(s, r, va);
4822
4823         switch (r) {
4824         case FIONREAD:
4825                 if (rc == 0) {
4826                         value_ptr = ((int *)va_arg(ap, int *));
4827                 }
4828
4829                 if (rc == -1 && errno != EAGAIN && errno != ENOBUFS) {
4830                         swrap_pcap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
4831                 } else if (value_ptr != NULL && *value_ptr == 0) { /* END OF FILE */
4832                         swrap_pcap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
4833                 }
4834                 break;
4835 #ifdef FIONWRITE
4836         case FIONWRITE:
4837                 /* this is FreeBSD */
4838                 FALL_THROUGH; /* to TIOCOUTQ */
4839 #endif /* FIONWRITE */
4840         case TIOCOUTQ: /* same as SIOCOUTQ on Linux */
4841                 /*
4842                  * This may return more bytes then the application
4843                  * sent into the socket, for tcp it should
4844                  * return the number of unacked bytes.
4845                  *
4846                  * On AF_UNIX, all bytes are immediately acked!
4847                  */
4848                 if (rc == 0) {
4849                         value_ptr = ((int *)va_arg(ap, int *));
4850                         *value_ptr = 0;
4851                 }
4852                 break;
4853         }
4854
4855         va_end(ap);
4856
4857         SWRAP_UNLOCK_SI(si);
4858         return rc;
4859 }
4860
4861 #ifdef HAVE_IOCTL_INT
4862 int ioctl(int s, int r, ...)
4863 #else
4864 int ioctl(int s, unsigned long int r, ...)
4865 #endif
4866 {
4867         va_list va;
4868         int rc;
4869
4870         va_start(va, r);
4871
4872         rc = swrap_vioctl(s, (unsigned long int) r, va);
4873
4874         va_end(va);
4875
4876         return rc;
4877 }
4878
4879 /*****************
4880  * CMSG
4881  *****************/
4882
4883 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4884
4885 #ifndef CMSG_ALIGN
4886 # ifdef _ALIGN /* BSD */
4887 #define CMSG_ALIGN _ALIGN
4888 # else
4889 #define CMSG_ALIGN(len) (((len) + sizeof(size_t) - 1) & ~(sizeof(size_t) - 1))
4890 # endif /* _ALIGN */
4891 #endif /* CMSG_ALIGN */
4892
4893 /**
4894  * @brief Add a cmsghdr to a msghdr.
4895  *
4896  * This is an function to add any type of cmsghdr. It will operate on the
4897  * msg->msg_control and msg->msg_controllen you pass in by adapting them to
4898  * the buffer position after the added cmsg element. Hence, this function is
4899  * intended to be used with an intermediate msghdr and not on the original
4900  * one handed in by the client.
4901  *
4902  * @param[in]  msg      The msghdr to which to add the cmsg.
4903  *
4904  * @param[in]  level    The cmsg level to set.
4905  *
4906  * @param[in]  type     The cmsg type to set.
4907  *
4908  * @param[in]  data     The cmsg data to set.
4909  *
4910  * @param[in]  len      the length of the data to set.
4911  */
4912 static void swrap_msghdr_add_cmsghdr(struct msghdr *msg,
4913                                      int level,
4914                                      int type,
4915                                      const void *data,
4916                                      size_t len)
4917 {
4918         size_t cmlen = CMSG_LEN(len);
4919         size_t cmspace = CMSG_SPACE(len);
4920         uint8_t cmbuf[cmspace];
4921         void *cast_ptr = (void *)cmbuf;
4922         struct cmsghdr *cm = (struct cmsghdr *)cast_ptr;
4923         uint8_t *p;
4924
4925         memset(cmbuf, 0, cmspace);
4926
4927         if (msg->msg_controllen < cmlen) {
4928                 cmlen = msg->msg_controllen;
4929                 msg->msg_flags |= MSG_CTRUNC;
4930         }
4931
4932         if (msg->msg_controllen < cmspace) {
4933                 cmspace = msg->msg_controllen;
4934         }
4935
4936         /*
4937          * We copy the full input data into an intermediate cmsghdr first
4938          * in order to more easily cope with truncation.
4939          */
4940         cm->cmsg_len = cmlen;
4941         cm->cmsg_level = level;
4942         cm->cmsg_type = type;
4943         memcpy(CMSG_DATA(cm), data, len);
4944
4945         /*
4946          * We now copy the possibly truncated buffer.
4947          * We copy cmlen bytes, but consume cmspace bytes,
4948          * leaving the possible padding uninitialiazed.
4949          */
4950         p = (uint8_t *)msg->msg_control;
4951         memcpy(p, cm, cmlen);
4952         p += cmspace;
4953         msg->msg_control = p;
4954         msg->msg_controllen -= cmspace;
4955
4956         return;
4957 }
4958
4959 static int swrap_msghdr_add_pktinfo(struct socket_info *si,
4960                                     struct msghdr *msg)
4961 {
4962         /* Add packet info */
4963         switch (si->pktinfo) {
4964 #if defined(IP_PKTINFO) && (defined(HAVE_STRUCT_IN_PKTINFO) || defined(IP_RECVDSTADDR))
4965         case AF_INET: {
4966                 struct sockaddr_in *sin;
4967 #if defined(HAVE_STRUCT_IN_PKTINFO)
4968                 struct in_pktinfo pkt;
4969 #elif defined(IP_RECVDSTADDR)
4970                 struct in_addr pkt;
4971 #endif
4972
4973                 if (si->bindname.sa_socklen == sizeof(struct sockaddr_in)) {
4974                         sin = &si->bindname.sa.in;
4975                 } else {
4976                         if (si->myname.sa_socklen != sizeof(struct sockaddr_in)) {
4977                                 return 0;
4978                         }
4979                         sin = &si->myname.sa.in;
4980                 }
4981
4982                 ZERO_STRUCT(pkt);
4983
4984 #if defined(HAVE_STRUCT_IN_PKTINFO)
4985                 pkt.ipi_ifindex = socket_wrapper_default_iface();
4986                 pkt.ipi_addr.s_addr = sin->sin_addr.s_addr;
4987 #elif defined(IP_RECVDSTADDR)
4988                 pkt = sin->sin_addr;
4989 #endif
4990
4991                 swrap_msghdr_add_cmsghdr(msg, IPPROTO_IP, IP_PKTINFO,
4992                                          &pkt, sizeof(pkt));
4993
4994                 break;
4995         }
4996 #endif /* IP_PKTINFO */
4997 #if defined(HAVE_IPV6)
4998         case AF_INET6: {
4999 #if defined(IPV6_PKTINFO) && defined(HAVE_STRUCT_IN6_PKTINFO)
5000                 struct sockaddr_in6 *sin6;
5001                 struct in6_pktinfo pkt6;
5002
5003                 if (si->bindname.sa_socklen == sizeof(struct sockaddr_in6)) {
5004                         sin6 = &si->bindname.sa.in6;
5005                 } else {
5006                         if (si->myname.sa_socklen != sizeof(struct sockaddr_in6)) {
5007                                 return 0;
5008                         }
5009                         sin6 = &si->myname.sa.in6;
5010                 }
5011
5012                 ZERO_STRUCT(pkt6);
5013
5014                 pkt6.ipi6_ifindex = socket_wrapper_default_iface();
5015                 pkt6.ipi6_addr = sin6->sin6_addr;
5016
5017                 swrap_msghdr_add_cmsghdr(msg, IPPROTO_IPV6, IPV6_PKTINFO,
5018                                         &pkt6, sizeof(pkt6));
5019 #endif /* HAVE_STRUCT_IN6_PKTINFO */
5020
5021                 break;
5022         }
5023 #endif /* IPV6_PKTINFO */
5024         default:
5025                 return -1;
5026         }
5027
5028         return 0;
5029 }
5030
5031 static int swrap_msghdr_add_socket_info(struct socket_info *si,
5032                                         struct msghdr *omsg)
5033 {
5034         int rc = 0;
5035
5036         if (si->pktinfo > 0) {
5037                 rc = swrap_msghdr_add_pktinfo(si, omsg);
5038         }
5039
5040         return rc;
5041 }
5042
5043 static int swrap_sendmsg_copy_cmsg(const struct cmsghdr *cmsg,
5044                                    uint8_t **cm_data,
5045                                    size_t *cm_data_space);
5046 static int swrap_sendmsg_filter_cmsg_ipproto_ip(const struct cmsghdr *cmsg,
5047                                                 uint8_t **cm_data,
5048                                                 size_t *cm_data_space);
5049 static int swrap_sendmsg_filter_cmsg_sol_socket(const struct cmsghdr *cmsg,
5050                                                 uint8_t **cm_data,
5051                                                 size_t *cm_data_space);
5052
5053 static int swrap_sendmsg_filter_cmsghdr(const struct msghdr *_msg,
5054                                         uint8_t **cm_data,
5055                                         size_t *cm_data_space)
5056 {
5057         struct msghdr *msg = discard_const_p(struct msghdr, _msg);
5058         struct cmsghdr *cmsg;
5059         int rc = -1;
5060
5061         /* Nothing to do */
5062         if (msg->msg_controllen == 0 || msg->msg_control == NULL) {
5063                 return 0;
5064         }
5065
5066         for (cmsg = CMSG_FIRSTHDR(msg);
5067              cmsg != NULL;
5068              cmsg = CMSG_NXTHDR(msg, cmsg)) {
5069                 switch (cmsg->cmsg_level) {
5070                 case IPPROTO_IP:
5071                         rc = swrap_sendmsg_filter_cmsg_ipproto_ip(cmsg,
5072                                                                   cm_data,
5073                                                                   cm_data_space);
5074                         break;
5075                 case SOL_SOCKET:
5076                         rc = swrap_sendmsg_filter_cmsg_sol_socket(cmsg,
5077                                                                   cm_data,
5078                                                                   cm_data_space);
5079                         break;
5080                 default:
5081                         rc = swrap_sendmsg_copy_cmsg(cmsg,
5082                                                      cm_data,
5083                                                      cm_data_space);
5084                         break;
5085                 }
5086                 if (rc < 0) {
5087                         int saved_errno = errno;
5088                         SAFE_FREE(*cm_data);
5089                         *cm_data_space = 0;
5090                         errno = saved_errno;
5091                         return rc;
5092                 }
5093         }
5094
5095         return rc;
5096 }
5097
5098 static int swrap_sendmsg_copy_cmsg(const struct cmsghdr *cmsg,
5099                                    uint8_t **cm_data,
5100                                    size_t *cm_data_space)
5101 {
5102         size_t cmspace;
5103         uint8_t *p;
5104
5105         cmspace = *cm_data_space + CMSG_ALIGN(cmsg->cmsg_len);
5106
5107         p = realloc((*cm_data), cmspace);
5108         if (p == NULL) {
5109                 return -1;
5110         }
5111         (*cm_data) = p;
5112
5113         p = (*cm_data) + (*cm_data_space);
5114         *cm_data_space = cmspace;
5115
5116         memcpy(p, cmsg, cmsg->cmsg_len);
5117
5118         return 0;
5119 }
5120
5121 static int swrap_sendmsg_filter_cmsg_pktinfo(const struct cmsghdr *cmsg,
5122                                             uint8_t **cm_data,
5123                                             size_t *cm_data_space);
5124
5125
5126 static int swrap_sendmsg_filter_cmsg_ipproto_ip(const struct cmsghdr *cmsg,
5127                                                 uint8_t **cm_data,
5128                                                 size_t *cm_data_space)
5129 {
5130         int rc = -1;
5131
5132         switch(cmsg->cmsg_type) {
5133 #ifdef IP_PKTINFO
5134         case IP_PKTINFO:
5135                 rc = swrap_sendmsg_filter_cmsg_pktinfo(cmsg,
5136                                                        cm_data,
5137                                                        cm_data_space);
5138                 break;
5139 #endif
5140 #ifdef IPV6_PKTINFO
5141         case IPV6_PKTINFO:
5142                 rc = swrap_sendmsg_filter_cmsg_pktinfo(cmsg,
5143                                                        cm_data,
5144                                                        cm_data_space);
5145                 break;
5146 #endif
5147         default:
5148                 break;
5149         }
5150
5151         return rc;
5152 }
5153
5154 static int swrap_sendmsg_filter_cmsg_pktinfo(const struct cmsghdr *cmsg,
5155                                              uint8_t **cm_data,
5156                                              size_t *cm_data_space)
5157 {
5158         (void)cmsg; /* unused */
5159         (void)cm_data; /* unused */
5160         (void)cm_data_space; /* unused */
5161
5162         /*
5163          * Passing a IP pktinfo to a unix socket might be rejected by the
5164          * Kernel, at least on FreeBSD. So skip this cmsg.
5165          */
5166         return 0;
5167 }
5168
5169 static int swrap_sendmsg_filter_cmsg_sol_socket(const struct cmsghdr *cmsg,
5170                                                 uint8_t **cm_data,
5171                                                 size_t *cm_data_space)
5172 {
5173         int rc = -1;
5174
5175         switch (cmsg->cmsg_type) {
5176         case SCM_RIGHTS:
5177                 SWRAP_LOG(SWRAP_LOG_TRACE,
5178                           "Ignoring SCM_RIGHTS on inet socket!");
5179                 rc = 0;
5180                 break;
5181 #ifdef SCM_CREDENTIALS
5182         case SCM_CREDENTIALS:
5183                 SWRAP_LOG(SWRAP_LOG_TRACE,
5184                           "Ignoring SCM_CREDENTIALS on inet socket!");
5185                 rc = 0;
5186                 break;
5187 #endif /* SCM_CREDENTIALS */
5188         default:
5189                 rc = swrap_sendmsg_copy_cmsg(cmsg,
5190                                              cm_data,
5191                                              cm_data_space);
5192                 break;
5193         }
5194
5195         return rc;
5196 }
5197
5198 static const uint64_t swrap_unix_scm_right_magic = 0x8e0e13f27c42fc36;
5199
5200 /*
5201  * We only allow up to 6 fds at a time
5202  * as that's more than enough for Samba
5203  * and it means we can keep the logic simple
5204  * and work with fixed size arrays.
5205  *
5206  * We also keep sizeof(struct swrap_unix_scm_rights)
5207  * under PIPE_BUF (4096) in order to allow a non-blocking
5208  * write into the pipe.
5209  */
5210 #ifndef PIPE_BUF
5211 #define PIPE_BUF 4096
5212 #endif
5213 #define SWRAP_MAX_PASSED_FDS ((size_t)6)
5214 #define SWRAP_MAX_PASSED_SOCKET_INFO SWRAP_MAX_PASSED_FDS
5215 struct swrap_unix_scm_rights_payload {
5216         uint8_t num_idxs;
5217         int8_t idxs[SWRAP_MAX_PASSED_FDS];
5218         struct socket_info infos[SWRAP_MAX_PASSED_SOCKET_INFO];
5219 };
5220 struct swrap_unix_scm_rights {
5221         uint64_t magic;
5222         char package_name[sizeof(SOCKET_WRAPPER_PACKAGE)];
5223         char package_version[sizeof(SOCKET_WRAPPER_VERSION)];
5224         uint32_t full_size;
5225         uint32_t payload_size;
5226         struct swrap_unix_scm_rights_payload payload;
5227 };
5228
5229 static void swrap_dec_fd_passed_array(size_t num, struct socket_info **array)
5230 {
5231         int saved_errno = errno;
5232         size_t i;
5233
5234         for (i = 0; i < num; i++) {
5235                 struct socket_info *si = array[i];
5236                 if (si == NULL) {
5237                         continue;
5238                 }
5239
5240                 SWRAP_LOCK_SI(si);
5241                 swrap_dec_refcount(si);
5242                 if (si->fd_passed > 0) {
5243                         si->fd_passed -= 1;
5244                 }
5245                 SWRAP_UNLOCK_SI(si);
5246                 array[i] = NULL;
5247         }
5248
5249         errno = saved_errno;
5250 }
5251
5252 static void swrap_undo_si_idx_array(size_t num, int *array)
5253 {
5254         int saved_errno = errno;
5255         size_t i;
5256
5257         swrap_mutex_lock(&first_free_mutex);
5258
5259         for (i = 0; i < num; i++) {
5260                 struct socket_info *si = NULL;
5261
5262                 if (array[i] == -1) {
5263                         continue;
5264                 }
5265
5266                 si = swrap_get_socket_info(array[i]);
5267                 if (si == NULL) {
5268                         continue;
5269                 }
5270
5271                 SWRAP_LOCK_SI(si);
5272                 swrap_dec_refcount(si);
5273                 SWRAP_UNLOCK_SI(si);
5274
5275                 swrap_set_next_free(si, first_free);
5276                 first_free = array[i];
5277                 array[i] = -1;
5278         }
5279
5280         swrap_mutex_unlock(&first_free_mutex);
5281         errno = saved_errno;
5282 }
5283
5284 static void swrap_close_fd_array(size_t num, const int *array)
5285 {
5286         int saved_errno = errno;
5287         size_t i;
5288
5289         for (i = 0; i < num; i++) {
5290                 if (array[i] == -1) {
5291                         continue;
5292                 }
5293                 libc_close(array[i]);
5294         }
5295
5296         errno = saved_errno;
5297 }
5298
5299 union __swrap_fds {
5300         const uint8_t *p;
5301         int *fds;
5302 };
5303
5304 union __swrap_cmsghdr {
5305         const uint8_t *p;
5306         struct cmsghdr *cmsg;
5307 };
5308
5309 static int swrap_sendmsg_unix_scm_rights(const struct cmsghdr *cmsg,
5310                                          uint8_t **cm_data,
5311                                          size_t *cm_data_space,
5312                                          int *scm_rights_pipe_fd)
5313 {
5314         struct swrap_unix_scm_rights info;
5315         struct swrap_unix_scm_rights_payload *payload = NULL;
5316         int si_idx_array[SWRAP_MAX_PASSED_FDS];
5317         struct socket_info *si_array[SWRAP_MAX_PASSED_FDS] = { NULL, };
5318         size_t info_idx = 0;
5319         size_t size_fds_in;
5320         size_t num_fds_in;
5321         union __swrap_fds __fds_in = { .p = NULL, };
5322         const int *fds_in = NULL;
5323         size_t num_fds_out;
5324         size_t size_fds_out;
5325         union __swrap_fds __fds_out = { .p = NULL, };
5326         int *fds_out = NULL;
5327         size_t cmsg_len;
5328         size_t cmsg_space;
5329         size_t new_cm_data_space;
5330         union __swrap_cmsghdr __new_cmsg = { .p = NULL, };
5331         struct cmsghdr *new_cmsg = NULL;
5332         uint8_t *p = NULL;
5333         size_t i;
5334         int pipefd[2] = { -1, -1 };
5335         int rc;
5336         ssize_t sret;
5337
5338         /*
5339          * We pass this a buffer to the kernel make sure any padding
5340          * is also cleared.
5341          */
5342         ZERO_STRUCT(info);
5343         info.magic = swrap_unix_scm_right_magic;
5344         memcpy(info.package_name,
5345                SOCKET_WRAPPER_PACKAGE,
5346                sizeof(info.package_name));
5347         memcpy(info.package_version,
5348                SOCKET_WRAPPER_VERSION,
5349                sizeof(info.package_version));
5350         info.full_size = sizeof(info);
5351         info.payload_size = sizeof(info.payload);
5352         payload = &info.payload;
5353
5354         if (*scm_rights_pipe_fd != -1) {
5355                 SWRAP_LOG(SWRAP_LOG_ERROR,
5356                           "Two SCM_RIGHTS headers are not supported by socket_wrapper");
5357                 errno = EINVAL;
5358                 return -1;
5359         }
5360
5361         if (cmsg->cmsg_len < CMSG_LEN(0)) {
5362                 SWRAP_LOG(SWRAP_LOG_ERROR,
5363                           "cmsg->cmsg_len=%zu < CMSG_LEN(0)=%zu",
5364                           (size_t)cmsg->cmsg_len,
5365                           CMSG_LEN(0));
5366                 errno = EINVAL;
5367                 return -1;
5368         }
5369         size_fds_in = cmsg->cmsg_len - CMSG_LEN(0);
5370         if ((size_fds_in % sizeof(int)) != 0) {
5371                 SWRAP_LOG(SWRAP_LOG_ERROR,
5372                           "cmsg->cmsg_len=%zu => (size_fds_in=%zu %% sizeof(int)=%zu) != 0",
5373                           (size_t)cmsg->cmsg_len,
5374                           size_fds_in,
5375                           sizeof(int));
5376                 errno = EINVAL;
5377                 return -1;
5378         }
5379         num_fds_in = size_fds_in / sizeof(int);
5380         if (num_fds_in > SWRAP_MAX_PASSED_FDS) {
5381                 SWRAP_LOG(SWRAP_LOG_ERROR,
5382                           "cmsg->cmsg_len=%zu,size_fds_in=%zu => "
5383                           "num_fds_in=%zu > "
5384                           "SWRAP_MAX_PASSED_FDS(%zu)",
5385                           (size_t)cmsg->cmsg_len,
5386                           size_fds_in,
5387                           num_fds_in,
5388                           SWRAP_MAX_PASSED_FDS);
5389                 errno = EINVAL;
5390                 return -1;
5391         }
5392         if (num_fds_in == 0) {
5393                 SWRAP_LOG(SWRAP_LOG_ERROR,
5394                           "cmsg->cmsg_len=%zu,size_fds_in=%zu => "
5395                           "num_fds_in=%zu",
5396                           (size_t)cmsg->cmsg_len,
5397                           size_fds_in,
5398                           num_fds_in);
5399                 errno = EINVAL;
5400                 return -1;
5401         }
5402         __fds_in.p = CMSG_DATA(cmsg);
5403         fds_in = __fds_in.fds;
5404         num_fds_out = num_fds_in + 1;
5405
5406         SWRAP_LOG(SWRAP_LOG_TRACE,
5407                   "num_fds_in=%zu num_fds_out=%zu",
5408                   num_fds_in, num_fds_out);
5409
5410         size_fds_out = sizeof(int) * num_fds_out;
5411         cmsg_len = CMSG_LEN(size_fds_out);
5412         cmsg_space = CMSG_SPACE(size_fds_out);
5413
5414         new_cm_data_space = *cm_data_space + cmsg_space;
5415
5416         p = realloc((*cm_data), new_cm_data_space);
5417         if (p == NULL) {
5418                 return -1;
5419         }
5420         (*cm_data) = p;
5421         p = (*cm_data) + (*cm_data_space);
5422         memset(p, 0, cmsg_space);
5423         __new_cmsg.p = p;
5424         new_cmsg = __new_cmsg.cmsg;
5425         *new_cmsg = *cmsg;
5426         __fds_out.p = CMSG_DATA(new_cmsg);
5427         fds_out = __fds_out.fds;
5428         memcpy(fds_out, fds_in, size_fds_in);
5429         new_cmsg->cmsg_len = cmsg->cmsg_len;
5430
5431         for (i = 0; i < num_fds_in; i++) {
5432                 size_t j;
5433
5434                 payload->idxs[i] = -1;
5435                 payload->num_idxs++;
5436
5437                 si_idx_array[i] = find_socket_info_index(fds_in[i]);
5438                 if (si_idx_array[i] == -1) {
5439                         continue;
5440                 }
5441
5442                 si_array[i] = swrap_get_socket_info(si_idx_array[i]);
5443                 if (si_array[i] == NULL) {
5444                         SWRAP_LOG(SWRAP_LOG_ERROR,
5445                                   "fds_in[%zu]=%d si_idx_array[%zu]=%d missing!",
5446                                   i, fds_in[i], i, si_idx_array[i]);
5447                         errno = EINVAL;
5448                         return -1;
5449                 }
5450
5451                 for (j = 0; j < i; j++) {
5452                         if (si_array[j] == si_array[i]) {
5453                                 payload->idxs[i] = payload->idxs[j];
5454                                 break;
5455                         }
5456                 }
5457                 if (payload->idxs[i] == -1) {
5458                         if (info_idx >= SWRAP_MAX_PASSED_SOCKET_INFO) {
5459                                 SWRAP_LOG(SWRAP_LOG_ERROR,
5460                                           "fds_in[%zu]=%d,si_idx_array[%zu]=%d: "
5461                                           "info_idx=%zu >= SWRAP_MAX_PASSED_FDS(%zu)!",
5462                                           i, fds_in[i], i, si_idx_array[i],
5463                                           info_idx,
5464                                           SWRAP_MAX_PASSED_SOCKET_INFO);
5465                                 errno = EINVAL;
5466                                 return -1;
5467                         }
5468                         payload->idxs[i] = info_idx;
5469                         info_idx += 1;
5470                         continue;
5471                 }
5472         }
5473
5474         for (i = 0; i < num_fds_in; i++) {
5475                 struct socket_info *si = si_array[i];
5476
5477                 if (si == NULL) {
5478                         SWRAP_LOG(SWRAP_LOG_TRACE,
5479                                   "fds_in[%zu]=%d not an inet socket",
5480                                   i, fds_in[i]);
5481                         continue;
5482                 }
5483
5484                 SWRAP_LOG(SWRAP_LOG_TRACE,
5485                           "fds_in[%zu]=%d si_idx_array[%zu]=%d "
5486                           "passing as info.idxs[%zu]=%d!",
5487                           i, fds_in[i],
5488                           i, si_idx_array[i],
5489                           i, payload->idxs[i]);
5490
5491                 SWRAP_LOCK_SI(si);
5492                 si->fd_passed += 1;
5493                 payload->infos[payload->idxs[i]] = *si;
5494                 payload->infos[payload->idxs[i]].fd_passed = 0;
5495                 SWRAP_UNLOCK_SI(si);
5496         }
5497
5498         rc = pipe(pipefd);
5499         if (rc == -1) {
5500                 int saved_errno = errno;
5501                 SWRAP_LOG(SWRAP_LOG_ERROR,
5502                           "pipe() failed - %d %s",
5503                           saved_errno,
5504                           strerror(saved_errno));
5505                 swrap_dec_fd_passed_array(num_fds_in, si_array);
5506                 errno = saved_errno;
5507                 return -1;
5508         }
5509
5510         sret = libc_write(pipefd[1], &info, sizeof(info));
5511         if (sret != sizeof(info)) {
5512                 int saved_errno = errno;
5513                 if (sret != -1) {
5514                         saved_errno = EINVAL;
5515                 }
5516                 SWRAP_LOG(SWRAP_LOG_ERROR,
5517                           "write() failed - sret=%zd - %d %s",
5518                           sret, saved_errno,
5519                           strerror(saved_errno));
5520                 swrap_dec_fd_passed_array(num_fds_in, si_array);
5521                 libc_close(pipefd[1]);
5522                 libc_close(pipefd[0]);
5523                 errno = saved_errno;
5524                 return -1;
5525         }
5526         libc_close(pipefd[1]);
5527
5528         /*
5529          * Add the pipe read end to the end of the passed fd array
5530          */
5531         fds_out[num_fds_in] = pipefd[0];
5532         new_cmsg->cmsg_len = cmsg_len;
5533
5534         /* we're done ... */
5535         *scm_rights_pipe_fd = pipefd[0];
5536         *cm_data_space = new_cm_data_space;
5537
5538         return 0;
5539 }
5540
5541 static int swrap_sendmsg_unix_sol_socket(const struct cmsghdr *cmsg,
5542                                          uint8_t **cm_data,
5543                                          size_t *cm_data_space,
5544                                          int *scm_rights_pipe_fd)
5545 {
5546         int rc = -1;
5547
5548         switch (cmsg->cmsg_type) {
5549         case SCM_RIGHTS:
5550                 rc = swrap_sendmsg_unix_scm_rights(cmsg,
5551                                                    cm_data,
5552                                                    cm_data_space,
5553                                                    scm_rights_pipe_fd);
5554                 break;
5555         default:
5556                 rc = swrap_sendmsg_copy_cmsg(cmsg,
5557                                              cm_data,
5558                                              cm_data_space);
5559                 break;
5560         }
5561
5562         return rc;
5563 }
5564
5565 static int swrap_recvmsg_unix_scm_rights(const struct cmsghdr *cmsg,
5566                                          uint8_t **cm_data,
5567                                          size_t *cm_data_space)
5568 {
5569         int scm_rights_pipe_fd = -1;
5570         struct swrap_unix_scm_rights info;
5571         struct swrap_unix_scm_rights_payload *payload = NULL;
5572         int si_idx_array[SWRAP_MAX_PASSED_FDS];
5573         size_t size_fds_in;
5574         size_t num_fds_in;
5575         union __swrap_fds __fds_in = { .p = NULL, };
5576         const int *fds_in = NULL;
5577         size_t num_fds_out;
5578         size_t size_fds_out;
5579         union __swrap_fds __fds_out = { .p = NULL, };
5580         int *fds_out = NULL;
5581         size_t cmsg_len;
5582         size_t cmsg_space;
5583         size_t new_cm_data_space;
5584         union __swrap_cmsghdr __new_cmsg = { .p = NULL, };
5585         struct cmsghdr *new_cmsg = NULL;
5586         uint8_t *p = NULL;
5587         ssize_t sret;
5588         size_t i;
5589         int cmp;
5590
5591         if (cmsg->cmsg_len < CMSG_LEN(0)) {
5592                 SWRAP_LOG(SWRAP_LOG_ERROR,
5593                           "cmsg->cmsg_len=%zu < CMSG_LEN(0)=%zu",
5594                           (size_t)cmsg->cmsg_len,
5595                           CMSG_LEN(0));
5596                 errno = EINVAL;
5597                 return -1;
5598         }
5599         size_fds_in = cmsg->cmsg_len - CMSG_LEN(0);
5600         if ((size_fds_in % sizeof(int)) != 0) {
5601                 SWRAP_LOG(SWRAP_LOG_ERROR,
5602                           "cmsg->cmsg_len=%zu => (size_fds_in=%zu %% sizeof(int)=%zu) != 0",
5603                           (size_t)cmsg->cmsg_len,
5604                           size_fds_in,
5605                           sizeof(int));
5606                 errno = EINVAL;
5607                 return -1;
5608         }
5609         num_fds_in = size_fds_in / sizeof(int);
5610         if (num_fds_in > (SWRAP_MAX_PASSED_FDS + 1)) {
5611                 SWRAP_LOG(SWRAP_LOG_ERROR,
5612                           "cmsg->cmsg_len=%zu,size_fds_in=%zu => "
5613                           "num_fds_in=%zu > SWRAP_MAX_PASSED_FDS+1(%zu)",
5614                           (size_t)cmsg->cmsg_len,
5615                           size_fds_in,
5616                           num_fds_in,
5617                           SWRAP_MAX_PASSED_FDS+1);
5618                 errno = EINVAL;
5619                 return -1;
5620         }
5621         if (num_fds_in <= 1) {
5622                 SWRAP_LOG(SWRAP_LOG_ERROR,
5623                           "cmsg->cmsg_len=%zu,size_fds_in=%zu => "
5624                           "num_fds_in=%zu",
5625                           (size_t)cmsg->cmsg_len,
5626                           size_fds_in,
5627                           num_fds_in);
5628                 errno = EINVAL;
5629                 return -1;
5630         }
5631         __fds_in.p = CMSG_DATA(cmsg);
5632         fds_in = __fds_in.fds;
5633         num_fds_out = num_fds_in - 1;
5634
5635         SWRAP_LOG(SWRAP_LOG_TRACE,
5636                   "num_fds_in=%zu num_fds_out=%zu",
5637                   num_fds_in, num_fds_out);
5638
5639         for (i = 0; i < num_fds_in; i++) {
5640                 /* Check if we have a stale fd and remove it */
5641                 swrap_remove_stale(fds_in[i]);
5642         }
5643
5644         scm_rights_pipe_fd = fds_in[num_fds_out];
5645         size_fds_out = sizeof(int) * num_fds_out;
5646         cmsg_len = CMSG_LEN(size_fds_out);
5647         cmsg_space = CMSG_SPACE(size_fds_out);
5648
5649         new_cm_data_space = *cm_data_space + cmsg_space;
5650
5651         p = realloc((*cm_data), new_cm_data_space);
5652         if (p == NULL) {
5653                 swrap_close_fd_array(num_fds_in, fds_in);
5654                 return -1;
5655         }
5656         (*cm_data) = p;
5657         p = (*cm_data) + (*cm_data_space);
5658         memset(p, 0, cmsg_space);
5659         __new_cmsg.p = p;
5660         new_cmsg = __new_cmsg.cmsg;
5661         *new_cmsg = *cmsg;
5662         __fds_out.p = CMSG_DATA(new_cmsg);
5663         fds_out = __fds_out.fds;
5664         memcpy(fds_out, fds_in, size_fds_out);
5665         new_cmsg->cmsg_len = cmsg_len;
5666
5667         sret = read(scm_rights_pipe_fd, &info, sizeof(info));
5668         if (sret != sizeof(info)) {
5669                 int saved_errno = errno;
5670                 if (sret != -1) {
5671                         saved_errno = EINVAL;
5672                 }
5673                 SWRAP_LOG(SWRAP_LOG_ERROR,
5674                           "read() failed - sret=%zd - %d %s",
5675                           sret, saved_errno,
5676                           strerror(saved_errno));
5677                 swrap_close_fd_array(num_fds_in, fds_in);
5678                 errno = saved_errno;
5679                 return -1;
5680         }
5681         libc_close(scm_rights_pipe_fd);
5682         payload = &info.payload;
5683
5684         if (info.magic != swrap_unix_scm_right_magic) {
5685                 SWRAP_LOG(SWRAP_LOG_ERROR,
5686                           "info.magic=0x%llx != swrap_unix_scm_right_magic=0x%llx",
5687                           (unsigned long long)info.magic,
5688                           (unsigned long long)swrap_unix_scm_right_magic);
5689                 swrap_close_fd_array(num_fds_out, fds_out);
5690                 errno = EINVAL;
5691                 return -1;
5692         }
5693
5694         cmp = memcmp(info.package_name,
5695                      SOCKET_WRAPPER_PACKAGE,
5696                      sizeof(info.package_name));
5697         if (cmp != 0) {
5698                 SWRAP_LOG(SWRAP_LOG_ERROR,
5699                           "info.package_name='%.*s' != '%s'",
5700                           (int)sizeof(info.package_name),
5701                           info.package_name,
5702                           SOCKET_WRAPPER_PACKAGE);
5703                 swrap_close_fd_array(num_fds_out, fds_out);
5704                 errno = EINVAL;
5705                 return -1;
5706         }
5707
5708         cmp = memcmp(info.package_version,
5709                      SOCKET_WRAPPER_VERSION,
5710                      sizeof(info.package_version));
5711         if (cmp != 0) {
5712                 SWRAP_LOG(SWRAP_LOG_ERROR,
5713                           "info.package_version='%.*s' != '%s'",
5714                           (int)sizeof(info.package_version),
5715                           info.package_version,
5716                           SOCKET_WRAPPER_VERSION);
5717                 swrap_close_fd_array(num_fds_out, fds_out);
5718                 errno = EINVAL;
5719                 return -1;
5720         }
5721
5722         if (info.full_size != sizeof(info)) {
5723                 SWRAP_LOG(SWRAP_LOG_ERROR,
5724                           "info.full_size=%zu != sizeof(info)=%zu",
5725                           (size_t)info.full_size,
5726                           sizeof(info));
5727                 swrap_close_fd_array(num_fds_out, fds_out);
5728                 errno = EINVAL;
5729                 return -1;
5730         }
5731
5732         if (info.payload_size != sizeof(info.payload)) {
5733                 SWRAP_LOG(SWRAP_LOG_ERROR,
5734                           "info.payload_size=%zu != sizeof(info.payload)=%zu",
5735                           (size_t)info.payload_size,
5736                           sizeof(info.payload));
5737                 swrap_close_fd_array(num_fds_out, fds_out);
5738                 errno = EINVAL;
5739                 return -1;
5740         }
5741
5742         if (payload->num_idxs != num_fds_out) {
5743                 SWRAP_LOG(SWRAP_LOG_ERROR,
5744                           "info.num_idxs=%u != num_fds_out=%zu",
5745                           payload->num_idxs, num_fds_out);
5746                 swrap_close_fd_array(num_fds_out, fds_out);
5747                 errno = EINVAL;
5748                 return -1;
5749         }
5750
5751         for (i = 0; i < num_fds_out; i++) {
5752                 size_t j;
5753
5754                 si_idx_array[i] = -1;
5755
5756                 if (payload->idxs[i] == -1) {
5757                         SWRAP_LOG(SWRAP_LOG_TRACE,
5758                                   "fds_out[%zu]=%d not an inet socket",
5759                                   i, fds_out[i]);
5760                         continue;
5761                 }
5762
5763                 if (payload->idxs[i] < 0) {
5764                         SWRAP_LOG(SWRAP_LOG_ERROR,
5765                                   "fds_out[%zu]=%d info.idxs[%zu]=%d < 0!",
5766                                   i, fds_out[i], i, payload->idxs[i]);
5767                         swrap_close_fd_array(num_fds_out, fds_out);
5768                         errno = EINVAL;
5769                         return -1;
5770                 }
5771
5772                 if (payload->idxs[i] >= payload->num_idxs) {
5773                         SWRAP_LOG(SWRAP_LOG_ERROR,
5774                                   "fds_out[%zu]=%d info.idxs[%zu]=%d >= %u!",
5775                                   i, fds_out[i], i, payload->idxs[i],
5776                                   payload->num_idxs);
5777                         swrap_close_fd_array(num_fds_out, fds_out);
5778                         errno = EINVAL;
5779                         return -1;
5780                 }
5781
5782                 if ((size_t)fds_out[i] >= socket_fds_max) {
5783                         SWRAP_LOG(SWRAP_LOG_ERROR,
5784                                   "The max socket index limit of %zu has been reached, "
5785                                   "trying to add %d",
5786                                   socket_fds_max,
5787                                   fds_out[i]);
5788                         swrap_close_fd_array(num_fds_out, fds_out);
5789                         errno = EMFILE;
5790                         return -1;
5791                 }
5792
5793                 SWRAP_LOG(SWRAP_LOG_TRACE,
5794                           "fds_in[%zu]=%d "
5795                           "received as info.idxs[%zu]=%d!",
5796                           i, fds_out[i],
5797                           i, payload->idxs[i]);
5798
5799                 for (j = 0; j < i; j++) {
5800                         if (payload->idxs[j] == -1) {
5801                                 continue;
5802                         }
5803                         if (payload->idxs[j] == payload->idxs[i]) {
5804                                 si_idx_array[i] = si_idx_array[j];
5805                         }
5806                 }
5807                 if (si_idx_array[i] == -1) {
5808                         const struct socket_info *si = &payload->infos[payload->idxs[i]];
5809
5810                         si_idx_array[i] = swrap_add_socket_info(si);
5811                         if (si_idx_array[i] == -1) {
5812                                 int saved_errno = errno;
5813                                 SWRAP_LOG(SWRAP_LOG_ERROR,
5814                                           "The max socket index limit of %zu has been reached, "
5815                                           "trying to add %d",
5816                                           socket_fds_max,
5817                                           fds_out[i]);
5818                                 swrap_undo_si_idx_array(i, si_idx_array);
5819                                 swrap_close_fd_array(num_fds_out, fds_out);
5820                                 errno = saved_errno;
5821                                 return -1;
5822                         }
5823                         SWRAP_LOG(SWRAP_LOG_TRACE,
5824                                   "Imported %s socket for protocol %s, fd=%d",
5825                                   si->family == AF_INET ? "IPv4" : "IPv6",
5826                                   si->type == SOCK_DGRAM ? "UDP" : "TCP",
5827                                   fds_out[i]);
5828                 }
5829         }
5830
5831         for (i = 0; i < num_fds_out; i++) {
5832                 if (si_idx_array[i] == -1) {
5833                         continue;
5834                 }
5835                 set_socket_info_index(fds_out[i], si_idx_array[i]);
5836         }
5837
5838         /* we're done ... */
5839         *cm_data_space = new_cm_data_space;
5840
5841         return 0;
5842 }
5843
5844 static int swrap_recvmsg_unix_sol_socket(const struct cmsghdr *cmsg,
5845                                          uint8_t **cm_data,
5846                                          size_t *cm_data_space)
5847 {
5848         int rc = -1;
5849
5850         switch (cmsg->cmsg_type) {
5851         case SCM_RIGHTS:
5852                 rc = swrap_recvmsg_unix_scm_rights(cmsg,
5853                                                    cm_data,
5854                                                    cm_data_space);
5855                 break;
5856         default:
5857                 rc = swrap_sendmsg_copy_cmsg(cmsg,
5858                                              cm_data,
5859                                              cm_data_space);
5860                 break;
5861         }
5862
5863         return rc;
5864 }
5865
5866 #endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
5867
5868 static int swrap_sendmsg_before_unix(const struct msghdr *_msg_in,
5869                                      struct msghdr *msg_tmp,
5870                                      int *scm_rights_pipe_fd)
5871 {
5872 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5873         struct msghdr *msg_in = discard_const_p(struct msghdr, _msg_in);
5874         struct cmsghdr *cmsg = NULL;
5875         uint8_t *cm_data = NULL;
5876         size_t cm_data_space = 0;
5877         int rc = -1;
5878
5879         *msg_tmp = *msg_in;
5880         *scm_rights_pipe_fd = -1;
5881
5882         /* Nothing to do */
5883         if (msg_in->msg_controllen == 0 || msg_in->msg_control == NULL) {
5884                 return 0;
5885         }
5886
5887         for (cmsg = CMSG_FIRSTHDR(msg_in);
5888              cmsg != NULL;
5889              cmsg = CMSG_NXTHDR(msg_in, cmsg)) {
5890                 switch (cmsg->cmsg_level) {
5891                 case SOL_SOCKET:
5892                         rc = swrap_sendmsg_unix_sol_socket(cmsg,
5893                                                            &cm_data,
5894                                                            &cm_data_space,
5895                                                            scm_rights_pipe_fd);
5896                         break;
5897
5898                 default:
5899                         rc = swrap_sendmsg_copy_cmsg(cmsg,
5900                                                      &cm_data,
5901                                                      &cm_data_space);
5902                         break;
5903                 }
5904                 if (rc < 0) {
5905                         int saved_errno = errno;
5906                         SAFE_FREE(cm_data);
5907                         errno = saved_errno;
5908                         return rc;
5909                 }
5910         }
5911
5912         msg_tmp->msg_controllen = cm_data_space;
5913         msg_tmp->msg_control = cm_data;
5914
5915         return 0;
5916 #else /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
5917         *msg_tmp = *_msg_in;
5918         return 0;
5919 #endif /* ! HAVE_STRUCT_MSGHDR_MSG_CONTROL */
5920 }
5921
5922 static ssize_t swrap_sendmsg_after_unix(struct msghdr *msg_tmp,
5923                                         ssize_t ret,
5924                                         int scm_rights_pipe_fd)
5925 {
5926 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5927         int saved_errno = errno;
5928         SAFE_FREE(msg_tmp->msg_control);
5929         if (scm_rights_pipe_fd != -1) {
5930                 libc_close(scm_rights_pipe_fd);
5931         }
5932         errno = saved_errno;
5933 #endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
5934         return ret;
5935 }
5936
5937 static int swrap_recvmsg_before_unix(struct msghdr *msg_in,
5938                                      struct msghdr *msg_tmp,
5939                                      uint8_t **tmp_control)
5940 {
5941 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5942         const size_t cm_extra_space = CMSG_SPACE(sizeof(int));
5943         uint8_t *cm_data = NULL;
5944         size_t cm_data_space = 0;
5945
5946         *msg_tmp = *msg_in;
5947         *tmp_control = NULL;
5948
5949         SWRAP_LOG(SWRAP_LOG_TRACE,
5950                   "msg_in->msg_controllen=%zu",
5951                   (size_t)msg_in->msg_controllen);
5952
5953         /* Nothing to do */
5954         if (msg_in->msg_controllen == 0 || msg_in->msg_control == NULL) {
5955                 return 0;
5956         }
5957
5958         /*
5959          * We need to give the kernel a bit more space in order
5960          * recv the pipe fd, added by swrap_sendmsg_before_unix()).
5961          * swrap_recvmsg_after_unix() will hide it again.
5962          */
5963         cm_data_space = msg_in->msg_controllen;
5964         if (cm_data_space < (INT32_MAX - cm_extra_space)) {
5965                 cm_data_space += cm_extra_space;
5966         }
5967         cm_data = calloc(1, cm_data_space);
5968         if (cm_data == NULL) {
5969                 return -1;
5970         }
5971
5972         msg_tmp->msg_controllen = cm_data_space;
5973         msg_tmp->msg_control = cm_data;
5974         *tmp_control = cm_data;
5975
5976         SWRAP_LOG(SWRAP_LOG_TRACE,
5977                   "msg_tmp->msg_controllen=%zu",
5978                   (size_t)msg_tmp->msg_controllen);
5979         return 0;
5980 #else /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
5981         *msg_tmp = *msg_in;
5982         *tmp_control = NULL;
5983         return 0;
5984 #endif /* ! HAVE_STRUCT_MSGHDR_MSG_CONTROL */
5985 }
5986
5987 static ssize_t swrap_recvmsg_after_unix(struct msghdr *msg_tmp,
5988                                         uint8_t **tmp_control,
5989                                         struct msghdr *msg_out,
5990                                         ssize_t ret)
5991 {
5992 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5993         struct cmsghdr *cmsg = NULL;
5994         uint8_t *cm_data = NULL;
5995         size_t cm_data_space = 0;
5996         int rc = -1;
5997
5998         if (ret < 0) {
5999                 int saved_errno = errno;
6000                 SWRAP_LOG(SWRAP_LOG_TRACE, "ret=%zd - %d - %s", ret,
6001                           saved_errno, strerror(saved_errno));
6002                 SAFE_FREE(*tmp_control);
6003                 /* msg_out should not be touched on error */
6004                 errno = saved_errno;
6005                 return ret;
6006         }
6007
6008         SWRAP_LOG(SWRAP_LOG_TRACE,
6009                   "msg_tmp->msg_controllen=%zu",
6010                   (size_t)msg_tmp->msg_controllen);
6011
6012         /* Nothing to do */
6013         if (msg_tmp->msg_controllen == 0 || msg_tmp->msg_control == NULL) {
6014                 int saved_errno = errno;
6015                 *msg_out = *msg_tmp;
6016                 SAFE_FREE(*tmp_control);
6017                 errno = saved_errno;
6018                 return ret;
6019         }
6020
6021         for (cmsg = CMSG_FIRSTHDR(msg_tmp);
6022              cmsg != NULL;
6023              cmsg = CMSG_NXTHDR(msg_tmp, cmsg)) {
6024                 switch (cmsg->cmsg_level) {
6025                 case SOL_SOCKET:
6026                         rc = swrap_recvmsg_unix_sol_socket(cmsg,
6027                                                            &cm_data,
6028                                                            &cm_data_space);
6029                         break;
6030
6031                 default:
6032                         rc = swrap_sendmsg_copy_cmsg(cmsg,
6033                                                      &cm_data,
6034                                                      &cm_data_space);
6035                         break;
6036                 }
6037                 if (rc < 0) {
6038                         int saved_errno = errno;
6039                         SAFE_FREE(cm_data);
6040                         SAFE_FREE(*tmp_control);
6041                         errno = saved_errno;
6042                         return rc;
6043                 }
6044         }
6045
6046         /*
6047          * msg_tmp->msg_control (*tmp_control) was created by
6048          * swrap_recvmsg_before_unix() and msg_out->msg_control
6049          * is still the buffer of the caller.
6050          */
6051         msg_tmp->msg_control = msg_out->msg_control;
6052         msg_tmp->msg_controllen = msg_out->msg_controllen;
6053         *msg_out = *msg_tmp;
6054
6055         cm_data_space = MIN(cm_data_space, msg_out->msg_controllen);
6056         memcpy(msg_out->msg_control, cm_data, cm_data_space);
6057         msg_out->msg_controllen = cm_data_space;
6058         SAFE_FREE(cm_data);
6059         SAFE_FREE(*tmp_control);
6060
6061         SWRAP_LOG(SWRAP_LOG_TRACE,
6062                   "msg_out->msg_controllen=%zu",
6063                   (size_t)msg_out->msg_controllen);
6064         return ret;
6065 #else /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
6066         int saved_errno = errno;
6067         *msg_out = *msg_tmp;
6068         SAFE_FREE(*tmp_control);
6069         errno = saved_errno;
6070         return ret;
6071 #endif /* ! HAVE_STRUCT_MSGHDR_MSG_CONTROL */
6072 }
6073
6074 static ssize_t swrap_sendmsg_before(int fd,
6075                                     struct socket_info *si,
6076                                     struct msghdr *msg,
6077                                     struct iovec *tmp_iov,
6078                                     struct sockaddr_un *tmp_un,
6079                                     const struct sockaddr_un **to_un,
6080                                     const struct sockaddr **to,
6081                                     int *bcast)
6082 {
6083         size_t i, len = 0;
6084         ssize_t ret = -1;
6085
6086         if (to_un) {
6087                 *to_un = NULL;
6088         }
6089         if (to) {
6090                 *to = NULL;
6091         }
6092         if (bcast) {
6093                 *bcast = 0;
6094         }
6095
6096         SWRAP_LOCK_SI(si);
6097
6098         switch (si->type) {
6099         case SOCK_STREAM: {
6100                 unsigned long mtu;
6101
6102                 if (!si->connected) {
6103                         errno = ENOTCONN;
6104                         goto out;
6105                 }
6106
6107                 if (msg->msg_iovlen == 0) {
6108                         break;
6109                 }
6110
6111                 mtu = socket_wrapper_mtu();
6112                 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
6113                         size_t nlen;
6114                         nlen = len + msg->msg_iov[i].iov_len;
6115                         if (nlen < len) {
6116                                 /* overflow */
6117                                 errno = EMSGSIZE;
6118                                 goto out;
6119                         }
6120                         if (nlen > mtu) {
6121                                 break;
6122                         }
6123                 }
6124                 msg->msg_iovlen = i;
6125                 if (msg->msg_iovlen == 0) {
6126                         *tmp_iov = msg->msg_iov[0];
6127                         tmp_iov->iov_len = MIN((size_t)tmp_iov->iov_len,
6128                                                (size_t)mtu);
6129                         msg->msg_iov = tmp_iov;
6130                         msg->msg_iovlen = 1;
6131                 }
6132                 break;
6133         }
6134         case SOCK_DGRAM:
6135                 if (si->connected) {
6136                         if (msg->msg_name != NULL) {
6137                                 /*
6138                                  * We are dealing with unix sockets and if we
6139                                  * are connected, we should only talk to the
6140                                  * connected unix path. Using the fd to send
6141                                  * to another server would be hard to achieve.
6142                                  */
6143                                 msg->msg_name = NULL;
6144                                 msg->msg_namelen = 0;
6145                         }
6146                 } else {
6147                         const struct sockaddr *msg_name;
6148                         msg_name = (const struct sockaddr *)msg->msg_name;
6149
6150                         if (msg_name == NULL) {
6151                                 errno = ENOTCONN;
6152                                 goto out;
6153                         }
6154
6155
6156                         ret = sockaddr_convert_to_un(si, msg_name, msg->msg_namelen,
6157                                                      tmp_un, 0, bcast);
6158                         if (ret == -1) {
6159                                 goto out;
6160                         }
6161
6162                         if (to_un) {
6163                                 *to_un = tmp_un;
6164                         }
6165                         if (to) {
6166                                 *to = msg_name;
6167                         }
6168                         msg->msg_name = tmp_un;
6169                         msg->msg_namelen = sizeof(*tmp_un);
6170                 }
6171
6172                 if (si->bound == 0) {
6173                         ret = swrap_auto_bind(fd, si, si->family);
6174                         if (ret == -1) {
6175                                 SWRAP_UNLOCK_SI(si);
6176                                 if (errno == ENOTSOCK) {
6177                                         swrap_remove_stale(fd);
6178                                         ret = -ENOTSOCK;
6179                                 } else {
6180                                         SWRAP_LOG(SWRAP_LOG_ERROR, "swrap_sendmsg_before failed");
6181                                 }
6182                                 return ret;
6183                         }
6184                 }
6185
6186                 if (!si->defer_connect) {
6187                         break;
6188                 }
6189
6190                 ret = sockaddr_convert_to_un(si,
6191                                              &si->peername.sa.s,
6192                                              si->peername.sa_socklen,
6193                                              tmp_un,
6194                                              0,
6195                                              NULL);
6196                 if (ret == -1) {
6197                         goto out;
6198                 }
6199
6200                 ret = libc_connect(fd,
6201                                    (struct sockaddr *)(void *)tmp_un,
6202                                    sizeof(*tmp_un));
6203
6204                 /* to give better errors */
6205                 if (ret == -1 && errno == ENOENT) {
6206                         errno = EHOSTUNREACH;
6207                 }
6208
6209                 if (ret == -1) {
6210                         goto out;
6211                 }
6212
6213                 si->defer_connect = 0;
6214                 break;
6215         default:
6216                 errno = EHOSTUNREACH;
6217                 goto out;
6218         }
6219
6220         ret = 0;
6221 out:
6222         SWRAP_UNLOCK_SI(si);
6223
6224         return ret;
6225 }
6226
6227 static void swrap_sendmsg_after(int fd,
6228                                 struct socket_info *si,
6229                                 struct msghdr *msg,
6230                                 const struct sockaddr *to,
6231                                 ssize_t ret)
6232 {
6233         int saved_errno = errno;
6234         size_t i, len = 0;
6235         uint8_t *buf;
6236         off_t ofs = 0;
6237         size_t avail = 0;
6238         size_t remain;
6239
6240         /* to give better errors */
6241         if (ret == -1) {
6242                 if (saved_errno == ENOENT) {
6243                         saved_errno = EHOSTUNREACH;
6244                 } else if (saved_errno == ENOTSOCK) {
6245                         /* If the fd is not a socket, remove it */
6246                         swrap_remove_stale(fd);
6247                 }
6248         }
6249
6250         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
6251                 avail += msg->msg_iov[i].iov_len;
6252         }
6253
6254         if (ret == -1) {
6255                 remain = MIN(80, avail);
6256         } else {
6257                 remain = ret;
6258         }
6259
6260         /* we capture it as one single packet */
6261         buf = (uint8_t *)malloc(remain);
6262         if (!buf) {
6263                 /* we just not capture the packet */
6264                 errno = saved_errno;
6265                 return;
6266         }
6267
6268         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
6269                 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
6270                 memcpy(buf + ofs,
6271                        msg->msg_iov[i].iov_base,
6272                        this_time);
6273                 ofs += this_time;
6274                 remain -= this_time;
6275         }
6276         len = ofs;
6277
6278         SWRAP_LOCK_SI(si);
6279
6280         switch (si->type) {
6281         case SOCK_STREAM:
6282                 if (ret == -1) {
6283                         swrap_pcap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
6284                         swrap_pcap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
6285                 } else {
6286                         swrap_pcap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
6287                 }
6288                 break;
6289
6290         case SOCK_DGRAM:
6291                 if (si->connected) {
6292                         to = &si->peername.sa.s;
6293                 }
6294                 if (ret == -1) {
6295                         swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
6296                         swrap_pcap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);
6297                 } else {
6298                         swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
6299                 }
6300                 break;
6301         }
6302
6303         SWRAP_UNLOCK_SI(si);
6304
6305         free(buf);
6306         errno = saved_errno;
6307 }
6308
6309 static int swrap_recvmsg_before(int fd,
6310                                 struct socket_info *si,
6311                                 struct msghdr *msg,
6312                                 struct iovec *tmp_iov)
6313 {
6314         size_t i, len = 0;
6315         int ret = -1;
6316
6317         SWRAP_LOCK_SI(si);
6318
6319         (void)fd; /* unused */
6320
6321         switch (si->type) {
6322         case SOCK_STREAM: {
6323                 unsigned int mtu;
6324                 if (!si->connected) {
6325                         errno = ENOTCONN;
6326                         goto out;
6327                 }
6328
6329                 if (msg->msg_iovlen == 0) {
6330                         break;
6331                 }
6332
6333                 mtu = socket_wrapper_mtu();
6334                 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
6335                         size_t nlen;
6336                         nlen = len + msg->msg_iov[i].iov_len;
6337                         if (nlen > mtu) {
6338                                 break;
6339                         }
6340                 }
6341                 msg->msg_iovlen = i;
6342                 if (msg->msg_iovlen == 0) {
6343                         *tmp_iov = msg->msg_iov[0];
6344                         tmp_iov->iov_len = MIN((size_t)tmp_iov->iov_len,
6345                                                (size_t)mtu);
6346                         msg->msg_iov = tmp_iov;
6347                         msg->msg_iovlen = 1;
6348                 }
6349                 break;
6350         }
6351         case SOCK_DGRAM:
6352                 if (msg->msg_name == NULL) {
6353                         errno = EINVAL;
6354                         goto out;
6355                 }
6356
6357                 if (msg->msg_iovlen == 0) {
6358                         break;
6359                 }
6360
6361                 if (si->bound == 0) {
6362                         ret = swrap_auto_bind(fd, si, si->family);
6363                         if (ret == -1) {
6364                                 SWRAP_UNLOCK_SI(si);
6365                                 /*
6366                                  * When attempting to read or write to a
6367                                  * descriptor, if an underlying autobind fails
6368                                  * because it's not a socket, stop intercepting
6369                                  * uses of that descriptor.
6370                                  */
6371                                 if (errno == ENOTSOCK) {
6372                                         swrap_remove_stale(fd);
6373                                         ret = -ENOTSOCK;
6374                                 } else {
6375                                         SWRAP_LOG(SWRAP_LOG_ERROR,
6376                                                   "swrap_recvmsg_before failed");
6377                                 }
6378                                 return ret;
6379                         }
6380                 }
6381                 break;
6382         default:
6383                 errno = EHOSTUNREACH;
6384                 goto out;
6385         }
6386
6387         ret = 0;
6388 out:
6389         SWRAP_UNLOCK_SI(si);
6390
6391         return ret;
6392 }
6393
6394 static int swrap_recvmsg_after(int fd,
6395                                struct socket_info *si,
6396                                struct msghdr *msg,
6397                                const struct sockaddr_un *un_addr,
6398                                socklen_t un_addrlen,
6399                                ssize_t ret)
6400 {
6401         int saved_errno = errno;
6402         size_t i;
6403         uint8_t *buf = NULL;
6404         off_t ofs = 0;
6405         size_t avail = 0;
6406         size_t remain;
6407         int rc;
6408
6409         /* to give better errors */
6410         if (ret == -1) {
6411                 if (saved_errno == ENOENT) {
6412                         saved_errno = EHOSTUNREACH;
6413                 } else if (saved_errno == ENOTSOCK) {
6414                         /* If the fd is not a socket, remove it */
6415                         swrap_remove_stale(fd);
6416                 }
6417         }
6418
6419         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
6420                 avail += msg->msg_iov[i].iov_len;
6421         }
6422
6423         SWRAP_LOCK_SI(si);
6424
6425         /* Convert the socket address before we leave */
6426         if (si->type == SOCK_DGRAM && un_addr != NULL) {
6427                 rc = sockaddr_convert_from_un(si,
6428                                               un_addr,
6429                                               un_addrlen,
6430                                               si->family,
6431                                               msg->msg_name,
6432                                               &msg->msg_namelen);
6433                 if (rc == -1) {
6434                         goto done;
6435                 }
6436         }
6437
6438         if (avail == 0) {
6439                 rc = 0;
6440                 goto done;
6441         }
6442
6443         if (ret == -1) {
6444                 remain = MIN(80, avail);
6445         } else {
6446                 remain = ret;
6447         }
6448
6449         /* we capture it as one single packet */
6450         buf = (uint8_t *)malloc(remain);
6451         if (buf == NULL) {
6452                 /* we just not capture the packet */
6453                 SWRAP_UNLOCK_SI(si);
6454                 errno = saved_errno;
6455                 return -1;
6456         }
6457
6458         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
6459                 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
6460                 memcpy(buf + ofs,
6461                        msg->msg_iov[i].iov_base,
6462                        this_time);
6463                 ofs += this_time;
6464                 remain -= this_time;
6465         }
6466
6467         switch (si->type) {
6468         case SOCK_STREAM:
6469                 if (ret == -1 && saved_errno != EAGAIN && saved_errno != ENOBUFS) {
6470                         swrap_pcap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
6471                 } else if (ret == 0) { /* END OF FILE */
6472                         swrap_pcap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
6473                 } else if (ret > 0) {
6474                         swrap_pcap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
6475                 }
6476                 break;
6477
6478         case SOCK_DGRAM:
6479                 if (ret == -1) {
6480                         break;
6481                 }
6482
6483                 if (un_addr != NULL) {
6484                         swrap_pcap_dump_packet(si,
6485                                           msg->msg_name,
6486                                           SWRAP_RECVFROM,
6487                                           buf,
6488                                           ret);
6489                 } else {
6490                         swrap_pcap_dump_packet(si,
6491                                           msg->msg_name,
6492                                           SWRAP_RECV,
6493                                           buf,
6494                                           ret);
6495                 }
6496
6497                 break;
6498         }
6499
6500         rc = 0;
6501 done:
6502         free(buf);
6503         errno = saved_errno;
6504
6505 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6506         if (rc == 0 &&
6507             msg->msg_controllen > 0 &&
6508             msg->msg_control != NULL) {
6509                 rc = swrap_msghdr_add_socket_info(si, msg);
6510                 if (rc < 0) {
6511                         SWRAP_UNLOCK_SI(si);
6512                         return -1;
6513                 }
6514         }
6515 #endif
6516
6517         SWRAP_UNLOCK_SI(si);
6518         return rc;
6519 }
6520
6521 /****************************************************************************
6522  *   RECVFROM
6523  ***************************************************************************/
6524
6525 static ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags,
6526                               struct sockaddr *from, socklen_t *fromlen)
6527 {
6528         struct swrap_address from_addr = {
6529                 .sa_socklen = sizeof(struct sockaddr_un),
6530         };
6531         ssize_t ret;
6532         struct socket_info *si = find_socket_info(s);
6533         struct swrap_address saddr = {
6534                 .sa_socklen = sizeof(struct sockaddr_storage),
6535         };
6536         struct msghdr msg;
6537         struct iovec tmp;
6538         int tret;
6539
6540         if (!si) {
6541                 return libc_recvfrom(s,
6542                                      buf,
6543                                      len,
6544                                      flags,
6545                                      from,
6546                                      fromlen);
6547         }
6548
6549         tmp.iov_base = buf;
6550         tmp.iov_len = len;
6551
6552         ZERO_STRUCT(msg);
6553         if (from != NULL && fromlen != NULL) {
6554                 msg.msg_name = from;   /* optional address */
6555                 msg.msg_namelen = *fromlen; /* size of address */
6556         } else {
6557                 msg.msg_name = &saddr.sa.s; /* optional address */
6558                 msg.msg_namelen = saddr.sa_socklen; /* size of address */
6559         }
6560         msg.msg_iov = &tmp;            /* scatter/gather array */
6561         msg.msg_iovlen = 1;            /* # elements in msg_iov */
6562 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6563         msg.msg_control = NULL;        /* ancillary data, see below */
6564         msg.msg_controllen = 0;        /* ancillary data buffer len */
6565         msg.msg_flags = 0;             /* flags on received message */
6566 #endif
6567
6568         tret = swrap_recvmsg_before(s, si, &msg, &tmp);
6569         if (tret < 0) {
6570                 return -1;
6571         }
6572
6573         buf = msg.msg_iov[0].iov_base;
6574         len = msg.msg_iov[0].iov_len;
6575
6576         ret = libc_recvfrom(s,
6577                             buf,
6578                             len,
6579                             flags,
6580                             &from_addr.sa.s,
6581                             &from_addr.sa_socklen);
6582         if (ret == -1) {
6583                 return ret;
6584         }
6585
6586         tret = swrap_recvmsg_after(s,
6587                                    si,
6588                                    &msg,
6589                                    &from_addr.sa.un,
6590                                    from_addr.sa_socklen,
6591                                    ret);
6592         if (tret != 0) {
6593                 return tret;
6594         }
6595
6596         if (from != NULL && fromlen != NULL) {
6597                 *fromlen = msg.msg_namelen;
6598         }
6599
6600         return ret;
6601 }
6602
6603 #ifdef HAVE_ACCEPT_PSOCKLEN_T
6604 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
6605                  struct sockaddr *from, Psocklen_t fromlen)
6606 #else
6607 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
6608                  struct sockaddr *from, socklen_t *fromlen)
6609 #endif
6610 {
6611         return swrap_recvfrom(s, buf, len, flags, from, (socklen_t *)fromlen);
6612 }
6613
6614 /****************************************************************************
6615  *   SENDTO
6616  ***************************************************************************/
6617
6618 static ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags,
6619                             const struct sockaddr *to, socklen_t tolen)
6620 {
6621         struct msghdr msg;
6622         struct iovec tmp;
6623         struct swrap_address un_addr = {
6624                 .sa_socklen = sizeof(struct sockaddr_un),
6625         };
6626         const struct sockaddr_un *to_un = NULL;
6627         ssize_t ret;
6628         int rc;
6629         struct socket_info *si = find_socket_info(s);
6630         int bcast = 0;
6631
6632         if (!si) {
6633                 return libc_sendto(s, buf, len, flags, to, tolen);
6634         }
6635
6636         tmp.iov_base = discard_const_p(char, buf);
6637         tmp.iov_len = len;
6638
6639         ZERO_STRUCT(msg);
6640         msg.msg_name = discard_const_p(struct sockaddr, to); /* optional address */
6641         msg.msg_namelen = tolen;       /* size of address */
6642         msg.msg_iov = &tmp;            /* scatter/gather array */
6643         msg.msg_iovlen = 1;            /* # elements in msg_iov */
6644 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6645         msg.msg_control = NULL;        /* ancillary data, see below */
6646         msg.msg_controllen = 0;        /* ancillary data buffer len */
6647         msg.msg_flags = 0;             /* flags on received message */
6648 #endif
6649
6650         rc = swrap_sendmsg_before(s,
6651                                   si,
6652                                   &msg,
6653                                   &tmp,
6654                                   &un_addr.sa.un,
6655                                   &to_un,
6656                                   &to,
6657                                   &bcast);
6658         if (rc < 0) {
6659                 return -1;
6660         }
6661
6662         buf = msg.msg_iov[0].iov_base;
6663         len = msg.msg_iov[0].iov_len;
6664
6665         if (bcast) {
6666                 struct stat st;
6667                 unsigned int iface;
6668                 unsigned int prt = ntohs(((const struct sockaddr_in *)(const void *)to)->sin_port);
6669                 char type;
6670                 char *swrap_dir = NULL;
6671
6672                 type = SOCKET_TYPE_CHAR_UDP;
6673
6674                 swrap_dir = socket_wrapper_dir();
6675                 if (swrap_dir == NULL) {
6676                         return -1;
6677                 }
6678
6679                 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
6680                         swrap_un_path(&un_addr.sa.un,
6681                                       swrap_dir,
6682                                       type,
6683                                       iface,
6684                                       prt);
6685                         if (stat(un_addr.sa.un.sun_path, &st) != 0) continue;
6686
6687                         /* ignore the any errors in broadcast sends */
6688                         libc_sendto(s,
6689                                     buf,
6690                                     len,
6691                                     flags,
6692                                     &un_addr.sa.s,
6693                                     un_addr.sa_socklen);
6694                 }
6695
6696                 SAFE_FREE(swrap_dir);
6697
6698                 SWRAP_LOCK_SI(si);
6699
6700                 swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
6701
6702                 SWRAP_UNLOCK_SI(si);
6703
6704                 return len;
6705         }
6706
6707         SWRAP_LOCK_SI(si);
6708         /*
6709          * If it is a dgram socket and we are connected, don't include the
6710          * 'to' address.
6711          */
6712         if (si->type == SOCK_DGRAM && si->connected) {
6713                 ret = libc_sendto(s,
6714                                   buf,
6715                                   len,
6716                                   flags,
6717                                   NULL,
6718                                   0);
6719         } else {
6720                 ret = libc_sendto(s,
6721                                   buf,
6722                                   len,
6723                                   flags,
6724                                   (struct sockaddr *)msg.msg_name,
6725                                   msg.msg_namelen);
6726         }
6727
6728         SWRAP_UNLOCK_SI(si);
6729
6730         swrap_sendmsg_after(s, si, &msg, to, ret);
6731
6732         return ret;
6733 }
6734
6735 ssize_t sendto(int s, const void *buf, size_t len, int flags,
6736                const struct sockaddr *to, socklen_t tolen)
6737 {
6738         return swrap_sendto(s, buf, len, flags, to, tolen);
6739 }
6740
6741 /****************************************************************************
6742  *   READV
6743  ***************************************************************************/
6744
6745 static ssize_t swrap_recv(int s, void *buf, size_t len, int flags)
6746 {
6747         struct socket_info *si;
6748         struct msghdr msg;
6749         struct swrap_address saddr = {
6750                 .sa_socklen = sizeof(struct sockaddr_storage),
6751         };
6752         struct iovec tmp;
6753         ssize_t ret;
6754         int tret;
6755
6756         si = find_socket_info(s);
6757         if (si == NULL) {
6758                 return libc_recv(s, buf, len, flags);
6759         }
6760
6761         tmp.iov_base = buf;
6762         tmp.iov_len = len;
6763
6764         ZERO_STRUCT(msg);
6765         msg.msg_name = &saddr.sa.s;    /* optional address */
6766         msg.msg_namelen = saddr.sa_socklen; /* size of address */
6767         msg.msg_iov = &tmp;            /* scatter/gather array */
6768         msg.msg_iovlen = 1;            /* # elements in msg_iov */
6769 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6770         msg.msg_control = NULL;        /* ancillary data, see below */
6771         msg.msg_controllen = 0;        /* ancillary data buffer len */
6772         msg.msg_flags = 0;             /* flags on received message */
6773 #endif
6774
6775         tret = swrap_recvmsg_before(s, si, &msg, &tmp);
6776         if (tret < 0) {
6777                 return -1;
6778         }
6779
6780         buf = msg.msg_iov[0].iov_base;
6781         len = msg.msg_iov[0].iov_len;
6782
6783         ret = libc_recv(s, buf, len, flags);
6784
6785         tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
6786         if (tret != 0) {
6787                 return tret;
6788         }
6789
6790         return ret;
6791 }
6792
6793 ssize_t recv(int s, void *buf, size_t len, int flags)
6794 {
6795         return swrap_recv(s, buf, len, flags);
6796 }
6797
6798 /****************************************************************************
6799  *   READ
6800  ***************************************************************************/
6801
6802 static ssize_t swrap_read(int s, void *buf, size_t len)
6803 {
6804         struct socket_info *si;
6805         struct msghdr msg;
6806         struct iovec tmp;
6807         struct swrap_address saddr = {
6808                 .sa_socklen = sizeof(struct sockaddr_storage),
6809         };
6810         ssize_t ret;
6811         int tret;
6812
6813         si = find_socket_info(s);
6814         if (si == NULL) {
6815                 return libc_read(s, buf, len);
6816         }
6817
6818         tmp.iov_base = buf;
6819         tmp.iov_len = len;
6820
6821         ZERO_STRUCT(msg);
6822         msg.msg_name = &saddr.sa.ss;   /* optional address */
6823         msg.msg_namelen = saddr.sa_socklen; /* size of address */
6824         msg.msg_iov = &tmp;            /* scatter/gather array */
6825         msg.msg_iovlen = 1;            /* # elements in msg_iov */
6826 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6827         msg.msg_control = NULL;        /* ancillary data, see below */
6828         msg.msg_controllen = 0;        /* ancillary data buffer len */
6829         msg.msg_flags = 0;             /* flags on received message */
6830 #endif
6831
6832         tret = swrap_recvmsg_before(s, si, &msg, &tmp);
6833         if (tret < 0) {
6834                 if (tret == -ENOTSOCK) {
6835                         return libc_read(s, buf, len);
6836                 }
6837                 return -1;
6838         }
6839
6840         buf = msg.msg_iov[0].iov_base;
6841         len = msg.msg_iov[0].iov_len;
6842
6843         ret = libc_read(s, buf, len);
6844
6845         tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
6846         if (tret != 0) {
6847                 return tret;
6848         }
6849
6850         return ret;
6851 }
6852
6853 ssize_t read(int s, void *buf, size_t len)
6854 {
6855         return swrap_read(s, buf, len);
6856 }
6857
6858 /****************************************************************************
6859  *   WRITE
6860  ***************************************************************************/
6861
6862 static ssize_t swrap_write(int s, const void *buf, size_t len)
6863 {
6864         struct msghdr msg;
6865         struct iovec tmp;
6866         struct sockaddr_un un_addr;
6867         ssize_t ret;
6868         int rc;
6869         struct socket_info *si;
6870
6871         si = find_socket_info(s);
6872         if (si == NULL) {
6873                 return libc_write(s, buf, len);
6874         }
6875
6876         tmp.iov_base = discard_const_p(char, buf);
6877         tmp.iov_len = len;
6878
6879         ZERO_STRUCT(msg);
6880         msg.msg_name = NULL;           /* optional address */
6881         msg.msg_namelen = 0;           /* size of address */
6882         msg.msg_iov = &tmp;            /* scatter/gather array */
6883         msg.msg_iovlen = 1;            /* # elements in msg_iov */
6884 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6885         msg.msg_control = NULL;        /* ancillary data, see below */
6886         msg.msg_controllen = 0;        /* ancillary data buffer len */
6887         msg.msg_flags = 0;             /* flags on received message */
6888 #endif
6889
6890         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
6891         if (rc < 0) {
6892                 return -1;
6893         }
6894
6895         buf = msg.msg_iov[0].iov_base;
6896         len = msg.msg_iov[0].iov_len;
6897
6898         ret = libc_write(s, buf, len);
6899
6900         swrap_sendmsg_after(s, si, &msg, NULL, ret);
6901
6902         return ret;
6903 }
6904
6905 ssize_t write(int s, const void *buf, size_t len)
6906 {
6907         return swrap_write(s, buf, len);
6908 }
6909
6910 /****************************************************************************
6911  *   SEND
6912  ***************************************************************************/
6913
6914 static ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
6915 {
6916         struct msghdr msg;
6917         struct iovec tmp;
6918         struct sockaddr_un un_addr;
6919         ssize_t ret;
6920         int rc;
6921         struct socket_info *si = find_socket_info(s);
6922
6923         if (!si) {
6924                 return libc_send(s, buf, len, flags);
6925         }
6926
6927         tmp.iov_base = discard_const_p(char, buf);
6928         tmp.iov_len = len;
6929
6930         ZERO_STRUCT(msg);
6931         msg.msg_name = NULL;           /* optional address */
6932         msg.msg_namelen = 0;           /* size of address */
6933         msg.msg_iov = &tmp;            /* scatter/gather array */
6934         msg.msg_iovlen = 1;            /* # elements in msg_iov */
6935 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6936         msg.msg_control = NULL;        /* ancillary data, see below */
6937         msg.msg_controllen = 0;        /* ancillary data buffer len */
6938         msg.msg_flags = 0;             /* flags on received message */
6939 #endif
6940
6941         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
6942         if (rc < 0) {
6943                 return -1;
6944         }
6945
6946         buf = msg.msg_iov[0].iov_base;
6947         len = msg.msg_iov[0].iov_len;
6948
6949         ret = libc_send(s, buf, len, flags);
6950
6951         swrap_sendmsg_after(s, si, &msg, NULL, ret);
6952
6953         return ret;
6954 }
6955
6956 ssize_t send(int s, const void *buf, size_t len, int flags)
6957 {
6958         return swrap_send(s, buf, len, flags);
6959 }
6960
6961 /****************************************************************************
6962  *   RECVMSG
6963  ***************************************************************************/
6964
6965 static ssize_t swrap_recvmsg(int s, struct msghdr *omsg, int flags)
6966 {
6967         struct swrap_address from_addr = {
6968                 .sa_socklen = sizeof(struct sockaddr_un),
6969         };
6970         struct swrap_address convert_addr = {
6971                 .sa_socklen = sizeof(struct sockaddr_storage),
6972         };
6973         struct socket_info *si;
6974         struct msghdr msg;
6975         struct iovec tmp;
6976 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6977         size_t msg_ctrllen_filled;
6978         size_t msg_ctrllen_left;
6979 #endif
6980
6981         ssize_t ret;
6982         int rc;
6983
6984         si = find_socket_info(s);
6985         if (si == NULL) {
6986                 uint8_t *tmp_control = NULL;
6987                 rc = swrap_recvmsg_before_unix(omsg, &msg, &tmp_control);
6988                 if (rc < 0) {
6989                         return rc;
6990                 }
6991                 ret = libc_recvmsg(s, &msg, flags);
6992                 return swrap_recvmsg_after_unix(&msg, &tmp_control, omsg, ret);
6993         }
6994
6995         tmp.iov_base = NULL;
6996         tmp.iov_len = 0;
6997
6998         ZERO_STRUCT(msg);
6999         msg.msg_name = &from_addr.sa;              /* optional address */
7000         msg.msg_namelen = from_addr.sa_socklen;    /* size of address */
7001         msg.msg_iov = omsg->msg_iov;               /* scatter/gather array */
7002         msg.msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
7003 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7004         msg_ctrllen_filled = 0;
7005         msg_ctrllen_left = omsg->msg_controllen;
7006
7007         msg.msg_control = omsg->msg_control;       /* ancillary data, see below */
7008         msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
7009         msg.msg_flags = omsg->msg_flags;           /* flags on received message */
7010 #endif
7011
7012         rc = swrap_recvmsg_before(s, si, &msg, &tmp);
7013         if (rc < 0) {
7014                 return -1;
7015         }
7016
7017         ret = libc_recvmsg(s, &msg, flags);
7018
7019 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7020         msg_ctrllen_filled += msg.msg_controllen;
7021         msg_ctrllen_left -= msg.msg_controllen;
7022
7023         if (omsg->msg_control != NULL) {
7024                 uint8_t *p;
7025
7026                 p = omsg->msg_control;
7027                 p += msg_ctrllen_filled;
7028
7029                 msg.msg_control = p;
7030                 msg.msg_controllen = msg_ctrllen_left;
7031         } else {
7032                 msg.msg_control = NULL;
7033                 msg.msg_controllen = 0;
7034         }
7035 #endif
7036
7037         /*
7038          * We convert the unix address to a IP address so we need a buffer
7039          * which can store the address in case of SOCK_DGRAM, see below.
7040          */
7041         msg.msg_name = &convert_addr.sa;
7042         msg.msg_namelen = convert_addr.sa_socklen;
7043
7044         rc = swrap_recvmsg_after(s,
7045                                  si,
7046                                  &msg,
7047                                  &from_addr.sa.un,
7048                                  from_addr.sa_socklen,
7049                                  ret);
7050         if (rc != 0) {
7051                 return rc;
7052         }
7053
7054 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7055         if (omsg->msg_control != NULL) {
7056                 /* msg.msg_controllen = space left */
7057                 msg_ctrllen_left = msg.msg_controllen;
7058                 msg_ctrllen_filled = omsg->msg_controllen - msg_ctrllen_left;
7059         }
7060
7061         /* Update the original message length */
7062         omsg->msg_controllen = msg_ctrllen_filled;
7063         omsg->msg_flags = msg.msg_flags;
7064 #endif
7065         omsg->msg_iovlen = msg.msg_iovlen;
7066
7067         SWRAP_LOCK_SI(si);
7068
7069         /*
7070          * From the manpage:
7071          *
7072          * The  msg_name  field  points  to a caller-allocated buffer that is
7073          * used to return the source address if the socket is unconnected.  The
7074          * caller should set msg_namelen to the size of this buffer before this
7075          * call; upon return from a successful call, msg_name will contain the
7076          * length of the returned address.  If the application  does  not  need
7077          * to know the source address, msg_name can be specified as NULL.
7078          */
7079         if (si->type == SOCK_STREAM) {
7080                 omsg->msg_namelen = 0;
7081         } else if (omsg->msg_name != NULL &&
7082                    omsg->msg_namelen != 0 &&
7083                    omsg->msg_namelen >= msg.msg_namelen) {
7084                 memcpy(omsg->msg_name, msg.msg_name, msg.msg_namelen);
7085                 omsg->msg_namelen = msg.msg_namelen;
7086         }
7087
7088         SWRAP_UNLOCK_SI(si);
7089
7090         return ret;
7091 }
7092
7093 ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)
7094 {
7095         return swrap_recvmsg(sockfd, msg, flags);
7096 }
7097
7098 /****************************************************************************
7099  *   SENDMSG
7100  ***************************************************************************/
7101
7102 static ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags)
7103 {
7104         struct msghdr msg;
7105         struct iovec tmp;
7106         struct sockaddr_un un_addr;
7107         const struct sockaddr_un *to_un = NULL;
7108         const struct sockaddr *to = NULL;
7109         ssize_t ret;
7110         int rc;
7111         struct socket_info *si = find_socket_info(s);
7112         int bcast = 0;
7113
7114         if (!si) {
7115                 int scm_rights_pipe_fd = -1;
7116
7117                 rc = swrap_sendmsg_before_unix(omsg, &msg,
7118                                                &scm_rights_pipe_fd);
7119                 if (rc < 0) {
7120                         return rc;
7121                 }
7122                 ret = libc_sendmsg(s, &msg, flags);
7123                 return swrap_sendmsg_after_unix(&msg, ret, scm_rights_pipe_fd);
7124         }
7125
7126         ZERO_STRUCT(un_addr);
7127
7128         tmp.iov_base = NULL;
7129         tmp.iov_len = 0;
7130
7131         ZERO_STRUCT(msg);
7132
7133         SWRAP_LOCK_SI(si);
7134
7135         if (si->connected == 0) {
7136                 msg.msg_name = omsg->msg_name;             /* optional address */
7137                 msg.msg_namelen = omsg->msg_namelen;       /* size of address */
7138         }
7139         msg.msg_iov = omsg->msg_iov;               /* scatter/gather array */
7140         msg.msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
7141
7142         SWRAP_UNLOCK_SI(si);
7143
7144 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7145         if (omsg != NULL && omsg->msg_controllen > 0 && omsg->msg_control != NULL) {
7146                 uint8_t *cmbuf = NULL;
7147                 size_t cmlen = 0;
7148
7149                 rc = swrap_sendmsg_filter_cmsghdr(omsg, &cmbuf, &cmlen);
7150                 if (rc < 0) {
7151                         return rc;
7152                 }
7153
7154                 if (cmlen == 0) {
7155                         msg.msg_controllen = 0;
7156                         msg.msg_control = NULL;
7157                 } else {
7158                         msg.msg_control = cmbuf;
7159                         msg.msg_controllen = cmlen;
7160                 }
7161         }
7162         msg.msg_flags = omsg->msg_flags;           /* flags on received message */
7163 #endif
7164         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
7165         if (rc < 0) {
7166                 int saved_errno = errno;
7167 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7168                 SAFE_FREE(msg.msg_control);
7169 #endif
7170                 errno = saved_errno;
7171                 return -1;
7172         }
7173
7174         if (bcast) {
7175                 struct stat st;
7176                 unsigned int iface;
7177                 unsigned int prt = ntohs(((const struct sockaddr_in *)(const void *)to)->sin_port);
7178                 char type;
7179                 size_t i, len = 0;
7180                 uint8_t *buf;
7181                 off_t ofs = 0;
7182                 size_t avail = 0;
7183                 size_t remain;
7184                 char *swrap_dir = NULL;
7185
7186                 for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
7187                         avail += msg.msg_iov[i].iov_len;
7188                 }
7189
7190                 len = avail;
7191                 remain = avail;
7192
7193                 /* we capture it as one single packet */
7194                 buf = (uint8_t *)malloc(remain);
7195                 if (!buf) {
7196                         int saved_errno = errno;
7197 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7198                         SAFE_FREE(msg.msg_control);
7199 #endif
7200                         errno = saved_errno;
7201                         return -1;
7202                 }
7203
7204                 for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
7205                         size_t this_time = MIN(remain, (size_t)msg.msg_iov[i].iov_len);
7206                         memcpy(buf + ofs,
7207                                msg.msg_iov[i].iov_base,
7208                                this_time);
7209                         ofs += this_time;
7210                         remain -= this_time;
7211                 }
7212
7213                 type = SOCKET_TYPE_CHAR_UDP;
7214
7215                 swrap_dir = socket_wrapper_dir();
7216                 if (swrap_dir == NULL) {
7217                         int saved_errno = errno;
7218 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7219                         SAFE_FREE(msg.msg_control);
7220 #endif
7221                         SAFE_FREE(buf);
7222                         errno = saved_errno;
7223                         return -1;
7224                 }
7225
7226                 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
7227                         swrap_un_path(&un_addr, swrap_dir, type, iface, prt);
7228                         if (stat(un_addr.sun_path, &st) != 0) continue;
7229
7230                         msg.msg_name = &un_addr;           /* optional address */
7231                         msg.msg_namelen = sizeof(un_addr); /* size of address */
7232
7233                         /* ignore the any errors in broadcast sends */
7234                         libc_sendmsg(s, &msg, flags);
7235                 }
7236
7237                 SAFE_FREE(swrap_dir);
7238
7239                 SWRAP_LOCK_SI(si);
7240
7241                 swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
7242                 free(buf);
7243
7244                 SWRAP_UNLOCK_SI(si);
7245
7246                 return len;
7247         }
7248
7249         ret = libc_sendmsg(s, &msg, flags);
7250
7251         swrap_sendmsg_after(s, si, &msg, to, ret);
7252
7253 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7254         {
7255                 int saved_errno = errno;
7256                 SAFE_FREE(msg.msg_control);
7257                 errno = saved_errno;
7258         }
7259 #endif
7260
7261         return ret;
7262 }
7263
7264 ssize_t sendmsg(int s, const struct msghdr *omsg, int flags)
7265 {
7266         return swrap_sendmsg(s, omsg, flags);
7267 }
7268
7269 /****************************************************************************
7270  *   READV
7271  ***************************************************************************/
7272
7273 static ssize_t swrap_readv(int s, const struct iovec *vector, int count)
7274 {
7275         struct socket_info *si;
7276         struct msghdr msg;
7277         struct iovec tmp;
7278         struct swrap_address saddr = {
7279                 .sa_socklen = sizeof(struct sockaddr_storage)
7280         };
7281         ssize_t ret;
7282         int rc;
7283
7284         si = find_socket_info(s);
7285         if (si == NULL) {
7286                 return libc_readv(s, vector, count);
7287         }
7288
7289         tmp.iov_base = NULL;
7290         tmp.iov_len = 0;
7291
7292         ZERO_STRUCT(msg);
7293         msg.msg_name = &saddr.sa.s; /* optional address */
7294         msg.msg_namelen = saddr.sa_socklen;      /* size of address */
7295         msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
7296         msg.msg_iovlen = count;        /* # elements in msg_iov */
7297 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7298         msg.msg_control = NULL;        /* ancillary data, see below */
7299         msg.msg_controllen = 0;        /* ancillary data buffer len */
7300         msg.msg_flags = 0;             /* flags on received message */
7301 #endif
7302
7303         rc = swrap_recvmsg_before(s, si, &msg, &tmp);
7304         if (rc < 0) {
7305                 if (rc == -ENOTSOCK) {
7306                         return libc_readv(s, vector, count);
7307                 }
7308                 return -1;
7309         }
7310
7311         ret = libc_readv(s, msg.msg_iov, msg.msg_iovlen);
7312
7313         rc = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
7314         if (rc != 0) {
7315                 return rc;
7316         }
7317
7318         return ret;
7319 }
7320
7321 ssize_t readv(int s, const struct iovec *vector, int count)
7322 {
7323         return swrap_readv(s, vector, count);
7324 }
7325
7326 /****************************************************************************
7327  *   WRITEV
7328  ***************************************************************************/
7329
7330 static ssize_t swrap_writev(int s, const struct iovec *vector, int count)
7331 {
7332         struct msghdr msg;
7333         struct iovec tmp;
7334         struct sockaddr_un un_addr;
7335         ssize_t ret;
7336         int rc;
7337         struct socket_info *si = find_socket_info(s);
7338
7339         if (!si) {
7340                 return libc_writev(s, vector, count);
7341         }
7342
7343         tmp.iov_base = NULL;
7344         tmp.iov_len = 0;
7345
7346         ZERO_STRUCT(msg);
7347         msg.msg_name = NULL;           /* optional address */
7348         msg.msg_namelen = 0;           /* size of address */
7349         msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
7350         msg.msg_iovlen = count;        /* # elements in msg_iov */
7351 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7352         msg.msg_control = NULL;        /* ancillary data, see below */
7353         msg.msg_controllen = 0;        /* ancillary data buffer len */
7354         msg.msg_flags = 0;             /* flags on received message */
7355 #endif
7356
7357         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
7358         if (rc < 0) {
7359                 if (rc == -ENOTSOCK) {
7360                         return libc_readv(s, vector, count);
7361                 }
7362                 return -1;
7363         }
7364
7365         ret = libc_writev(s, msg.msg_iov, msg.msg_iovlen);
7366
7367         swrap_sendmsg_after(s, si, &msg, NULL, ret);
7368
7369         return ret;
7370 }
7371
7372 ssize_t writev(int s, const struct iovec *vector, int count)
7373 {
7374         return swrap_writev(s, vector, count);
7375 }
7376
7377 /****************************
7378  * CLOSE
7379  ***************************/
7380
7381 static int swrap_remove_wrapper(const char *__func_name,
7382                                 int (*__close_fd_fn)(int fd),
7383                                 int fd)
7384 {
7385         struct socket_info *si = NULL;
7386         int si_index;
7387         int ret_errno = errno;
7388         int ret;
7389
7390         swrap_mutex_lock(&socket_reset_mutex);
7391
7392         si_index = find_socket_info_index(fd);
7393         if (si_index == -1) {
7394                 swrap_mutex_unlock(&socket_reset_mutex);
7395                 return __close_fd_fn(fd);
7396         }
7397
7398         swrap_log(SWRAP_LOG_TRACE, __func_name, "Remove wrapper for fd=%d", fd);
7399         reset_socket_info_index(fd);
7400
7401         si = swrap_get_socket_info(si_index);
7402
7403         swrap_mutex_lock(&first_free_mutex);
7404         SWRAP_LOCK_SI(si);
7405
7406         ret = __close_fd_fn(fd);
7407         if (ret == -1) {
7408                 ret_errno = errno;
7409         }
7410
7411         swrap_dec_refcount(si);
7412
7413         if (swrap_get_refcount(si) > 0) {
7414                 /* there are still references left */
7415                 goto out;
7416         }
7417
7418         if (si->fd_passed) {
7419                 goto set_next_free;
7420         }
7421
7422         if (si->myname.sa_socklen > 0 && si->peername.sa_socklen > 0) {
7423                 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0);
7424         }
7425
7426         if (si->myname.sa_socklen > 0 && si->peername.sa_socklen > 0) {
7427                 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0);
7428                 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0);
7429         }
7430
7431         if (si->un_addr.sun_path[0] != '\0') {
7432                 unlink(si->un_addr.sun_path);
7433         }
7434
7435 set_next_free:
7436         swrap_set_next_free(si, first_free);
7437         first_free = si_index;
7438
7439 out:
7440         SWRAP_UNLOCK_SI(si);
7441         swrap_mutex_unlock(&first_free_mutex);
7442         swrap_mutex_unlock(&socket_reset_mutex);
7443
7444         errno = ret_errno;
7445         return ret;
7446 }
7447
7448 static int swrap_noop_close(int fd)
7449 {
7450         (void)fd; /* unused */
7451         return 0;
7452 }
7453
7454 static void swrap_remove_stale(int fd)
7455 {
7456         swrap_remove_wrapper(__func__, swrap_noop_close, fd);
7457 }
7458
7459 /*
7460  * This allows socket_wrapper aware applications to
7461  * indicate that the given fd does not belong to
7462  * an inet socket.
7463  *
7464  * We already overload a lot of unrelated functions
7465  * like eventfd(), timerfd_create(), ... in order to
7466  * call swrap_remove_stale() on the returned fd, but
7467  * we'll never be able to handle all possible syscalls.
7468  *
7469  * socket_wrapper_indicate_no_inet_fd() gives them a way
7470  * to do the same.
7471  *
7472  * We don't export swrap_remove_stale() in order to
7473  * make it easier to analyze SOCKET_WRAPPER_DEBUGLEVEL=3
7474  * log files.
7475  */
7476 void socket_wrapper_indicate_no_inet_fd(int fd)
7477 {
7478         swrap_remove_wrapper(__func__, swrap_noop_close, fd);
7479 }
7480
7481 static int swrap_close(int fd)
7482 {
7483         return swrap_remove_wrapper(__func__, libc_close, fd);
7484 }
7485
7486 int close(int fd)
7487 {
7488         return swrap_close(fd);
7489 }
7490
7491 /****************************
7492  * DUP
7493  ***************************/
7494
7495 static int swrap_dup(int fd)
7496 {
7497         struct socket_info *si;
7498         int dup_fd, idx;
7499
7500         idx = find_socket_info_index(fd);
7501         if (idx == -1) {
7502                 return libc_dup(fd);
7503         }
7504
7505         si = swrap_get_socket_info(idx);
7506
7507         dup_fd = libc_dup(fd);
7508         if (dup_fd == -1) {
7509                 int saved_errno = errno;
7510                 errno = saved_errno;
7511                 return -1;
7512         }
7513
7514         if ((size_t)dup_fd >= socket_fds_max) {
7515                 SWRAP_LOG(SWRAP_LOG_ERROR,
7516                           "The max socket index limit of %zu has been reached, "
7517                           "trying to add %d",
7518                           socket_fds_max,
7519                           dup_fd);
7520                 libc_close(dup_fd);
7521                 errno = EMFILE;
7522                 return -1;
7523         }
7524
7525         SWRAP_LOCK_SI(si);
7526
7527         swrap_inc_refcount(si);
7528
7529         SWRAP_UNLOCK_SI(si);
7530
7531         /* Make sure we don't have an entry for the fd */
7532         swrap_remove_stale(dup_fd);
7533
7534         set_socket_info_index(dup_fd, idx);
7535
7536         return dup_fd;
7537 }
7538
7539 int dup(int fd)
7540 {
7541         return swrap_dup(fd);
7542 }
7543
7544 /****************************
7545  * DUP2
7546  ***************************/
7547
7548 static int swrap_dup2(int fd, int newfd)
7549 {
7550         struct socket_info *si;
7551         int dup_fd, idx;
7552
7553         idx = find_socket_info_index(fd);
7554         if (idx == -1) {
7555                 return libc_dup2(fd, newfd);
7556         }
7557
7558         si = swrap_get_socket_info(idx);
7559
7560         if (fd == newfd) {
7561                 /*
7562                  * According to the manpage:
7563                  *
7564                  * "If oldfd is a valid file descriptor, and newfd has the same
7565                  * value as oldfd, then dup2() does nothing, and returns newfd."
7566                  */
7567                 return newfd;
7568         }
7569
7570         if ((size_t)newfd >= socket_fds_max) {
7571                 SWRAP_LOG(SWRAP_LOG_ERROR,
7572                           "The max socket index limit of %zu has been reached, "
7573                           "trying to add %d",
7574                           socket_fds_max,
7575                           newfd);
7576                 errno = EMFILE;
7577                 return -1;
7578         }
7579
7580         if (find_socket_info(newfd)) {
7581                 /* dup2() does an implicit close of newfd, which we
7582                  * need to emulate */
7583                 swrap_close(newfd);
7584         }
7585
7586         dup_fd = libc_dup2(fd, newfd);
7587         if (dup_fd == -1) {
7588                 int saved_errno = errno;
7589                 errno = saved_errno;
7590                 return -1;
7591         }
7592
7593         SWRAP_LOCK_SI(si);
7594
7595         swrap_inc_refcount(si);
7596
7597         SWRAP_UNLOCK_SI(si);
7598
7599         /* Make sure we don't have an entry for the fd */
7600         swrap_remove_stale(dup_fd);
7601
7602         set_socket_info_index(dup_fd, idx);
7603
7604         return dup_fd;
7605 }
7606
7607 int dup2(int fd, int newfd)
7608 {
7609         return swrap_dup2(fd, newfd);
7610 }
7611
7612 /****************************
7613  * FCNTL
7614  ***************************/
7615
7616 static int swrap_vfcntl(int fd, int cmd, va_list va)
7617 {
7618         struct socket_info *si;
7619         int rc, dup_fd, idx;
7620
7621         idx = find_socket_info_index(fd);
7622         if (idx == -1) {
7623                 return libc_vfcntl(fd, cmd, va);
7624         }
7625
7626         si = swrap_get_socket_info(idx);
7627
7628         switch (cmd) {
7629         case F_DUPFD:
7630                 dup_fd = libc_vfcntl(fd, cmd, va);
7631                 if (dup_fd == -1) {
7632                         int saved_errno = errno;
7633                         errno = saved_errno;
7634                         return -1;
7635                 }
7636
7637                 /* Make sure we don't have an entry for the fd */
7638                 swrap_remove_stale(dup_fd);
7639
7640                 if ((size_t)dup_fd >= socket_fds_max) {
7641                         SWRAP_LOG(SWRAP_LOG_ERROR,
7642                           "The max socket index limit of %zu has been reached, "
7643                           "trying to add %d",
7644                           socket_fds_max,
7645                           dup_fd);
7646                         libc_close(dup_fd);
7647                         errno = EMFILE;
7648                         return -1;
7649                 }
7650
7651                 SWRAP_LOCK_SI(si);
7652
7653                 swrap_inc_refcount(si);
7654
7655                 SWRAP_UNLOCK_SI(si);
7656
7657
7658                 set_socket_info_index(dup_fd, idx);
7659
7660                 rc = dup_fd;
7661                 break;
7662         default:
7663                 rc = libc_vfcntl(fd, cmd, va);
7664                 break;
7665         }
7666
7667         return rc;
7668 }
7669
7670 int fcntl(int fd, int cmd, ...)
7671 {
7672         va_list va;
7673         int rc;
7674
7675         va_start(va, cmd);
7676
7677         rc = swrap_vfcntl(fd, cmd, va);
7678
7679         va_end(va);
7680
7681         return rc;
7682 }
7683
7684 /****************************
7685  * EVENTFD
7686  ***************************/
7687
7688 #ifdef HAVE_EVENTFD
7689 static int swrap_eventfd(int count, int flags)
7690 {
7691         int fd;
7692
7693         fd = libc_eventfd(count, flags);
7694         if (fd != -1) {
7695                 swrap_remove_stale(fd);
7696         }
7697
7698         return fd;
7699 }
7700
7701 #ifdef HAVE_EVENTFD_UNSIGNED_INT
7702 int eventfd(unsigned int count, int flags)
7703 #else
7704 int eventfd(int count, int flags)
7705 #endif
7706 {
7707         return swrap_eventfd(count, flags);
7708 }
7709 #endif
7710
7711 #ifdef HAVE_PLEDGE
7712 int pledge(const char *promises, const char *paths[])
7713 {
7714         (void)promises; /* unused */
7715         (void)paths; /* unused */
7716
7717         return 0;
7718 }
7719 #endif /* HAVE_PLEDGE */
7720
7721 static void swrap_thread_prepare(void)
7722 {
7723         /*
7724          * This function should only be called here!!
7725          *
7726          * We bind all symobls to avoid deadlocks of the fork is
7727          * interrupted by a signal handler using a symbol of this
7728          * library.
7729          */
7730         swrap_bind_symbol_all();
7731
7732         SWRAP_LOCK_ALL;
7733 }
7734
7735 static void swrap_thread_parent(void)
7736 {
7737         SWRAP_UNLOCK_ALL;
7738 }
7739
7740 static void swrap_thread_child(void)
7741 {
7742         SWRAP_REINIT_ALL;
7743 }
7744
7745 /****************************
7746  * CONSTRUCTOR
7747  ***************************/
7748 void swrap_constructor(void)
7749 {
7750         if (PIPE_BUF < sizeof(struct swrap_unix_scm_rights)) {
7751                 SWRAP_LOG(SWRAP_LOG_ERROR,
7752                           "PIPE_BUF=%zu < "
7753                           "sizeof(struct swrap_unix_scm_rights)=%zu\n"
7754                           "sizeof(struct swrap_unix_scm_rights_payload)=%zu "
7755                           "sizeof(struct socket_info)=%zu",
7756                           (size_t)PIPE_BUF,
7757                           sizeof(struct swrap_unix_scm_rights),
7758                           sizeof(struct swrap_unix_scm_rights_payload),
7759                           sizeof(struct socket_info));
7760                 exit(-1);
7761         }
7762
7763         SWRAP_REINIT_ALL;
7764
7765         /*
7766         * If we hold a lock and the application forks, then the child
7767         * is not able to unlock the mutex and we are in a deadlock.
7768         * This should prevent such deadlocks.
7769         */
7770         pthread_atfork(&swrap_thread_prepare,
7771                        &swrap_thread_parent,
7772                        &swrap_thread_child);
7773 }
7774
7775 /****************************
7776  * DESTRUCTOR
7777  ***************************/
7778
7779 /*
7780  * This function is called when the library is unloaded and makes sure that
7781  * sockets get closed and the unix file for the socket are unlinked.
7782  */
7783 void swrap_destructor(void)
7784 {
7785         size_t i;
7786
7787         if (socket_fds_idx != NULL) {
7788                 for (i = 0; i < socket_fds_max; ++i) {
7789                         if (socket_fds_idx[i] != -1) {
7790                                 swrap_close(i);
7791                         }
7792                 }
7793                 SAFE_FREE(socket_fds_idx);
7794         }
7795
7796         SAFE_FREE(sockets);
7797
7798         if (swrap.libc.handle != NULL) {
7799                 dlclose(swrap.libc.handle);
7800         }
7801         if (swrap.libc.socket_handle) {
7802                 dlclose(swrap.libc.socket_handle);
7803         }
7804 }
7805
7806 #if defined(HAVE__SOCKET) && defined(HAVE__CLOSE)
7807 /*
7808  * On FreeBSD 12 (and maybe other platforms)
7809  * system libraries like libresolv prefix there
7810  * syscalls with '_' in order to always use
7811  * the symbols from libc.
7812  *
7813  * In the interaction with resolv_wrapper,
7814  * we need to inject socket wrapper into libresolv,
7815  * which means we need to private all socket
7816  * related syscalls also with the '_' prefix.
7817  *
7818  * This is tested in Samba's 'make test',
7819  * there we noticed that providing '_read'
7820  * and '_open' would cause errors, which
7821  * means we skip '_read', '_write' and
7822  * all non socket related calls without
7823  * further analyzing the problem.
7824  */
7825 #define SWRAP_SYMBOL_ALIAS(__sym, __aliassym) \
7826         extern typeof(__sym) __aliassym __attribute__ ((alias(#__sym)))
7827
7828 #ifdef HAVE_ACCEPT4
7829 SWRAP_SYMBOL_ALIAS(accept4, _accept4);
7830 #endif
7831 SWRAP_SYMBOL_ALIAS(accept, _accept);
7832 SWRAP_SYMBOL_ALIAS(bind, _bind);
7833 SWRAP_SYMBOL_ALIAS(close, _close);
7834 SWRAP_SYMBOL_ALIAS(connect, _connect);
7835 SWRAP_SYMBOL_ALIAS(dup, _dup);
7836 SWRAP_SYMBOL_ALIAS(dup2, _dup2);
7837 SWRAP_SYMBOL_ALIAS(fcntl, _fcntl);
7838 SWRAP_SYMBOL_ALIAS(getpeername, _getpeername);
7839 SWRAP_SYMBOL_ALIAS(getsockname, _getsockname);
7840 SWRAP_SYMBOL_ALIAS(getsockopt, _getsockopt);
7841 SWRAP_SYMBOL_ALIAS(ioctl, _ioctl);
7842 SWRAP_SYMBOL_ALIAS(listen, _listen);
7843 SWRAP_SYMBOL_ALIAS(readv, _readv);
7844 SWRAP_SYMBOL_ALIAS(recv, _recv);
7845 SWRAP_SYMBOL_ALIAS(recvfrom, _recvfrom);
7846 SWRAP_SYMBOL_ALIAS(recvmsg, _recvmsg);
7847 SWRAP_SYMBOL_ALIAS(send, _send);
7848 SWRAP_SYMBOL_ALIAS(sendmsg, _sendmsg);
7849 SWRAP_SYMBOL_ALIAS(sendto, _sendto);
7850 SWRAP_SYMBOL_ALIAS(setsockopt, _setsockopt);
7851 SWRAP_SYMBOL_ALIAS(socket, _socket);
7852 SWRAP_SYMBOL_ALIAS(socketpair, _socketpair);
7853 SWRAP_SYMBOL_ALIAS(writev, _writev);
7854
7855 #endif /* SOCKET_WRAPPER_EXPORT_UNDERSCORE_SYMBOLS */