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