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