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