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