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