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