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