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