bddadbbaf81b0a7e9e30ef9983280078f7f664c9
[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-2021, Stefan Metzmacher <metze@samba.org>
6  * Copyright (c) 2013-2021, 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 #ifdef HAVE_SYS_SYSCALL_H
51 #include <sys/syscall.h>
52 #endif
53 #ifdef HAVE_SYSCALL_H
54 #include <syscall.h>
55 #endif
56 #include <sys/socket.h>
57 #include <sys/ioctl.h>
58 #ifdef HAVE_SYS_FILIO_H
59 #include <sys/filio.h>
60 #endif
61 #ifdef HAVE_SYS_SIGNALFD_H
62 #include <sys/signalfd.h>
63 #endif
64 #ifdef HAVE_SYS_EVENTFD_H
65 #include <sys/eventfd.h>
66 #endif
67 #ifdef HAVE_SYS_TIMERFD_H
68 #include <sys/timerfd.h>
69 #endif
70 #include <sys/uio.h>
71 #include <errno.h>
72 #include <sys/un.h>
73 #include <netinet/in.h>
74 #include <netinet/tcp.h>
75 #ifdef HAVE_NETINET_TCP_FSM_H
76 #include <netinet/tcp_fsm.h>
77 #endif
78 #include <arpa/inet.h>
79 #include <fcntl.h>
80 #include <stdlib.h>
81 #include <string.h>
82 #include <stdio.h>
83 #include <stdint.h>
84 #include <stdarg.h>
85 #include <stdbool.h>
86 #include <unistd.h>
87 #ifdef HAVE_GNU_LIB_NAMES_H
88 #include <gnu/lib-names.h>
89 #endif
90 #ifdef HAVE_RPC_RPC_H
91 #include <rpc/rpc.h>
92 #endif
93 #include <pthread.h>
94
95 #include "socket_wrapper.h"
96
97 enum swrap_dbglvl_e {
98         SWRAP_LOG_ERROR = 0,
99         SWRAP_LOG_WARN,
100         SWRAP_LOG_DEBUG,
101         SWRAP_LOG_TRACE
102 };
103
104 /* GCC have printf type attribute check. */
105 #ifdef HAVE_FUNCTION_ATTRIBUTE_FORMAT
106 #define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
107 #else
108 #define PRINTF_ATTRIBUTE(a,b)
109 #endif /* HAVE_FUNCTION_ATTRIBUTE_FORMAT */
110
111 #ifdef HAVE_CONSTRUCTOR_ATTRIBUTE
112 #define CONSTRUCTOR_ATTRIBUTE __attribute__ ((constructor))
113 #else
114 #define CONSTRUCTOR_ATTRIBUTE
115 #endif /* HAVE_CONSTRUCTOR_ATTRIBUTE */
116
117 #ifdef HAVE_DESTRUCTOR_ATTRIBUTE
118 #define DESTRUCTOR_ATTRIBUTE __attribute__ ((destructor))
119 #else
120 #define DESTRUCTOR_ATTRIBUTE
121 #endif
122
123 #ifndef FALL_THROUGH
124 # ifdef HAVE_FALLTHROUGH_ATTRIBUTE
125 #  define FALL_THROUGH __attribute__ ((fallthrough))
126 # else /* HAVE_FALLTHROUGH_ATTRIBUTE */
127 #  define FALL_THROUGH ((void)0)
128 # endif /* HAVE_FALLTHROUGH_ATTRIBUTE */
129 #endif /* FALL_THROUGH */
130
131 #ifdef HAVE_ADDRESS_SANITIZER_ATTRIBUTE
132 #define DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE __attribute__((no_sanitize_address))
133 #else
134 #define DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
135 #endif
136
137 #ifdef HAVE_GCC_THREAD_LOCAL_STORAGE
138 # define SWRAP_THREAD __thread
139 #else
140 # define SWRAP_THREAD
141 #endif
142
143 #ifndef MIN
144 #define MIN(a,b) ((a)<(b)?(a):(b))
145 #endif
146
147 #ifndef ZERO_STRUCT
148 #define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
149 #endif
150
151 #ifndef ZERO_STRUCTP
152 #define ZERO_STRUCTP(x) do { \
153                 if ((x) != NULL) \
154                         memset((char *)(x), 0, sizeof(*(x))); \
155         } while(0)
156 #endif
157
158 #ifndef SAFE_FREE
159 #define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0)
160 #endif
161
162 #ifndef discard_const
163 #define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
164 #endif
165
166 #ifndef discard_const_p
167 #define discard_const_p(type, ptr) ((type *)discard_const(ptr))
168 #endif
169
170 #define UNUSED(x) (void)(x)
171
172 #ifdef IPV6_PKTINFO
173 # ifndef IPV6_RECVPKTINFO
174 #  define IPV6_RECVPKTINFO IPV6_PKTINFO
175 # endif /* IPV6_RECVPKTINFO */
176 #endif /* IPV6_PKTINFO */
177
178 /*
179  * On BSD IP_PKTINFO has a different name because during
180  * the time when they implemented it, there was no RFC.
181  * The name for IPv6 is the same as on Linux.
182  */
183 #ifndef IP_PKTINFO
184 # ifdef IP_RECVDSTADDR
185 #  define IP_PKTINFO IP_RECVDSTADDR
186 # endif
187 #endif
188
189 #define socket_wrapper_init_mutex(m) \
190         _socket_wrapper_init_mutex(m, #m)
191
192 /* Add new global locks here please */
193 # define SWRAP_REINIT_ALL do { \
194         int ret; \
195         ret = socket_wrapper_init_mutex(&sockets_mutex); \
196         if (ret != 0) exit(-1); \
197         ret = socket_wrapper_init_mutex(&socket_reset_mutex); \
198         if (ret != 0) exit(-1); \
199         ret = socket_wrapper_init_mutex(&first_free_mutex); \
200         if (ret != 0) exit(-1); \
201         ret = socket_wrapper_init_mutex(&sockets_si_global); \
202         if (ret != 0) exit(-1); \
203         ret = socket_wrapper_init_mutex(&autobind_start_mutex); \
204         if (ret != 0) exit(-1); \
205         ret = socket_wrapper_init_mutex(&pcap_dump_mutex); \
206         if (ret != 0) exit(-1); \
207         ret = socket_wrapper_init_mutex(&mtu_update_mutex); \
208         if (ret != 0) exit(-1); \
209 } while(0)
210
211 # define SWRAP_LOCK_ALL do { \
212         swrap_mutex_lock(&sockets_mutex); \
213         swrap_mutex_lock(&socket_reset_mutex); \
214         swrap_mutex_lock(&first_free_mutex); \
215         swrap_mutex_lock(&sockets_si_global); \
216         swrap_mutex_lock(&autobind_start_mutex); \
217         swrap_mutex_lock(&pcap_dump_mutex); \
218         swrap_mutex_lock(&mtu_update_mutex); \
219 } while(0)
220
221 # define SWRAP_UNLOCK_ALL do { \
222         swrap_mutex_unlock(&mtu_update_mutex); \
223         swrap_mutex_unlock(&pcap_dump_mutex); \
224         swrap_mutex_unlock(&autobind_start_mutex); \
225         swrap_mutex_unlock(&sockets_si_global); \
226         swrap_mutex_unlock(&first_free_mutex); \
227         swrap_mutex_unlock(&socket_reset_mutex); \
228         swrap_mutex_unlock(&sockets_mutex); \
229 } while(0)
230
231 #define SOCKET_INFO_CONTAINER(si) \
232         (struct socket_info_container *)(si)
233
234 #define SWRAP_LOCK_SI(si) do { \
235         struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si); \
236         if (sic != NULL) { \
237                 swrap_mutex_lock(&sockets_si_global); \
238         } else { \
239                 abort(); \
240         } \
241 } while(0)
242
243 #define SWRAP_UNLOCK_SI(si) do { \
244         struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si); \
245         if (sic != NULL) { \
246                 swrap_mutex_unlock(&sockets_si_global); \
247         } else { \
248                 abort(); \
249         } \
250 } while(0)
251
252 #if defined(HAVE_GETTIMEOFDAY_TZ) || defined(HAVE_GETTIMEOFDAY_TZ_VOID)
253 #define swrapGetTimeOfDay(tval) gettimeofday(tval,NULL)
254 #else
255 #define swrapGetTimeOfDay(tval) gettimeofday(tval)
256 #endif
257
258 /* we need to use a very terse format here as IRIX 6.4 silently
259    truncates names to 16 chars, so if we use a longer name then we
260    can't tell which port a packet came from with recvfrom()
261
262    with this format we have 8 chars left for the directory name
263 */
264 #define SOCKET_FORMAT "%c%02X%04X"
265 #define SOCKET_TYPE_CHAR_TCP            'T'
266 #define SOCKET_TYPE_CHAR_UDP            'U'
267 #define SOCKET_TYPE_CHAR_TCP_V6         'X'
268 #define SOCKET_TYPE_CHAR_UDP_V6         'Y'
269
270 /*
271  * Set the packet MTU to 1500 bytes for stream sockets to make it it easier to
272  * format PCAP capture files (as the caller will simply continue from here).
273  */
274 #define SOCKET_WRAPPER_MTU_DEFAULT 1500
275 #define SOCKET_WRAPPER_MTU_MIN     512
276 #define SOCKET_WRAPPER_MTU_MAX     32768
277
278 #define SOCKET_MAX_SOCKETS 1024
279
280 /*
281  * Maximum number of socket_info structures that can
282  * be used. Can be overriden by the environment variable
283  * SOCKET_WRAPPER_MAX_SOCKETS.
284  */
285 #define SOCKET_WRAPPER_MAX_SOCKETS_DEFAULT 65535
286
287 #define SOCKET_WRAPPER_MAX_SOCKETS_LIMIT 262140
288
289 /* This limit is to avoid broadcast sendto() needing to stat too many
290  * files.  It may be raised (with a performance cost) to up to 254
291  * without changing the format above */
292 #define MAX_WRAPPED_INTERFACES 64
293
294 struct swrap_address {
295         socklen_t sa_socklen;
296         union {
297                 struct sockaddr s;
298                 struct sockaddr_in in;
299 #ifdef HAVE_IPV6
300                 struct sockaddr_in6 in6;
301 #endif
302                 struct sockaddr_un un;
303                 struct sockaddr_storage ss;
304         } sa;
305 };
306
307 static int first_free;
308
309 struct socket_info
310 {
311         /*
312          * Remember to update swrap_unix_scm_right_magic
313          * on any change.
314          */
315
316         int family;
317         int type;
318         int protocol;
319         int bound;
320         int bcast;
321         int is_server;
322         int connected;
323         int defer_connect;
324         int pktinfo;
325         int tcp_nodelay;
326         int listening;
327         int fd_passed;
328
329         /* The unix path so we can unlink it on close() */
330         struct sockaddr_un un_addr;
331
332         struct swrap_address bindname;
333         struct swrap_address myname;
334         struct swrap_address peername;
335
336         struct {
337                 unsigned long pck_snd;
338                 unsigned long pck_rcv;
339         } io;
340 };
341
342 struct socket_info_meta
343 {
344         unsigned int refcount;
345         int next_free;
346         /*
347          * As long as we don't use shared memory
348          * for the sockets array, we use
349          * sockets_si_global as a single mutex.
350          *
351          * pthread_mutex_t mutex;
352          */
353 };
354
355 struct socket_info_container
356 {
357         struct socket_info info;
358         struct socket_info_meta meta;
359 };
360
361 static struct socket_info_container *sockets;
362
363 static size_t socket_info_max = 0;
364
365 /*
366  * Allocate the socket array always on the limit value. We want it to be
367  * at least bigger than the default so if we reach the limit we can
368  * still deal with duplicate fds pointing to the same socket_info.
369  */
370 static size_t socket_fds_max = SOCKET_WRAPPER_MAX_SOCKETS_LIMIT;
371
372 /* Hash table to map fds to corresponding socket_info index */
373 static int *socket_fds_idx;
374
375 /* Mutex for syncronizing port selection during swrap_auto_bind() */
376 static pthread_mutex_t autobind_start_mutex = PTHREAD_MUTEX_INITIALIZER;
377
378 /* Mutex to guard the initialization of array of socket_info structures */
379 static pthread_mutex_t sockets_mutex = PTHREAD_MUTEX_INITIALIZER;
380
381 /* Mutex to guard the socket reset in swrap_remove_wrapper() */
382 static pthread_mutex_t socket_reset_mutex = PTHREAD_MUTEX_INITIALIZER;
383
384 /* Mutex to synchronize access to first free index in socket_info array */
385 static pthread_mutex_t first_free_mutex = PTHREAD_MUTEX_INITIALIZER;
386
387 /*
388  * Mutex to synchronize access to to socket_info structures
389  * We use a single global mutex in order to avoid leaking
390  * ~ 38M copy on write memory per fork.
391  * max_sockets=65535 * sizeof(struct socket_info_container)=592 = 38796720
392  */
393 static pthread_mutex_t sockets_si_global = PTHREAD_MUTEX_INITIALIZER;
394
395 /* Mutex to synchronize access to packet capture dump file */
396 static pthread_mutex_t pcap_dump_mutex = PTHREAD_MUTEX_INITIALIZER;
397
398 /* Mutex for synchronizing mtu value fetch*/
399 static pthread_mutex_t mtu_update_mutex = PTHREAD_MUTEX_INITIALIZER;
400
401 /* Function prototypes */
402
403 #if ! defined(HAVE_CONSTRUCTOR_ATTRIBUTE) && defined(HAVE_PRAGMA_INIT)
404 /* xlC and other oldschool compilers support (only) this */
405 #pragma init (swrap_constructor)
406 #endif
407 void swrap_constructor(void) CONSTRUCTOR_ATTRIBUTE;
408 #if ! defined(HAVE_DESTRUCTOR_ATTRIBUTE) && defined(HAVE_PRAGMA_FINI)
409 #pragma fini (swrap_destructor)
410 #endif
411 void swrap_destructor(void) DESTRUCTOR_ATTRIBUTE;
412
413 #ifndef HAVE_GETPROGNAME
414 static const char *getprogname(void)
415 {
416 #if defined(HAVE_PROGRAM_INVOCATION_SHORT_NAME)
417         return program_invocation_short_name;
418 #elif defined(HAVE_GETEXECNAME)
419         return getexecname();
420 #else
421         return NULL;
422 #endif /* HAVE_PROGRAM_INVOCATION_SHORT_NAME */
423 }
424 #endif /* HAVE_GETPROGNAME */
425
426 static void swrap_log(enum swrap_dbglvl_e dbglvl, const char *func, const char *format, ...) PRINTF_ATTRIBUTE(3, 4);
427 # define SWRAP_LOG(dbglvl, ...) swrap_log((dbglvl), __func__, __VA_ARGS__)
428
429 static void swrap_log(enum swrap_dbglvl_e dbglvl,
430                       const char *func,
431                       const char *format, ...)
432 {
433         char buffer[1024];
434         va_list va;
435         const char *d;
436         unsigned int lvl = 0;
437         const char *prefix = "SWRAP";
438         const char *progname = getprogname();
439
440         d = getenv("SOCKET_WRAPPER_DEBUGLEVEL");
441         if (d != NULL) {
442                 lvl = atoi(d);
443         }
444
445         if (lvl < dbglvl) {
446                 return;
447         }
448
449         va_start(va, format);
450         vsnprintf(buffer, sizeof(buffer), format, va);
451         va_end(va);
452
453         switch (dbglvl) {
454                 case SWRAP_LOG_ERROR:
455                         prefix = "SWRAP_ERROR";
456                         break;
457                 case SWRAP_LOG_WARN:
458                         prefix = "SWRAP_WARN";
459                         break;
460                 case SWRAP_LOG_DEBUG:
461                         prefix = "SWRAP_DEBUG";
462                         break;
463                 case SWRAP_LOG_TRACE:
464                         prefix = "SWRAP_TRACE";
465                         break;
466         }
467
468         if (progname == NULL) {
469                 progname = "<unknown>";
470         }
471
472         fprintf(stderr,
473                 "%s[%s (%u)] - %s: %s\n",
474                 prefix,
475                 progname,
476                 (unsigned int)getpid(),
477                 func,
478                 buffer);
479 }
480
481 /*********************************************************
482  * SWRAP LOADING LIBC FUNCTIONS
483  *********************************************************/
484
485 #include <dlfcn.h>
486
487 #ifdef HAVE_ACCEPT4
488 typedef int (*__libc_accept4)(int sockfd,
489                               struct sockaddr *addr,
490                               socklen_t *addrlen,
491                               int flags);
492 #else
493 typedef int (*__libc_accept)(int sockfd,
494                              struct sockaddr *addr,
495                              socklen_t *addrlen);
496 #endif
497 typedef int (*__libc_bind)(int sockfd,
498                            const struct sockaddr *addr,
499                            socklen_t addrlen);
500 typedef int (*__libc_close)(int fd);
501 #ifdef HAVE___CLOSE_NOCANCEL
502 typedef int (*__libc___close_nocancel)(int fd);
503 #endif
504 typedef int (*__libc_connect)(int sockfd,
505                               const struct sockaddr *addr,
506                               socklen_t addrlen);
507 typedef int (*__libc_dup)(int fd);
508 typedef int (*__libc_dup2)(int oldfd, int newfd);
509 typedef int (*__libc_fcntl)(int fd, int cmd, ...);
510 typedef FILE *(*__libc_fopen)(const char *name, const char *mode);
511 #ifdef HAVE_FOPEN64
512 typedef FILE *(*__libc_fopen64)(const char *name, const char *mode);
513 #endif
514 #ifdef HAVE_EVENTFD
515 typedef int (*__libc_eventfd)(int count, int flags);
516 #endif
517 typedef int (*__libc_getpeername)(int sockfd,
518                                   struct sockaddr *addr,
519                                   socklen_t *addrlen);
520 typedef int (*__libc_getsockname)(int sockfd,
521                                   struct sockaddr *addr,
522                                   socklen_t *addrlen);
523 typedef int (*__libc_getsockopt)(int sockfd,
524                                int level,
525                                int optname,
526                                void *optval,
527                                socklen_t *optlen);
528 typedef int (*__libc_ioctl)(int d, unsigned long int request, ...);
529 typedef int (*__libc_listen)(int sockfd, int backlog);
530 typedef int (*__libc_open)(const char *pathname, int flags, ...);
531 #ifdef HAVE_OPEN64
532 typedef int (*__libc_open64)(const char *pathname, int flags, ...);
533 #endif /* HAVE_OPEN64 */
534 typedef int (*__libc_openat)(int dirfd, const char *path, int flags, ...);
535 typedef int (*__libc_pipe)(int pipefd[2]);
536 typedef int (*__libc_read)(int fd, void *buf, size_t count);
537 typedef ssize_t (*__libc_readv)(int fd, const struct iovec *iov, int iovcnt);
538 typedef int (*__libc_recv)(int sockfd, void *buf, size_t len, int flags);
539 typedef int (*__libc_recvfrom)(int sockfd,
540                              void *buf,
541                              size_t len,
542                              int flags,
543                              struct sockaddr *src_addr,
544                              socklen_t *addrlen);
545 typedef int (*__libc_recvmsg)(int sockfd, const struct msghdr *msg, int flags);
546 #ifdef HAVE_RECVMMSG
547 #if defined(HAVE_RECVMMSG_SSIZE_T_CONST_TIMEOUT)
548 /* FreeBSD */
549 typedef ssize_t (*__libc_recvmmsg)(int sockfd, struct mmsghdr *msgvec, size_t vlen, int flags, const struct timespec *timeout);
550 #elif defined(HAVE_RECVMMSG_CONST_TIMEOUT)
551 /* Linux legacy glibc < 2.21 */
552 typedef int (*__libc_recvmmsg)(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, const struct timespec *timeout);
553 #else
554 /* Linux glibc >= 2.21 */
555 typedef int (*__libc_recvmmsg)(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, struct timespec *timeout);
556 #endif
557 #endif /* HAVE_RECVMMSG */
558 typedef int (*__libc_send)(int sockfd, const void *buf, size_t len, int flags);
559 typedef int (*__libc_sendmsg)(int sockfd, const struct msghdr *msg, int flags);
560 #ifdef HAVE_SENDMMSG
561 #if defined(HAVE_SENDMMSG_SSIZE_T)
562 /* FreeBSD */
563 typedef ssize_t (*__libc_sendmmsg)(int sockfd, struct mmsghdr *msgvec, size_t vlen, int flags);
564 #else
565 /* Linux */
566 typedef int (*__libc_sendmmsg)(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags);
567 #endif
568 #endif /* HAVE_SENDMMSG */
569 typedef int (*__libc_sendto)(int sockfd,
570                            const void *buf,
571                            size_t len,
572                            int flags,
573                            const  struct sockaddr *dst_addr,
574                            socklen_t addrlen);
575 typedef int (*__libc_setsockopt)(int sockfd,
576                                int level,
577                                int optname,
578                                const void *optval,
579                                socklen_t optlen);
580 #ifdef HAVE_SIGNALFD
581 typedef int (*__libc_signalfd)(int fd, const sigset_t *mask, int flags);
582 #endif
583 typedef int (*__libc_socket)(int domain, int type, int protocol);
584 typedef int (*__libc_socketpair)(int domain, int type, int protocol, int sv[2]);
585 #ifdef HAVE_TIMERFD_CREATE
586 typedef int (*__libc_timerfd_create)(int clockid, int flags);
587 #endif
588 typedef ssize_t (*__libc_write)(int fd, const void *buf, size_t count);
589 typedef ssize_t (*__libc_writev)(int fd, const struct iovec *iov, int iovcnt);
590 #ifdef HAVE_SYSCALL
591 typedef long int (*__libc_syscall)(long int sysno, ...);
592 #endif
593
594 #define SWRAP_SYMBOL_ENTRY(i) \
595         union { \
596                 __libc_##i f; \
597                 void *obj; \
598         } _libc_##i
599
600 struct swrap_libc_symbols {
601 #ifdef HAVE_ACCEPT4
602         SWRAP_SYMBOL_ENTRY(accept4);
603 #else
604         SWRAP_SYMBOL_ENTRY(accept);
605 #endif
606         SWRAP_SYMBOL_ENTRY(bind);
607         SWRAP_SYMBOL_ENTRY(close);
608 #ifdef HAVE___CLOSE_NOCANCEL
609         SWRAP_SYMBOL_ENTRY(__close_nocancel);
610 #endif
611         SWRAP_SYMBOL_ENTRY(connect);
612         SWRAP_SYMBOL_ENTRY(dup);
613         SWRAP_SYMBOL_ENTRY(dup2);
614         SWRAP_SYMBOL_ENTRY(fcntl);
615         SWRAP_SYMBOL_ENTRY(fopen);
616 #ifdef HAVE_FOPEN64
617         SWRAP_SYMBOL_ENTRY(fopen64);
618 #endif
619 #ifdef HAVE_EVENTFD
620         SWRAP_SYMBOL_ENTRY(eventfd);
621 #endif
622         SWRAP_SYMBOL_ENTRY(getpeername);
623         SWRAP_SYMBOL_ENTRY(getsockname);
624         SWRAP_SYMBOL_ENTRY(getsockopt);
625         SWRAP_SYMBOL_ENTRY(ioctl);
626         SWRAP_SYMBOL_ENTRY(listen);
627         SWRAP_SYMBOL_ENTRY(open);
628 #ifdef HAVE_OPEN64
629         SWRAP_SYMBOL_ENTRY(open64);
630 #endif
631         SWRAP_SYMBOL_ENTRY(openat);
632         SWRAP_SYMBOL_ENTRY(pipe);
633         SWRAP_SYMBOL_ENTRY(read);
634         SWRAP_SYMBOL_ENTRY(readv);
635         SWRAP_SYMBOL_ENTRY(recv);
636         SWRAP_SYMBOL_ENTRY(recvfrom);
637         SWRAP_SYMBOL_ENTRY(recvmsg);
638 #ifdef HAVE_RECVMMSG
639         SWRAP_SYMBOL_ENTRY(recvmmsg);
640 #endif
641         SWRAP_SYMBOL_ENTRY(send);
642         SWRAP_SYMBOL_ENTRY(sendmsg);
643 #ifdef HAVE_SENDMMSG
644         SWRAP_SYMBOL_ENTRY(sendmmsg);
645 #endif
646         SWRAP_SYMBOL_ENTRY(sendto);
647         SWRAP_SYMBOL_ENTRY(setsockopt);
648 #ifdef HAVE_SIGNALFD
649         SWRAP_SYMBOL_ENTRY(signalfd);
650 #endif
651         SWRAP_SYMBOL_ENTRY(socket);
652         SWRAP_SYMBOL_ENTRY(socketpair);
653 #ifdef HAVE_TIMERFD_CREATE
654         SWRAP_SYMBOL_ENTRY(timerfd_create);
655 #endif
656         SWRAP_SYMBOL_ENTRY(write);
657         SWRAP_SYMBOL_ENTRY(writev);
658 #ifdef HAVE_SYSCALL
659         SWRAP_SYMBOL_ENTRY(syscall);
660 #endif
661 };
662
663 struct swrap {
664         struct {
665                 void *handle;
666                 void *socket_handle;
667                 struct swrap_libc_symbols symbols;
668         } libc;
669 };
670
671 static struct swrap swrap;
672
673 /* prototypes */
674 static char *socket_wrapper_dir(void);
675
676 #define LIBC_NAME "libc.so"
677
678 enum swrap_lib {
679     SWRAP_LIBC,
680     SWRAP_LIBSOCKET,
681 };
682
683 static const char *swrap_str_lib(enum swrap_lib lib)
684 {
685         switch (lib) {
686         case SWRAP_LIBC:
687                 return "libc";
688         case SWRAP_LIBSOCKET:
689                 return "libsocket";
690         }
691
692         /* Compiler would warn us about unhandled enum value if we get here */
693         return "unknown";
694 }
695
696 static void *swrap_load_lib_handle(enum swrap_lib lib)
697 {
698         int flags = RTLD_LAZY;
699         void *handle = NULL;
700         int i;
701
702 #ifdef RTLD_DEEPBIND
703         const char *env_preload = getenv("LD_PRELOAD");
704         const char *env_deepbind = getenv("SOCKET_WRAPPER_DISABLE_DEEPBIND");
705         bool enable_deepbind = true;
706
707         /* Don't do a deepbind if we run with libasan */
708         if (env_preload != NULL && strlen(env_preload) < 1024) {
709                 const char *p = strstr(env_preload, "libasan.so");
710                 if (p != NULL) {
711                         enable_deepbind = false;
712                 }
713         }
714
715         if (env_deepbind != NULL && strlen(env_deepbind) >= 1) {
716                 enable_deepbind = false;
717         }
718
719         if (enable_deepbind) {
720                 flags |= RTLD_DEEPBIND;
721         }
722 #endif
723
724         switch (lib) {
725         case SWRAP_LIBSOCKET:
726 #ifdef HAVE_LIBSOCKET
727                 handle = swrap.libc.socket_handle;
728                 if (handle == NULL) {
729                         for (i = 10; i >= 0; i--) {
730                                 char soname[256] = {0};
731
732                                 snprintf(soname, sizeof(soname), "libsocket.so.%d", i);
733                                 handle = dlopen(soname, flags);
734                                 if (handle != NULL) {
735                                         break;
736                                 }
737                         }
738
739                         swrap.libc.socket_handle = handle;
740                 }
741                 break;
742 #endif
743         case SWRAP_LIBC:
744                 handle = swrap.libc.handle;
745 #ifdef LIBC_SO
746                 if (handle == NULL) {
747                         handle = dlopen(LIBC_SO, flags);
748
749                         swrap.libc.handle = handle;
750                 }
751 #endif
752                 if (handle == NULL) {
753                         for (i = 10; i >= 0; i--) {
754                                 char soname[256] = {0};
755
756                                 snprintf(soname, sizeof(soname), "libc.so.%d", i);
757                                 handle = dlopen(soname, flags);
758                                 if (handle != NULL) {
759                                         break;
760                                 }
761                         }
762
763                         swrap.libc.handle = handle;
764                 }
765                 break;
766         }
767
768         if (handle == NULL) {
769 #ifdef RTLD_NEXT
770                 handle = swrap.libc.handle = swrap.libc.socket_handle = RTLD_NEXT;
771 #else
772                 SWRAP_LOG(SWRAP_LOG_ERROR,
773                           "Failed to dlopen library: %s",
774                           dlerror());
775                 exit(-1);
776 #endif
777         }
778
779         return handle;
780 }
781
782 static void *_swrap_bind_symbol(enum swrap_lib lib, const char *fn_name)
783 {
784         void *handle;
785         void *func;
786
787         handle = swrap_load_lib_handle(lib);
788
789         func = dlsym(handle, fn_name);
790         if (func == NULL) {
791                 SWRAP_LOG(SWRAP_LOG_ERROR,
792                           "Failed to find %s: %s",
793                           fn_name,
794                           dlerror());
795                 exit(-1);
796         }
797
798         SWRAP_LOG(SWRAP_LOG_TRACE,
799                   "Loaded %s from %s",
800                   fn_name,
801                   swrap_str_lib(lib));
802
803         return func;
804 }
805
806 #define swrap_mutex_lock(m) _swrap_mutex_lock(m, #m, __func__, __LINE__)
807 static void _swrap_mutex_lock(pthread_mutex_t *mutex, const char *name, const char *caller, unsigned line)
808 {
809         int ret;
810
811         ret = pthread_mutex_lock(mutex);
812         if (ret != 0) {
813                 SWRAP_LOG(SWRAP_LOG_ERROR, "PID(%d):PPID(%d): %s(%u): Couldn't lock pthread mutex(%s) - %s",
814                           getpid(), getppid(), caller, line, name, strerror(ret));
815                 abort();
816         }
817 }
818
819 #define swrap_mutex_unlock(m) _swrap_mutex_unlock(m, #m, __func__, __LINE__)
820 static void _swrap_mutex_unlock(pthread_mutex_t *mutex, const char *name, const char *caller, unsigned line)
821 {
822         int ret;
823
824         ret = pthread_mutex_unlock(mutex);
825         if (ret != 0) {
826                 SWRAP_LOG(SWRAP_LOG_ERROR, "PID(%d):PPID(%d): %s(%u): Couldn't unlock pthread mutex(%s) - %s",
827                           getpid(), getppid(), caller, line, name, strerror(ret));
828                 abort();
829         }
830 }
831
832 /*
833  * These macros have a thread race condition on purpose!
834  *
835  * This is an optimization to avoid locking each time we check if the symbol is
836  * bound.
837  */
838 #define _swrap_bind_symbol_generic(lib, sym_name) do { \
839         swrap.libc.symbols._libc_##sym_name.obj = \
840                 _swrap_bind_symbol(lib, #sym_name); \
841 } while(0);
842
843 #define swrap_bind_symbol_libc(sym_name) \
844         _swrap_bind_symbol_generic(SWRAP_LIBC, sym_name)
845
846 #define swrap_bind_symbol_libsocket(sym_name) \
847         _swrap_bind_symbol_generic(SWRAP_LIBSOCKET, sym_name)
848
849 static void swrap_bind_symbol_all(void);
850
851 /****************************************************************************
852  *                               IMPORTANT
853  ****************************************************************************
854  *
855  * Functions especially from libc need to be loaded individually, you can't
856  * load all at once or gdb will segfault at startup. The same applies to
857  * valgrind and has probably something todo with with the linker.  So we need
858  * load each function at the point it is called the first time.
859  *
860  ****************************************************************************/
861
862 #ifdef HAVE_ACCEPT4
863 static int libc_accept4(int sockfd,
864                         struct sockaddr *addr,
865                         socklen_t *addrlen,
866                         int flags)
867 {
868         swrap_bind_symbol_all();
869
870         return swrap.libc.symbols._libc_accept4.f(sockfd, addr, addrlen, flags);
871 }
872
873 #else /* HAVE_ACCEPT4 */
874
875 static int libc_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
876 {
877         swrap_bind_symbol_all();
878
879         return swrap.libc.symbols._libc_accept.f(sockfd, addr, addrlen);
880 }
881 #endif /* HAVE_ACCEPT4 */
882
883 static int libc_bind(int sockfd,
884                      const struct sockaddr *addr,
885                      socklen_t addrlen)
886 {
887         swrap_bind_symbol_all();
888
889         return swrap.libc.symbols._libc_bind.f(sockfd, addr, addrlen);
890 }
891
892 static int libc_close(int fd)
893 {
894         swrap_bind_symbol_all();
895
896         return swrap.libc.symbols._libc_close.f(fd);
897 }
898
899 #ifdef HAVE___CLOSE_NOCANCEL
900 static int libc___close_nocancel(int fd)
901 {
902         swrap_bind_symbol_all();
903
904         return swrap.libc.symbols._libc___close_nocancel.f(fd);
905 }
906 #endif /* HAVE___CLOSE_NOCANCEL */
907
908 static int libc_connect(int sockfd,
909                         const struct sockaddr *addr,
910                         socklen_t addrlen)
911 {
912         swrap_bind_symbol_all();
913
914         return swrap.libc.symbols._libc_connect.f(sockfd, addr, addrlen);
915 }
916
917 static int libc_dup(int fd)
918 {
919         swrap_bind_symbol_all();
920
921         return swrap.libc.symbols._libc_dup.f(fd);
922 }
923
924 static int libc_dup2(int oldfd, int newfd)
925 {
926         swrap_bind_symbol_all();
927
928         return swrap.libc.symbols._libc_dup2.f(oldfd, newfd);
929 }
930
931 #ifdef HAVE_EVENTFD
932 static int libc_eventfd(int count, int flags)
933 {
934         swrap_bind_symbol_all();
935
936         return swrap.libc.symbols._libc_eventfd.f(count, flags);
937 }
938 #endif
939
940 DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
941 static int libc_vfcntl(int fd, int cmd, va_list ap)
942 {
943         void *arg;
944         int rc;
945
946         swrap_bind_symbol_all();
947
948         arg = va_arg(ap, void *);
949
950         rc = swrap.libc.symbols._libc_fcntl.f(fd, cmd, arg);
951
952         return rc;
953 }
954
955 static int libc_getpeername(int sockfd,
956                             struct sockaddr *addr,
957                             socklen_t *addrlen)
958 {
959         swrap_bind_symbol_all();
960
961         return swrap.libc.symbols._libc_getpeername.f(sockfd, addr, addrlen);
962 }
963
964 static int libc_getsockname(int sockfd,
965                             struct sockaddr *addr,
966                             socklen_t *addrlen)
967 {
968         swrap_bind_symbol_all();
969
970         return swrap.libc.symbols._libc_getsockname.f(sockfd, addr, addrlen);
971 }
972
973 static int libc_getsockopt(int sockfd,
974                            int level,
975                            int optname,
976                            void *optval,
977                            socklen_t *optlen)
978 {
979         swrap_bind_symbol_all();
980
981         return swrap.libc.symbols._libc_getsockopt.f(sockfd,
982                                                      level,
983                                                      optname,
984                                                      optval,
985                                                      optlen);
986 }
987
988 DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
989 static int libc_vioctl(int d, unsigned long int request, va_list ap)
990 {
991         void *arg;
992         int rc;
993
994         swrap_bind_symbol_all();
995
996         arg = va_arg(ap, void *);
997
998         rc = swrap.libc.symbols._libc_ioctl.f(d, request, arg);
999
1000         return rc;
1001 }
1002
1003 static int libc_listen(int sockfd, int backlog)
1004 {
1005         swrap_bind_symbol_all();
1006
1007         return swrap.libc.symbols._libc_listen.f(sockfd, backlog);
1008 }
1009
1010 static FILE *libc_fopen(const char *name, const char *mode)
1011 {
1012         swrap_bind_symbol_all();
1013
1014         return swrap.libc.symbols._libc_fopen.f(name, mode);
1015 }
1016
1017 #ifdef HAVE_FOPEN64
1018 static FILE *libc_fopen64(const char *name, const char *mode)
1019 {
1020         swrap_bind_symbol_all();
1021
1022         return swrap.libc.symbols._libc_fopen64.f(name, mode);
1023 }
1024 #endif /* HAVE_FOPEN64 */
1025
1026 static void swrap_inject_o_largefile(int *flags)
1027 {
1028         (void)*flags; /* maybe unused */
1029 #if SIZE_MAX == 0xffffffffUL && defined(O_LARGEFILE)
1030 #ifdef O_PATH
1031         if (((*flags) & O_PATH) == 0)
1032 #endif
1033         {
1034                 *flags |= O_LARGEFILE;
1035         }
1036 #endif
1037 }
1038
1039 static int libc_vopen(const char *pathname, int flags, va_list ap)
1040 {
1041         int mode = 0;
1042         int fd;
1043
1044         swrap_bind_symbol_all();
1045
1046         swrap_inject_o_largefile(&flags);
1047
1048         if (flags & O_CREAT) {
1049                 mode = va_arg(ap, int);
1050         }
1051         fd = swrap.libc.symbols._libc_open.f(pathname, flags, (mode_t)mode);
1052
1053         return fd;
1054 }
1055
1056 static int libc_open(const char *pathname, int flags, ...)
1057 {
1058         va_list ap;
1059         int fd;
1060
1061         va_start(ap, flags);
1062         fd = libc_vopen(pathname, flags, ap);
1063         va_end(ap);
1064
1065         return fd;
1066 }
1067
1068 #ifdef HAVE_OPEN64
1069 static int libc_vopen64(const char *pathname, int flags, va_list ap)
1070 {
1071         int mode = 0;
1072         int fd;
1073
1074         swrap_bind_symbol_all();
1075
1076         swrap_inject_o_largefile(&flags);
1077
1078         if (flags & O_CREAT) {
1079                 mode = va_arg(ap, int);
1080         }
1081         fd = swrap.libc.symbols._libc_open64.f(pathname, flags, (mode_t)mode);
1082
1083         return fd;
1084 }
1085 #endif /* HAVE_OPEN64 */
1086
1087 static int libc_vopenat(int dirfd, const char *path, int flags, va_list ap)
1088 {
1089         int mode = 0;
1090         int fd;
1091
1092         swrap_bind_symbol_all();
1093
1094         swrap_inject_o_largefile(&flags);
1095
1096         if (flags & O_CREAT) {
1097                 mode = va_arg(ap, int);
1098         }
1099         fd = swrap.libc.symbols._libc_openat.f(dirfd,
1100                                                path,
1101                                                flags,
1102                                                (mode_t)mode);
1103
1104         return fd;
1105 }
1106
1107 #if 0
1108 static int libc_openat(int dirfd, const char *path, int flags, ...)
1109 {
1110         va_list ap;
1111         int fd;
1112
1113         va_start(ap, flags);
1114         fd = libc_vopenat(dirfd, path, flags, ap);
1115         va_end(ap);
1116
1117         return fd;
1118 }
1119 #endif
1120
1121 static int libc_pipe(int pipefd[2])
1122 {
1123         swrap_bind_symbol_all();
1124
1125         return swrap.libc.symbols._libc_pipe.f(pipefd);
1126 }
1127
1128 static int libc_read(int fd, void *buf, size_t count)
1129 {
1130         swrap_bind_symbol_all();
1131
1132         return swrap.libc.symbols._libc_read.f(fd, buf, count);
1133 }
1134
1135 static ssize_t libc_readv(int fd, const struct iovec *iov, int iovcnt)
1136 {
1137         swrap_bind_symbol_all();
1138
1139         return swrap.libc.symbols._libc_readv.f(fd, iov, iovcnt);
1140 }
1141
1142 static int libc_recv(int sockfd, void *buf, size_t len, int flags)
1143 {
1144         swrap_bind_symbol_all();
1145
1146         return swrap.libc.symbols._libc_recv.f(sockfd, buf, len, flags);
1147 }
1148
1149 static int libc_recvfrom(int sockfd,
1150                          void *buf,
1151                          size_t len,
1152                          int flags,
1153                          struct sockaddr *src_addr,
1154                          socklen_t *addrlen)
1155 {
1156         swrap_bind_symbol_all();
1157
1158         return swrap.libc.symbols._libc_recvfrom.f(sockfd,
1159                                                    buf,
1160                                                    len,
1161                                                    flags,
1162                                                    src_addr,
1163                                                    addrlen);
1164 }
1165
1166 static int libc_recvmsg(int sockfd, struct msghdr *msg, int flags)
1167 {
1168         swrap_bind_symbol_all();
1169
1170         return swrap.libc.symbols._libc_recvmsg.f(sockfd, msg, flags);
1171 }
1172
1173 #ifdef HAVE_RECVMMSG
1174 #if defined(HAVE_RECVMMSG_SSIZE_T_CONST_TIMEOUT)
1175 /* FreeBSD */
1176 static ssize_t libc_recvmmsg(int sockfd, struct mmsghdr *msgvec, size_t vlen, int flags, const struct timespec *timeout)
1177 #elif defined(HAVE_RECVMMSG_CONST_TIMEOUT)
1178 /* Linux legacy glibc < 2.21 */
1179 static int libc_recvmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, const struct timespec *timeout)
1180 #else
1181 /* Linux glibc >= 2.21 */
1182 static int libc_recvmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, struct timespec *timeout)
1183 #endif
1184 {
1185         swrap_bind_symbol_all();
1186
1187         return swrap.libc.symbols._libc_recvmmsg.f(sockfd, msgvec, vlen, flags, timeout);
1188 }
1189 #endif
1190
1191 static int libc_send(int sockfd, const void *buf, size_t len, int flags)
1192 {
1193         swrap_bind_symbol_all();
1194
1195         return swrap.libc.symbols._libc_send.f(sockfd, buf, len, flags);
1196 }
1197
1198 static int libc_sendmsg(int sockfd, const struct msghdr *msg, int flags)
1199 {
1200         swrap_bind_symbol_all();
1201
1202         return swrap.libc.symbols._libc_sendmsg.f(sockfd, msg, flags);
1203 }
1204
1205 #ifdef HAVE_SENDMMSG
1206 #if defined(HAVE_SENDMMSG_SSIZE_T)
1207 /* FreeBSD */
1208 static ssize_t libc_sendmmsg(int sockfd, struct mmsghdr *msgvec, size_t vlen, int flags)
1209 #else
1210 /* Linux */
1211 static int libc_sendmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags)
1212 #endif
1213 {
1214         swrap_bind_symbol_all();
1215
1216         return swrap.libc.symbols._libc_sendmmsg.f(sockfd, msgvec, vlen, flags);
1217 }
1218 #endif
1219
1220 static int libc_sendto(int sockfd,
1221                        const void *buf,
1222                        size_t len,
1223                        int flags,
1224                        const  struct sockaddr *dst_addr,
1225                        socklen_t addrlen)
1226 {
1227         swrap_bind_symbol_all();
1228
1229         return swrap.libc.symbols._libc_sendto.f(sockfd,
1230                                                  buf,
1231                                                  len,
1232                                                  flags,
1233                                                  dst_addr,
1234                                                  addrlen);
1235 }
1236
1237 static int libc_setsockopt(int sockfd,
1238                            int level,
1239                            int optname,
1240                            const void *optval,
1241                            socklen_t optlen)
1242 {
1243         swrap_bind_symbol_all();
1244
1245         return swrap.libc.symbols._libc_setsockopt.f(sockfd,
1246                                                      level,
1247                                                      optname,
1248                                                      optval,
1249                                                      optlen);
1250 }
1251
1252 #ifdef HAVE_SIGNALFD
1253 static int libc_signalfd(int fd, const sigset_t *mask, int flags)
1254 {
1255         swrap_bind_symbol_all();
1256
1257         return swrap.libc.symbols._libc_signalfd.f(fd, mask, flags);
1258 }
1259 #endif
1260
1261 static int libc_socket(int domain, int type, int protocol)
1262 {
1263         swrap_bind_symbol_all();
1264
1265         return swrap.libc.symbols._libc_socket.f(domain, type, protocol);
1266 }
1267
1268 static int libc_socketpair(int domain, int type, int protocol, int sv[2])
1269 {
1270         swrap_bind_symbol_all();
1271
1272         return swrap.libc.symbols._libc_socketpair.f(domain, type, protocol, sv);
1273 }
1274
1275 #ifdef HAVE_TIMERFD_CREATE
1276 static int libc_timerfd_create(int clockid, int flags)
1277 {
1278         swrap_bind_symbol_all();
1279
1280         return swrap.libc.symbols._libc_timerfd_create.f(clockid, flags);
1281 }
1282 #endif
1283
1284 static ssize_t libc_write(int fd, const void *buf, size_t count)
1285 {
1286         swrap_bind_symbol_all();
1287
1288         return swrap.libc.symbols._libc_write.f(fd, buf, count);
1289 }
1290
1291 static ssize_t libc_writev(int fd, const struct iovec *iov, int iovcnt)
1292 {
1293         swrap_bind_symbol_all();
1294
1295         return swrap.libc.symbols._libc_writev.f(fd, iov, iovcnt);
1296 }
1297
1298 #ifdef HAVE_SYSCALL
1299 DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
1300 static long int libc_vsyscall(long int sysno, va_list va)
1301 {
1302         long int args[8];
1303         long int rc;
1304         int i;
1305
1306         swrap_bind_symbol_all();
1307
1308         for (i = 0; i < 8; i++) {
1309                 args[i] = va_arg(va, long int);
1310         }
1311
1312         rc = swrap.libc.symbols._libc_syscall.f(sysno,
1313                                                 args[0],
1314                                                 args[1],
1315                                                 args[2],
1316                                                 args[3],
1317                                                 args[4],
1318                                                 args[5],
1319                                                 args[6],
1320                                                 args[7]);
1321
1322         return rc;
1323 }
1324 #endif /* HAVE_SYSCALL */
1325
1326 /* DO NOT call this function during library initialization! */
1327 static void __swrap_bind_symbol_all_once(void)
1328 {
1329 #ifdef HAVE_ACCEPT4
1330         swrap_bind_symbol_libsocket(accept4);
1331 #else
1332         swrap_bind_symbol_libsocket(accept);
1333 #endif
1334         swrap_bind_symbol_libsocket(bind);
1335         swrap_bind_symbol_libc(close);
1336 #ifdef HAVE___CLOSE_NOCANCEL
1337         swrap_bind_symbol_libc(__close_nocancel);
1338 #endif
1339         swrap_bind_symbol_libsocket(connect);
1340         swrap_bind_symbol_libc(dup);
1341         swrap_bind_symbol_libc(dup2);
1342         swrap_bind_symbol_libc(fcntl);
1343         swrap_bind_symbol_libc(fopen);
1344 #ifdef HAVE_FOPEN64
1345         swrap_bind_symbol_libc(fopen64);
1346 #endif
1347 #ifdef HAVE_EVENTFD
1348         swrap_bind_symbol_libc(eventfd);
1349 #endif
1350         swrap_bind_symbol_libsocket(getpeername);
1351         swrap_bind_symbol_libsocket(getsockname);
1352         swrap_bind_symbol_libsocket(getsockopt);
1353         swrap_bind_symbol_libc(ioctl);
1354         swrap_bind_symbol_libsocket(listen);
1355         swrap_bind_symbol_libc(open);
1356 #ifdef HAVE_OPEN64
1357         swrap_bind_symbol_libc(open64);
1358 #endif
1359         swrap_bind_symbol_libc(openat);
1360         swrap_bind_symbol_libsocket(pipe);
1361         swrap_bind_symbol_libc(read);
1362         swrap_bind_symbol_libsocket(readv);
1363         swrap_bind_symbol_libsocket(recv);
1364         swrap_bind_symbol_libsocket(recvfrom);
1365         swrap_bind_symbol_libsocket(recvmsg);
1366 #ifdef HAVE_RECVMMSG
1367         swrap_bind_symbol_libsocket(recvmmsg);
1368 #endif
1369         swrap_bind_symbol_libsocket(send);
1370         swrap_bind_symbol_libsocket(sendmsg);
1371 #ifdef HAVE_SENDMMSG
1372         swrap_bind_symbol_libsocket(sendmmsg);
1373 #endif
1374         swrap_bind_symbol_libsocket(sendto);
1375         swrap_bind_symbol_libsocket(setsockopt);
1376 #ifdef HAVE_SIGNALFD
1377         swrap_bind_symbol_libsocket(signalfd);
1378 #endif
1379         swrap_bind_symbol_libsocket(socket);
1380         swrap_bind_symbol_libsocket(socketpair);
1381 #ifdef HAVE_TIMERFD_CREATE
1382         swrap_bind_symbol_libc(timerfd_create);
1383 #endif
1384         swrap_bind_symbol_libc(write);
1385         swrap_bind_symbol_libsocket(writev);
1386 #ifdef HAVE_SYSCALL
1387         swrap_bind_symbol_libc(syscall);
1388 #endif
1389 }
1390
1391 static void swrap_bind_symbol_all(void)
1392 {
1393         static pthread_once_t all_symbol_binding_once = PTHREAD_ONCE_INIT;
1394
1395         pthread_once(&all_symbol_binding_once, __swrap_bind_symbol_all_once);
1396 }
1397
1398 /*********************************************************
1399  * SWRAP HELPER FUNCTIONS
1400  *********************************************************/
1401
1402 /*
1403  * We return 127.0.0.0 (default) or 10.53.57.0.
1404  *
1405  * This can be controlled by:
1406  * SOCKET_WRAPPER_IPV4_NETWORK=127.0.0.0 (default)
1407  * or
1408  * SOCKET_WRAPPER_IPV4_NETWORK=10.53.57.0
1409  */
1410 static in_addr_t swrap_ipv4_net(void)
1411 {
1412         static int initialized;
1413         static in_addr_t hv;
1414         const char *net_str = NULL;
1415         struct in_addr nv;
1416         int ret;
1417
1418         if (initialized) {
1419                 return hv;
1420         }
1421         initialized = 1;
1422
1423         net_str = getenv("SOCKET_WRAPPER_IPV4_NETWORK");
1424         if (net_str == NULL) {
1425                 net_str = "127.0.0.0";
1426         }
1427
1428         ret = inet_pton(AF_INET, net_str, &nv);
1429         if (ret <= 0) {
1430                 SWRAP_LOG(SWRAP_LOG_ERROR,
1431                           "INVALID IPv4 Network [%s]",
1432                           net_str);
1433                 abort();
1434         }
1435
1436         hv = ntohl(nv.s_addr);
1437
1438         switch (hv) {
1439         case 0x7f000000:
1440                 /* 127.0.0.0 */
1441                 break;
1442         case 0x0a353900:
1443                 /* 10.53.57.0 */
1444                 break;
1445         default:
1446                 SWRAP_LOG(SWRAP_LOG_ERROR,
1447                           "INVALID IPv4 Network [%s][0x%x] should be "
1448                           "127.0.0.0 or 10.53.57.0",
1449                           net_str, (unsigned)hv);
1450                 abort();
1451         }
1452
1453         return hv;
1454 }
1455
1456 /*
1457  * This returns 127.255.255.255 or 10.255.255.255
1458  */
1459 static in_addr_t swrap_ipv4_bcast(void)
1460 {
1461         in_addr_t hv;
1462
1463         hv = swrap_ipv4_net();
1464         hv |= IN_CLASSA_HOST;
1465
1466         return hv;
1467 }
1468
1469 /*
1470  * This returns 127.0.0.${iface} or 10.53.57.${iface}
1471  */
1472 static in_addr_t swrap_ipv4_iface(unsigned int iface)
1473 {
1474         in_addr_t hv;
1475
1476         if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
1477                 SWRAP_LOG(SWRAP_LOG_ERROR,
1478                           "swrap_ipv4_iface(%u) invalid!",
1479                           iface);
1480                 abort();
1481                 return -1;
1482         }
1483
1484         hv = swrap_ipv4_net();
1485         hv |= iface;
1486
1487         return hv;
1488 }
1489
1490 #ifdef HAVE_IPV6
1491 /*
1492  * FD00::5357:5FXX
1493  */
1494 static const struct in6_addr *swrap_ipv6(void)
1495 {
1496         static struct in6_addr v;
1497         static int initialized;
1498         int ret;
1499
1500         if (initialized) {
1501                 return &v;
1502         }
1503         initialized = 1;
1504
1505         ret = inet_pton(AF_INET6, "FD00::5357:5F00", &v);
1506         if (ret <= 0) {
1507                 abort();
1508         }
1509
1510         return &v;
1511 }
1512 #endif
1513
1514 static void set_port(int family, int prt, struct swrap_address *addr)
1515 {
1516         switch (family) {
1517         case AF_INET:
1518                 addr->sa.in.sin_port = htons(prt);
1519                 break;
1520 #ifdef HAVE_IPV6
1521         case AF_INET6:
1522                 addr->sa.in6.sin6_port = htons(prt);
1523                 break;
1524 #endif
1525         }
1526 }
1527
1528 static size_t socket_length(int family)
1529 {
1530         switch (family) {
1531         case AF_INET:
1532                 return sizeof(struct sockaddr_in);
1533 #ifdef HAVE_IPV6
1534         case AF_INET6:
1535                 return sizeof(struct sockaddr_in6);
1536 #endif
1537         }
1538         return 0;
1539 }
1540
1541 struct swrap_sockaddr_buf {
1542         char str[128];
1543 };
1544
1545 static const char *swrap_sockaddr_string(struct swrap_sockaddr_buf *buf,
1546                                          const struct sockaddr *saddr)
1547 {
1548         unsigned int port = 0;
1549         char addr[64] = {0,};
1550
1551         switch (saddr->sa_family) {
1552         case AF_INET: {
1553                 const struct sockaddr_in *in =
1554                     (const struct sockaddr_in *)(const void *)saddr;
1555
1556                 port = ntohs(in->sin_port);
1557
1558                 inet_ntop(saddr->sa_family,
1559                           &in->sin_addr,
1560                           addr, sizeof(addr));
1561                 break;
1562         }
1563 #ifdef HAVE_IPV6
1564         case AF_INET6: {
1565                 const struct sockaddr_in6 *in6 =
1566                     (const struct sockaddr_in6 *)(const void *)saddr;
1567
1568                 port = ntohs(in6->sin6_port);
1569
1570                 inet_ntop(saddr->sa_family,
1571                           &in6->sin6_addr,
1572                           addr, sizeof(addr));
1573                 break;
1574         }
1575 #endif
1576         default:
1577                 snprintf(addr, sizeof(addr),
1578                          "<Unknown address family %u>",
1579                          saddr->sa_family);
1580                 break;
1581         }
1582
1583         snprintf(buf->str, sizeof(buf->str),
1584                  "addr[%s]/port[%u]",
1585                  addr, port);
1586
1587         return buf->str;
1588 }
1589
1590 static struct socket_info *swrap_get_socket_info(int si_index)
1591 {
1592         return (struct socket_info *)(&(sockets[si_index].info));
1593 }
1594
1595 static int swrap_get_refcount(struct socket_info *si)
1596 {
1597         struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si);
1598         return sic->meta.refcount;
1599 }
1600
1601 static void swrap_inc_refcount(struct socket_info *si)
1602 {
1603         struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si);
1604
1605         sic->meta.refcount += 1;
1606 }
1607
1608 static void swrap_dec_refcount(struct socket_info *si)
1609 {
1610         struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si);
1611
1612         sic->meta.refcount -= 1;
1613 }
1614
1615 static int swrap_get_next_free(struct socket_info *si)
1616 {
1617         struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si);
1618
1619         return sic->meta.next_free;
1620 }
1621
1622 static void swrap_set_next_free(struct socket_info *si, int next_free)
1623 {
1624         struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si);
1625
1626         sic->meta.next_free = next_free;
1627 }
1628
1629 static int swrap_un_path(struct sockaddr_un *un,
1630                          const char *swrap_dir,
1631                          char type,
1632                          unsigned int iface,
1633                          unsigned int prt)
1634 {
1635         int ret;
1636
1637         ret = snprintf(un->sun_path,
1638                        sizeof(un->sun_path),
1639                        "%s/"SOCKET_FORMAT,
1640                        swrap_dir,
1641                        type,
1642                        iface,
1643                        prt);
1644         if ((size_t)ret >= sizeof(un->sun_path)) {
1645                 return ENAMETOOLONG;
1646         }
1647
1648         return 0;
1649 }
1650
1651 static int swrap_un_path_EINVAL(struct sockaddr_un *un,
1652                                 const char *swrap_dir)
1653 {
1654         int ret;
1655
1656         ret = snprintf(un->sun_path,
1657                        sizeof(un->sun_path),
1658                        "%s/EINVAL",
1659                        swrap_dir);
1660
1661         if ((size_t)ret >= sizeof(un->sun_path)) {
1662                 return ENAMETOOLONG;
1663         }
1664
1665         return 0;
1666 }
1667
1668 static bool swrap_dir_usable(const char *swrap_dir)
1669 {
1670         struct sockaddr_un un;
1671         int ret;
1672
1673         ret = swrap_un_path(&un, swrap_dir, SOCKET_TYPE_CHAR_TCP, 0, 0);
1674         if (ret == 0) {
1675                 return true;
1676         }
1677
1678         ret = swrap_un_path_EINVAL(&un, swrap_dir);
1679         if (ret == 0) {
1680                 return true;
1681         }
1682
1683         return false;
1684 }
1685
1686 static char *socket_wrapper_dir(void)
1687 {
1688         char *swrap_dir = NULL;
1689         char *s = getenv("SOCKET_WRAPPER_DIR");
1690         char *t;
1691         bool ok;
1692
1693         if (s == NULL || s[0] == '\0') {
1694                 SWRAP_LOG(SWRAP_LOG_WARN, "SOCKET_WRAPPER_DIR not set");
1695                 return NULL;
1696         }
1697
1698         swrap_dir = realpath(s, NULL);
1699         if (swrap_dir == NULL) {
1700                 SWRAP_LOG(SWRAP_LOG_ERROR,
1701                           "Unable to resolve socket_wrapper dir path: %s - %s",
1702                           s,
1703                           strerror(errno));
1704                 abort();
1705         }
1706
1707         ok = swrap_dir_usable(swrap_dir);
1708         if (ok) {
1709                 goto done;
1710         }
1711
1712         free(swrap_dir);
1713
1714         ok = swrap_dir_usable(s);
1715         if (!ok) {
1716                 SWRAP_LOG(SWRAP_LOG_ERROR, "SOCKET_WRAPPER_DIR is too long");
1717                 abort();
1718         }
1719
1720         t = getenv("SOCKET_WRAPPER_DIR_ALLOW_ORIG");
1721         if (t == NULL) {
1722                 SWRAP_LOG(SWRAP_LOG_ERROR,
1723                           "realpath(SOCKET_WRAPPER_DIR) too long and "
1724                           "SOCKET_WRAPPER_DIR_ALLOW_ORIG not set");
1725                 abort();
1726
1727         }
1728
1729         swrap_dir = strdup(s);
1730         if (swrap_dir == NULL) {
1731                 SWRAP_LOG(SWRAP_LOG_ERROR,
1732                           "Unable to duplicate socket_wrapper dir path");
1733                 abort();
1734         }
1735
1736         SWRAP_LOG(SWRAP_LOG_WARN,
1737                   "realpath(SOCKET_WRAPPER_DIR) too long, "
1738                   "using original SOCKET_WRAPPER_DIR\n");
1739
1740 done:
1741         SWRAP_LOG(SWRAP_LOG_TRACE, "socket_wrapper_dir: %s", swrap_dir);
1742         return swrap_dir;
1743 }
1744
1745 static unsigned int socket_wrapper_mtu(void)
1746 {
1747         static unsigned int max_mtu = 0;
1748         unsigned int tmp;
1749         const char *s;
1750         char *endp;
1751
1752         swrap_mutex_lock(&mtu_update_mutex);
1753
1754         if (max_mtu != 0) {
1755                 goto done;
1756         }
1757
1758         max_mtu = SOCKET_WRAPPER_MTU_DEFAULT;
1759
1760         s = getenv("SOCKET_WRAPPER_MTU");
1761         if (s == NULL) {
1762                 goto done;
1763         }
1764
1765         tmp = strtol(s, &endp, 10);
1766         if (s == endp) {
1767                 goto done;
1768         }
1769
1770         if (tmp < SOCKET_WRAPPER_MTU_MIN || tmp > SOCKET_WRAPPER_MTU_MAX) {
1771                 goto done;
1772         }
1773         max_mtu = tmp;
1774
1775 done:
1776         swrap_mutex_unlock(&mtu_update_mutex);
1777         return max_mtu;
1778 }
1779
1780 static int _socket_wrapper_init_mutex(pthread_mutex_t *m, const char *name)
1781 {
1782         pthread_mutexattr_t ma;
1783         bool need_destroy = false;
1784         int ret = 0;
1785
1786 #define __CHECK(cmd) do { \
1787         ret = cmd; \
1788         if (ret != 0) { \
1789                 SWRAP_LOG(SWRAP_LOG_ERROR, \
1790                           "%s: %s - failed %d", \
1791                           name, #cmd, ret); \
1792                 goto done; \
1793         } \
1794 } while(0)
1795
1796         *m = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;
1797         __CHECK(pthread_mutexattr_init(&ma));
1798         need_destroy = true;
1799         __CHECK(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK));
1800         __CHECK(pthread_mutex_init(m, &ma));
1801 done:
1802         if (need_destroy) {
1803                 pthread_mutexattr_destroy(&ma);
1804         }
1805         return ret;
1806 }
1807
1808 static size_t socket_wrapper_max_sockets(void)
1809 {
1810         const char *s;
1811         size_t tmp;
1812         char *endp;
1813
1814         if (socket_info_max != 0) {
1815                 return socket_info_max;
1816         }
1817
1818         socket_info_max = SOCKET_WRAPPER_MAX_SOCKETS_DEFAULT;
1819
1820         s = getenv("SOCKET_WRAPPER_MAX_SOCKETS");
1821         if (s == NULL || s[0] == '\0') {
1822                 goto done;
1823         }
1824
1825         tmp = strtoul(s, &endp, 10);
1826         if (s == endp) {
1827                 goto done;
1828         }
1829         if (tmp == 0) {
1830                 tmp = SOCKET_WRAPPER_MAX_SOCKETS_DEFAULT;
1831                 SWRAP_LOG(SWRAP_LOG_ERROR,
1832                           "Invalid number of sockets specified, "
1833                           "using default (%zu)",
1834                           tmp);
1835         }
1836
1837         if (tmp > SOCKET_WRAPPER_MAX_SOCKETS_LIMIT) {
1838                 tmp = SOCKET_WRAPPER_MAX_SOCKETS_LIMIT;
1839                 SWRAP_LOG(SWRAP_LOG_ERROR,
1840                           "Invalid number of sockets specified, "
1841                           "using maximum (%zu).",
1842                           tmp);
1843         }
1844
1845         socket_info_max = tmp;
1846
1847 done:
1848         return socket_info_max;
1849 }
1850
1851 static void socket_wrapper_init_fds_idx(void)
1852 {
1853         int *tmp = NULL;
1854         size_t i;
1855
1856         if (socket_fds_idx != NULL) {
1857                 return;
1858         }
1859
1860         tmp = (int *)calloc(socket_fds_max, sizeof(int));
1861         if (tmp == NULL) {
1862                 SWRAP_LOG(SWRAP_LOG_ERROR,
1863                           "Failed to allocate socket fds index array: %s",
1864                           strerror(errno));
1865                 exit(-1);
1866         }
1867
1868         for (i = 0; i < socket_fds_max; i++) {
1869                 tmp[i] = -1;
1870         }
1871
1872         socket_fds_idx = tmp;
1873 }
1874
1875 static void socket_wrapper_init_sockets(void)
1876 {
1877         size_t max_sockets;
1878         size_t i;
1879         int ret = 0;
1880
1881         swrap_bind_symbol_all();
1882
1883         swrap_mutex_lock(&sockets_mutex);
1884
1885         if (sockets != NULL) {
1886                 swrap_mutex_unlock(&sockets_mutex);
1887                 return;
1888         }
1889
1890         SWRAP_LOG(SWRAP_LOG_DEBUG,
1891                   "SOCKET_WRAPPER_PACKAGE[%s] SOCKET_WRAPPER_VERSION[%s]",
1892                   SOCKET_WRAPPER_PACKAGE, SOCKET_WRAPPER_VERSION);
1893
1894         /*
1895          * Intialize the static cache early before
1896          * any thread is able to start.
1897          */
1898         (void)swrap_ipv4_net();
1899
1900         socket_wrapper_init_fds_idx();
1901
1902         /* Needs to be called inside the sockets_mutex lock here. */
1903         max_sockets = socket_wrapper_max_sockets();
1904
1905         sockets = (struct socket_info_container *)calloc(max_sockets,
1906                                         sizeof(struct socket_info_container));
1907
1908         if (sockets == NULL) {
1909                 SWRAP_LOG(SWRAP_LOG_ERROR,
1910                           "Failed to allocate sockets array: %s",
1911                           strerror(errno));
1912                 swrap_mutex_unlock(&sockets_mutex);
1913                 exit(-1);
1914         }
1915
1916         swrap_mutex_lock(&first_free_mutex);
1917         swrap_mutex_lock(&sockets_si_global);
1918
1919         first_free = 0;
1920
1921         for (i = 0; i < max_sockets; i++) {
1922                 swrap_set_next_free(&sockets[i].info, i+1);
1923         }
1924
1925         /* mark the end of the free list */
1926         swrap_set_next_free(&sockets[max_sockets-1].info, -1);
1927
1928         swrap_mutex_unlock(&sockets_si_global);
1929         swrap_mutex_unlock(&first_free_mutex);
1930         swrap_mutex_unlock(&sockets_mutex);
1931         if (ret != 0) {
1932                 exit(-1);
1933         }
1934 }
1935
1936 bool socket_wrapper_enabled(void)
1937 {
1938         char *s = socket_wrapper_dir();
1939
1940         if (s == NULL) {
1941                 return false;
1942         }
1943
1944         SAFE_FREE(s);
1945
1946         socket_wrapper_init_sockets();
1947
1948         return true;
1949 }
1950
1951 static unsigned int socket_wrapper_default_iface(void)
1952 {
1953         const char *s = getenv("SOCKET_WRAPPER_DEFAULT_IFACE");
1954         if (s) {
1955                 unsigned int iface;
1956                 if (sscanf(s, "%u", &iface) == 1) {
1957                         if (iface >= 1 && iface <= MAX_WRAPPED_INTERFACES) {
1958                                 return iface;
1959                         }
1960                 }
1961         }
1962
1963         return 1;/* 127.0.0.1 */
1964 }
1965
1966 static void set_socket_info_index(int fd, int idx)
1967 {
1968         SWRAP_LOG(SWRAP_LOG_TRACE,
1969                   "fd=%d idx=%d",
1970                   fd, idx);
1971         socket_fds_idx[fd] = idx;
1972         /* This builtin issues a full memory barrier. */
1973         __sync_synchronize();
1974 }
1975
1976 static void reset_socket_info_index(int fd)
1977 {
1978         SWRAP_LOG(SWRAP_LOG_TRACE,
1979                   "fd=%d idx=%d",
1980                   fd, -1);
1981         set_socket_info_index(fd, -1);
1982 }
1983
1984 static int find_socket_info_index(int fd)
1985 {
1986         if (fd < 0) {
1987                 return -1;
1988         }
1989
1990         if (socket_fds_idx == NULL) {
1991                 return -1;
1992         }
1993
1994         if ((size_t)fd >= socket_fds_max) {
1995                 /*
1996                  * Do not add a log here as some applications do stupid things
1997                  * like:
1998                  *
1999                  *     for (fd = 0; fd <= getdtablesize(); fd++) {
2000                  *         close(fd)
2001                  *     };
2002                  *
2003                  * This would produce millions of lines of debug messages.
2004                  */
2005 #if 0
2006                 SWRAP_LOG(SWRAP_LOG_ERROR,
2007                           "Looking for a socket info for the fd %d is over the "
2008                           "max socket index limit of %zu.",
2009                           fd,
2010                           socket_fds_max);
2011 #endif
2012                 return -1;
2013         }
2014
2015         /* This builtin issues a full memory barrier. */
2016         __sync_synchronize();
2017         return socket_fds_idx[fd];
2018 }
2019
2020 static int swrap_add_socket_info(const struct socket_info *si_input)
2021 {
2022         struct socket_info *si = NULL;
2023         int si_index = -1;
2024
2025         if (si_input == NULL) {
2026                 errno = EINVAL;
2027                 return -1;
2028         }
2029
2030         swrap_mutex_lock(&first_free_mutex);
2031         if (first_free == -1) {
2032                 errno = ENFILE;
2033                 goto out;
2034         }
2035
2036         si_index = first_free;
2037         si = swrap_get_socket_info(si_index);
2038
2039         SWRAP_LOCK_SI(si);
2040
2041         first_free = swrap_get_next_free(si);
2042         *si = *si_input;
2043         swrap_inc_refcount(si);
2044
2045         SWRAP_UNLOCK_SI(si);
2046
2047 out:
2048         swrap_mutex_unlock(&first_free_mutex);
2049
2050         return si_index;
2051 }
2052
2053 static int swrap_create_socket(struct socket_info *si, int fd)
2054 {
2055         int idx;
2056
2057         if ((size_t)fd >= socket_fds_max) {
2058                 SWRAP_LOG(SWRAP_LOG_ERROR,
2059                           "The max socket index limit of %zu has been reached, "
2060                           "trying to add %d",
2061                           socket_fds_max,
2062                           fd);
2063                 errno = EMFILE;
2064                 return -1;
2065         }
2066
2067         idx = swrap_add_socket_info(si);
2068         if (idx == -1) {
2069                 return -1;
2070         }
2071
2072         set_socket_info_index(fd, idx);
2073
2074         return idx;
2075 }
2076
2077 static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, socklen_t *len)
2078 {
2079         unsigned int iface;
2080         unsigned int prt;
2081         const char *p;
2082         char type;
2083
2084         p = strrchr(un->sun_path, '/');
2085         if (p) p++; else p = un->sun_path;
2086
2087         if (sscanf(p, SOCKET_FORMAT, &type, &iface, &prt) != 3) {
2088                 SWRAP_LOG(SWRAP_LOG_ERROR, "sun_path[%s] p[%s]",
2089                           un->sun_path, p);
2090                 errno = EINVAL;
2091                 return -1;
2092         }
2093
2094         if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
2095                 SWRAP_LOG(SWRAP_LOG_ERROR, "type %c iface %u port %u",
2096                           type, iface, prt);
2097                 errno = EINVAL;
2098                 return -1;
2099         }
2100
2101         if (prt > 0xFFFF) {
2102                 SWRAP_LOG(SWRAP_LOG_ERROR, "type %c iface %u port %u",
2103                           type, iface, prt);
2104                 errno = EINVAL;
2105                 return -1;
2106         }
2107
2108         SWRAP_LOG(SWRAP_LOG_TRACE, "type %c iface %u port %u",
2109                   type, iface, prt);
2110
2111         switch(type) {
2112         case SOCKET_TYPE_CHAR_TCP:
2113         case SOCKET_TYPE_CHAR_UDP: {
2114                 struct sockaddr_in *in2 = (struct sockaddr_in *)(void *)in;
2115
2116                 if ((*len) < sizeof(*in2)) {
2117                         SWRAP_LOG(SWRAP_LOG_ERROR,
2118                                   "V4: *len(%zu) < sizeof(*in2)=%zu",
2119                                   (size_t)*len, sizeof(*in2));
2120                         errno = EINVAL;
2121                         return -1;
2122                 }
2123
2124                 memset(in2, 0, sizeof(*in2));
2125                 in2->sin_family = AF_INET;
2126                 in2->sin_addr.s_addr = htonl(swrap_ipv4_iface(iface));
2127                 in2->sin_port = htons(prt);
2128
2129                 *len = sizeof(*in2);
2130                 break;
2131         }
2132 #ifdef HAVE_IPV6
2133         case SOCKET_TYPE_CHAR_TCP_V6:
2134         case SOCKET_TYPE_CHAR_UDP_V6: {
2135                 struct sockaddr_in6 *in2 = (struct sockaddr_in6 *)(void *)in;
2136
2137                 if ((*len) < sizeof(*in2)) {
2138                         SWRAP_LOG(SWRAP_LOG_ERROR,
2139                                   "V6: *len(%zu) < sizeof(*in2)=%zu",
2140                                   (size_t)*len, sizeof(*in2));
2141                         SWRAP_LOG(SWRAP_LOG_ERROR, "LINE:%d", __LINE__);
2142                         errno = EINVAL;
2143                         return -1;
2144                 }
2145
2146                 memset(in2, 0, sizeof(*in2));
2147                 in2->sin6_family = AF_INET6;
2148                 in2->sin6_addr = *swrap_ipv6();
2149                 in2->sin6_addr.s6_addr[15] = iface;
2150                 in2->sin6_port = htons(prt);
2151
2152                 *len = sizeof(*in2);
2153                 break;
2154         }
2155 #endif
2156         default:
2157                 SWRAP_LOG(SWRAP_LOG_ERROR, "type %c iface %u port %u",
2158                           type, iface, prt);
2159                 errno = EINVAL;
2160                 return -1;
2161         }
2162
2163         return 0;
2164 }
2165
2166 static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un,
2167                                 int *bcast)
2168 {
2169         char type = '\0';
2170         unsigned int prt;
2171         unsigned int iface;
2172         int is_bcast = 0;
2173         char *swrap_dir = NULL;
2174
2175         if (bcast) *bcast = 0;
2176
2177         switch (inaddr->sa_family) {
2178         case AF_INET: {
2179                 const struct sockaddr_in *in =
2180                     (const struct sockaddr_in *)(const void *)inaddr;
2181                 unsigned int addr = ntohl(in->sin_addr.s_addr);
2182                 char u_type = '\0';
2183                 char b_type = '\0';
2184                 char a_type = '\0';
2185                 const unsigned int sw_net_addr = swrap_ipv4_net();
2186                 const unsigned int sw_bcast_addr = swrap_ipv4_bcast();
2187
2188                 switch (si->type) {
2189                 case SOCK_STREAM:
2190                         u_type = SOCKET_TYPE_CHAR_TCP;
2191                         break;
2192                 case SOCK_DGRAM:
2193                         u_type = SOCKET_TYPE_CHAR_UDP;
2194                         a_type = SOCKET_TYPE_CHAR_UDP;
2195                         b_type = SOCKET_TYPE_CHAR_UDP;
2196                         break;
2197                 default:
2198                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!");
2199                         errno = ESOCKTNOSUPPORT;
2200                         return -1;
2201                 }
2202
2203                 prt = ntohs(in->sin_port);
2204                 if (a_type && addr == 0xFFFFFFFF) {
2205                         /* 255.255.255.255 only udp */
2206                         is_bcast = 2;
2207                         type = a_type;
2208                         iface = socket_wrapper_default_iface();
2209                 } else if (b_type && addr == sw_bcast_addr) {
2210                         /*
2211                          * 127.255.255.255
2212                          * or
2213                          * 10.255.255.255
2214                          * only udp
2215                          */
2216                         is_bcast = 1;
2217                         type = b_type;
2218                         iface = socket_wrapper_default_iface();
2219                 } else if ((addr & 0xFFFFFF00) == sw_net_addr) {
2220                         /* 127.0.0.X or 10.53.57.X */
2221                         is_bcast = 0;
2222                         type = u_type;
2223                         iface = (addr & 0x000000FF);
2224                 } else {
2225                         struct swrap_sockaddr_buf buf = {};
2226                         SWRAP_LOG(SWRAP_LOG_WARN,
2227                                   "%s",
2228                                   swrap_sockaddr_string(&buf, inaddr));
2229                         errno = ENETUNREACH;
2230                         return -1;
2231                 }
2232                 if (bcast) *bcast = is_bcast;
2233                 break;
2234         }
2235 #ifdef HAVE_IPV6
2236         case AF_INET6: {
2237                 const struct sockaddr_in6 *in =
2238                     (const struct sockaddr_in6 *)(const void *)inaddr;
2239                 struct in6_addr cmp1, cmp2;
2240
2241                 switch (si->type) {
2242                 case SOCK_STREAM:
2243                         type = SOCKET_TYPE_CHAR_TCP_V6;
2244                         break;
2245                 case SOCK_DGRAM:
2246                         type = SOCKET_TYPE_CHAR_UDP_V6;
2247                         break;
2248                 default:
2249                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!");
2250                         errno = ESOCKTNOSUPPORT;
2251                         return -1;
2252                 }
2253
2254                 /* XXX no multicast/broadcast */
2255
2256                 prt = ntohs(in->sin6_port);
2257
2258                 cmp1 = *swrap_ipv6();
2259                 cmp2 = in->sin6_addr;
2260                 cmp2.s6_addr[15] = 0;
2261                 if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
2262                         iface = in->sin6_addr.s6_addr[15];
2263                 } else {
2264                         struct swrap_sockaddr_buf buf = {};
2265                         SWRAP_LOG(SWRAP_LOG_WARN,
2266                                   "%s",
2267                                   swrap_sockaddr_string(&buf, inaddr));
2268                         errno = ENETUNREACH;
2269                         return -1;
2270                 }
2271
2272                 break;
2273         }
2274 #endif
2275         default:
2276                 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family!");
2277                 errno = ENETUNREACH;
2278                 return -1;
2279         }
2280
2281         if (prt == 0) {
2282                 SWRAP_LOG(SWRAP_LOG_WARN, "Port not set");
2283                 errno = EINVAL;
2284                 return -1;
2285         }
2286
2287         swrap_dir = socket_wrapper_dir();
2288         if (swrap_dir == NULL) {
2289                 errno = EINVAL;
2290                 return -1;
2291         }
2292
2293         if (is_bcast) {
2294                 swrap_un_path_EINVAL(un, swrap_dir);
2295                 SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
2296                 SAFE_FREE(swrap_dir);
2297                 /* the caller need to do more processing */
2298                 return 0;
2299         }
2300
2301         swrap_un_path(un, swrap_dir, type, iface, prt);
2302         SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
2303
2304         SAFE_FREE(swrap_dir);
2305
2306         return 0;
2307 }
2308
2309 static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un,
2310                                int *bcast)
2311 {
2312         char type = '\0';
2313         unsigned int prt;
2314         unsigned int iface;
2315         struct stat st;
2316         int is_bcast = 0;
2317         char *swrap_dir = NULL;
2318
2319         if (bcast) *bcast = 0;
2320
2321         switch (si->family) {
2322         case AF_INET: {
2323                 const struct sockaddr_in *in =
2324                     (const struct sockaddr_in *)(const void *)inaddr;
2325                 unsigned int addr = ntohl(in->sin_addr.s_addr);
2326                 char u_type = '\0';
2327                 char d_type = '\0';
2328                 char b_type = '\0';
2329                 char a_type = '\0';
2330                 const unsigned int sw_net_addr = swrap_ipv4_net();
2331                 const unsigned int sw_bcast_addr = swrap_ipv4_bcast();
2332
2333                 prt = ntohs(in->sin_port);
2334
2335                 switch (si->type) {
2336                 case SOCK_STREAM:
2337                         u_type = SOCKET_TYPE_CHAR_TCP;
2338                         d_type = SOCKET_TYPE_CHAR_TCP;
2339                         break;
2340                 case SOCK_DGRAM:
2341                         u_type = SOCKET_TYPE_CHAR_UDP;
2342                         d_type = SOCKET_TYPE_CHAR_UDP;
2343                         a_type = SOCKET_TYPE_CHAR_UDP;
2344                         b_type = SOCKET_TYPE_CHAR_UDP;
2345                         break;
2346                 default:
2347                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!");
2348                         errno = ESOCKTNOSUPPORT;
2349                         return -1;
2350                 }
2351
2352                 if (addr == 0) {
2353                         /* 0.0.0.0 */
2354                         is_bcast = 0;
2355                         type = d_type;
2356                         iface = socket_wrapper_default_iface();
2357                 } else if (a_type && addr == 0xFFFFFFFF) {
2358                         /* 255.255.255.255 only udp */
2359                         is_bcast = 2;
2360                         type = a_type;
2361                         iface = socket_wrapper_default_iface();
2362                 } else if (b_type && addr == sw_bcast_addr) {
2363                         /* 127.255.255.255 only udp */
2364                         is_bcast = 1;
2365                         type = b_type;
2366                         iface = socket_wrapper_default_iface();
2367                 } else if ((addr & 0xFFFFFF00) == sw_net_addr) {
2368                         /* 127.0.0.X */
2369                         is_bcast = 0;
2370                         type = u_type;
2371                         iface = (addr & 0x000000FF);
2372                 } else {
2373                         errno = EADDRNOTAVAIL;
2374                         return -1;
2375                 }
2376
2377                 /* Store the bind address for connect() */
2378                 if (si->bindname.sa_socklen == 0) {
2379                         struct sockaddr_in bind_in;
2380                         socklen_t blen = sizeof(struct sockaddr_in);
2381
2382                         ZERO_STRUCT(bind_in);
2383                         bind_in.sin_family = in->sin_family;
2384                         bind_in.sin_port = in->sin_port;
2385                         bind_in.sin_addr.s_addr = htonl(swrap_ipv4_iface(iface));
2386                         si->bindname.sa_socklen = blen;
2387                         memcpy(&si->bindname.sa.in, &bind_in, blen);
2388                 }
2389
2390                 break;
2391         }
2392 #ifdef HAVE_IPV6
2393         case AF_INET6: {
2394                 const struct sockaddr_in6 *in =
2395                     (const struct sockaddr_in6 *)(const void *)inaddr;
2396                 struct in6_addr cmp1, cmp2;
2397
2398                 switch (si->type) {
2399                 case SOCK_STREAM:
2400                         type = SOCKET_TYPE_CHAR_TCP_V6;
2401                         break;
2402                 case SOCK_DGRAM:
2403                         type = SOCKET_TYPE_CHAR_UDP_V6;
2404                         break;
2405                 default:
2406                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!");
2407                         errno = ESOCKTNOSUPPORT;
2408                         return -1;
2409                 }
2410
2411                 /* XXX no multicast/broadcast */
2412
2413                 prt = ntohs(in->sin6_port);
2414
2415                 cmp1 = *swrap_ipv6();
2416                 cmp2 = in->sin6_addr;
2417                 cmp2.s6_addr[15] = 0;
2418                 if (IN6_IS_ADDR_UNSPECIFIED(&in->sin6_addr)) {
2419                         iface = socket_wrapper_default_iface();
2420                 } else if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
2421                         iface = in->sin6_addr.s6_addr[15];
2422                 } else {
2423                         errno = EADDRNOTAVAIL;
2424                         return -1;
2425                 }
2426
2427                 /* Store the bind address for connect() */
2428                 if (si->bindname.sa_socklen == 0) {
2429                         struct sockaddr_in6 bind_in;
2430                         socklen_t blen = sizeof(struct sockaddr_in6);
2431
2432                         ZERO_STRUCT(bind_in);
2433                         bind_in.sin6_family = in->sin6_family;
2434                         bind_in.sin6_port = in->sin6_port;
2435
2436                         bind_in.sin6_addr = *swrap_ipv6();
2437                         bind_in.sin6_addr.s6_addr[15] = iface;
2438
2439                         memcpy(&si->bindname.sa.in6, &bind_in, blen);
2440                         si->bindname.sa_socklen = blen;
2441                 }
2442
2443                 break;
2444         }
2445 #endif
2446         default:
2447                 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family");
2448                 errno = EADDRNOTAVAIL;
2449                 return -1;
2450         }
2451
2452
2453         if (bcast) *bcast = is_bcast;
2454
2455         if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
2456                 errno = EINVAL;
2457                 return -1;
2458         }
2459
2460         swrap_dir = socket_wrapper_dir();
2461         if (swrap_dir == NULL) {
2462                 errno = EINVAL;
2463                 return -1;
2464         }
2465
2466         if (prt == 0) {
2467                 /* handle auto-allocation of ephemeral ports */
2468                 for (prt = 5001; prt < 10000; prt++) {
2469                         swrap_un_path(un, swrap_dir, type, iface, prt);
2470                         if (stat(un->sun_path, &st) == 0) continue;
2471
2472                         set_port(si->family, prt, &si->myname);
2473                         set_port(si->family, prt, &si->bindname);
2474
2475                         break;
2476                 }
2477
2478                 if (prt == 10000) {
2479                         errno = ENFILE;
2480                         SAFE_FREE(swrap_dir);
2481                         return -1;
2482                 }
2483         }
2484
2485         swrap_un_path(un, swrap_dir, type, iface, prt);
2486         SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
2487
2488         SAFE_FREE(swrap_dir);
2489
2490         return 0;
2491 }
2492
2493 static struct socket_info *find_socket_info(int fd)
2494 {
2495         int idx = find_socket_info_index(fd);
2496
2497         if (idx == -1) {
2498                 return NULL;
2499         }
2500
2501         return swrap_get_socket_info(idx);
2502 }
2503
2504 #if 0 /* FIXME */
2505 static bool check_addr_port_in_use(const struct sockaddr *sa, socklen_t len)
2506 {
2507         struct socket_info_fd *f;
2508         const struct socket_info *last_s = NULL;
2509
2510         /* first catch invalid input */
2511         switch (sa->sa_family) {
2512         case AF_INET:
2513                 if (len < sizeof(struct sockaddr_in)) {
2514                         return false;
2515                 }
2516                 break;
2517 #ifdef HAVE_IPV6
2518         case AF_INET6:
2519                 if (len < sizeof(struct sockaddr_in6)) {
2520                         return false;
2521                 }
2522                 break;
2523 #endif
2524         default:
2525                 return false;
2526                 break;
2527         }
2528
2529         for (f = socket_fds; f; f = f->next) {
2530                 struct socket_info *s = swrap_get_socket_info(f->si_index);
2531
2532                 if (s == last_s) {
2533                         continue;
2534                 }
2535                 last_s = s;
2536
2537                 if (s->myname == NULL) {
2538                         continue;
2539                 }
2540                 if (s->myname->sa_family != sa->sa_family) {
2541                         continue;
2542                 }
2543                 switch (s->myname->sa_family) {
2544                 case AF_INET: {
2545                         struct sockaddr_in *sin1, *sin2;
2546
2547                         sin1 = (struct sockaddr_in *)s->myname;
2548                         sin2 = (struct sockaddr_in *)sa;
2549
2550                         if (sin1->sin_addr.s_addr == htonl(INADDR_ANY)) {
2551                                 continue;
2552                         }
2553                         if (sin1->sin_port != sin2->sin_port) {
2554                                 continue;
2555                         }
2556                         if (sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) {
2557                                 continue;
2558                         }
2559
2560                         /* found */
2561                         return true;
2562                         break;
2563                 }
2564 #ifdef HAVE_IPV6
2565                 case AF_INET6: {
2566                         struct sockaddr_in6 *sin1, *sin2;
2567
2568                         sin1 = (struct sockaddr_in6 *)s->myname;
2569                         sin2 = (struct sockaddr_in6 *)sa;
2570
2571                         if (sin1->sin6_port != sin2->sin6_port) {
2572                                 continue;
2573                         }
2574                         if (!IN6_ARE_ADDR_EQUAL(&sin1->sin6_addr,
2575                                                 &sin2->sin6_addr))
2576                         {
2577                                 continue;
2578                         }
2579
2580                         /* found */
2581                         return true;
2582                         break;
2583                 }
2584 #endif
2585                 default:
2586                         continue;
2587                         break;
2588
2589                 }
2590         }
2591
2592         return false;
2593 }
2594 #endif
2595
2596 static void swrap_remove_stale(int fd);
2597
2598 static int sockaddr_convert_to_un(struct socket_info *si,
2599                                   const struct sockaddr *in_addr,
2600                                   socklen_t in_len,
2601                                   struct sockaddr_un *out_addr,
2602                                   int alloc_sock,
2603                                   int *bcast)
2604 {
2605         struct sockaddr *out = (struct sockaddr *)(void *)out_addr;
2606
2607         (void) in_len; /* unused */
2608
2609         if (out_addr == NULL) {
2610                 return 0;
2611         }
2612
2613         out->sa_family = AF_UNIX;
2614 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
2615         out->sa_len = sizeof(*out_addr);
2616 #endif
2617
2618         switch (in_addr->sa_family) {
2619         case AF_UNSPEC: {
2620                 const struct sockaddr_in *sin;
2621                 if (si->family != AF_INET) {
2622                         break;
2623                 }
2624                 if (in_len < sizeof(struct sockaddr_in)) {
2625                         break;
2626                 }
2627                 sin = (const struct sockaddr_in *)(const void *)in_addr;
2628                 if(sin->sin_addr.s_addr != htonl(INADDR_ANY)) {
2629                         break;
2630                 }
2631
2632                 /*
2633                  * Note: in the special case of AF_UNSPEC and INADDR_ANY,
2634                  * AF_UNSPEC is mapped to AF_INET and must be treated here.
2635                  */
2636
2637                 FALL_THROUGH;
2638         }
2639         case AF_INET:
2640 #ifdef HAVE_IPV6
2641         case AF_INET6:
2642 #endif
2643                 switch (si->type) {
2644                 case SOCK_STREAM:
2645                 case SOCK_DGRAM:
2646                         break;
2647                 default:
2648                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!");
2649                         errno = ESOCKTNOSUPPORT;
2650                         return -1;
2651                 }
2652                 if (alloc_sock) {
2653                         return convert_in_un_alloc(si, in_addr, out_addr, bcast);
2654                 } else {
2655                         return convert_in_un_remote(si, in_addr, out_addr, bcast);
2656                 }
2657         default:
2658                 break;
2659         }
2660
2661         errno = EAFNOSUPPORT;
2662         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family");
2663         return -1;
2664 }
2665
2666 static int sockaddr_convert_from_un(const struct socket_info *si,
2667                                     const struct sockaddr_un *in_addr,
2668                                     socklen_t un_addrlen,
2669                                     int family,
2670                                     struct sockaddr *out_addr,
2671                                     socklen_t *out_addrlen)
2672 {
2673         int ret;
2674
2675         if (out_addr == NULL || out_addrlen == NULL)
2676                 return 0;
2677
2678         if (un_addrlen == 0) {
2679                 *out_addrlen = 0;
2680                 return 0;
2681         }
2682
2683         switch (family) {
2684         case AF_INET:
2685 #ifdef HAVE_IPV6
2686         case AF_INET6:
2687 #endif
2688                 switch (si->type) {
2689                 case SOCK_STREAM:
2690                 case SOCK_DGRAM:
2691                         break;
2692                 default:
2693                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!");
2694                         errno = ESOCKTNOSUPPORT;
2695                         return -1;
2696                 }
2697                 ret = convert_un_in(in_addr, out_addr, out_addrlen);
2698 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
2699                 out_addr->sa_len = *out_addrlen;
2700 #endif
2701                 return ret;
2702         default:
2703                 break;
2704         }
2705
2706         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family");
2707         errno = EAFNOSUPPORT;
2708         return -1;
2709 }
2710
2711 enum swrap_packet_type {
2712         SWRAP_CONNECT_SEND,
2713         SWRAP_CONNECT_UNREACH,
2714         SWRAP_CONNECT_RECV,
2715         SWRAP_CONNECT_ACK,
2716         SWRAP_ACCEPT_SEND,
2717         SWRAP_ACCEPT_RECV,
2718         SWRAP_ACCEPT_ACK,
2719         SWRAP_RECVFROM,
2720         SWRAP_SENDTO,
2721         SWRAP_SENDTO_UNREACH,
2722         SWRAP_PENDING_RST,
2723         SWRAP_RECV,
2724         SWRAP_RECV_RST,
2725         SWRAP_SEND,
2726         SWRAP_SEND_RST,
2727         SWRAP_CLOSE_SEND,
2728         SWRAP_CLOSE_RECV,
2729         SWRAP_CLOSE_ACK,
2730 };
2731
2732 struct swrap_file_hdr {
2733         uint32_t        magic;
2734         uint16_t        version_major;
2735         uint16_t        version_minor;
2736         int32_t         timezone;
2737         uint32_t        sigfigs;
2738         uint32_t        frame_max_len;
2739 #define SWRAP_FRAME_LENGTH_MAX 0xFFFF
2740         uint32_t        link_type;
2741 };
2742 #define SWRAP_FILE_HDR_SIZE 24
2743
2744 struct swrap_packet_frame {
2745         uint32_t seconds;
2746         uint32_t micro_seconds;
2747         uint32_t recorded_length;
2748         uint32_t full_length;
2749 };
2750 #define SWRAP_PACKET_FRAME_SIZE 16
2751
2752 union swrap_packet_ip {
2753         struct {
2754                 uint8_t         ver_hdrlen;
2755                 uint8_t         tos;
2756                 uint16_t        packet_length;
2757                 uint16_t        identification;
2758                 uint8_t         flags;
2759                 uint8_t         fragment;
2760                 uint8_t         ttl;
2761                 uint8_t         protocol;
2762                 uint16_t        hdr_checksum;
2763                 uint32_t        src_addr;
2764                 uint32_t        dest_addr;
2765         } v4;
2766 #define SWRAP_PACKET_IP_V4_SIZE 20
2767         struct {
2768                 uint8_t         ver_prio;
2769                 uint8_t         flow_label_high;
2770                 uint16_t        flow_label_low;
2771                 uint16_t        payload_length;
2772                 uint8_t         next_header;
2773                 uint8_t         hop_limit;
2774                 uint8_t         src_addr[16];
2775                 uint8_t         dest_addr[16];
2776         } v6;
2777 #define SWRAP_PACKET_IP_V6_SIZE 40
2778 };
2779 #define SWRAP_PACKET_IP_SIZE 40
2780
2781 union swrap_packet_payload {
2782         struct {
2783                 uint16_t        source_port;
2784                 uint16_t        dest_port;
2785                 uint32_t        seq_num;
2786                 uint32_t        ack_num;
2787                 uint8_t         hdr_length;
2788                 uint8_t         control;
2789                 uint16_t        window;
2790                 uint16_t        checksum;
2791                 uint16_t        urg;
2792         } tcp;
2793 #define SWRAP_PACKET_PAYLOAD_TCP_SIZE 20
2794         struct {
2795                 uint16_t        source_port;
2796                 uint16_t        dest_port;
2797                 uint16_t        length;
2798                 uint16_t        checksum;
2799         } udp;
2800 #define SWRAP_PACKET_PAYLOAD_UDP_SIZE 8
2801         struct {
2802                 uint8_t         type;
2803                 uint8_t         code;
2804                 uint16_t        checksum;
2805                 uint32_t        unused;
2806         } icmp4;
2807 #define SWRAP_PACKET_PAYLOAD_ICMP4_SIZE 8
2808         struct {
2809                 uint8_t         type;
2810                 uint8_t         code;
2811                 uint16_t        checksum;
2812                 uint32_t        unused;
2813         } icmp6;
2814 #define SWRAP_PACKET_PAYLOAD_ICMP6_SIZE 8
2815 };
2816 #define SWRAP_PACKET_PAYLOAD_SIZE 20
2817
2818 #define SWRAP_PACKET_MIN_ALLOC \
2819         (SWRAP_PACKET_FRAME_SIZE + \
2820          SWRAP_PACKET_IP_SIZE + \
2821          SWRAP_PACKET_PAYLOAD_SIZE)
2822
2823 static const char *swrap_pcap_init_file(void)
2824 {
2825         static int initialized = 0;
2826         static const char *s = NULL;
2827         static const struct swrap_file_hdr h;
2828         static const struct swrap_packet_frame f;
2829         static const union swrap_packet_ip i;
2830         static const union swrap_packet_payload p;
2831
2832         if (initialized == 1) {
2833                 return s;
2834         }
2835         initialized = 1;
2836
2837         /*
2838          * TODO: don't use the structs use plain buffer offsets
2839          *       and PUSH_U8(), PUSH_U16() and PUSH_U32()
2840          *
2841          * for now make sure we disable PCAP support
2842          * if the struct has alignment!
2843          */
2844         if (sizeof(h) != SWRAP_FILE_HDR_SIZE) {
2845                 return NULL;
2846         }
2847         if (sizeof(f) != SWRAP_PACKET_FRAME_SIZE) {
2848                 return NULL;
2849         }
2850         if (sizeof(i) != SWRAP_PACKET_IP_SIZE) {
2851                 return NULL;
2852         }
2853         if (sizeof(i.v4) != SWRAP_PACKET_IP_V4_SIZE) {
2854                 return NULL;
2855         }
2856         if (sizeof(i.v6) != SWRAP_PACKET_IP_V6_SIZE) {
2857                 return NULL;
2858         }
2859         if (sizeof(p) != SWRAP_PACKET_PAYLOAD_SIZE) {
2860                 return NULL;
2861         }
2862         if (sizeof(p.tcp) != SWRAP_PACKET_PAYLOAD_TCP_SIZE) {
2863                 return NULL;
2864         }
2865         if (sizeof(p.udp) != SWRAP_PACKET_PAYLOAD_UDP_SIZE) {
2866                 return NULL;
2867         }
2868         if (sizeof(p.icmp4) != SWRAP_PACKET_PAYLOAD_ICMP4_SIZE) {
2869                 return NULL;
2870         }
2871         if (sizeof(p.icmp6) != SWRAP_PACKET_PAYLOAD_ICMP6_SIZE) {
2872                 return NULL;
2873         }
2874
2875         s = getenv("SOCKET_WRAPPER_PCAP_FILE");
2876         if (s == NULL) {
2877                 return NULL;
2878         }
2879         if (strncmp(s, "./", 2) == 0) {
2880                 s += 2;
2881         }
2882         SWRAP_LOG(SWRAP_LOG_TRACE, "SOCKET_WRAPPER_PCAP_FILE: %s", s);
2883         return s;
2884 }
2885
2886 static uint8_t *swrap_pcap_packet_init(struct timeval *tval,
2887                                        const struct sockaddr *src,
2888                                        const struct sockaddr *dest,
2889                                        int socket_type,
2890                                        const uint8_t *payload,
2891                                        size_t payload_len,
2892                                        unsigned long tcp_seqno,
2893                                        unsigned long tcp_ack,
2894                                        unsigned char tcp_ctl,
2895                                        int unreachable,
2896                                        size_t *_packet_len)
2897 {
2898         uint8_t *base = NULL;
2899         uint8_t *buf = NULL;
2900         union {
2901                 uint8_t *ptr;
2902                 struct swrap_packet_frame *frame;
2903         } f;
2904         union {
2905                 uint8_t *ptr;
2906                 union swrap_packet_ip *ip;
2907         } i;
2908         union swrap_packet_payload *pay;
2909         size_t packet_len;
2910         size_t alloc_len;
2911         size_t nonwire_len = sizeof(struct swrap_packet_frame);
2912         size_t wire_hdr_len = 0;
2913         size_t wire_len = 0;
2914         size_t ip_hdr_len = 0;
2915         size_t icmp_hdr_len = 0;
2916         size_t icmp_truncate_len = 0;
2917         uint8_t protocol = 0, icmp_protocol = 0;
2918         const struct sockaddr_in *src_in = NULL;
2919         const struct sockaddr_in *dest_in = NULL;
2920 #ifdef HAVE_IPV6
2921         const struct sockaddr_in6 *src_in6 = NULL;
2922         const struct sockaddr_in6 *dest_in6 = NULL;
2923 #endif
2924         uint16_t src_port;
2925         uint16_t dest_port;
2926
2927         switch (src->sa_family) {
2928         case AF_INET:
2929                 src_in = (const struct sockaddr_in *)(const void *)src;
2930                 dest_in = (const struct sockaddr_in *)(const void *)dest;
2931                 src_port = src_in->sin_port;
2932                 dest_port = dest_in->sin_port;
2933                 ip_hdr_len = sizeof(i.ip->v4);
2934                 break;
2935 #ifdef HAVE_IPV6
2936         case AF_INET6:
2937                 src_in6 = (const struct sockaddr_in6 *)(const void *)src;
2938                 dest_in6 = (const struct sockaddr_in6 *)(const void *)dest;
2939                 src_port = src_in6->sin6_port;
2940                 dest_port = dest_in6->sin6_port;
2941                 ip_hdr_len = sizeof(i.ip->v6);
2942                 break;
2943 #endif
2944         default:
2945                 return NULL;
2946         }
2947
2948         switch (socket_type) {
2949         case SOCK_STREAM:
2950                 protocol = 0x06; /* TCP */
2951                 wire_hdr_len = ip_hdr_len + sizeof(pay->tcp);
2952                 wire_len = wire_hdr_len + payload_len;
2953                 break;
2954
2955         case SOCK_DGRAM:
2956                 protocol = 0x11; /* UDP */
2957                 wire_hdr_len = ip_hdr_len + sizeof(pay->udp);
2958                 wire_len = wire_hdr_len + payload_len;
2959                 break;
2960
2961         default:
2962                 return NULL;
2963         }
2964
2965         if (unreachable) {
2966                 icmp_protocol = protocol;
2967                 switch (src->sa_family) {
2968                 case AF_INET:
2969                         protocol = 0x01; /* ICMPv4 */
2970                         icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp4);
2971                         break;
2972 #ifdef HAVE_IPV6
2973                 case AF_INET6:
2974                         protocol = 0x3A; /* ICMPv6 */
2975                         icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp6);
2976                         break;
2977 #endif
2978                 }
2979                 if (wire_len > 64 ) {
2980                         icmp_truncate_len = wire_len - 64;
2981                 }
2982                 wire_len += icmp_hdr_len;
2983         }
2984
2985         packet_len = nonwire_len + wire_len;
2986         alloc_len = packet_len;
2987         if (alloc_len < SWRAP_PACKET_MIN_ALLOC) {
2988                 alloc_len = SWRAP_PACKET_MIN_ALLOC;
2989         }
2990
2991         base = (uint8_t *)calloc(1, alloc_len);
2992         if (base == NULL) {
2993                 return NULL;
2994         }
2995
2996         buf = base;
2997         f.ptr = buf;
2998
2999         f.frame->seconds                = tval->tv_sec;
3000         f.frame->micro_seconds  = tval->tv_usec;
3001         f.frame->recorded_length        = wire_len - icmp_truncate_len;
3002         f.frame->full_length    = wire_len - icmp_truncate_len;
3003
3004         buf += SWRAP_PACKET_FRAME_SIZE;
3005
3006         i.ptr = buf;
3007         switch (src->sa_family) {
3008         case AF_INET:
3009                 if (src_in == NULL || dest_in == NULL) {
3010                         SAFE_FREE(base);
3011                         return NULL;
3012                 }
3013
3014                 i.ip->v4.ver_hdrlen     = 0x45; /* version 4 and 5 * 32 bit words */
3015                 i.ip->v4.tos            = 0x00;
3016                 i.ip->v4.packet_length  = htons(wire_len - icmp_truncate_len);
3017                 i.ip->v4.identification = htons(0xFFFF);
3018                 i.ip->v4.flags          = 0x40; /* BIT 1 set - means don't fragment */
3019                 i.ip->v4.fragment       = htons(0x0000);
3020                 i.ip->v4.ttl            = 0xFF;
3021                 i.ip->v4.protocol       = protocol;
3022                 i.ip->v4.hdr_checksum   = htons(0x0000);
3023                 i.ip->v4.src_addr       = src_in->sin_addr.s_addr;
3024                 i.ip->v4.dest_addr      = dest_in->sin_addr.s_addr;
3025                 buf += SWRAP_PACKET_IP_V4_SIZE;
3026                 break;
3027 #ifdef HAVE_IPV6
3028         case AF_INET6:
3029                 if (src_in6 == NULL || dest_in6 == NULL) {
3030                         SAFE_FREE(base);
3031                         return NULL;
3032                 }
3033
3034                 i.ip->v6.ver_prio               = 0x60; /* version 4 and 5 * 32 bit words */
3035                 i.ip->v6.flow_label_high        = 0x00;
3036                 i.ip->v6.flow_label_low = 0x0000;
3037                 i.ip->v6.payload_length = htons(wire_len - icmp_truncate_len); /* TODO */
3038                 i.ip->v6.next_header    = protocol;
3039                 memcpy(i.ip->v6.src_addr, src_in6->sin6_addr.s6_addr, 16);
3040                 memcpy(i.ip->v6.dest_addr, dest_in6->sin6_addr.s6_addr, 16);
3041                 buf += SWRAP_PACKET_IP_V6_SIZE;
3042                 break;
3043 #endif
3044         }
3045
3046         if (unreachable) {
3047                 pay = (union swrap_packet_payload *)(void *)buf;
3048                 switch (src->sa_family) {
3049                 case AF_INET:
3050                         pay->icmp4.type         = 0x03; /* destination unreachable */
3051                         pay->icmp4.code         = 0x01; /* host unreachable */
3052                         pay->icmp4.checksum     = htons(0x0000);
3053                         pay->icmp4.unused       = htonl(0x00000000);
3054
3055                         buf += SWRAP_PACKET_PAYLOAD_ICMP4_SIZE;
3056
3057                         /* set the ip header in the ICMP payload */
3058                         i.ptr = buf;
3059                         i.ip->v4.ver_hdrlen     = 0x45; /* version 4 and 5 * 32 bit words */
3060                         i.ip->v4.tos            = 0x00;
3061                         i.ip->v4.packet_length  = htons(wire_len - icmp_hdr_len);
3062                         i.ip->v4.identification = htons(0xFFFF);
3063                         i.ip->v4.flags          = 0x40; /* BIT 1 set - means don't fragment */
3064                         i.ip->v4.fragment       = htons(0x0000);
3065                         i.ip->v4.ttl            = 0xFF;
3066                         i.ip->v4.protocol       = icmp_protocol;
3067                         i.ip->v4.hdr_checksum   = htons(0x0000);
3068                         i.ip->v4.src_addr       = dest_in->sin_addr.s_addr;
3069                         i.ip->v4.dest_addr      = src_in->sin_addr.s_addr;
3070
3071                         buf += SWRAP_PACKET_IP_V4_SIZE;
3072
3073                         src_port = dest_in->sin_port;
3074                         dest_port = src_in->sin_port;
3075                         break;
3076 #ifdef HAVE_IPV6
3077                 case AF_INET6:
3078                         pay->icmp6.type         = 0x01; /* destination unreachable */
3079                         pay->icmp6.code         = 0x03; /* address unreachable */
3080                         pay->icmp6.checksum     = htons(0x0000);
3081                         pay->icmp6.unused       = htonl(0x00000000);
3082                         buf += SWRAP_PACKET_PAYLOAD_ICMP6_SIZE;
3083
3084                         /* set the ip header in the ICMP payload */
3085                         i.ptr = buf;
3086                         i.ip->v6.ver_prio               = 0x60; /* version 4 and 5 * 32 bit words */
3087                         i.ip->v6.flow_label_high        = 0x00;
3088                         i.ip->v6.flow_label_low = 0x0000;
3089                         i.ip->v6.payload_length = htons(wire_len - icmp_truncate_len); /* TODO */
3090                         i.ip->v6.next_header    = protocol;
3091                         memcpy(i.ip->v6.src_addr, dest_in6->sin6_addr.s6_addr, 16);
3092                         memcpy(i.ip->v6.dest_addr, src_in6->sin6_addr.s6_addr, 16);
3093
3094                         buf += SWRAP_PACKET_IP_V6_SIZE;
3095
3096                         src_port = dest_in6->sin6_port;
3097                         dest_port = src_in6->sin6_port;
3098                         break;
3099 #endif
3100                 }
3101         }
3102
3103         pay = (union swrap_packet_payload *)(void *)buf;
3104
3105         switch (socket_type) {
3106         case SOCK_STREAM:
3107                 pay->tcp.source_port    = src_port;
3108                 pay->tcp.dest_port      = dest_port;
3109                 pay->tcp.seq_num        = htonl(tcp_seqno);
3110                 pay->tcp.ack_num        = htonl(tcp_ack);
3111                 pay->tcp.hdr_length     = 0x50; /* 5 * 32 bit words */
3112                 pay->tcp.control        = tcp_ctl;
3113                 pay->tcp.window         = htons(0x7FFF);
3114                 pay->tcp.checksum       = htons(0x0000);
3115                 pay->tcp.urg            = htons(0x0000);
3116                 buf += SWRAP_PACKET_PAYLOAD_TCP_SIZE;
3117
3118                 break;
3119
3120         case SOCK_DGRAM:
3121                 pay->udp.source_port    = src_port;
3122                 pay->udp.dest_port      = dest_port;
3123                 pay->udp.length         = htons(8 + payload_len);
3124                 pay->udp.checksum       = htons(0x0000);
3125                 buf += SWRAP_PACKET_PAYLOAD_UDP_SIZE;
3126
3127                 break;
3128         }
3129
3130         if (payload && payload_len > 0) {
3131                 memcpy(buf, payload, payload_len);
3132         }
3133
3134         *_packet_len = packet_len - icmp_truncate_len;
3135         return base;
3136 }
3137
3138 static int swrap_pcap_get_fd(const char *fname)
3139 {
3140         static int fd = -1;
3141
3142         if (fd != -1) {
3143                 return fd;
3144         }
3145
3146         fd = libc_open(fname, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0644);
3147         if (fd != -1) {
3148                 struct swrap_file_hdr file_hdr;
3149                 file_hdr.magic          = 0xA1B2C3D4;
3150                 file_hdr.version_major  = 0x0002;
3151                 file_hdr.version_minor  = 0x0004;
3152                 file_hdr.timezone       = 0x00000000;
3153                 file_hdr.sigfigs        = 0x00000000;
3154                 file_hdr.frame_max_len  = SWRAP_FRAME_LENGTH_MAX;
3155                 file_hdr.link_type      = 0x0065; /* 101 RAW IP */
3156
3157                 if (libc_write(fd, &file_hdr, sizeof(file_hdr)) != sizeof(file_hdr)) {
3158                         libc_close(fd);
3159                         fd = -1;
3160                 }
3161                 return fd;
3162         }
3163
3164         fd = libc_open(fname, O_WRONLY|O_APPEND, 0644);
3165
3166         return fd;
3167 }
3168
3169 static uint8_t *swrap_pcap_marshall_packet(struct socket_info *si,
3170                                            const struct sockaddr *addr,
3171                                            enum swrap_packet_type type,
3172                                            const void *buf, size_t len,
3173                                            size_t *packet_len)
3174 {
3175         const struct sockaddr *src_addr;
3176         const struct sockaddr *dest_addr;
3177         unsigned long tcp_seqno = 0;
3178         unsigned long tcp_ack = 0;
3179         unsigned char tcp_ctl = 0;
3180         int unreachable = 0;
3181
3182         struct timeval tv;
3183
3184         switch (si->family) {
3185         case AF_INET:
3186                 break;
3187 #ifdef HAVE_IPV6
3188         case AF_INET6:
3189                 break;
3190 #endif
3191         default:
3192                 return NULL;
3193         }
3194
3195         switch (type) {
3196         case SWRAP_CONNECT_SEND:
3197                 if (si->type != SOCK_STREAM) {
3198                         return NULL;
3199                 }
3200
3201                 src_addr  = &si->myname.sa.s;
3202                 dest_addr = addr;
3203
3204                 tcp_seqno = si->io.pck_snd;
3205                 tcp_ack = si->io.pck_rcv;
3206                 tcp_ctl = 0x02; /* SYN */
3207
3208                 si->io.pck_snd += 1;
3209
3210                 break;
3211
3212         case SWRAP_CONNECT_RECV:
3213                 if (si->type != SOCK_STREAM) {
3214                         return NULL;
3215                 }
3216
3217                 dest_addr = &si->myname.sa.s;
3218                 src_addr = addr;
3219
3220                 tcp_seqno = si->io.pck_rcv;
3221                 tcp_ack = si->io.pck_snd;
3222                 tcp_ctl = 0x12; /** SYN,ACK */
3223
3224                 si->io.pck_rcv += 1;
3225
3226                 break;
3227
3228         case SWRAP_CONNECT_UNREACH:
3229                 if (si->type != SOCK_STREAM) {
3230                         return NULL;
3231                 }
3232
3233                 dest_addr = &si->myname.sa.s;
3234                 src_addr  = addr;
3235
3236                 /* Unreachable: resend the data of SWRAP_CONNECT_SEND */
3237                 tcp_seqno = si->io.pck_snd - 1;
3238                 tcp_ack = si->io.pck_rcv;
3239                 tcp_ctl = 0x02; /* SYN */
3240                 unreachable = 1;
3241
3242                 break;
3243
3244         case SWRAP_CONNECT_ACK:
3245                 if (si->type != SOCK_STREAM) {
3246                         return NULL;
3247                 }
3248
3249                 src_addr  = &si->myname.sa.s;
3250                 dest_addr = addr;
3251
3252                 tcp_seqno = si->io.pck_snd;
3253                 tcp_ack = si->io.pck_rcv;
3254                 tcp_ctl = 0x10; /* ACK */
3255
3256                 break;
3257
3258         case SWRAP_ACCEPT_SEND:
3259                 if (si->type != SOCK_STREAM) {
3260                         return NULL;
3261                 }
3262
3263                 dest_addr = &si->myname.sa.s;
3264                 src_addr = addr;
3265
3266                 tcp_seqno = si->io.pck_rcv;
3267                 tcp_ack = si->io.pck_snd;
3268                 tcp_ctl = 0x02; /* SYN */
3269
3270                 si->io.pck_rcv += 1;
3271
3272                 break;
3273
3274         case SWRAP_ACCEPT_RECV:
3275                 if (si->type != SOCK_STREAM) {
3276                         return NULL;
3277                 }
3278
3279                 src_addr = &si->myname.sa.s;
3280                 dest_addr = addr;
3281
3282                 tcp_seqno = si->io.pck_snd;
3283                 tcp_ack = si->io.pck_rcv;
3284                 tcp_ctl = 0x12; /* SYN,ACK */
3285
3286                 si->io.pck_snd += 1;
3287
3288                 break;
3289
3290         case SWRAP_ACCEPT_ACK:
3291                 if (si->type != SOCK_STREAM) {
3292                         return NULL;
3293                 }
3294
3295                 dest_addr = &si->myname.sa.s;
3296                 src_addr = addr;
3297
3298                 tcp_seqno = si->io.pck_rcv;
3299                 tcp_ack = si->io.pck_snd;
3300                 tcp_ctl = 0x10; /* ACK */
3301
3302                 break;
3303
3304         case SWRAP_SEND:
3305                 src_addr  = &si->myname.sa.s;
3306                 dest_addr = &si->peername.sa.s;
3307
3308                 tcp_seqno = si->io.pck_snd;
3309                 tcp_ack = si->io.pck_rcv;
3310                 tcp_ctl = 0x18; /* PSH,ACK */
3311
3312                 si->io.pck_snd += len;
3313
3314                 break;
3315
3316         case SWRAP_SEND_RST:
3317                 dest_addr = &si->myname.sa.s;
3318                 src_addr  = &si->peername.sa.s;
3319
3320                 if (si->type == SOCK_DGRAM) {
3321                         return swrap_pcap_marshall_packet(si,
3322                                                           &si->peername.sa.s,
3323                                                           SWRAP_SENDTO_UNREACH,
3324                                                           buf,
3325                                                           len,
3326                                                           packet_len);
3327                 }
3328
3329                 tcp_seqno = si->io.pck_rcv;
3330                 tcp_ack = si->io.pck_snd;
3331                 tcp_ctl = 0x14; /** RST,ACK */
3332
3333                 break;
3334
3335         case SWRAP_PENDING_RST:
3336                 dest_addr = &si->myname.sa.s;
3337                 src_addr  = &si->peername.sa.s;
3338
3339                 if (si->type == SOCK_DGRAM) {
3340                         return NULL;
3341                 }
3342
3343                 tcp_seqno = si->io.pck_rcv;
3344                 tcp_ack = si->io.pck_snd;
3345                 tcp_ctl = 0x14; /* RST,ACK */
3346
3347                 break;
3348
3349         case SWRAP_RECV:
3350                 dest_addr = &si->myname.sa.s;
3351                 src_addr  = &si->peername.sa.s;
3352
3353                 tcp_seqno = si->io.pck_rcv;
3354                 tcp_ack = si->io.pck_snd;
3355                 tcp_ctl = 0x18; /* PSH,ACK */
3356
3357                 si->io.pck_rcv += len;
3358
3359                 break;
3360
3361         case SWRAP_RECV_RST:
3362                 dest_addr = &si->myname.sa.s;
3363                 src_addr  = &si->peername.sa.s;
3364
3365                 if (si->type == SOCK_DGRAM) {
3366                         return NULL;
3367                 }
3368
3369                 tcp_seqno = si->io.pck_rcv;
3370                 tcp_ack = si->io.pck_snd;
3371                 tcp_ctl = 0x14; /* RST,ACK */
3372
3373                 break;
3374
3375         case SWRAP_SENDTO:
3376                 src_addr = &si->myname.sa.s;
3377                 dest_addr = addr;
3378
3379                 si->io.pck_snd += len;
3380
3381                 break;
3382
3383         case SWRAP_SENDTO_UNREACH:
3384                 dest_addr = &si->myname.sa.s;
3385                 src_addr = addr;
3386
3387                 unreachable = 1;
3388
3389                 break;
3390
3391         case SWRAP_RECVFROM:
3392                 dest_addr = &si->myname.sa.s;
3393                 src_addr = addr;
3394
3395                 si->io.pck_rcv += len;
3396
3397                 break;
3398
3399         case SWRAP_CLOSE_SEND:
3400                 if (si->type != SOCK_STREAM) {
3401                         return NULL;
3402                 }
3403
3404                 src_addr  = &si->myname.sa.s;
3405                 dest_addr = &si->peername.sa.s;
3406
3407                 tcp_seqno = si->io.pck_snd;
3408                 tcp_ack = si->io.pck_rcv;
3409                 tcp_ctl = 0x11; /* FIN, ACK */
3410
3411                 si->io.pck_snd += 1;
3412
3413                 break;
3414
3415         case SWRAP_CLOSE_RECV:
3416                 if (si->type != SOCK_STREAM) {
3417                         return NULL;
3418                 }
3419
3420                 dest_addr = &si->myname.sa.s;
3421                 src_addr  = &si->peername.sa.s;
3422
3423                 tcp_seqno = si->io.pck_rcv;
3424                 tcp_ack = si->io.pck_snd;
3425                 tcp_ctl = 0x11; /* FIN,ACK */
3426
3427                 si->io.pck_rcv += 1;
3428
3429                 break;
3430
3431         case SWRAP_CLOSE_ACK:
3432                 if (si->type != SOCK_STREAM) {
3433                         return NULL;
3434                 }
3435
3436                 src_addr  = &si->myname.sa.s;
3437                 dest_addr = &si->peername.sa.s;
3438
3439                 tcp_seqno = si->io.pck_snd;
3440                 tcp_ack = si->io.pck_rcv;
3441                 tcp_ctl = 0x10; /* ACK */
3442
3443                 break;
3444         default:
3445                 return NULL;
3446         }
3447
3448         swrapGetTimeOfDay(&tv);
3449
3450         return swrap_pcap_packet_init(&tv,
3451                                       src_addr,
3452                                       dest_addr,
3453                                       si->type,
3454                                       (const uint8_t *)buf,
3455                                       len,
3456                                       tcp_seqno,
3457                                       tcp_ack,
3458                                       tcp_ctl,
3459                                       unreachable,
3460                                       packet_len);
3461 }
3462
3463 static void swrap_pcap_dump_packet(struct socket_info *si,
3464                                    const struct sockaddr *addr,
3465                                    enum swrap_packet_type type,
3466                                    const void *buf, size_t len)
3467 {
3468         const char *file_name;
3469         uint8_t *packet;
3470         size_t packet_len = 0;
3471         int fd;
3472
3473         swrap_mutex_lock(&pcap_dump_mutex);
3474
3475         file_name = swrap_pcap_init_file();
3476         if (!file_name) {
3477                 goto done;
3478         }
3479
3480         packet = swrap_pcap_marshall_packet(si,
3481                                             addr,
3482                                             type,
3483                                             buf,
3484                                             len,
3485                                             &packet_len);
3486         if (packet == NULL) {
3487                 goto done;
3488         }
3489
3490         fd = swrap_pcap_get_fd(file_name);
3491         if (fd != -1) {
3492                 if (libc_write(fd, packet, packet_len) != (ssize_t)packet_len) {
3493                         free(packet);
3494                         goto done;
3495                 }
3496         }
3497
3498         free(packet);
3499
3500 done:
3501         swrap_mutex_unlock(&pcap_dump_mutex);
3502 }
3503
3504 /****************************************************************************
3505  *   SIGNALFD
3506  ***************************************************************************/
3507
3508 #ifdef HAVE_SIGNALFD
3509 static int swrap_signalfd(int fd, const sigset_t *mask, int flags)
3510 {
3511         int rc;
3512
3513         rc = libc_signalfd(fd, mask, flags);
3514         if (rc != -1) {
3515                 swrap_remove_stale(fd);
3516         }
3517
3518         return rc;
3519 }
3520
3521 int signalfd(int fd, const sigset_t *mask, int flags)
3522 {
3523         return swrap_signalfd(fd, mask, flags);
3524 }
3525 #endif
3526
3527 /****************************************************************************
3528  *   SOCKET
3529  ***************************************************************************/
3530
3531 static int swrap_socket(int family, int type, int protocol)
3532 {
3533         struct socket_info *si = NULL;
3534         struct socket_info _si = { 0 };
3535         int fd;
3536         int ret;
3537         int real_type = type;
3538
3539         /*
3540          * Remove possible addition flags passed to socket() so
3541          * do not fail checking the type.
3542          * See https://lwn.net/Articles/281965/
3543          */
3544 #ifdef SOCK_CLOEXEC
3545         real_type &= ~SOCK_CLOEXEC;
3546 #endif
3547 #ifdef SOCK_NONBLOCK
3548         real_type &= ~SOCK_NONBLOCK;
3549 #endif
3550
3551         if (!socket_wrapper_enabled()) {
3552                 return libc_socket(family, type, protocol);
3553         }
3554
3555         switch (family) {
3556         case AF_INET:
3557 #ifdef HAVE_IPV6
3558         case AF_INET6:
3559 #endif
3560                 break;
3561 #ifdef AF_NETLINK
3562         case AF_NETLINK:
3563 #endif /* AF_NETLINK */
3564 #ifdef AF_PACKET
3565         case AF_PACKET:
3566 #endif /* AF_PACKET */
3567         case AF_UNIX:
3568                 fd = libc_socket(family, type, protocol);
3569                 if (fd != -1) {
3570                         /* Check if we have a stale fd and remove it */
3571                         swrap_remove_stale(fd);
3572                         SWRAP_LOG(SWRAP_LOG_TRACE,
3573                                   "Unix socket fd=%d",
3574                                   fd);
3575                 }
3576                 return fd;
3577         default:
3578                 errno = EAFNOSUPPORT;
3579                 return -1;
3580         }
3581
3582         switch (real_type) {
3583         case SOCK_STREAM:
3584                 break;
3585         case SOCK_DGRAM:
3586                 break;
3587         default:
3588                 errno = EPROTONOSUPPORT;
3589                 return -1;
3590         }
3591
3592         switch (protocol) {
3593         case 0:
3594                 break;
3595         case 6:
3596                 if (real_type == SOCK_STREAM) {
3597                         break;
3598                 }
3599                 FALL_THROUGH;
3600         case 17:
3601                 if (real_type == SOCK_DGRAM) {
3602                         break;
3603                 }
3604                 FALL_THROUGH;
3605         default:
3606                 errno = EPROTONOSUPPORT;
3607                 return -1;
3608         }
3609
3610         /*
3611          * We must call libc_socket with type, from the caller, not the version
3612          * we removed SOCK_CLOEXEC and SOCK_NONBLOCK from
3613          */
3614         fd = libc_socket(AF_UNIX, type, 0);
3615
3616         if (fd == -1) {
3617                 return -1;
3618         }
3619
3620         /* Check if we have a stale fd and remove it */
3621         swrap_remove_stale(fd);
3622
3623         si = &_si;
3624         si->family = family;
3625
3626         /* however, the rest of the socket_wrapper code expects just
3627          * the type, not the flags */
3628         si->type = real_type;
3629         si->protocol = protocol;
3630
3631         /*
3632          * Setup myname so getsockname() can succeed to find out the socket
3633          * type.
3634          */
3635         switch(si->family) {
3636         case AF_INET: {
3637                 struct sockaddr_in sin = {
3638                         .sin_family = AF_INET,
3639                 };
3640
3641                 si->myname.sa_socklen = sizeof(struct sockaddr_in);
3642                 memcpy(&si->myname.sa.in, &sin, si->myname.sa_socklen);
3643                 break;
3644         }
3645 #ifdef HAVE_IPV6
3646         case AF_INET6: {
3647                 struct sockaddr_in6 sin6 = {
3648                         .sin6_family = AF_INET6,
3649                 };
3650
3651                 si->myname.sa_socklen = sizeof(struct sockaddr_in6);
3652                 memcpy(&si->myname.sa.in6, &sin6, si->myname.sa_socklen);
3653                 break;
3654         }
3655 #endif
3656         default:
3657                 errno = EINVAL;
3658                 return -1;
3659         }
3660
3661         ret = swrap_create_socket(si, fd);
3662         if (ret == -1) {
3663                 int saved_errno = errno;
3664                 libc_close(fd);
3665                 errno = saved_errno;
3666                 return -1;
3667         }
3668
3669         SWRAP_LOG(SWRAP_LOG_TRACE,
3670                   "Created %s socket for protocol %s, fd=%d",
3671                   family == AF_INET ? "IPv4" : "IPv6",
3672                   real_type == SOCK_DGRAM ? "UDP" : "TCP",
3673                   fd);
3674
3675         return fd;
3676 }
3677
3678 int socket(int family, int type, int protocol)
3679 {
3680         return swrap_socket(family, type, protocol);
3681 }
3682
3683 /****************************************************************************
3684  *   SOCKETPAIR
3685  ***************************************************************************/
3686
3687 static int swrap_socketpair(int family, int type, int protocol, int sv[2])
3688 {
3689         int rc;
3690
3691         rc = libc_socketpair(family, type, protocol, sv);
3692         if (rc != -1) {
3693                 swrap_remove_stale(sv[0]);
3694                 swrap_remove_stale(sv[1]);
3695         }
3696
3697         return rc;
3698 }
3699
3700 int socketpair(int family, int type, int protocol, int sv[2])
3701 {
3702         return swrap_socketpair(family, type, protocol, sv);
3703 }
3704
3705 /****************************************************************************
3706  *   SOCKETPAIR
3707  ***************************************************************************/
3708
3709 #ifdef HAVE_TIMERFD_CREATE
3710 static int swrap_timerfd_create(int clockid, int flags)
3711 {
3712         int fd;
3713
3714         fd = libc_timerfd_create(clockid, flags);
3715         if (fd != -1) {
3716                 swrap_remove_stale(fd);
3717         }
3718
3719         return fd;
3720 }
3721
3722 int timerfd_create(int clockid, int flags)
3723 {
3724         return swrap_timerfd_create(clockid, flags);
3725 }
3726 #endif
3727
3728 /****************************************************************************
3729  *   PIPE
3730  ***************************************************************************/
3731
3732 static int swrap_pipe(int pipefd[2])
3733 {
3734         int rc;
3735
3736         rc = libc_pipe(pipefd);
3737         if (rc != -1) {
3738                 swrap_remove_stale(pipefd[0]);
3739                 swrap_remove_stale(pipefd[1]);
3740         }
3741
3742         return rc;
3743 }
3744
3745 int pipe(int pipefd[2])
3746 {
3747         return swrap_pipe(pipefd);
3748 }
3749
3750 /****************************************************************************
3751  *   ACCEPT
3752  ***************************************************************************/
3753
3754 static int swrap_accept(int s,
3755                         struct sockaddr *addr,
3756                         socklen_t *addrlen,
3757                         int flags)
3758 {
3759         struct socket_info *parent_si, *child_si;
3760         struct socket_info new_si = { 0 };
3761         int fd;
3762         int idx;
3763         struct swrap_address un_addr = {
3764                 .sa_socklen = sizeof(struct sockaddr_un),
3765         };
3766         struct swrap_address un_my_addr = {
3767                 .sa_socklen = sizeof(struct sockaddr_un),
3768         };
3769         struct swrap_address in_addr = {
3770                 .sa_socklen = sizeof(struct sockaddr_storage),
3771         };
3772         struct swrap_address in_my_addr = {
3773                 .sa_socklen = sizeof(struct sockaddr_storage),
3774         };
3775         int ret;
3776
3777         parent_si = find_socket_info(s);
3778         if (!parent_si) {
3779 #ifdef HAVE_ACCEPT4
3780                 return libc_accept4(s, addr, addrlen, flags);
3781 #else
3782                 UNUSED(flags);
3783                 return libc_accept(s, addr, addrlen);
3784 #endif
3785         }
3786
3787
3788         /*
3789          * prevent parent_si from being altered / closed
3790          * while we read it
3791          */
3792         SWRAP_LOCK_SI(parent_si);
3793
3794         /*
3795          * assume out sockaddr have the same size as the in parent
3796          * socket family
3797          */
3798         in_addr.sa_socklen = socket_length(parent_si->family);
3799         if (in_addr.sa_socklen <= 0) {
3800                 SWRAP_UNLOCK_SI(parent_si);
3801                 errno = EINVAL;
3802                 return -1;
3803         }
3804
3805         SWRAP_UNLOCK_SI(parent_si);
3806
3807 #ifdef HAVE_ACCEPT4
3808         ret = libc_accept4(s, &un_addr.sa.s, &un_addr.sa_socklen, flags);
3809 #else
3810         UNUSED(flags);
3811         ret = libc_accept(s, &un_addr.sa.s, &un_addr.sa_socklen);
3812 #endif
3813         if (ret == -1) {
3814                 int saved_errno = errno;
3815                 if (saved_errno == ENOTSOCK) {
3816                         /* Remove stale fds */
3817                         swrap_remove_stale(s);
3818                 }
3819                 errno = saved_errno;
3820                 return ret;
3821         }
3822
3823         fd = ret;
3824
3825         /* Check if we have a stale fd and remove it */
3826         swrap_remove_stale(fd);
3827
3828         if (un_addr.sa.un.sun_path[0] == '\0') {
3829                 /*
3830                  * FreeBSD seems to have a problem where
3831                  * accept4() on the unix socket doesn't
3832                  * ECONNABORTED for already disconnected connections.
3833                  *
3834                  * Let's try libc_getpeername() to get the peer address
3835                  * as a fallback, but it'll likely return ENOTCONN,
3836                  * which we have to map to ECONNABORTED.
3837                  */
3838                 un_addr.sa_socklen = sizeof(struct sockaddr_un),
3839                 ret = libc_getpeername(fd, &un_addr.sa.s, &un_addr.sa_socklen);
3840                 if (ret == -1) {
3841                         int saved_errno = errno;
3842                         libc_close(fd);
3843                         if (saved_errno == ENOTCONN) {
3844                                 /*
3845                                  * If the connection is already disconnected
3846                                  * we should return ECONNABORTED.
3847                                  */
3848                                 saved_errno = ECONNABORTED;
3849                         }
3850                         errno = saved_errno;
3851                         return ret;
3852                 }
3853         }
3854
3855         ret = libc_getsockname(fd,
3856                                &un_my_addr.sa.s,
3857                                &un_my_addr.sa_socklen);
3858         if (ret == -1) {
3859                 int saved_errno = errno;
3860                 libc_close(fd);
3861                 if (saved_errno == ENOTCONN) {
3862                         /*
3863                          * If the connection is already disconnected
3864                          * we should return ECONNABORTED.
3865                          */
3866                         saved_errno = ECONNABORTED;
3867                 }
3868                 errno = saved_errno;
3869                 return ret;
3870         }
3871
3872         SWRAP_LOCK_SI(parent_si);
3873
3874         ret = sockaddr_convert_from_un(parent_si,
3875                                        &un_addr.sa.un,
3876                                        un_addr.sa_socklen,
3877                                        parent_si->family,
3878                                        &in_addr.sa.s,
3879                                        &in_addr.sa_socklen);
3880         if (ret == -1) {
3881                 int saved_errno = errno;
3882                 SWRAP_UNLOCK_SI(parent_si);
3883                 libc_close(fd);
3884                 errno = saved_errno;
3885                 return ret;
3886         }
3887
3888         child_si = &new_si;
3889
3890         child_si->family = parent_si->family;
3891         child_si->type = parent_si->type;
3892         child_si->protocol = parent_si->protocol;
3893         child_si->bound = 1;
3894         child_si->is_server = 1;
3895         child_si->connected = 1;
3896
3897         SWRAP_UNLOCK_SI(parent_si);
3898
3899         child_si->peername = (struct swrap_address) {
3900                 .sa_socklen = in_addr.sa_socklen,
3901         };
3902         memcpy(&child_si->peername.sa.ss, &in_addr.sa.ss, in_addr.sa_socklen);
3903
3904         if (addr != NULL && addrlen != NULL) {
3905                 size_t copy_len = MIN(*addrlen, in_addr.sa_socklen);
3906                 if (copy_len > 0) {
3907                         memcpy(addr, &in_addr.sa.ss, copy_len);
3908                 }
3909                 *addrlen = in_addr.sa_socklen;
3910         }
3911
3912         ret = sockaddr_convert_from_un(child_si,
3913                                        &un_my_addr.sa.un,
3914                                        un_my_addr.sa_socklen,
3915                                        child_si->family,
3916                                        &in_my_addr.sa.s,
3917                                        &in_my_addr.sa_socklen);
3918         if (ret == -1) {
3919                 int saved_errno = errno;
3920                 libc_close(fd);
3921                 errno = saved_errno;
3922                 return ret;
3923         }
3924
3925         SWRAP_LOG(SWRAP_LOG_TRACE,
3926                   "accept() path=%s, fd=%d",
3927                   un_my_addr.sa.un.sun_path, s);
3928
3929         child_si->myname = (struct swrap_address) {
3930                 .sa_socklen = in_my_addr.sa_socklen,
3931         };
3932         memcpy(&child_si->myname.sa.ss, &in_my_addr.sa.ss, in_my_addr.sa_socklen);
3933
3934         idx = swrap_create_socket(&new_si, fd);
3935         if (idx == -1) {
3936                 int saved_errno = errno;
3937                 libc_close(fd);
3938                 errno = saved_errno;
3939                 return -1;
3940         }
3941
3942         if (addr != NULL) {
3943                 struct socket_info *si = swrap_get_socket_info(idx);
3944
3945                 SWRAP_LOCK_SI(si);
3946                 swrap_pcap_dump_packet(si, addr, SWRAP_ACCEPT_SEND, NULL, 0);
3947                 swrap_pcap_dump_packet(si, addr, SWRAP_ACCEPT_RECV, NULL, 0);
3948                 swrap_pcap_dump_packet(si, addr, SWRAP_ACCEPT_ACK, NULL, 0);
3949                 SWRAP_UNLOCK_SI(si);
3950         }
3951
3952         return fd;
3953 }
3954
3955 #ifdef HAVE_ACCEPT4
3956 int accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags)
3957 {
3958         return swrap_accept(s, addr, (socklen_t *)addrlen, flags);
3959 }
3960 #endif
3961
3962 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3963 int accept(int s, struct sockaddr *addr, Psocklen_t addrlen)
3964 #else
3965 int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
3966 #endif
3967 {
3968         return swrap_accept(s, addr, (socklen_t *)addrlen, 0);
3969 }
3970
3971 static int autobind_start_init;
3972 static int autobind_start;
3973
3974 /* using sendto() or connect() on an unbound socket would give the
3975    recipient no way to reply, as unlike UDP and TCP, a unix domain
3976    socket can't auto-assign ephemeral port numbers, so we need to
3977    assign it here.
3978    Note: this might change the family from ipv6 to ipv4
3979 */
3980 static int swrap_auto_bind(int fd, struct socket_info *si, int family)
3981 {
3982         struct swrap_address un_addr = {
3983                 .sa_socklen = sizeof(struct sockaddr_un),
3984         };
3985         int i;
3986         char type;
3987         int ret;
3988         int port;
3989         char *swrap_dir = NULL;
3990
3991         swrap_mutex_lock(&autobind_start_mutex);
3992
3993         if (autobind_start_init != 1) {
3994                 autobind_start_init = 1;
3995                 autobind_start = getpid();
3996                 autobind_start %= 50000;
3997                 autobind_start += 10000;
3998         }
3999
4000         un_addr.sa.un.sun_family = AF_UNIX;
4001
4002         switch (family) {
4003         case AF_INET: {
4004                 struct sockaddr_in in;
4005
4006                 switch (si->type) {
4007                 case SOCK_STREAM:
4008                         type = SOCKET_TYPE_CHAR_TCP;
4009                         break;
4010                 case SOCK_DGRAM:
4011                         type = SOCKET_TYPE_CHAR_UDP;
4012                         break;
4013                 default:
4014                         errno = ESOCKTNOSUPPORT;
4015                         ret = -1;
4016                         goto done;
4017                 }
4018
4019                 memset(&in, 0, sizeof(in));
4020                 in.sin_family = AF_INET;
4021                 in.sin_addr.s_addr = htonl(swrap_ipv4_iface(
4022                                            socket_wrapper_default_iface()));
4023
4024                 si->myname = (struct swrap_address) {
4025                         .sa_socklen = sizeof(in),
4026                 };
4027                 memcpy(&si->myname.sa.in, &in, si->myname.sa_socklen);
4028                 break;
4029         }
4030 #ifdef HAVE_IPV6
4031         case AF_INET6: {
4032                 struct sockaddr_in6 in6;
4033
4034                 if (si->family != family) {
4035                         errno = ENETUNREACH;
4036                         ret = -1;
4037                         goto done;
4038                 }
4039
4040                 switch (si->type) {
4041                 case SOCK_STREAM:
4042                         type = SOCKET_TYPE_CHAR_TCP_V6;
4043                         break;
4044                 case SOCK_DGRAM:
4045                         type = SOCKET_TYPE_CHAR_UDP_V6;
4046                         break;
4047                 default:
4048                         errno = ESOCKTNOSUPPORT;
4049                         ret = -1;
4050                         goto done;
4051                 }
4052
4053                 memset(&in6, 0, sizeof(in6));
4054                 in6.sin6_family = AF_INET6;
4055                 in6.sin6_addr = *swrap_ipv6();
4056                 in6.sin6_addr.s6_addr[15] = socket_wrapper_default_iface();
4057
4058                 si->myname = (struct swrap_address) {
4059                         .sa_socklen = sizeof(in6),
4060                 };
4061                 memcpy(&si->myname.sa.in6, &in6, si->myname.sa_socklen);
4062                 break;
4063         }
4064 #endif
4065         default:
4066                 errno = ESOCKTNOSUPPORT;
4067                 ret = -1;
4068                 goto done;
4069         }
4070
4071         if (autobind_start > 60000) {
4072                 autobind_start = 10000;
4073         }
4074
4075         swrap_dir = socket_wrapper_dir();
4076         if (swrap_dir == NULL) {
4077                 errno = EINVAL;
4078                 ret = -1;
4079                 goto done;
4080         }
4081
4082         for (i = 0; i < SOCKET_MAX_SOCKETS; i++) {
4083                 port = autobind_start + i;
4084                 swrap_un_path(&un_addr.sa.un,
4085                               swrap_dir,
4086                               type,
4087                               socket_wrapper_default_iface(),
4088                               port);
4089
4090                 ret = libc_bind(fd, &un_addr.sa.s, un_addr.sa_socklen);
4091                 if (ret == -1) {
4092                         if (errno == EALREADY || errno == EADDRINUSE) {
4093                                 continue;
4094                         }
4095                         goto done;
4096                 }
4097
4098                 si->un_addr = un_addr.sa.un;
4099
4100                 si->bound = 1;
4101                 autobind_start = port + 1;
4102                 break;
4103         }
4104         if (i == SOCKET_MAX_SOCKETS) {
4105                 SWRAP_LOG(SWRAP_LOG_ERROR, "Too many open unix sockets (%u) for "
4106                                            "interface "SOCKET_FORMAT,
4107                                            SOCKET_MAX_SOCKETS,
4108                                            type,
4109                                            socket_wrapper_default_iface(),
4110                                            0);
4111                 errno = ENFILE;
4112                 ret = -1;
4113                 goto done;
4114         }
4115
4116         si->family = family;
4117         set_port(si->family, port, &si->myname);
4118
4119         ret = 0;
4120
4121 done:
4122         SAFE_FREE(swrap_dir);
4123         swrap_mutex_unlock(&autobind_start_mutex);
4124         return ret;
4125 }
4126
4127 /****************************************************************************
4128  *   CONNECT
4129  ***************************************************************************/
4130
4131 static int swrap_connect(int s, const struct sockaddr *serv_addr,
4132                          socklen_t addrlen)
4133 {
4134         int ret;
4135         struct swrap_address un_addr = {
4136                 .sa_socklen = sizeof(struct sockaddr_un),
4137         };
4138         struct socket_info *si = find_socket_info(s);
4139         struct swrap_sockaddr_buf buf = {};
4140         int bcast = 0;
4141
4142         if (!si) {
4143                 return libc_connect(s, serv_addr, addrlen);
4144         }
4145
4146         SWRAP_LOCK_SI(si);
4147
4148         if (si->bound == 0) {
4149                 ret = swrap_auto_bind(s, si, serv_addr->sa_family);
4150                 if (ret == -1) {
4151                         goto done;
4152                 }
4153         }
4154
4155         if (si->family != serv_addr->sa_family) {
4156                 SWRAP_LOG(SWRAP_LOG_ERROR,
4157                           "called for fd=%d (family=%d) called with invalid family=%d",
4158                           s, si->family, serv_addr->sa_family);
4159                 errno = EINVAL;
4160                 ret = -1;
4161                 goto done;
4162         }
4163
4164         ret = sockaddr_convert_to_un(si, serv_addr,
4165                                      addrlen, &un_addr.sa.un, 0, &bcast);
4166         if (ret == -1) {
4167                 goto done;
4168         }
4169
4170         if (bcast) {
4171                 errno = ENETUNREACH;
4172                 ret = -1;
4173                 goto done;
4174         }
4175
4176         if (si->type == SOCK_DGRAM) {
4177                 si->defer_connect = 1;
4178                 ret = 0;
4179         } else {
4180                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0);
4181
4182                 ret = libc_connect(s,
4183                                    &un_addr.sa.s,
4184                                    un_addr.sa_socklen);
4185         }
4186
4187         SWRAP_LOG(SWRAP_LOG_TRACE,
4188                   "connect(%s) path=%s, fd=%d",
4189                   swrap_sockaddr_string(&buf, serv_addr),
4190                   un_addr.sa.un.sun_path, s);
4191
4192
4193         /* to give better errors */
4194         if (ret == -1 && errno == ENOENT) {
4195                 errno = EHOSTUNREACH;
4196         }
4197
4198         if (ret == 0) {
4199                 si->peername = (struct swrap_address) {
4200                         .sa_socklen = addrlen,
4201                 };
4202
4203                 memcpy(&si->peername.sa.ss, serv_addr, addrlen);
4204                 si->connected = 1;
4205
4206                 /*
4207                  * When we connect() on a socket than we have to bind the
4208                  * outgoing connection on the interface we use for the
4209                  * transport. We already bound it on the right interface
4210                  * but here we have to update the name so getsockname()
4211                  * returns correct information.
4212                  */
4213                 if (si->bindname.sa_socklen > 0) {
4214                         si->myname = (struct swrap_address) {
4215                                 .sa_socklen = si->bindname.sa_socklen,
4216                         };
4217
4218                         memcpy(&si->myname.sa.ss,
4219                                &si->bindname.sa.ss,
4220                                si->bindname.sa_socklen);
4221
4222                         /* Cleanup bindname */
4223                         si->bindname = (struct swrap_address) {
4224                                 .sa_socklen = 0,
4225                         };
4226                 }
4227
4228                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0);
4229                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0);
4230         } else {
4231                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0);
4232         }
4233
4234 done:
4235         SWRAP_UNLOCK_SI(si);
4236         return ret;
4237 }
4238
4239 int connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen)
4240 {
4241         return swrap_connect(s, serv_addr, addrlen);
4242 }
4243
4244 /****************************************************************************
4245  *   BIND
4246  ***************************************************************************/
4247
4248 static int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
4249 {
4250         int ret;
4251         struct swrap_address un_addr = {
4252                 .sa_socklen = sizeof(struct sockaddr_un),
4253         };
4254         struct socket_info *si = find_socket_info(s);
4255         struct swrap_sockaddr_buf buf = {};
4256         int ret_errno = errno;
4257         int bind_error = 0;
4258 #if 0 /* FIXME */
4259         bool in_use;
4260 #endif
4261
4262         if (!si) {
4263                 return libc_bind(s, myaddr, addrlen);
4264         }
4265
4266         SWRAP_LOCK_SI(si);
4267
4268         switch (si->family) {
4269         case AF_INET: {
4270                 const struct sockaddr_in *sin;
4271                 if (addrlen < sizeof(struct sockaddr_in)) {
4272                         bind_error = EINVAL;
4273                         break;
4274                 }
4275
4276                 sin = (const struct sockaddr_in *)(const void *)myaddr;
4277
4278                 if (sin->sin_family != AF_INET) {
4279                         bind_error = EAFNOSUPPORT;
4280                 }
4281
4282                 /* special case for AF_UNSPEC */
4283                 if (sin->sin_family == AF_UNSPEC &&
4284                     (sin->sin_addr.s_addr == htonl(INADDR_ANY)))
4285                 {
4286                         bind_error = 0;
4287                 }
4288
4289                 break;
4290         }
4291 #ifdef HAVE_IPV6
4292         case AF_INET6: {
4293                 const struct sockaddr_in6 *sin6;
4294                 if (addrlen < sizeof(struct sockaddr_in6)) {
4295                         bind_error = EINVAL;
4296                         break;
4297                 }
4298
4299                 sin6 = (const struct sockaddr_in6 *)(const void *)myaddr;
4300
4301                 if (sin6->sin6_family != AF_INET6) {
4302                         bind_error = EAFNOSUPPORT;
4303                 }
4304
4305                 break;
4306         }
4307 #endif
4308         default:
4309                 bind_error = EINVAL;
4310                 break;
4311         }
4312
4313         if (bind_error != 0) {
4314                 ret_errno = bind_error;
4315                 ret = -1;
4316                 goto out;
4317         }
4318
4319 #if 0 /* FIXME */
4320         in_use = check_addr_port_in_use(myaddr, addrlen);
4321         if (in_use) {
4322                 errno = EADDRINUSE;
4323                 ret = -1;
4324                 goto out;
4325         }
4326 #endif
4327
4328         si->myname.sa_socklen = addrlen;
4329         memcpy(&si->myname.sa.ss, myaddr, addrlen);
4330
4331         ret = sockaddr_convert_to_un(si,
4332                                      myaddr,
4333                                      addrlen,
4334                                      &un_addr.sa.un,
4335                                      1,
4336                                      &si->bcast);
4337         if (ret == -1) {
4338                 ret_errno = errno;
4339                 goto out;
4340         }
4341
4342         unlink(un_addr.sa.un.sun_path);
4343
4344         ret = libc_bind(s, &un_addr.sa.s, un_addr.sa_socklen);
4345         if (ret == -1) {
4346                 ret_errno = errno;
4347         }
4348
4349         SWRAP_LOG(SWRAP_LOG_TRACE,
4350                   "bind(%s) path=%s, fd=%d ret=%d ret_errno=%d",
4351                   swrap_sockaddr_string(&buf, myaddr),
4352                   un_addr.sa.un.sun_path, s, ret, ret_errno);
4353
4354         if (ret == 0) {
4355                 si->bound = 1;
4356         }
4357
4358 out:
4359         SWRAP_UNLOCK_SI(si);
4360         errno = ret_errno;
4361         return ret;
4362 }
4363
4364 int bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
4365 {
4366         return swrap_bind(s, myaddr, addrlen);
4367 }
4368
4369 /****************************************************************************
4370  *   BINDRESVPORT
4371  ***************************************************************************/
4372
4373 #ifdef HAVE_BINDRESVPORT
4374 static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen);
4375
4376 static int swrap_bindresvport_sa(int sd, struct sockaddr *sa)
4377 {
4378         struct swrap_address myaddr = {
4379                 .sa_socklen = sizeof(struct sockaddr_storage),
4380         };
4381         socklen_t salen;
4382         static uint16_t port;
4383         uint16_t i;
4384         int rc = -1;
4385         int af;
4386
4387 #define SWRAP_STARTPORT 600
4388 #define SWRAP_ENDPORT (IPPORT_RESERVED - 1)
4389 #define SWRAP_NPORTS (SWRAP_ENDPORT - SWRAP_STARTPORT + 1)
4390
4391         if (port == 0) {
4392                 port = (getpid() % SWRAP_NPORTS) + SWRAP_STARTPORT;
4393         }
4394
4395         if (sa == NULL) {
4396                 salen = myaddr.sa_socklen;
4397                 sa = &myaddr.sa.s;
4398
4399                 rc = swrap_getsockname(sd, &myaddr.sa.s, &salen);
4400                 if (rc < 0) {
4401                         return -1;
4402                 }
4403
4404                 af = sa->sa_family;
4405                 memset(&myaddr.sa.ss, 0, salen);
4406         } else {
4407                 af = sa->sa_family;
4408         }
4409
4410         for (i = 0; i < SWRAP_NPORTS; i++, port++) {
4411                 switch(af) {
4412                 case AF_INET: {
4413                         struct sockaddr_in *sinp = (struct sockaddr_in *)(void *)sa;
4414
4415                         salen = sizeof(struct sockaddr_in);
4416                         sinp->sin_port = htons(port);
4417                         break;
4418                 }
4419                 case AF_INET6: {
4420                         struct sockaddr_in6 *sin6p = (struct sockaddr_in6 *)(void *)sa;
4421
4422                         salen = sizeof(struct sockaddr_in6);
4423                         sin6p->sin6_port = htons(port);
4424                         break;
4425                 }
4426                 default:
4427                         errno = EAFNOSUPPORT;
4428                         return -1;
4429                 }
4430                 sa->sa_family = af;
4431
4432                 if (port > SWRAP_ENDPORT) {
4433                         port = SWRAP_STARTPORT;
4434                 }
4435
4436                 rc = swrap_bind(sd, (struct sockaddr *)sa, salen);
4437                 if (rc == 0 || errno != EADDRINUSE) {
4438                         break;
4439                 }
4440         }
4441
4442         return rc;
4443 }
4444
4445 int bindresvport(int sockfd, struct sockaddr_in *sinp)
4446 {
4447         return swrap_bindresvport_sa(sockfd, (struct sockaddr *)sinp);
4448 }
4449 #endif
4450
4451 /****************************************************************************
4452  *   LISTEN
4453  ***************************************************************************/
4454
4455 static int swrap_listen(int s, int backlog)
4456 {
4457         int ret;
4458         struct socket_info *si = find_socket_info(s);
4459
4460         if (!si) {
4461                 return libc_listen(s, backlog);
4462         }
4463
4464         SWRAP_LOCK_SI(si);
4465
4466         if (si->bound == 0) {
4467                 ret = swrap_auto_bind(s, si, si->family);
4468                 if (ret == -1) {
4469                         errno = EADDRINUSE;
4470                         goto out;
4471                 }
4472         }
4473
4474         ret = libc_listen(s, backlog);
4475         if (ret == 0) {
4476                 si->listening = 1;
4477         }
4478
4479 out:
4480         SWRAP_UNLOCK_SI(si);
4481
4482         return ret;
4483 }
4484
4485 int listen(int s, int backlog)
4486 {
4487         return swrap_listen(s, backlog);
4488 }
4489
4490 /****************************************************************************
4491  *   FOPEN
4492  ***************************************************************************/
4493
4494 static FILE *swrap_fopen(const char *name, const char *mode)
4495 {
4496         FILE *fp;
4497
4498         fp = libc_fopen(name, mode);
4499         if (fp != NULL) {
4500                 int fd = fileno(fp);
4501
4502                 swrap_remove_stale(fd);
4503         }
4504
4505         return fp;
4506 }
4507
4508 FILE *fopen(const char *name, const char *mode)
4509 {
4510         return swrap_fopen(name, mode);
4511 }
4512
4513 /****************************************************************************
4514  *   FOPEN64
4515  ***************************************************************************/
4516
4517 #ifdef HAVE_FOPEN64
4518 static FILE *swrap_fopen64(const char *name, const char *mode)
4519 {
4520         FILE *fp;
4521
4522         fp = libc_fopen64(name, mode);
4523         if (fp != NULL) {
4524                 int fd = fileno(fp);
4525
4526                 swrap_remove_stale(fd);
4527         }
4528
4529         return fp;
4530 }
4531
4532 FILE *fopen64(const char *name, const char *mode)
4533 {
4534         return swrap_fopen64(name, mode);
4535 }
4536 #endif /* HAVE_FOPEN64 */
4537
4538 /****************************************************************************
4539  *   OPEN
4540  ***************************************************************************/
4541
4542 static int swrap_vopen(const char *pathname, int flags, va_list ap)
4543 {
4544         int ret;
4545
4546         ret = libc_vopen(pathname, flags, ap);
4547         if (ret != -1) {
4548                 /*
4549                  * There are methods for closing descriptors (libc-internal code
4550                  * paths, direct syscalls) which close descriptors in ways that
4551                  * we can't intercept, so try to recover when we notice that
4552                  * that's happened
4553                  */
4554                 swrap_remove_stale(ret);
4555         }
4556         return ret;
4557 }
4558
4559 int open(const char *pathname, int flags, ...)
4560 {
4561         va_list ap;
4562         int fd;
4563
4564         va_start(ap, flags);
4565         fd = swrap_vopen(pathname, flags, ap);
4566         va_end(ap);
4567
4568         return fd;
4569 }
4570
4571 /****************************************************************************
4572  *   OPEN64
4573  ***************************************************************************/
4574
4575 #ifdef HAVE_OPEN64
4576 static int swrap_vopen64(const char *pathname, int flags, va_list ap)
4577 {
4578         int ret;
4579
4580         ret = libc_vopen64(pathname, flags, ap);
4581         if (ret != -1) {
4582                 /*
4583                  * There are methods for closing descriptors (libc-internal code
4584                  * paths, direct syscalls) which close descriptors in ways that
4585                  * we can't intercept, so try to recover when we notice that
4586                  * that's happened
4587                  */
4588                 swrap_remove_stale(ret);
4589         }
4590         return ret;
4591 }
4592
4593 int open64(const char *pathname, int flags, ...)
4594 {
4595         va_list ap;
4596         int fd;
4597
4598         va_start(ap, flags);
4599         fd = swrap_vopen64(pathname, flags, ap);
4600         va_end(ap);
4601
4602         return fd;
4603 }
4604 #endif /* HAVE_OPEN64 */
4605
4606 /****************************************************************************
4607  *   OPENAT
4608  ***************************************************************************/
4609
4610 static int swrap_vopenat(int dirfd, const char *path, int flags, va_list ap)
4611 {
4612         int ret;
4613
4614         ret = libc_vopenat(dirfd, path, flags, ap);
4615         if (ret != -1) {
4616                 /*
4617                  * There are methods for closing descriptors (libc-internal code
4618                  * paths, direct syscalls) which close descriptors in ways that
4619                  * we can't intercept, so try to recover when we notice that
4620                  * that's happened
4621                  */
4622                 swrap_remove_stale(ret);
4623         }
4624
4625         return ret;
4626 }
4627
4628 int openat(int dirfd, const char *path, int flags, ...)
4629 {
4630         va_list ap;
4631         int fd;
4632
4633         va_start(ap, flags);
4634         fd = swrap_vopenat(dirfd, path, flags, ap);
4635         va_end(ap);
4636
4637         return fd;
4638 }
4639
4640 /****************************************************************************
4641  *   GETPEERNAME
4642  ***************************************************************************/
4643
4644 static int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
4645 {
4646         struct socket_info *si = find_socket_info(s);
4647         socklen_t len;
4648         int ret = -1;
4649
4650         if (!si) {
4651                 return libc_getpeername(s, name, addrlen);
4652         }
4653
4654         SWRAP_LOCK_SI(si);
4655
4656         if (si->peername.sa_socklen == 0)
4657         {
4658                 errno = ENOTCONN;
4659                 goto out;
4660         }
4661
4662         len = MIN(*addrlen, si->peername.sa_socklen);
4663         if (len == 0) {
4664                 ret = 0;
4665                 goto out;
4666         }
4667
4668         memcpy(name, &si->peername.sa.ss, len);
4669         *addrlen = si->peername.sa_socklen;
4670
4671         ret = 0;
4672 out:
4673         SWRAP_UNLOCK_SI(si);
4674
4675         return ret;
4676 }
4677
4678 #ifdef HAVE_ACCEPT_PSOCKLEN_T
4679 int getpeername(int s, struct sockaddr *name, Psocklen_t addrlen)
4680 #else
4681 int getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
4682 #endif
4683 {
4684         return swrap_getpeername(s, name, (socklen_t *)addrlen);
4685 }
4686
4687 /****************************************************************************
4688  *   GETSOCKNAME
4689  ***************************************************************************/
4690
4691 static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
4692 {
4693         struct socket_info *si = find_socket_info(s);
4694         socklen_t len;
4695         int ret = -1;
4696
4697         if (!si) {
4698                 return libc_getsockname(s, name, addrlen);
4699         }
4700
4701         SWRAP_LOCK_SI(si);
4702
4703         len = MIN(*addrlen, si->myname.sa_socklen);
4704         if (len == 0) {
4705                 ret = 0;
4706                 goto out;
4707         }
4708
4709         memcpy(name, &si->myname.sa.ss, len);
4710         *addrlen = si->myname.sa_socklen;
4711
4712         ret = 0;
4713 out:
4714         SWRAP_UNLOCK_SI(si);
4715
4716         return ret;
4717 }
4718
4719 #ifdef HAVE_ACCEPT_PSOCKLEN_T
4720 int getsockname(int s, struct sockaddr *name, Psocklen_t addrlen)
4721 #else
4722 int getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
4723 #endif
4724 {
4725         return swrap_getsockname(s, name, (socklen_t *)addrlen);
4726 }
4727
4728 /****************************************************************************
4729  *   GETSOCKOPT
4730  ***************************************************************************/
4731
4732 #ifndef SO_PROTOCOL
4733 # ifdef SO_PROTOTYPE /* The Solaris name */
4734 #  define SO_PROTOCOL SO_PROTOTYPE
4735 # endif /* SO_PROTOTYPE */
4736 #endif /* SO_PROTOCOL */
4737
4738 static int swrap_getsockopt(int s, int level, int optname,
4739                             void *optval, socklen_t *optlen)
4740 {
4741         struct socket_info *si = find_socket_info(s);
4742         int ret;
4743
4744         if (!si) {
4745                 return libc_getsockopt(s,
4746                                        level,
4747                                        optname,
4748                                        optval,
4749                                        optlen);
4750         }
4751
4752         SWRAP_LOCK_SI(si);
4753
4754         if (level == SOL_SOCKET) {
4755                 switch (optname) {
4756 #ifdef SO_DOMAIN
4757                 case SO_DOMAIN:
4758                         if (optval == NULL || optlen == NULL ||
4759                             *optlen < (socklen_t)sizeof(int)) {
4760                                 errno = EINVAL;
4761                                 ret = -1;
4762                                 goto done;
4763                         }
4764
4765                         *optlen = sizeof(int);
4766                         *(int *)optval = si->family;
4767                         ret = 0;
4768                         goto done;
4769 #endif /* SO_DOMAIN */
4770
4771 #ifdef SO_PROTOCOL
4772                 case SO_PROTOCOL:
4773                         if (optval == NULL || optlen == NULL ||
4774                             *optlen < (socklen_t)sizeof(int)) {
4775                                 errno = EINVAL;
4776                                 ret = -1;
4777                                 goto done;
4778                         }
4779
4780                         *optlen = sizeof(int);
4781                         *(int *)optval = si->protocol;
4782                         ret = 0;
4783                         goto done;
4784 #endif /* SO_PROTOCOL */
4785                 case SO_TYPE:
4786                         if (optval == NULL || optlen == NULL ||
4787                             *optlen < (socklen_t)sizeof(int)) {
4788                                 errno = EINVAL;
4789                                 ret = -1;
4790                                 goto done;
4791                         }
4792
4793                         *optlen = sizeof(int);
4794                         *(int *)optval = si->type;
4795                         ret = 0;
4796                         goto done;
4797                 default:
4798                         ret = libc_getsockopt(s,
4799                                               level,
4800                                               optname,
4801                                               optval,
4802                                               optlen);
4803                         goto done;
4804                 }
4805         } else if (level == IPPROTO_TCP) {
4806                 switch (optname) {
4807 #ifdef TCP_NODELAY
4808                 case TCP_NODELAY:
4809                         /*
4810                          * This enables sending packets directly out over TCP.
4811                          * As a unix socket is doing that any way, report it as
4812                          * enabled.
4813                          */
4814                         if (optval == NULL || optlen == NULL ||
4815                             *optlen < (socklen_t)sizeof(int)) {
4816                                 errno = EINVAL;
4817                                 ret = -1;
4818                                 goto done;
4819                         }
4820
4821                         *optlen = sizeof(int);
4822                         *(int *)optval = si->tcp_nodelay;
4823
4824                         ret = 0;
4825                         goto done;
4826 #endif /* TCP_NODELAY */
4827 #ifdef TCP_INFO
4828                 case TCP_INFO: {
4829                         struct tcp_info info;
4830                         socklen_t ilen = sizeof(info);
4831
4832 #ifdef HAVE_NETINET_TCP_FSM_H
4833 /* This is FreeBSD */
4834 # define __TCP_LISTEN TCPS_LISTEN
4835 # define __TCP_ESTABLISHED TCPS_ESTABLISHED
4836 # define __TCP_CLOSE TCPS_CLOSED
4837 #else
4838 /* This is Linux */
4839 # define __TCP_LISTEN TCP_LISTEN
4840 # define __TCP_ESTABLISHED TCP_ESTABLISHED
4841 # define __TCP_CLOSE TCP_CLOSE
4842 #endif
4843
4844                         ZERO_STRUCT(info);
4845                         if (si->listening) {
4846                                 info.tcpi_state = __TCP_LISTEN;
4847                         } else if (si->connected) {
4848                                 /*
4849                                  * For now we just fake a few values
4850                                  * supported both by FreeBSD and Linux
4851                                  */
4852                                 info.tcpi_state = __TCP_ESTABLISHED;
4853                                 info.tcpi_rto = 200000;  /* 200 msec */
4854                                 info.tcpi_rtt = 5000;    /* 5 msec */
4855                                 info.tcpi_rttvar = 5000; /* 5 msec */
4856                         } else {
4857                                 info.tcpi_state = __TCP_CLOSE;
4858                                 info.tcpi_rto = 1000000;  /* 1 sec */
4859                                 info.tcpi_rtt = 0;
4860                                 info.tcpi_rttvar = 250000; /* 250 msec */
4861                         }
4862
4863                         if (optval == NULL || optlen == NULL ||
4864                             *optlen < (socklen_t)ilen) {
4865                                 errno = EINVAL;
4866                                 ret = -1;
4867                                 goto done;
4868                         }
4869
4870                         *optlen = ilen;
4871                         memcpy(optval, &info, ilen);
4872
4873                         ret = 0;
4874                         goto done;
4875                 }
4876 #endif /* TCP_INFO */
4877                 default:
4878                         break;
4879                 }
4880         }
4881
4882         errno = ENOPROTOOPT;
4883         ret = -1;
4884
4885 done:
4886         SWRAP_UNLOCK_SI(si);
4887         return ret;
4888 }
4889
4890 #ifdef HAVE_ACCEPT_PSOCKLEN_T
4891 int getsockopt(int s, int level, int optname, void *optval, Psocklen_t optlen)
4892 #else
4893 int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
4894 #endif
4895 {
4896         return swrap_getsockopt(s, level, optname, optval, (socklen_t *)optlen);
4897 }
4898
4899 /****************************************************************************
4900  *   SETSOCKOPT
4901  ***************************************************************************/
4902
4903 static int swrap_setsockopt(int s, int level, int optname,
4904                             const void *optval, socklen_t optlen)
4905 {
4906         struct socket_info *si = find_socket_info(s);
4907         int ret;
4908
4909         if (!si) {
4910                 return libc_setsockopt(s,
4911                                        level,
4912                                        optname,
4913                                        optval,
4914                                        optlen);
4915         }
4916
4917         if (level == SOL_SOCKET) {
4918                 return libc_setsockopt(s,
4919                                        level,
4920                                        optname,
4921                                        optval,
4922                                        optlen);
4923         }
4924
4925         SWRAP_LOCK_SI(si);
4926
4927         if (level == IPPROTO_TCP) {
4928                 switch (optname) {
4929 #ifdef TCP_NODELAY
4930                 case TCP_NODELAY: {
4931                         int i;
4932
4933                         /*
4934                          * This enables sending packets directly out over TCP.
4935                          * A unix socket is doing that any way.
4936                          */
4937                         if (optval == NULL || optlen == 0 ||
4938                             optlen < (socklen_t)sizeof(int)) {
4939                                 errno = EINVAL;
4940                                 ret = -1;
4941                                 goto done;
4942                         }
4943
4944                         i = *discard_const_p(int, optval);
4945                         if (i != 0 && i != 1) {
4946                                 errno = EINVAL;
4947                                 ret = -1;
4948                                 goto done;
4949                         }
4950                         si->tcp_nodelay = i;
4951
4952                         ret = 0;
4953                         goto done;
4954                 }
4955 #endif /* TCP_NODELAY */
4956                 default:
4957                         break;
4958                 }
4959         }
4960
4961         switch (si->family) {
4962         case AF_INET:
4963                 if (level == IPPROTO_IP) {
4964 #ifdef IP_PKTINFO
4965                         if (optname == IP_PKTINFO) {
4966                                 si->pktinfo = AF_INET;
4967                         }
4968 #endif /* IP_PKTINFO */
4969                 }
4970                 ret = 0;
4971                 goto done;
4972 #ifdef HAVE_IPV6
4973         case AF_INET6:
4974                 if (level == IPPROTO_IPV6) {
4975 #ifdef IPV6_RECVPKTINFO
4976                         if (optname == IPV6_RECVPKTINFO) {
4977                                 si->pktinfo = AF_INET6;
4978                         }
4979 #endif /* IPV6_PKTINFO */
4980                 }
4981                 ret = 0;
4982                 goto done;
4983 #endif
4984         default:
4985                 errno = ENOPROTOOPT;
4986                 ret = -1;
4987                 goto done;
4988         }
4989
4990 done:
4991         SWRAP_UNLOCK_SI(si);
4992         return ret;
4993 }
4994
4995 int setsockopt(int s, int level, int optname,
4996                const void *optval, socklen_t optlen)
4997 {
4998         return swrap_setsockopt(s, level, optname, optval, optlen);
4999 }
5000
5001 /****************************************************************************
5002  *   IOCTL
5003  ***************************************************************************/
5004
5005 static int swrap_vioctl(int s, unsigned long int r, va_list va)
5006 {
5007         struct socket_info *si = find_socket_info(s);
5008         va_list ap;
5009         int *value_ptr = NULL;
5010         int rc;
5011
5012         if (!si) {
5013                 return libc_vioctl(s, r, va);
5014         }
5015
5016         SWRAP_LOCK_SI(si);
5017
5018         va_copy(ap, va);
5019
5020         rc = libc_vioctl(s, r, va);
5021
5022         switch (r) {
5023         case FIONREAD:
5024                 if (rc == 0) {
5025                         value_ptr = ((int *)va_arg(ap, int *));
5026                 }
5027
5028                 if (rc == -1 && errno != EAGAIN && errno != ENOBUFS) {
5029                         swrap_pcap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
5030                 } else if (value_ptr != NULL && *value_ptr == 0) { /* END OF FILE */
5031                         swrap_pcap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
5032                 }
5033                 break;
5034 #ifdef FIONWRITE
5035         case FIONWRITE:
5036                 /* this is FreeBSD */
5037                 FALL_THROUGH; /* to TIOCOUTQ */
5038 #endif /* FIONWRITE */
5039         case TIOCOUTQ: /* same as SIOCOUTQ on Linux */
5040                 /*
5041                  * This may return more bytes then the application
5042                  * sent into the socket, for tcp it should
5043                  * return the number of unacked bytes.
5044                  *
5045                  * On AF_UNIX, all bytes are immediately acked!
5046                  */
5047                 if (rc == 0) {
5048                         value_ptr = ((int *)va_arg(ap, int *));
5049                         *value_ptr = 0;
5050                 }
5051                 break;
5052         }
5053
5054         va_end(ap);
5055
5056         SWRAP_UNLOCK_SI(si);
5057         return rc;
5058 }
5059
5060 #ifdef HAVE_IOCTL_INT
5061 int ioctl(int s, int r, ...)
5062 #else
5063 int ioctl(int s, unsigned long int r, ...)
5064 #endif
5065 {
5066         va_list va;
5067         int rc;
5068
5069         va_start(va, r);
5070
5071         rc = swrap_vioctl(s, (unsigned long int) r, va);
5072
5073         va_end(va);
5074
5075         return rc;
5076 }
5077
5078 /*****************
5079  * CMSG
5080  *****************/
5081
5082 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5083
5084 #ifndef CMSG_ALIGN
5085 # ifdef _ALIGN /* BSD */
5086 #define CMSG_ALIGN _ALIGN
5087 # else
5088 #define CMSG_ALIGN(len) (((len) + sizeof(size_t) - 1) & ~(sizeof(size_t) - 1))
5089 # endif /* _ALIGN */
5090 #endif /* CMSG_ALIGN */
5091
5092 /**
5093  * @brief Add a cmsghdr to a msghdr.
5094  *
5095  * This is an function to add any type of cmsghdr. It will operate on the
5096  * msg->msg_control and msg->msg_controllen you pass in by adapting them to
5097  * the buffer position after the added cmsg element. Hence, this function is
5098  * intended to be used with an intermediate msghdr and not on the original
5099  * one handed in by the client.
5100  *
5101  * @param[in]  msg      The msghdr to which to add the cmsg.
5102  *
5103  * @param[in]  level    The cmsg level to set.
5104  *
5105  * @param[in]  type     The cmsg type to set.
5106  *
5107  * @param[in]  data     The cmsg data to set.
5108  *
5109  * @param[in]  len      the length of the data to set.
5110  */
5111 static void swrap_msghdr_add_cmsghdr(struct msghdr *msg,
5112                                      int level,
5113                                      int type,
5114                                      const void *data,
5115                                      size_t len)
5116 {
5117         size_t cmlen = CMSG_LEN(len);
5118         size_t cmspace = CMSG_SPACE(len);
5119         uint8_t cmbuf[cmspace];
5120         void *cast_ptr = (void *)cmbuf;
5121         struct cmsghdr *cm = (struct cmsghdr *)cast_ptr;
5122         uint8_t *p;
5123
5124         memset(cmbuf, 0, cmspace);
5125
5126         if (msg->msg_controllen < cmlen) {
5127                 cmlen = msg->msg_controllen;
5128                 msg->msg_flags |= MSG_CTRUNC;
5129         }
5130
5131         if (msg->msg_controllen < cmspace) {
5132                 cmspace = msg->msg_controllen;
5133         }
5134
5135         /*
5136          * We copy the full input data into an intermediate cmsghdr first
5137          * in order to more easily cope with truncation.
5138          */
5139         cm->cmsg_len = cmlen;
5140         cm->cmsg_level = level;
5141         cm->cmsg_type = type;
5142         memcpy(CMSG_DATA(cm), data, len);
5143
5144         /*
5145          * We now copy the possibly truncated buffer.
5146          * We copy cmlen bytes, but consume cmspace bytes,
5147          * leaving the possible padding uninitialiazed.
5148          */
5149         p = (uint8_t *)msg->msg_control;
5150         memcpy(p, cm, cmlen);
5151         p += cmspace;
5152         msg->msg_control = p;
5153         msg->msg_controllen -= cmspace;
5154
5155         return;
5156 }
5157
5158 static int swrap_msghdr_add_pktinfo(struct socket_info *si,
5159                                     struct msghdr *msg)
5160 {
5161         /* Add packet info */
5162         switch (si->pktinfo) {
5163 #if defined(IP_PKTINFO) && (defined(HAVE_STRUCT_IN_PKTINFO) || defined(IP_RECVDSTADDR))
5164         case AF_INET: {
5165                 struct sockaddr_in *sin;
5166 #if defined(HAVE_STRUCT_IN_PKTINFO)
5167                 struct in_pktinfo pkt;
5168 #elif defined(IP_RECVDSTADDR)
5169                 struct in_addr pkt;
5170 #endif
5171
5172                 if (si->bindname.sa_socklen == sizeof(struct sockaddr_in)) {
5173                         sin = &si->bindname.sa.in;
5174                 } else {
5175                         if (si->myname.sa_socklen != sizeof(struct sockaddr_in)) {
5176                                 return 0;
5177                         }
5178                         sin = &si->myname.sa.in;
5179                 }
5180
5181                 ZERO_STRUCT(pkt);
5182
5183 #if defined(HAVE_STRUCT_IN_PKTINFO)
5184                 pkt.ipi_ifindex = socket_wrapper_default_iface();
5185                 pkt.ipi_addr.s_addr = sin->sin_addr.s_addr;
5186 #elif defined(IP_RECVDSTADDR)
5187                 pkt = sin->sin_addr;
5188 #endif
5189
5190                 swrap_msghdr_add_cmsghdr(msg, IPPROTO_IP, IP_PKTINFO,
5191                                          &pkt, sizeof(pkt));
5192
5193                 break;
5194         }
5195 #endif /* IP_PKTINFO */
5196 #if defined(HAVE_IPV6)
5197         case AF_INET6: {
5198 #if defined(IPV6_PKTINFO) && defined(HAVE_STRUCT_IN6_PKTINFO)
5199                 struct sockaddr_in6 *sin6;
5200                 struct in6_pktinfo pkt6;
5201
5202                 if (si->bindname.sa_socklen == sizeof(struct sockaddr_in6)) {
5203                         sin6 = &si->bindname.sa.in6;
5204                 } else {
5205                         if (si->myname.sa_socklen != sizeof(struct sockaddr_in6)) {
5206                                 return 0;
5207                         }
5208                         sin6 = &si->myname.sa.in6;
5209                 }
5210
5211                 ZERO_STRUCT(pkt6);
5212
5213                 pkt6.ipi6_ifindex = socket_wrapper_default_iface();
5214                 pkt6.ipi6_addr = sin6->sin6_addr;
5215
5216                 swrap_msghdr_add_cmsghdr(msg, IPPROTO_IPV6, IPV6_PKTINFO,
5217                                         &pkt6, sizeof(pkt6));
5218 #endif /* HAVE_STRUCT_IN6_PKTINFO */
5219
5220                 break;
5221         }
5222 #endif /* IPV6_PKTINFO */
5223         default:
5224                 return -1;
5225         }
5226
5227         return 0;
5228 }
5229
5230 static int swrap_msghdr_add_socket_info(struct socket_info *si,
5231                                         struct msghdr *omsg)
5232 {
5233         int rc = 0;
5234
5235         if (si->pktinfo > 0) {
5236                 rc = swrap_msghdr_add_pktinfo(si, omsg);
5237         }
5238
5239         return rc;
5240 }
5241
5242 static int swrap_sendmsg_copy_cmsg(const struct cmsghdr *cmsg,
5243                                    uint8_t **cm_data,
5244                                    size_t *cm_data_space);
5245 static int swrap_sendmsg_filter_cmsg_ipproto_ip(const struct cmsghdr *cmsg,
5246                                                 uint8_t **cm_data,
5247                                                 size_t *cm_data_space);
5248 static int swrap_sendmsg_filter_cmsg_sol_socket(const struct cmsghdr *cmsg,
5249                                                 uint8_t **cm_data,
5250                                                 size_t *cm_data_space);
5251
5252 static int swrap_sendmsg_filter_cmsghdr(const struct msghdr *_msg,
5253                                         uint8_t **cm_data,
5254                                         size_t *cm_data_space)
5255 {
5256         struct msghdr *msg = discard_const_p(struct msghdr, _msg);
5257         struct cmsghdr *cmsg;
5258         int rc = -1;
5259
5260         /* Nothing to do */
5261         if (msg->msg_controllen == 0 || msg->msg_control == NULL) {
5262                 return 0;
5263         }
5264
5265         for (cmsg = CMSG_FIRSTHDR(msg);
5266              cmsg != NULL;
5267              cmsg = CMSG_NXTHDR(msg, cmsg)) {
5268                 switch (cmsg->cmsg_level) {
5269                 case IPPROTO_IP:
5270                         rc = swrap_sendmsg_filter_cmsg_ipproto_ip(cmsg,
5271                                                                   cm_data,
5272                                                                   cm_data_space);
5273                         break;
5274                 case SOL_SOCKET:
5275                         rc = swrap_sendmsg_filter_cmsg_sol_socket(cmsg,
5276                                                                   cm_data,
5277                                                                   cm_data_space);
5278                         break;
5279                 default:
5280                         rc = swrap_sendmsg_copy_cmsg(cmsg,
5281                                                      cm_data,
5282                                                      cm_data_space);
5283                         break;
5284                 }
5285                 if (rc < 0) {
5286                         int saved_errno = errno;
5287                         SAFE_FREE(*cm_data);
5288                         *cm_data_space = 0;
5289                         errno = saved_errno;
5290                         return rc;
5291                 }
5292         }
5293
5294         return rc;
5295 }
5296
5297 static int swrap_sendmsg_copy_cmsg(const struct cmsghdr *cmsg,
5298                                    uint8_t **cm_data,
5299                                    size_t *cm_data_space)
5300 {
5301         size_t cmspace;
5302         uint8_t *p;
5303
5304         cmspace = *cm_data_space + CMSG_ALIGN(cmsg->cmsg_len);
5305
5306         p = realloc((*cm_data), cmspace);
5307         if (p == NULL) {
5308                 return -1;
5309         }
5310         (*cm_data) = p;
5311
5312         p = (*cm_data) + (*cm_data_space);
5313         *cm_data_space = cmspace;
5314
5315         memcpy(p, cmsg, cmsg->cmsg_len);
5316
5317         return 0;
5318 }
5319
5320 static int swrap_sendmsg_filter_cmsg_pktinfo(const struct cmsghdr *cmsg,
5321                                             uint8_t **cm_data,
5322                                             size_t *cm_data_space);
5323
5324
5325 static int swrap_sendmsg_filter_cmsg_ipproto_ip(const struct cmsghdr *cmsg,
5326                                                 uint8_t **cm_data,
5327                                                 size_t *cm_data_space)
5328 {
5329         int rc = -1;
5330
5331         switch(cmsg->cmsg_type) {
5332 #ifdef IP_PKTINFO
5333         case IP_PKTINFO:
5334                 rc = swrap_sendmsg_filter_cmsg_pktinfo(cmsg,
5335                                                        cm_data,
5336                                                        cm_data_space);
5337                 break;
5338 #endif
5339 #ifdef IPV6_PKTINFO
5340         case IPV6_PKTINFO:
5341                 rc = swrap_sendmsg_filter_cmsg_pktinfo(cmsg,
5342                                                        cm_data,
5343                                                        cm_data_space);
5344                 break;
5345 #endif
5346         default:
5347                 break;
5348         }
5349
5350         return rc;
5351 }
5352
5353 static int swrap_sendmsg_filter_cmsg_pktinfo(const struct cmsghdr *cmsg,
5354                                              uint8_t **cm_data,
5355                                              size_t *cm_data_space)
5356 {
5357         (void)cmsg; /* unused */
5358         (void)cm_data; /* unused */
5359         (void)cm_data_space; /* unused */
5360
5361         /*
5362          * Passing a IP pktinfo to a unix socket might be rejected by the
5363          * Kernel, at least on FreeBSD. So skip this cmsg.
5364          */
5365         return 0;
5366 }
5367
5368 static int swrap_sendmsg_filter_cmsg_sol_socket(const struct cmsghdr *cmsg,
5369                                                 uint8_t **cm_data,
5370                                                 size_t *cm_data_space)
5371 {
5372         int rc = -1;
5373
5374         switch (cmsg->cmsg_type) {
5375         case SCM_RIGHTS:
5376                 SWRAP_LOG(SWRAP_LOG_TRACE,
5377                           "Ignoring SCM_RIGHTS on inet socket!");
5378                 rc = 0;
5379                 break;
5380 #ifdef SCM_CREDENTIALS
5381         case SCM_CREDENTIALS:
5382                 SWRAP_LOG(SWRAP_LOG_TRACE,
5383                           "Ignoring SCM_CREDENTIALS on inet socket!");
5384                 rc = 0;
5385                 break;
5386 #endif /* SCM_CREDENTIALS */
5387         default:
5388                 rc = swrap_sendmsg_copy_cmsg(cmsg,
5389                                              cm_data,
5390                                              cm_data_space);
5391                 break;
5392         }
5393
5394         return rc;
5395 }
5396
5397 static const uint64_t swrap_unix_scm_right_magic = 0x8e0e13f27c42fc36;
5398
5399 /*
5400  * We only allow up to 6 fds at a time
5401  * as that's more than enough for Samba
5402  * and it means we can keep the logic simple
5403  * and work with fixed size arrays.
5404  *
5405  * We also keep sizeof(struct swrap_unix_scm_rights)
5406  * under PIPE_BUF (4096) in order to allow a non-blocking
5407  * write into the pipe.
5408  */
5409 #ifndef PIPE_BUF
5410 #define PIPE_BUF 4096
5411 #endif
5412 #define SWRAP_MAX_PASSED_FDS ((size_t)6)
5413 #define SWRAP_MAX_PASSED_SOCKET_INFO SWRAP_MAX_PASSED_FDS
5414 struct swrap_unix_scm_rights_payload {
5415         uint8_t num_idxs;
5416         int8_t idxs[SWRAP_MAX_PASSED_FDS];
5417         struct socket_info infos[SWRAP_MAX_PASSED_SOCKET_INFO];
5418 };
5419 struct swrap_unix_scm_rights {
5420         uint64_t magic;
5421         char package_name[sizeof(SOCKET_WRAPPER_PACKAGE)];
5422         char package_version[sizeof(SOCKET_WRAPPER_VERSION)];
5423         uint32_t full_size;
5424         uint32_t payload_size;
5425         struct swrap_unix_scm_rights_payload payload;
5426 };
5427
5428 static void swrap_dec_fd_passed_array(size_t num, struct socket_info **array)
5429 {
5430         int saved_errno = errno;
5431         size_t i;
5432
5433         for (i = 0; i < num; i++) {
5434                 struct socket_info *si = array[i];
5435                 if (si == NULL) {
5436                         continue;
5437                 }
5438
5439                 SWRAP_LOCK_SI(si);
5440                 swrap_dec_refcount(si);
5441                 if (si->fd_passed > 0) {
5442                         si->fd_passed -= 1;
5443                 }
5444                 SWRAP_UNLOCK_SI(si);
5445                 array[i] = NULL;
5446         }
5447
5448         errno = saved_errno;
5449 }
5450
5451 static void swrap_undo_si_idx_array(size_t num, int *array)
5452 {
5453         int saved_errno = errno;
5454         size_t i;
5455
5456         swrap_mutex_lock(&first_free_mutex);
5457
5458         for (i = 0; i < num; i++) {
5459                 struct socket_info *si = NULL;
5460
5461                 if (array[i] == -1) {
5462                         continue;
5463                 }
5464
5465                 si = swrap_get_socket_info(array[i]);
5466                 if (si == NULL) {
5467                         continue;
5468                 }
5469
5470                 SWRAP_LOCK_SI(si);
5471                 swrap_dec_refcount(si);
5472                 SWRAP_UNLOCK_SI(si);
5473
5474                 swrap_set_next_free(si, first_free);
5475                 first_free = array[i];
5476                 array[i] = -1;
5477         }
5478
5479         swrap_mutex_unlock(&first_free_mutex);
5480         errno = saved_errno;
5481 }
5482
5483 static void swrap_close_fd_array(size_t num, const int *array)
5484 {
5485         int saved_errno = errno;
5486         size_t i;
5487
5488         for (i = 0; i < num; i++) {
5489                 if (array[i] == -1) {
5490                         continue;
5491                 }
5492                 libc_close(array[i]);
5493         }
5494
5495         errno = saved_errno;
5496 }
5497
5498 union __swrap_fds {
5499         const uint8_t *p;
5500         int *fds;
5501 };
5502
5503 union __swrap_cmsghdr {
5504         const uint8_t *p;
5505         struct cmsghdr *cmsg;
5506 };
5507
5508 static int swrap_sendmsg_unix_scm_rights(struct cmsghdr *cmsg,
5509                                          uint8_t **cm_data,
5510                                          size_t *cm_data_space,
5511                                          int *scm_rights_pipe_fd)
5512 {
5513         struct swrap_unix_scm_rights info;
5514         struct swrap_unix_scm_rights_payload *payload = NULL;
5515         int si_idx_array[SWRAP_MAX_PASSED_FDS];
5516         struct socket_info *si_array[SWRAP_MAX_PASSED_FDS] = { NULL, };
5517         size_t info_idx = 0;
5518         size_t size_fds_in;
5519         size_t num_fds_in;
5520         union __swrap_fds __fds_in = { .p = NULL, };
5521         const int *fds_in = NULL;
5522         size_t num_fds_out;
5523         size_t size_fds_out;
5524         union __swrap_fds __fds_out = { .p = NULL, };
5525         int *fds_out = NULL;
5526         size_t cmsg_len;
5527         size_t cmsg_space;
5528         size_t new_cm_data_space;
5529         union __swrap_cmsghdr __new_cmsg = { .p = NULL, };
5530         struct cmsghdr *new_cmsg = NULL;
5531         uint8_t *p = NULL;
5532         size_t i;
5533         int pipefd[2] = { -1, -1 };
5534         int rc;
5535         ssize_t sret;
5536
5537         /*
5538          * We pass this a buffer to the kernel make sure any padding
5539          * is also cleared.
5540          */
5541         ZERO_STRUCT(info);
5542         info.magic = swrap_unix_scm_right_magic;
5543         memcpy(info.package_name,
5544                SOCKET_WRAPPER_PACKAGE,
5545                sizeof(info.package_name));
5546         memcpy(info.package_version,
5547                SOCKET_WRAPPER_VERSION,
5548                sizeof(info.package_version));
5549         info.full_size = sizeof(info);
5550         info.payload_size = sizeof(info.payload);
5551         payload = &info.payload;
5552
5553         if (*scm_rights_pipe_fd != -1) {
5554                 SWRAP_LOG(SWRAP_LOG_ERROR,
5555                           "Two SCM_RIGHTS headers are not supported by socket_wrapper");
5556                 errno = EINVAL;
5557                 return -1;
5558         }
5559
5560         if (cmsg->cmsg_len < CMSG_LEN(0)) {
5561                 SWRAP_LOG(SWRAP_LOG_ERROR,
5562                           "cmsg->cmsg_len=%zu < CMSG_LEN(0)=%zu",
5563                           (size_t)cmsg->cmsg_len,
5564                           CMSG_LEN(0));
5565                 errno = EINVAL;
5566                 return -1;
5567         }
5568         size_fds_in = cmsg->cmsg_len - CMSG_LEN(0);
5569         if ((size_fds_in % sizeof(int)) != 0) {
5570                 SWRAP_LOG(SWRAP_LOG_ERROR,
5571                           "cmsg->cmsg_len=%zu => (size_fds_in=%zu %% sizeof(int)=%zu) != 0",
5572                           (size_t)cmsg->cmsg_len,
5573                           size_fds_in,
5574                           sizeof(int));
5575                 errno = EINVAL;
5576                 return -1;
5577         }
5578         num_fds_in = size_fds_in / sizeof(int);
5579         if (num_fds_in > SWRAP_MAX_PASSED_FDS) {
5580                 SWRAP_LOG(SWRAP_LOG_ERROR,
5581                           "cmsg->cmsg_len=%zu,size_fds_in=%zu => "
5582                           "num_fds_in=%zu > "
5583                           "SWRAP_MAX_PASSED_FDS(%zu)",
5584                           (size_t)cmsg->cmsg_len,
5585                           size_fds_in,
5586                           num_fds_in,
5587                           SWRAP_MAX_PASSED_FDS);
5588                 errno = EINVAL;
5589                 return -1;
5590         }
5591         if (num_fds_in == 0) {
5592                 SWRAP_LOG(SWRAP_LOG_ERROR,
5593                           "cmsg->cmsg_len=%zu,size_fds_in=%zu => "
5594                           "num_fds_in=%zu",
5595                           (size_t)cmsg->cmsg_len,
5596                           size_fds_in,
5597                           num_fds_in);
5598                 errno = EINVAL;
5599                 return -1;
5600         }
5601         __fds_in.p = CMSG_DATA(cmsg);
5602         fds_in = __fds_in.fds;
5603         num_fds_out = num_fds_in + 1;
5604
5605         SWRAP_LOG(SWRAP_LOG_TRACE,
5606                   "num_fds_in=%zu num_fds_out=%zu",
5607                   num_fds_in, num_fds_out);
5608
5609         size_fds_out = sizeof(int) * num_fds_out;
5610         cmsg_len = CMSG_LEN(size_fds_out);
5611         cmsg_space = CMSG_SPACE(size_fds_out);
5612
5613         new_cm_data_space = *cm_data_space + cmsg_space;
5614
5615         p = realloc((*cm_data), new_cm_data_space);
5616         if (p == NULL) {
5617                 return -1;
5618         }
5619         (*cm_data) = p;
5620         p = (*cm_data) + (*cm_data_space);
5621         memset(p, 0, cmsg_space);
5622         __new_cmsg.p = p;
5623         new_cmsg = __new_cmsg.cmsg;
5624         *new_cmsg = *cmsg;
5625         __fds_out.p = CMSG_DATA(new_cmsg);
5626         fds_out = __fds_out.fds;
5627         memcpy(fds_out, fds_in, size_fds_in);
5628         new_cmsg->cmsg_len = cmsg->cmsg_len;
5629
5630         for (i = 0; i < num_fds_in; i++) {
5631                 size_t j;
5632
5633                 payload->idxs[i] = -1;
5634                 payload->num_idxs++;
5635
5636                 si_idx_array[i] = find_socket_info_index(fds_in[i]);
5637                 if (si_idx_array[i] == -1) {
5638                         continue;
5639                 }
5640
5641                 si_array[i] = swrap_get_socket_info(si_idx_array[i]);
5642                 if (si_array[i] == NULL) {
5643                         SWRAP_LOG(SWRAP_LOG_ERROR,
5644                                   "fds_in[%zu]=%d si_idx_array[%zu]=%d missing!",
5645                                   i, fds_in[i], i, si_idx_array[i]);
5646                         errno = EINVAL;
5647                         return -1;
5648                 }
5649
5650                 for (j = 0; j < i; j++) {
5651                         if (si_array[j] == si_array[i]) {
5652                                 payload->idxs[i] = payload->idxs[j];
5653                                 break;
5654                         }
5655                 }
5656                 if (payload->idxs[i] == -1) {
5657                         if (info_idx >= SWRAP_MAX_PASSED_SOCKET_INFO) {
5658                                 SWRAP_LOG(SWRAP_LOG_ERROR,
5659                                           "fds_in[%zu]=%d,si_idx_array[%zu]=%d: "
5660                                           "info_idx=%zu >= SWRAP_MAX_PASSED_FDS(%zu)!",
5661                                           i, fds_in[i], i, si_idx_array[i],
5662                                           info_idx,
5663                                           SWRAP_MAX_PASSED_SOCKET_INFO);
5664                                 errno = EINVAL;
5665                                 return -1;
5666                         }
5667                         payload->idxs[i] = info_idx;
5668                         info_idx += 1;
5669                         continue;
5670                 }
5671         }
5672
5673         for (i = 0; i < num_fds_in; i++) {
5674                 struct socket_info *si = si_array[i];
5675
5676                 if (si == NULL) {
5677                         SWRAP_LOG(SWRAP_LOG_TRACE,
5678                                   "fds_in[%zu]=%d not an inet socket",
5679                                   i, fds_in[i]);
5680                         continue;
5681                 }
5682
5683                 SWRAP_LOG(SWRAP_LOG_TRACE,
5684                           "fds_in[%zu]=%d si_idx_array[%zu]=%d "
5685                           "passing as info.idxs[%zu]=%d!",
5686                           i, fds_in[i],
5687                           i, si_idx_array[i],
5688                           i, payload->idxs[i]);
5689
5690                 SWRAP_LOCK_SI(si);
5691                 si->fd_passed += 1;
5692                 payload->infos[payload->idxs[i]] = *si;
5693                 payload->infos[payload->idxs[i]].fd_passed = 0;
5694                 SWRAP_UNLOCK_SI(si);
5695         }
5696
5697         rc = pipe(pipefd);
5698         if (rc == -1) {
5699                 int saved_errno = errno;
5700                 SWRAP_LOG(SWRAP_LOG_ERROR,
5701                           "pipe() failed - %d %s",
5702                           saved_errno,
5703                           strerror(saved_errno));
5704                 swrap_dec_fd_passed_array(num_fds_in, si_array);
5705                 errno = saved_errno;
5706                 return -1;
5707         }
5708
5709         sret = libc_write(pipefd[1], &info, sizeof(info));
5710         if (sret != sizeof(info)) {
5711                 int saved_errno = errno;
5712                 if (sret != -1) {
5713                         saved_errno = EINVAL;
5714                 }
5715                 SWRAP_LOG(SWRAP_LOG_ERROR,
5716                           "write() failed - sret=%zd - %d %s",
5717                           sret, saved_errno,
5718                           strerror(saved_errno));
5719                 swrap_dec_fd_passed_array(num_fds_in, si_array);
5720                 libc_close(pipefd[1]);
5721                 libc_close(pipefd[0]);
5722                 errno = saved_errno;
5723                 return -1;
5724         }
5725         libc_close(pipefd[1]);
5726
5727         /*
5728          * Add the pipe read end to the end of the passed fd array
5729          */
5730         fds_out[num_fds_in] = pipefd[0];
5731         new_cmsg->cmsg_len = cmsg_len;
5732
5733         /* we're done ... */
5734         *scm_rights_pipe_fd = pipefd[0];
5735         *cm_data_space = new_cm_data_space;
5736
5737         return 0;
5738 }
5739
5740 static int swrap_sendmsg_unix_sol_socket(struct cmsghdr *cmsg,
5741                                          uint8_t **cm_data,
5742                                          size_t *cm_data_space,
5743                                          int *scm_rights_pipe_fd)
5744 {
5745         int rc = -1;
5746
5747         switch (cmsg->cmsg_type) {
5748         case SCM_RIGHTS:
5749                 rc = swrap_sendmsg_unix_scm_rights(cmsg,
5750                                                    cm_data,
5751                                                    cm_data_space,
5752                                                    scm_rights_pipe_fd);
5753                 break;
5754         default:
5755                 rc = swrap_sendmsg_copy_cmsg(cmsg,
5756                                              cm_data,
5757                                              cm_data_space);
5758                 break;
5759         }
5760
5761         return rc;
5762 }
5763
5764 static int swrap_recvmsg_unix_scm_rights(struct cmsghdr *cmsg,
5765                                          uint8_t **cm_data,
5766                                          size_t *cm_data_space)
5767 {
5768         int scm_rights_pipe_fd = -1;
5769         struct swrap_unix_scm_rights info;
5770         struct swrap_unix_scm_rights_payload *payload = NULL;
5771         int si_idx_array[SWRAP_MAX_PASSED_FDS];
5772         size_t size_fds_in;
5773         size_t num_fds_in;
5774         union __swrap_fds __fds_in = { .p = NULL, };
5775         const int *fds_in = NULL;
5776         size_t num_fds_out;
5777         size_t size_fds_out;
5778         union __swrap_fds __fds_out = { .p = NULL, };
5779         int *fds_out = NULL;
5780         size_t cmsg_len;
5781         size_t cmsg_space;
5782         size_t new_cm_data_space;
5783         union __swrap_cmsghdr __new_cmsg = { .p = NULL, };
5784         struct cmsghdr *new_cmsg = NULL;
5785         uint8_t *p = NULL;
5786         ssize_t sret;
5787         size_t i;
5788         int cmp;
5789
5790         if (cmsg->cmsg_len < CMSG_LEN(0)) {
5791                 SWRAP_LOG(SWRAP_LOG_ERROR,
5792                           "cmsg->cmsg_len=%zu < CMSG_LEN(0)=%zu",
5793                           (size_t)cmsg->cmsg_len,
5794                           CMSG_LEN(0));
5795                 errno = EINVAL;
5796                 return -1;
5797         }
5798         size_fds_in = cmsg->cmsg_len - CMSG_LEN(0);
5799         if ((size_fds_in % sizeof(int)) != 0) {
5800                 SWRAP_LOG(SWRAP_LOG_ERROR,
5801                           "cmsg->cmsg_len=%zu => (size_fds_in=%zu %% sizeof(int)=%zu) != 0",
5802                           (size_t)cmsg->cmsg_len,
5803                           size_fds_in,
5804                           sizeof(int));
5805                 errno = EINVAL;
5806                 return -1;
5807         }
5808         num_fds_in = size_fds_in / sizeof(int);
5809         if (num_fds_in > (SWRAP_MAX_PASSED_FDS + 1)) {
5810                 SWRAP_LOG(SWRAP_LOG_ERROR,
5811                           "cmsg->cmsg_len=%zu,size_fds_in=%zu => "
5812                           "num_fds_in=%zu > SWRAP_MAX_PASSED_FDS+1(%zu)",
5813                           (size_t)cmsg->cmsg_len,
5814                           size_fds_in,
5815                           num_fds_in,
5816                           SWRAP_MAX_PASSED_FDS+1);
5817                 errno = EINVAL;
5818                 return -1;
5819         }
5820         if (num_fds_in <= 1) {
5821                 SWRAP_LOG(SWRAP_LOG_ERROR,
5822                           "cmsg->cmsg_len=%zu,size_fds_in=%zu => "
5823                           "num_fds_in=%zu",
5824                           (size_t)cmsg->cmsg_len,
5825                           size_fds_in,
5826                           num_fds_in);
5827                 errno = EINVAL;
5828                 return -1;
5829         }
5830         __fds_in.p = CMSG_DATA(cmsg);
5831         fds_in = __fds_in.fds;
5832         num_fds_out = num_fds_in - 1;
5833
5834         SWRAP_LOG(SWRAP_LOG_TRACE,
5835                   "num_fds_in=%zu num_fds_out=%zu",
5836                   num_fds_in, num_fds_out);
5837
5838         for (i = 0; i < num_fds_in; i++) {
5839                 /* Check if we have a stale fd and remove it */
5840                 swrap_remove_stale(fds_in[i]);
5841         }
5842
5843         scm_rights_pipe_fd = fds_in[num_fds_out];
5844         size_fds_out = sizeof(int) * num_fds_out;
5845         cmsg_len = CMSG_LEN(size_fds_out);
5846         cmsg_space = CMSG_SPACE(size_fds_out);
5847
5848         new_cm_data_space = *cm_data_space + cmsg_space;
5849
5850         p = realloc((*cm_data), new_cm_data_space);
5851         if (p == NULL) {
5852                 swrap_close_fd_array(num_fds_in, fds_in);
5853                 return -1;
5854         }
5855         (*cm_data) = p;
5856         p = (*cm_data) + (*cm_data_space);
5857         memset(p, 0, cmsg_space);
5858         __new_cmsg.p = p;
5859         new_cmsg = __new_cmsg.cmsg;
5860         *new_cmsg = *cmsg;
5861         __fds_out.p = CMSG_DATA(new_cmsg);
5862         fds_out = __fds_out.fds;
5863         memcpy(fds_out, fds_in, size_fds_out);
5864         new_cmsg->cmsg_len = cmsg_len;
5865
5866         sret = read(scm_rights_pipe_fd, &info, sizeof(info));
5867         if (sret != sizeof(info)) {
5868                 int saved_errno = errno;
5869                 if (sret != -1) {
5870                         saved_errno = EINVAL;
5871                 }
5872                 SWRAP_LOG(SWRAP_LOG_ERROR,
5873                           "read() failed - sret=%zd - %d %s",
5874                           sret, saved_errno,
5875                           strerror(saved_errno));
5876                 swrap_close_fd_array(num_fds_in, fds_in);
5877                 errno = saved_errno;
5878                 return -1;
5879         }
5880         libc_close(scm_rights_pipe_fd);
5881         payload = &info.payload;
5882
5883         if (info.magic != swrap_unix_scm_right_magic) {
5884                 SWRAP_LOG(SWRAP_LOG_ERROR,
5885                           "info.magic=0x%llx != swrap_unix_scm_right_magic=0x%llx",
5886                           (unsigned long long)info.magic,
5887                           (unsigned long long)swrap_unix_scm_right_magic);
5888                 swrap_close_fd_array(num_fds_out, fds_out);
5889                 errno = EINVAL;
5890                 return -1;
5891         }
5892
5893         cmp = memcmp(info.package_name,
5894                      SOCKET_WRAPPER_PACKAGE,
5895                      sizeof(info.package_name));
5896         if (cmp != 0) {
5897                 SWRAP_LOG(SWRAP_LOG_ERROR,
5898                           "info.package_name='%.*s' != '%s'",
5899                           (int)sizeof(info.package_name),
5900                           info.package_name,
5901                           SOCKET_WRAPPER_PACKAGE);
5902                 swrap_close_fd_array(num_fds_out, fds_out);
5903                 errno = EINVAL;
5904                 return -1;
5905         }
5906
5907         cmp = memcmp(info.package_version,
5908                      SOCKET_WRAPPER_VERSION,
5909                      sizeof(info.package_version));
5910         if (cmp != 0) {
5911                 SWRAP_LOG(SWRAP_LOG_ERROR,
5912                           "info.package_version='%.*s' != '%s'",
5913                           (int)sizeof(info.package_version),
5914                           info.package_version,
5915                           SOCKET_WRAPPER_VERSION);
5916                 swrap_close_fd_array(num_fds_out, fds_out);
5917                 errno = EINVAL;
5918                 return -1;
5919         }
5920
5921         if (info.full_size != sizeof(info)) {
5922                 SWRAP_LOG(SWRAP_LOG_ERROR,
5923                           "info.full_size=%zu != sizeof(info)=%zu",
5924                           (size_t)info.full_size,
5925                           sizeof(info));
5926                 swrap_close_fd_array(num_fds_out, fds_out);
5927                 errno = EINVAL;
5928                 return -1;
5929         }
5930
5931         if (info.payload_size != sizeof(info.payload)) {
5932                 SWRAP_LOG(SWRAP_LOG_ERROR,
5933                           "info.payload_size=%zu != sizeof(info.payload)=%zu",
5934                           (size_t)info.payload_size,
5935                           sizeof(info.payload));
5936                 swrap_close_fd_array(num_fds_out, fds_out);
5937                 errno = EINVAL;
5938                 return -1;
5939         }
5940
5941         if (payload->num_idxs != num_fds_out) {
5942                 SWRAP_LOG(SWRAP_LOG_ERROR,
5943                           "info.num_idxs=%u != num_fds_out=%zu",
5944                           payload->num_idxs, num_fds_out);
5945                 swrap_close_fd_array(num_fds_out, fds_out);
5946                 errno = EINVAL;
5947                 return -1;
5948         }
5949
5950         for (i = 0; i < num_fds_out; i++) {
5951                 size_t j;
5952
5953                 si_idx_array[i] = -1;
5954
5955                 if (payload->idxs[i] == -1) {
5956                         SWRAP_LOG(SWRAP_LOG_TRACE,
5957                                   "fds_out[%zu]=%d not an inet socket",
5958                                   i, fds_out[i]);
5959                         continue;
5960                 }
5961
5962                 if (payload->idxs[i] < 0) {
5963                         SWRAP_LOG(SWRAP_LOG_ERROR,
5964                                   "fds_out[%zu]=%d info.idxs[%zu]=%d < 0!",
5965                                   i, fds_out[i], i, payload->idxs[i]);
5966                         swrap_close_fd_array(num_fds_out, fds_out);
5967                         errno = EINVAL;
5968                         return -1;
5969                 }
5970
5971                 if (payload->idxs[i] >= payload->num_idxs) {
5972                         SWRAP_LOG(SWRAP_LOG_ERROR,
5973                                   "fds_out[%zu]=%d info.idxs[%zu]=%d >= %u!",
5974                                   i, fds_out[i], i, payload->idxs[i],
5975                                   payload->num_idxs);
5976                         swrap_close_fd_array(num_fds_out, fds_out);
5977                         errno = EINVAL;
5978                         return -1;
5979                 }
5980
5981                 if ((size_t)fds_out[i] >= socket_fds_max) {
5982                         SWRAP_LOG(SWRAP_LOG_ERROR,
5983                                   "The max socket index limit of %zu has been reached, "
5984                                   "trying to add %d",
5985                                   socket_fds_max,
5986                                   fds_out[i]);
5987                         swrap_close_fd_array(num_fds_out, fds_out);
5988                         errno = EMFILE;
5989                         return -1;
5990                 }
5991
5992                 SWRAP_LOG(SWRAP_LOG_TRACE,
5993                           "fds_in[%zu]=%d "
5994                           "received as info.idxs[%zu]=%d!",
5995                           i, fds_out[i],
5996                           i, payload->idxs[i]);
5997
5998                 for (j = 0; j < i; j++) {
5999                         if (payload->idxs[j] == -1) {
6000                                 continue;
6001                         }
6002                         if (payload->idxs[j] == payload->idxs[i]) {
6003                                 si_idx_array[i] = si_idx_array[j];
6004                         }
6005                 }
6006                 if (si_idx_array[i] == -1) {
6007                         const struct socket_info *si = &payload->infos[payload->idxs[i]];
6008
6009                         si_idx_array[i] = swrap_add_socket_info(si);
6010                         if (si_idx_array[i] == -1) {
6011                                 int saved_errno = errno;
6012                                 SWRAP_LOG(SWRAP_LOG_ERROR,
6013                                           "The max socket index limit of %zu has been reached, "
6014                                           "trying to add %d",
6015                                           socket_fds_max,
6016                                           fds_out[i]);
6017                                 swrap_undo_si_idx_array(i, si_idx_array);
6018                                 swrap_close_fd_array(num_fds_out, fds_out);
6019                                 errno = saved_errno;
6020                                 return -1;
6021                         }
6022                         SWRAP_LOG(SWRAP_LOG_TRACE,
6023                                   "Imported %s socket for protocol %s, fd=%d",
6024                                   si->family == AF_INET ? "IPv4" : "IPv6",
6025                                   si->type == SOCK_DGRAM ? "UDP" : "TCP",
6026                                   fds_out[i]);
6027                 }
6028         }
6029
6030         for (i = 0; i < num_fds_out; i++) {
6031                 if (si_idx_array[i] == -1) {
6032                         continue;
6033                 }
6034                 set_socket_info_index(fds_out[i], si_idx_array[i]);
6035         }
6036
6037         /* we're done ... */
6038         *cm_data_space = new_cm_data_space;
6039
6040         return 0;
6041 }
6042
6043 static int swrap_recvmsg_unix_sol_socket(struct cmsghdr *cmsg,
6044                                          uint8_t **cm_data,
6045                                          size_t *cm_data_space)
6046 {
6047         int rc = -1;
6048
6049         switch (cmsg->cmsg_type) {
6050         case SCM_RIGHTS:
6051                 rc = swrap_recvmsg_unix_scm_rights(cmsg,
6052                                                    cm_data,
6053                                                    cm_data_space);
6054                 break;
6055         default:
6056                 rc = swrap_sendmsg_copy_cmsg(cmsg,
6057                                              cm_data,
6058                                              cm_data_space);
6059                 break;
6060         }
6061
6062         return rc;
6063 }
6064
6065 #endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
6066
6067 static int swrap_sendmsg_before_unix(const struct msghdr *_msg_in,
6068                                      struct msghdr *msg_tmp,
6069                                      int *scm_rights_pipe_fd)
6070 {
6071 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6072         struct msghdr *msg_in = discard_const_p(struct msghdr, _msg_in);
6073         struct cmsghdr *cmsg = NULL;
6074         uint8_t *cm_data = NULL;
6075         size_t cm_data_space = 0;
6076         int rc = -1;
6077
6078         *msg_tmp = *msg_in;
6079         *scm_rights_pipe_fd = -1;
6080
6081         /* Nothing to do */
6082         if (msg_in->msg_controllen == 0 || msg_in->msg_control == NULL) {
6083                 return 0;
6084         }
6085
6086         for (cmsg = CMSG_FIRSTHDR(msg_in);
6087              cmsg != NULL;
6088              cmsg = CMSG_NXTHDR(msg_in, cmsg)) {
6089                 switch (cmsg->cmsg_level) {
6090                 case SOL_SOCKET:
6091                         rc = swrap_sendmsg_unix_sol_socket(cmsg,
6092                                                            &cm_data,
6093                                                            &cm_data_space,
6094                                                            scm_rights_pipe_fd);
6095                         break;
6096
6097                 default:
6098                         rc = swrap_sendmsg_copy_cmsg(cmsg,
6099                                                      &cm_data,
6100                                                      &cm_data_space);
6101                         break;
6102                 }
6103                 if (rc < 0) {
6104                         int saved_errno = errno;
6105                         SAFE_FREE(cm_data);
6106                         errno = saved_errno;
6107                         return rc;
6108                 }
6109         }
6110
6111         msg_tmp->msg_controllen = cm_data_space;
6112         msg_tmp->msg_control = cm_data;
6113
6114         return 0;
6115 #else /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
6116         *msg_tmp = *_msg_in;
6117         return 0;
6118 #endif /* ! HAVE_STRUCT_MSGHDR_MSG_CONTROL */
6119 }
6120
6121 static ssize_t swrap_sendmsg_after_unix(struct msghdr *msg_tmp,
6122                                         ssize_t ret,
6123                                         int scm_rights_pipe_fd)
6124 {
6125 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6126         int saved_errno = errno;
6127         SAFE_FREE(msg_tmp->msg_control);
6128         if (scm_rights_pipe_fd != -1) {
6129                 libc_close(scm_rights_pipe_fd);
6130         }
6131         errno = saved_errno;
6132 #endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
6133         return ret;
6134 }
6135
6136 static int swrap_recvmsg_before_unix(struct msghdr *msg_in,
6137                                      struct msghdr *msg_tmp,
6138                                      uint8_t **tmp_control)
6139 {
6140 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6141         const size_t cm_extra_space = CMSG_SPACE(sizeof(int));
6142         uint8_t *cm_data = NULL;
6143         size_t cm_data_space = 0;
6144
6145         *msg_tmp = *msg_in;
6146         *tmp_control = NULL;
6147
6148         SWRAP_LOG(SWRAP_LOG_TRACE,
6149                   "msg_in->msg_controllen=%zu",
6150                   (size_t)msg_in->msg_controllen);
6151
6152         /* Nothing to do */
6153         if (msg_in->msg_controllen == 0 || msg_in->msg_control == NULL) {
6154                 return 0;
6155         }
6156
6157         /*
6158          * We need to give the kernel a bit more space in order
6159          * recv the pipe fd, added by swrap_sendmsg_before_unix()).
6160          * swrap_recvmsg_after_unix() will hide it again.
6161          */
6162         cm_data_space = msg_in->msg_controllen;
6163         if (cm_data_space < (INT32_MAX - cm_extra_space)) {
6164                 cm_data_space += cm_extra_space;
6165         }
6166         cm_data = calloc(1, cm_data_space);
6167         if (cm_data == NULL) {
6168                 return -1;
6169         }
6170
6171         msg_tmp->msg_controllen = cm_data_space;
6172         msg_tmp->msg_control = cm_data;
6173         *tmp_control = cm_data;
6174
6175         SWRAP_LOG(SWRAP_LOG_TRACE,
6176                   "msg_tmp->msg_controllen=%zu",
6177                   (size_t)msg_tmp->msg_controllen);
6178         return 0;
6179 #else /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
6180         *msg_tmp = *msg_in;
6181         *tmp_control = NULL;
6182         return 0;
6183 #endif /* ! HAVE_STRUCT_MSGHDR_MSG_CONTROL */
6184 }
6185
6186 static ssize_t swrap_recvmsg_after_unix(struct msghdr *msg_tmp,
6187                                         uint8_t **tmp_control,
6188                                         struct msghdr *msg_out,
6189                                         ssize_t ret)
6190 {
6191 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6192         struct cmsghdr *cmsg = NULL;
6193         uint8_t *cm_data = NULL;
6194         size_t cm_data_space = 0;
6195         int rc = -1;
6196
6197         if (ret < 0) {
6198                 int saved_errno = errno;
6199                 SWRAP_LOG(SWRAP_LOG_TRACE, "ret=%zd - %d - %s", ret,
6200                           saved_errno, strerror(saved_errno));
6201                 SAFE_FREE(*tmp_control);
6202                 /* msg_out should not be touched on error */
6203                 errno = saved_errno;
6204                 return ret;
6205         }
6206
6207         SWRAP_LOG(SWRAP_LOG_TRACE,
6208                   "msg_tmp->msg_controllen=%zu",
6209                   (size_t)msg_tmp->msg_controllen);
6210
6211         /* Nothing to do */
6212         if (msg_tmp->msg_controllen == 0 || msg_tmp->msg_control == NULL) {
6213                 int saved_errno = errno;
6214                 *msg_out = *msg_tmp;
6215                 SAFE_FREE(*tmp_control);
6216                 errno = saved_errno;
6217                 return ret;
6218         }
6219
6220         for (cmsg = CMSG_FIRSTHDR(msg_tmp);
6221              cmsg != NULL;
6222              cmsg = CMSG_NXTHDR(msg_tmp, cmsg)) {
6223                 switch (cmsg->cmsg_level) {
6224                 case SOL_SOCKET:
6225                         rc = swrap_recvmsg_unix_sol_socket(cmsg,
6226                                                            &cm_data,
6227                                                            &cm_data_space);
6228                         break;
6229
6230                 default:
6231                         rc = swrap_sendmsg_copy_cmsg(cmsg,
6232                                                      &cm_data,
6233                                                      &cm_data_space);
6234                         break;
6235                 }
6236                 if (rc < 0) {
6237                         int saved_errno = errno;
6238                         SAFE_FREE(cm_data);
6239                         SAFE_FREE(*tmp_control);
6240                         errno = saved_errno;
6241                         return rc;
6242                 }
6243         }
6244
6245         /*
6246          * msg_tmp->msg_control (*tmp_control) was created by
6247          * swrap_recvmsg_before_unix() and msg_out->msg_control
6248          * is still the buffer of the caller.
6249          */
6250         msg_tmp->msg_control = msg_out->msg_control;
6251         msg_tmp->msg_controllen = msg_out->msg_controllen;
6252         *msg_out = *msg_tmp;
6253
6254         cm_data_space = MIN(cm_data_space, msg_out->msg_controllen);
6255         memcpy(msg_out->msg_control, cm_data, cm_data_space);
6256         msg_out->msg_controllen = cm_data_space;
6257         SAFE_FREE(cm_data);
6258         SAFE_FREE(*tmp_control);
6259
6260         SWRAP_LOG(SWRAP_LOG_TRACE,
6261                   "msg_out->msg_controllen=%zu",
6262                   (size_t)msg_out->msg_controllen);
6263         return ret;
6264 #else /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
6265         int saved_errno = errno;
6266         *msg_out = *msg_tmp;
6267         SAFE_FREE(*tmp_control);
6268         errno = saved_errno;
6269         return ret;
6270 #endif /* ! HAVE_STRUCT_MSGHDR_MSG_CONTROL */
6271 }
6272
6273 static ssize_t swrap_sendmsg_before(int fd,
6274                                     struct socket_info *si,
6275                                     struct msghdr *msg,
6276                                     struct iovec *tmp_iov,
6277                                     struct sockaddr_un *tmp_un,
6278                                     const struct sockaddr_un **to_un,
6279                                     const struct sockaddr **to,
6280                                     int *bcast)
6281 {
6282         size_t i, len = 0;
6283         ssize_t ret = -1;
6284         struct swrap_sockaddr_buf buf = {};
6285
6286         if (to_un) {
6287                 *to_un = NULL;
6288         }
6289         if (to) {
6290                 *to = NULL;
6291         }
6292         if (bcast) {
6293                 *bcast = 0;
6294         }
6295
6296         SWRAP_LOCK_SI(si);
6297
6298         switch (si->type) {
6299         case SOCK_STREAM: {
6300                 unsigned long mtu;
6301
6302                 if (!si->connected) {
6303                         errno = ENOTCONN;
6304                         goto out;
6305                 }
6306
6307                 if (msg->msg_iovlen == 0) {
6308                         break;
6309                 }
6310
6311                 mtu = socket_wrapper_mtu();
6312                 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
6313                         size_t nlen;
6314                         nlen = len + msg->msg_iov[i].iov_len;
6315                         if (nlen < len) {
6316                                 /* overflow */
6317                                 errno = EMSGSIZE;
6318                                 goto out;
6319                         }
6320                         if (nlen > mtu) {
6321                                 break;
6322                         }
6323                 }
6324                 msg->msg_iovlen = i;
6325                 if (msg->msg_iovlen == 0) {
6326                         *tmp_iov = msg->msg_iov[0];
6327                         tmp_iov->iov_len = MIN((size_t)tmp_iov->iov_len,
6328                                                (size_t)mtu);
6329                         msg->msg_iov = tmp_iov;
6330                         msg->msg_iovlen = 1;
6331                 }
6332                 break;
6333         }
6334         case SOCK_DGRAM:
6335                 if (si->connected) {
6336                         if (msg->msg_name != NULL) {
6337                                 /*
6338                                  * We are dealing with unix sockets and if we
6339                                  * are connected, we should only talk to the
6340                                  * connected unix path. Using the fd to send
6341                                  * to another server would be hard to achieve.
6342                                  */
6343                                 msg->msg_name = NULL;
6344                                 msg->msg_namelen = 0;
6345                         }
6346                         SWRAP_LOG(SWRAP_LOG_TRACE,
6347                                   "connected(%s) fd=%d",
6348                                   swrap_sockaddr_string(&buf, &si->peername.sa.s),
6349                                   fd);
6350                 } else {
6351                         const struct sockaddr *msg_name;
6352                         msg_name = (const struct sockaddr *)msg->msg_name;
6353
6354                         if (msg_name == NULL) {
6355                                 errno = ENOTCONN;
6356                                 goto out;
6357                         }
6358
6359
6360                         ret = sockaddr_convert_to_un(si, msg_name, msg->msg_namelen,
6361                                                      tmp_un, 0, bcast);
6362                         if (ret == -1) {
6363                                 goto out;
6364                         }
6365
6366                         if (to_un) {
6367                                 *to_un = tmp_un;
6368                         }
6369                         if (to) {
6370                                 *to = msg_name;
6371                         }
6372                         msg->msg_name = tmp_un;
6373                         msg->msg_namelen = sizeof(*tmp_un);
6374                 }
6375
6376                 if (si->bound == 0) {
6377                         ret = swrap_auto_bind(fd, si, si->family);
6378                         if (ret == -1) {
6379                                 SWRAP_UNLOCK_SI(si);
6380                                 if (errno == ENOTSOCK) {
6381                                         swrap_remove_stale(fd);
6382                                         ret = -ENOTSOCK;
6383                                 } else {
6384                                         SWRAP_LOG(SWRAP_LOG_ERROR, "swrap_sendmsg_before failed");
6385                                 }
6386                                 return ret;
6387                         }
6388                 }
6389
6390                 if (!si->defer_connect) {
6391                         break;
6392                 }
6393
6394                 ret = sockaddr_convert_to_un(si,
6395                                              &si->peername.sa.s,
6396                                              si->peername.sa_socklen,
6397                                              tmp_un,
6398                                              0,
6399                                              NULL);
6400                 if (ret == -1) {
6401                         goto out;
6402                 }
6403
6404                 SWRAP_LOG(SWRAP_LOG_TRACE,
6405                           "deferred connect(%s) path=%s, fd=%d",
6406                           swrap_sockaddr_string(&buf, &si->peername.sa.s),
6407                           tmp_un->sun_path, fd);
6408
6409                 ret = libc_connect(fd,
6410                                    (struct sockaddr *)(void *)tmp_un,
6411                                    sizeof(*tmp_un));
6412
6413                 /* to give better errors */
6414                 if (ret == -1 && errno == ENOENT) {
6415                         errno = EHOSTUNREACH;
6416                 }
6417
6418                 if (ret == -1) {
6419                         goto out;
6420                 }
6421
6422                 si->defer_connect = 0;
6423                 break;
6424         default:
6425                 errno = EHOSTUNREACH;
6426                 goto out;
6427         }
6428
6429         ret = 0;
6430 out:
6431         SWRAP_UNLOCK_SI(si);
6432
6433         return ret;
6434 }
6435
6436 static void swrap_sendmsg_after(int fd,
6437                                 struct socket_info *si,
6438                                 struct msghdr *msg,
6439                                 const struct sockaddr *to,
6440                                 ssize_t ret)
6441 {
6442         int saved_errno = errno;
6443         size_t i, len = 0;
6444         uint8_t *buf;
6445         off_t ofs = 0;
6446         size_t avail = 0;
6447         size_t remain;
6448
6449         /* to give better errors */
6450         if (ret == -1) {
6451                 if (saved_errno == ENOENT) {
6452                         saved_errno = EHOSTUNREACH;
6453                 } else if (saved_errno == ENOTSOCK) {
6454                         /* If the fd is not a socket, remove it */
6455                         swrap_remove_stale(fd);
6456                 }
6457         }
6458
6459         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
6460                 avail += msg->msg_iov[i].iov_len;
6461         }
6462
6463         if (ret == -1) {
6464                 remain = MIN(80, avail);
6465         } else {
6466                 remain = ret;
6467         }
6468
6469         /* we capture it as one single packet */
6470         buf = (uint8_t *)malloc(remain);
6471         if (!buf) {
6472                 /* we just not capture the packet */
6473                 errno = saved_errno;
6474                 return;
6475         }
6476
6477         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
6478                 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
6479                 if (this_time > 0) {
6480                         memcpy(buf + ofs,
6481                                msg->msg_iov[i].iov_base,
6482                                this_time);
6483                 }
6484                 ofs += this_time;
6485                 remain -= this_time;
6486         }
6487         len = ofs;
6488
6489         SWRAP_LOCK_SI(si);
6490
6491         switch (si->type) {
6492         case SOCK_STREAM:
6493                 if (ret == -1) {
6494                         swrap_pcap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
6495                         swrap_pcap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
6496                 } else {
6497                         swrap_pcap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
6498                 }
6499                 break;
6500
6501         case SOCK_DGRAM:
6502                 if (si->connected) {
6503                         to = &si->peername.sa.s;
6504                 }
6505                 if (ret == -1) {
6506                         swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
6507                         swrap_pcap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);
6508                 } else {
6509                         swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
6510                 }
6511                 break;
6512         }
6513
6514         SWRAP_UNLOCK_SI(si);
6515
6516         free(buf);
6517         errno = saved_errno;
6518 }
6519
6520 static int swrap_recvmsg_before(int fd,
6521                                 struct socket_info *si,
6522                                 struct msghdr *msg,
6523                                 struct iovec *tmp_iov)
6524 {
6525         size_t i, len = 0;
6526         int ret = -1;
6527
6528         SWRAP_LOCK_SI(si);
6529
6530         (void)fd; /* unused */
6531
6532         switch (si->type) {
6533         case SOCK_STREAM: {
6534                 unsigned int mtu;
6535                 if (!si->connected) {
6536                         errno = ENOTCONN;
6537                         goto out;
6538                 }
6539
6540                 if (msg->msg_iovlen == 0) {
6541                         break;
6542                 }
6543
6544                 mtu = socket_wrapper_mtu();
6545                 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
6546                         size_t nlen;
6547                         nlen = len + msg->msg_iov[i].iov_len;
6548                         if (nlen > mtu) {
6549                                 break;
6550                         }
6551                 }
6552                 msg->msg_iovlen = i;
6553                 if (msg->msg_iovlen == 0) {
6554                         *tmp_iov = msg->msg_iov[0];
6555                         tmp_iov->iov_len = MIN((size_t)tmp_iov->iov_len,
6556                                                (size_t)mtu);
6557                         msg->msg_iov = tmp_iov;
6558                         msg->msg_iovlen = 1;
6559                 }
6560                 break;
6561         }
6562         case SOCK_DGRAM:
6563                 if (msg->msg_name == NULL) {
6564                         errno = EINVAL;
6565                         goto out;
6566                 }
6567
6568                 if (msg->msg_iovlen == 0) {
6569                         break;
6570                 }
6571
6572                 if (si->bound == 0) {
6573                         ret = swrap_auto_bind(fd, si, si->family);
6574                         if (ret == -1) {
6575                                 SWRAP_UNLOCK_SI(si);
6576                                 /*
6577                                  * When attempting to read or write to a
6578                                  * descriptor, if an underlying autobind fails
6579                                  * because it's not a socket, stop intercepting
6580                                  * uses of that descriptor.
6581                                  */
6582                                 if (errno == ENOTSOCK) {
6583                                         swrap_remove_stale(fd);
6584                                         ret = -ENOTSOCK;
6585                                 } else {
6586                                         SWRAP_LOG(SWRAP_LOG_ERROR,
6587                                                   "swrap_recvmsg_before failed");
6588                                 }
6589                                 return ret;
6590                         }
6591                 }
6592                 break;
6593         default:
6594                 errno = EHOSTUNREACH;
6595                 goto out;
6596         }
6597
6598         ret = 0;
6599 out:
6600         SWRAP_UNLOCK_SI(si);
6601
6602         return ret;
6603 }
6604
6605 static int swrap_recvmsg_after(int fd,
6606                                struct socket_info *si,
6607                                struct msghdr *msg,
6608                                const struct sockaddr_un *un_addr,
6609                                socklen_t un_addrlen,
6610                                ssize_t ret)
6611 {
6612         int saved_errno = errno;
6613         size_t i;
6614         uint8_t *buf = NULL;
6615         off_t ofs = 0;
6616         size_t avail = 0;
6617         size_t remain;
6618         int rc;
6619
6620         /* to give better errors */
6621         if (ret == -1) {
6622                 if (saved_errno == ENOENT) {
6623                         saved_errno = EHOSTUNREACH;
6624                 } else if (saved_errno == ENOTSOCK) {
6625                         /* If the fd is not a socket, remove it */
6626                         swrap_remove_stale(fd);
6627                 }
6628         }
6629
6630         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
6631                 avail += msg->msg_iov[i].iov_len;
6632         }
6633
6634         SWRAP_LOCK_SI(si);
6635
6636         /* Convert the socket address before we leave */
6637         if (si->type == SOCK_DGRAM && un_addr != NULL) {
6638                 rc = sockaddr_convert_from_un(si,
6639                                               un_addr,
6640                                               un_addrlen,
6641                                               si->family,
6642                                               msg->msg_name,
6643                                               &msg->msg_namelen);
6644                 if (rc == -1) {
6645                         goto done;
6646                 }
6647         }
6648
6649         if (avail == 0) {
6650                 rc = 0;
6651                 goto done;
6652         }
6653
6654         if (ret == -1) {
6655                 remain = MIN(80, avail);
6656         } else {
6657                 remain = ret;
6658         }
6659
6660         /* we capture it as one single packet */
6661         buf = (uint8_t *)malloc(remain);
6662         if (buf == NULL) {
6663                 /* we just not capture the packet */
6664                 SWRAP_UNLOCK_SI(si);
6665                 errno = saved_errno;
6666                 return -1;
6667         }
6668
6669         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
6670                 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
6671                 memcpy(buf + ofs,
6672                        msg->msg_iov[i].iov_base,
6673                        this_time);
6674                 ofs += this_time;
6675                 remain -= this_time;
6676         }
6677
6678         switch (si->type) {
6679         case SOCK_STREAM:
6680                 if (ret == -1 && saved_errno != EAGAIN && saved_errno != ENOBUFS) {
6681                         swrap_pcap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
6682                 } else if (ret == 0) { /* END OF FILE */
6683                         swrap_pcap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
6684                 } else if (ret > 0) {
6685                         swrap_pcap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
6686                 }
6687                 break;
6688
6689         case SOCK_DGRAM:
6690                 if (ret == -1) {
6691                         break;
6692                 }
6693
6694                 if (un_addr != NULL) {
6695                         swrap_pcap_dump_packet(si,
6696                                           msg->msg_name,
6697                                           SWRAP_RECVFROM,
6698                                           buf,
6699                                           ret);
6700                 } else {
6701                         swrap_pcap_dump_packet(si,
6702                                           msg->msg_name,
6703                                           SWRAP_RECV,
6704                                           buf,
6705                                           ret);
6706                 }
6707
6708                 break;
6709         }
6710
6711         rc = 0;
6712 done:
6713         free(buf);
6714         errno = saved_errno;
6715
6716 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6717         if (rc == 0 &&
6718             msg->msg_controllen > 0 &&
6719             msg->msg_control != NULL) {
6720                 rc = swrap_msghdr_add_socket_info(si, msg);
6721                 if (rc < 0) {
6722                         SWRAP_UNLOCK_SI(si);
6723                         return -1;
6724                 }
6725         }
6726 #endif
6727
6728         SWRAP_UNLOCK_SI(si);
6729         return rc;
6730 }
6731
6732 /****************************************************************************
6733  *   RECVFROM
6734  ***************************************************************************/
6735
6736 static ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags,
6737                               struct sockaddr *from, socklen_t *fromlen)
6738 {
6739         struct swrap_address from_addr = {
6740                 .sa_socklen = sizeof(struct sockaddr_un),
6741         };
6742         ssize_t ret;
6743         struct socket_info *si = find_socket_info(s);
6744         struct swrap_address saddr = {
6745                 .sa_socklen = sizeof(struct sockaddr_storage),
6746         };
6747         struct msghdr msg;
6748         struct iovec tmp;
6749         int tret;
6750
6751         if (!si) {
6752                 return libc_recvfrom(s,
6753                                      buf,
6754                                      len,
6755                                      flags,
6756                                      from,
6757                                      fromlen);
6758         }
6759
6760         tmp.iov_base = buf;
6761         tmp.iov_len = len;
6762
6763         ZERO_STRUCT(msg);
6764         if (from != NULL && fromlen != NULL) {
6765                 msg.msg_name = from;   /* optional address */
6766                 msg.msg_namelen = *fromlen; /* size of address */
6767         } else {
6768                 msg.msg_name = &saddr.sa.s; /* optional address */
6769                 msg.msg_namelen = saddr.sa_socklen; /* size of address */
6770         }
6771         msg.msg_iov = &tmp;            /* scatter/gather array */
6772         msg.msg_iovlen = 1;            /* # elements in msg_iov */
6773 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6774         msg.msg_control = NULL;        /* ancillary data, see below */
6775         msg.msg_controllen = 0;        /* ancillary data buffer len */
6776         msg.msg_flags = 0;             /* flags on received message */
6777 #endif
6778
6779         tret = swrap_recvmsg_before(s, si, &msg, &tmp);
6780         if (tret < 0) {
6781                 return -1;
6782         }
6783
6784         buf = msg.msg_iov[0].iov_base;
6785         len = msg.msg_iov[0].iov_len;
6786
6787         ret = libc_recvfrom(s,
6788                             buf,
6789                             len,
6790                             flags,
6791                             &from_addr.sa.s,
6792                             &from_addr.sa_socklen);
6793         if (ret == -1) {
6794                 return ret;
6795         }
6796
6797         tret = swrap_recvmsg_after(s,
6798                                    si,
6799                                    &msg,
6800                                    &from_addr.sa.un,
6801                                    from_addr.sa_socklen,
6802                                    ret);
6803         if (tret != 0) {
6804                 return tret;
6805         }
6806
6807         if (from != NULL && fromlen != NULL) {
6808                 *fromlen = msg.msg_namelen;
6809         }
6810
6811         return ret;
6812 }
6813
6814 #ifdef HAVE_ACCEPT_PSOCKLEN_T
6815 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
6816                  struct sockaddr *from, Psocklen_t fromlen)
6817 #else
6818 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
6819                  struct sockaddr *from, socklen_t *fromlen)
6820 #endif
6821 {
6822         return swrap_recvfrom(s, buf, len, flags, from, (socklen_t *)fromlen);
6823 }
6824
6825 /****************************************************************************
6826  *   SENDTO
6827  ***************************************************************************/
6828
6829 static ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags,
6830                             const struct sockaddr *to, socklen_t tolen)
6831 {
6832         struct msghdr msg;
6833         struct iovec tmp;
6834         struct swrap_address un_addr = {
6835                 .sa_socklen = sizeof(struct sockaddr_un),
6836         };
6837         const struct sockaddr_un *to_un = NULL;
6838         ssize_t ret;
6839         int rc;
6840         struct socket_info *si = find_socket_info(s);
6841         int bcast = 0;
6842
6843         if (!si) {
6844                 return libc_sendto(s, buf, len, flags, to, tolen);
6845         }
6846
6847         tmp.iov_base = discard_const_p(char, buf);
6848         tmp.iov_len = len;
6849
6850         ZERO_STRUCT(msg);
6851         msg.msg_name = discard_const_p(struct sockaddr, to); /* optional address */
6852         msg.msg_namelen = tolen;       /* size of address */
6853         msg.msg_iov = &tmp;            /* scatter/gather array */
6854         msg.msg_iovlen = 1;            /* # elements in msg_iov */
6855 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6856         msg.msg_control = NULL;        /* ancillary data, see below */
6857         msg.msg_controllen = 0;        /* ancillary data buffer len */
6858         msg.msg_flags = 0;             /* flags on received message */
6859 #endif
6860
6861         rc = swrap_sendmsg_before(s,
6862                                   si,
6863                                   &msg,
6864                                   &tmp,
6865                                   &un_addr.sa.un,
6866                                   &to_un,
6867                                   &to,
6868                                   &bcast);
6869         if (rc < 0) {
6870                 return -1;
6871         }
6872
6873         buf = msg.msg_iov[0].iov_base;
6874         len = msg.msg_iov[0].iov_len;
6875
6876         if (bcast) {
6877                 struct stat st;
6878                 unsigned int iface;
6879                 unsigned int prt = ntohs(((const struct sockaddr_in *)(const void *)to)->sin_port);
6880                 char type;
6881                 char *swrap_dir = NULL;
6882
6883                 type = SOCKET_TYPE_CHAR_UDP;
6884
6885                 swrap_dir = socket_wrapper_dir();
6886                 if (swrap_dir == NULL) {
6887                         return -1;
6888                 }
6889
6890                 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
6891                         swrap_un_path(&un_addr.sa.un,
6892                                       swrap_dir,
6893                                       type,
6894                                       iface,
6895                                       prt);
6896                         if (stat(un_addr.sa.un.sun_path, &st) != 0) continue;
6897
6898                         /* ignore the any errors in broadcast sends */
6899                         libc_sendto(s,
6900                                     buf,
6901                                     len,
6902                                     flags,
6903                                     &un_addr.sa.s,
6904                                     un_addr.sa_socklen);
6905                 }
6906
6907                 SAFE_FREE(swrap_dir);
6908
6909                 SWRAP_LOCK_SI(si);
6910
6911                 swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
6912
6913                 SWRAP_UNLOCK_SI(si);
6914
6915                 return len;
6916         }
6917
6918         SWRAP_LOCK_SI(si);
6919         /*
6920          * If it is a dgram socket and we are connected, don't include the
6921          * 'to' address.
6922          */
6923         if (si->type == SOCK_DGRAM && si->connected) {
6924                 ret = libc_sendto(s,
6925                                   buf,
6926                                   len,
6927                                   flags,
6928                                   NULL,
6929                                   0);
6930         } else {
6931                 ret = libc_sendto(s,
6932                                   buf,
6933                                   len,
6934                                   flags,
6935                                   (struct sockaddr *)msg.msg_name,
6936                                   msg.msg_namelen);
6937         }
6938
6939         SWRAP_UNLOCK_SI(si);
6940
6941         swrap_sendmsg_after(s, si, &msg, to, ret);
6942
6943         return ret;
6944 }
6945
6946 ssize_t sendto(int s, const void *buf, size_t len, int flags,
6947                const struct sockaddr *to, socklen_t tolen)
6948 {
6949         return swrap_sendto(s, buf, len, flags, to, tolen);
6950 }
6951
6952 /****************************************************************************
6953  *   READV
6954  ***************************************************************************/
6955
6956 static ssize_t swrap_recv(int s, void *buf, size_t len, int flags)
6957 {
6958         struct socket_info *si;
6959         struct msghdr msg;
6960         struct swrap_address saddr = {
6961                 .sa_socklen = sizeof(struct sockaddr_storage),
6962         };
6963         struct iovec tmp;
6964         ssize_t ret;
6965         int tret;
6966
6967         si = find_socket_info(s);
6968         if (si == NULL) {
6969                 return libc_recv(s, buf, len, flags);
6970         }
6971
6972         tmp.iov_base = buf;
6973         tmp.iov_len = len;
6974
6975         ZERO_STRUCT(msg);
6976         msg.msg_name = &saddr.sa.s;    /* optional address */
6977         msg.msg_namelen = saddr.sa_socklen; /* size of address */
6978         msg.msg_iov = &tmp;            /* scatter/gather array */
6979         msg.msg_iovlen = 1;            /* # elements in msg_iov */
6980 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6981         msg.msg_control = NULL;        /* ancillary data, see below */
6982         msg.msg_controllen = 0;        /* ancillary data buffer len */
6983         msg.msg_flags = 0;             /* flags on received message */
6984 #endif
6985
6986         tret = swrap_recvmsg_before(s, si, &msg, &tmp);
6987         if (tret < 0) {
6988                 return -1;
6989         }
6990
6991         buf = msg.msg_iov[0].iov_base;
6992         len = msg.msg_iov[0].iov_len;
6993
6994         ret = libc_recv(s, buf, len, flags);
6995
6996         tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
6997         if (tret != 0) {
6998                 return tret;
6999         }
7000
7001         return ret;
7002 }
7003
7004 ssize_t recv(int s, void *buf, size_t len, int flags)
7005 {
7006         return swrap_recv(s, buf, len, flags);
7007 }
7008
7009 /****************************************************************************
7010  *   READ
7011  ***************************************************************************/
7012
7013 static ssize_t swrap_read(int s, void *buf, size_t len)
7014 {
7015         struct socket_info *si;
7016         struct msghdr msg;
7017         struct iovec tmp;
7018         struct swrap_address saddr = {
7019                 .sa_socklen = sizeof(struct sockaddr_storage),
7020         };
7021         ssize_t ret;
7022         int tret;
7023
7024         si = find_socket_info(s);
7025         if (si == NULL) {
7026                 return libc_read(s, buf, len);
7027         }
7028
7029         tmp.iov_base = buf;
7030         tmp.iov_len = len;
7031
7032         ZERO_STRUCT(msg);
7033         msg.msg_name = &saddr.sa.ss;   /* optional address */
7034         msg.msg_namelen = saddr.sa_socklen; /* size of address */
7035         msg.msg_iov = &tmp;            /* scatter/gather array */
7036         msg.msg_iovlen = 1;            /* # elements in msg_iov */
7037 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7038         msg.msg_control = NULL;        /* ancillary data, see below */
7039         msg.msg_controllen = 0;        /* ancillary data buffer len */
7040         msg.msg_flags = 0;             /* flags on received message */
7041 #endif
7042
7043         tret = swrap_recvmsg_before(s, si, &msg, &tmp);
7044         if (tret < 0) {
7045                 if (tret == -ENOTSOCK) {
7046                         return libc_read(s, buf, len);
7047                 }
7048                 return -1;
7049         }
7050
7051         buf = msg.msg_iov[0].iov_base;
7052         len = msg.msg_iov[0].iov_len;
7053
7054         ret = libc_read(s, buf, len);
7055
7056         tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
7057         if (tret != 0) {
7058                 return tret;
7059         }
7060
7061         return ret;
7062 }
7063
7064 ssize_t read(int s, void *buf, size_t len)
7065 {
7066         return swrap_read(s, buf, len);
7067 }
7068
7069 /****************************************************************************
7070  *   WRITE
7071  ***************************************************************************/
7072
7073 static ssize_t swrap_write(int s, const void *buf, size_t len)
7074 {
7075         struct msghdr msg;
7076         struct iovec tmp;
7077         struct sockaddr_un un_addr;
7078         ssize_t ret;
7079         int rc;
7080         struct socket_info *si;
7081
7082         si = find_socket_info(s);
7083         if (si == NULL) {
7084                 return libc_write(s, buf, len);
7085         }
7086
7087         tmp.iov_base = discard_const_p(char, buf);
7088         tmp.iov_len = len;
7089
7090         ZERO_STRUCT(msg);
7091         msg.msg_name = NULL;           /* optional address */
7092         msg.msg_namelen = 0;           /* size of address */
7093         msg.msg_iov = &tmp;            /* scatter/gather array */
7094         msg.msg_iovlen = 1;            /* # elements in msg_iov */
7095 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7096         msg.msg_control = NULL;        /* ancillary data, see below */
7097         msg.msg_controllen = 0;        /* ancillary data buffer len */
7098         msg.msg_flags = 0;             /* flags on received message */
7099 #endif
7100
7101         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
7102         if (rc < 0) {
7103                 return -1;
7104         }
7105
7106         buf = msg.msg_iov[0].iov_base;
7107         len = msg.msg_iov[0].iov_len;
7108
7109         ret = libc_write(s, buf, len);
7110
7111         swrap_sendmsg_after(s, si, &msg, NULL, ret);
7112
7113         return ret;
7114 }
7115
7116 ssize_t write(int s, const void *buf, size_t len)
7117 {
7118         return swrap_write(s, buf, len);
7119 }
7120
7121 /****************************************************************************
7122  *   SEND
7123  ***************************************************************************/
7124
7125 static ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
7126 {
7127         struct msghdr msg;
7128         struct iovec tmp;
7129         struct sockaddr_un un_addr;
7130         ssize_t ret;
7131         int rc;
7132         struct socket_info *si = find_socket_info(s);
7133
7134         if (!si) {
7135                 return libc_send(s, buf, len, flags);
7136         }
7137
7138         tmp.iov_base = discard_const_p(char, buf);
7139         tmp.iov_len = len;
7140
7141         ZERO_STRUCT(msg);
7142         msg.msg_name = NULL;           /* optional address */
7143         msg.msg_namelen = 0;           /* size of address */
7144         msg.msg_iov = &tmp;            /* scatter/gather array */
7145         msg.msg_iovlen = 1;            /* # elements in msg_iov */
7146 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7147         msg.msg_control = NULL;        /* ancillary data, see below */
7148         msg.msg_controllen = 0;        /* ancillary data buffer len */
7149         msg.msg_flags = 0;             /* flags on received message */
7150 #endif
7151
7152         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
7153         if (rc < 0) {
7154                 return -1;
7155         }
7156
7157         buf = msg.msg_iov[0].iov_base;
7158         len = msg.msg_iov[0].iov_len;
7159
7160         ret = libc_send(s, buf, len, flags);
7161
7162         swrap_sendmsg_after(s, si, &msg, NULL, ret);
7163
7164         return ret;
7165 }
7166
7167 ssize_t send(int s, const void *buf, size_t len, int flags)
7168 {
7169         return swrap_send(s, buf, len, flags);
7170 }
7171
7172 /****************************************************************************
7173  *   RECVMSG
7174  ***************************************************************************/
7175
7176 static ssize_t swrap_recvmsg(int s, struct msghdr *omsg, int flags)
7177 {
7178         struct swrap_address from_addr = {
7179                 .sa_socklen = sizeof(struct sockaddr_un),
7180         };
7181         struct swrap_address convert_addr = {
7182                 .sa_socklen = sizeof(struct sockaddr_storage),
7183         };
7184         struct socket_info *si;
7185         struct msghdr msg;
7186         struct iovec tmp;
7187 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7188         size_t msg_ctrllen_filled;
7189         size_t msg_ctrllen_left;
7190 #endif
7191
7192         ssize_t ret;
7193         int rc;
7194
7195         si = find_socket_info(s);
7196         if (si == NULL) {
7197                 uint8_t *tmp_control = NULL;
7198                 rc = swrap_recvmsg_before_unix(omsg, &msg, &tmp_control);
7199                 if (rc < 0) {
7200                         return rc;
7201                 }
7202                 ret = libc_recvmsg(s, &msg, flags);
7203                 return swrap_recvmsg_after_unix(&msg, &tmp_control, omsg, ret);
7204         }
7205
7206         tmp.iov_base = NULL;
7207         tmp.iov_len = 0;
7208
7209         ZERO_STRUCT(msg);
7210         msg.msg_name = &from_addr.sa;              /* optional address */
7211         msg.msg_namelen = from_addr.sa_socklen;    /* size of address */
7212         msg.msg_iov = omsg->msg_iov;               /* scatter/gather array */
7213         msg.msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
7214 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7215         msg_ctrllen_filled = 0;
7216         msg_ctrllen_left = omsg->msg_controllen;
7217
7218         msg.msg_control = omsg->msg_control;       /* ancillary data, see below */
7219         msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
7220         msg.msg_flags = omsg->msg_flags;           /* flags on received message */
7221 #endif
7222
7223         rc = swrap_recvmsg_before(s, si, &msg, &tmp);
7224         if (rc < 0) {
7225                 return -1;
7226         }
7227
7228         ret = libc_recvmsg(s, &msg, flags);
7229
7230 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7231         msg_ctrllen_filled += msg.msg_controllen;
7232         msg_ctrllen_left -= msg.msg_controllen;
7233
7234         if (omsg->msg_control != NULL) {
7235                 uint8_t *p;
7236
7237                 p = omsg->msg_control;
7238                 p += msg_ctrllen_filled;
7239
7240                 msg.msg_control = p;
7241                 msg.msg_controllen = msg_ctrllen_left;
7242         } else {
7243                 msg.msg_control = NULL;
7244                 msg.msg_controllen = 0;
7245         }
7246 #endif
7247
7248         /*
7249          * We convert the unix address to a IP address so we need a buffer
7250          * which can store the address in case of SOCK_DGRAM, see below.
7251          */
7252         msg.msg_name = &convert_addr.sa;
7253         msg.msg_namelen = convert_addr.sa_socklen;
7254
7255         rc = swrap_recvmsg_after(s,
7256                                  si,
7257                                  &msg,
7258                                  &from_addr.sa.un,
7259                                  from_addr.sa_socklen,
7260                                  ret);
7261         if (rc != 0) {
7262                 return rc;
7263         }
7264
7265 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7266         if (omsg->msg_control != NULL) {
7267                 /* msg.msg_controllen = space left */
7268                 msg_ctrllen_left = msg.msg_controllen;
7269                 msg_ctrllen_filled = omsg->msg_controllen - msg_ctrllen_left;
7270         }
7271
7272         /* Update the original message length */
7273         omsg->msg_controllen = msg_ctrllen_filled;
7274         omsg->msg_flags = msg.msg_flags;
7275 #endif
7276         omsg->msg_iovlen = msg.msg_iovlen;
7277
7278         SWRAP_LOCK_SI(si);
7279
7280         /*
7281          * From the manpage:
7282          *
7283          * The  msg_name  field  points  to a caller-allocated buffer that is
7284          * used to return the source address if the socket is unconnected.  The
7285          * caller should set msg_namelen to the size of this buffer before this
7286          * call; upon return from a successful call, msg_name will contain the
7287          * length of the returned address.  If the application  does  not  need
7288          * to know the source address, msg_name can be specified as NULL.
7289          */
7290         if (si->type == SOCK_STREAM) {
7291                 omsg->msg_namelen = 0;
7292         } else if (omsg->msg_name != NULL &&
7293                    omsg->msg_namelen != 0 &&
7294                    omsg->msg_namelen >= msg.msg_namelen) {
7295                 memcpy(omsg->msg_name, msg.msg_name, msg.msg_namelen);
7296                 omsg->msg_namelen = msg.msg_namelen;
7297         }
7298
7299         SWRAP_UNLOCK_SI(si);
7300
7301         return ret;
7302 }
7303
7304 ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)
7305 {
7306         return swrap_recvmsg(sockfd, msg, flags);
7307 }
7308
7309 /****************************************************************************
7310  *   RECVMMSG
7311  ***************************************************************************/
7312
7313 #ifdef HAVE_RECVMMSG
7314 #if defined(HAVE_RECVMMSG_SSIZE_T_CONST_TIMEOUT)
7315 /* FreeBSD */
7316 static ssize_t swrap_recvmmsg(int s, struct mmsghdr *omsgvec, size_t _vlen, int flags, const struct timespec *timeout)
7317 #elif defined(HAVE_RECVMMSG_CONST_TIMEOUT)
7318 /* Linux legacy glibc < 2.21 */
7319 static int swrap_recvmmsg(int s, struct mmsghdr *omsgvec, unsigned int _vlen, int flags, const struct timespec *timeout)
7320 #else
7321 /* Linux glibc >= 2.21 */
7322 static int swrap_recvmmsg(int s, struct mmsghdr *omsgvec, unsigned int _vlen, int flags, struct timespec *timeout)
7323 #endif
7324 {
7325         struct socket_info *si = find_socket_info(s);
7326 #define __SWRAP_RECVMMSG_MAX_VLEN 16
7327         struct mmsghdr msgvec[__SWRAP_RECVMMSG_MAX_VLEN] = {};
7328         struct {
7329                 struct iovec iov;
7330                 struct swrap_address from_addr;
7331                 struct swrap_address convert_addr;
7332 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7333                 size_t msg_ctrllen_filled;
7334                 size_t msg_ctrllen_left;
7335 #endif
7336         } tmp[__SWRAP_RECVMMSG_MAX_VLEN] = {};
7337         int vlen;
7338         int i;
7339         int ret;
7340         int rc;
7341         int saved_errno;
7342
7343         if (_vlen > __SWRAP_RECVMMSG_MAX_VLEN) {
7344                 vlen = __SWRAP_RECVMMSG_MAX_VLEN;
7345         } else {
7346                 vlen = _vlen;
7347         }
7348
7349         if (si == NULL) {
7350                 uint8_t *tmp_control[__SWRAP_RECVMMSG_MAX_VLEN] = { NULL, };
7351
7352                 for (i = 0; i < vlen; i++) {
7353                         struct msghdr *omsg = &omsgvec[i].msg_hdr;
7354                         struct msghdr *msg = &msgvec[i].msg_hdr;
7355
7356                         rc = swrap_recvmsg_before_unix(omsg, msg,
7357                                                        &tmp_control[i]);
7358                         if (rc < 0) {
7359                                 ret = rc;
7360                                 goto fail_libc;
7361                         }
7362                 }
7363
7364                 ret = libc_recvmmsg(s, msgvec, vlen, flags, timeout);
7365                 if (ret < 0) {
7366                         goto fail_libc;
7367                 }
7368
7369                 for (i = 0; i < ret; i++) {
7370                         omsgvec[i].msg_len = msgvec[i].msg_len;
7371                 }
7372
7373 fail_libc:
7374                 saved_errno = errno;
7375                 for (i = 0; i < vlen; i++) {
7376                         struct msghdr *omsg = &omsgvec[i].msg_hdr;
7377                         struct msghdr *msg = &msgvec[i].msg_hdr;
7378
7379                         if (i == 0 || i < ret) {
7380                                 swrap_recvmsg_after_unix(msg, &tmp_control[i], omsg, ret);
7381                         }
7382                         SAFE_FREE(tmp_control[i]);
7383                 }
7384                 errno = saved_errno;
7385
7386                 return ret;
7387         }
7388
7389         for (i = 0; i < vlen; i++) {
7390                 struct msghdr *omsg = &omsgvec[i].msg_hdr;
7391                 struct msghdr *msg = &msgvec[i].msg_hdr;
7392
7393                 tmp[i].from_addr.sa_socklen = sizeof(struct sockaddr_un);
7394                 tmp[i].convert_addr.sa_socklen = sizeof(struct sockaddr_storage);
7395
7396                 msg->msg_name = &tmp[i].from_addr.sa;              /* optional address */
7397                 msg->msg_namelen = tmp[i].from_addr.sa_socklen;    /* size of address */
7398                 msg->msg_iov = omsg->msg_iov;               /* scatter/gather array */
7399                 msg->msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
7400 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7401                 tmp[i].msg_ctrllen_filled = 0;
7402                 tmp[i].msg_ctrllen_left = omsg->msg_controllen;
7403
7404                 msg->msg_control = omsg->msg_control;       /* ancillary data, see below */
7405                 msg->msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
7406                 msg->msg_flags = omsg->msg_flags;           /* flags on received message */
7407 #endif
7408
7409                 rc = swrap_recvmsg_before(s, si, msg, &tmp[i].iov);
7410                 if (rc < 0) {
7411                         ret = rc;
7412                         goto fail_swrap;
7413                 }
7414         }
7415
7416         ret = libc_recvmmsg(s, msgvec, vlen, flags, timeout);
7417         if (ret < 0) {
7418                 goto fail_swrap;
7419         }
7420
7421         for (i = 0; i < ret; i++) {
7422                 omsgvec[i].msg_len = msgvec[i].msg_len;
7423         }
7424
7425 fail_swrap:
7426
7427         saved_errno = errno;
7428         for (i = 0; i < vlen; i++) {
7429                 struct msghdr *omsg = &omsgvec[i].msg_hdr;
7430                 struct msghdr *msg = &msgvec[i].msg_hdr;
7431
7432                 if (!(i == 0 || i < ret)) {
7433                         break;
7434                 }
7435
7436 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7437                 tmp[i].msg_ctrllen_filled += msg->msg_controllen;
7438                 tmp[i].msg_ctrllen_left -= msg->msg_controllen;
7439
7440                 if (omsg->msg_control != NULL) {
7441                         uint8_t *p;
7442
7443                         p = omsg->msg_control;
7444                         p += tmp[i].msg_ctrllen_filled;
7445
7446                         msg->msg_control = p;
7447                         msg->msg_controllen = tmp[i].msg_ctrllen_left;
7448                 } else {
7449                         msg->msg_control = NULL;
7450                         msg->msg_controllen = 0;
7451                 }
7452 #endif
7453
7454                 /*
7455                  * We convert the unix address to a IP address so we need a buffer
7456                  * which can store the address in case of SOCK_DGRAM, see below.
7457                  */
7458                 msg->msg_name = &tmp[i].convert_addr.sa;
7459                 msg->msg_namelen = tmp[i].convert_addr.sa_socklen;
7460
7461                 swrap_recvmsg_after(s, si, msg,
7462                                     &tmp[i].from_addr.sa.un,
7463                                     tmp[i].from_addr.sa_socklen,
7464                                     ret);
7465
7466 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7467                 if (omsg->msg_control != NULL) {
7468                         /* msg->msg_controllen = space left */
7469                         tmp[i].msg_ctrllen_left = msg->msg_controllen;
7470                         tmp[i].msg_ctrllen_filled = omsg->msg_controllen - tmp[i].msg_ctrllen_left;
7471                 }
7472
7473                 /* Update the original message length */
7474                 omsg->msg_controllen = tmp[i].msg_ctrllen_filled;
7475                 omsg->msg_flags = msg->msg_flags;
7476 #endif
7477                 omsg->msg_iovlen = msg->msg_iovlen;
7478
7479                 SWRAP_LOCK_SI(si);
7480
7481                 /*
7482                  * From the manpage:
7483                  *
7484                  * The  msg_name  field  points  to a caller-allocated buffer that is
7485                  * used to return the source address if the socket is unconnected.  The
7486                  * caller should set msg_namelen to the size of this buffer before this
7487                  * call; upon return from a successful call, msg_name will contain the
7488                  * length of the returned address.  If the application  does  not  need
7489                  * to know the source address, msg_name can be specified as NULL.
7490                  */
7491                 if (si->type == SOCK_STREAM) {
7492                         omsg->msg_namelen = 0;
7493                 } else if (omsg->msg_name != NULL &&
7494                            omsg->msg_namelen != 0 &&
7495                            omsg->msg_namelen >= msg->msg_namelen) {
7496                         memcpy(omsg->msg_name, msg->msg_name, msg->msg_namelen);
7497                         omsg->msg_namelen = msg->msg_namelen;
7498                 }
7499
7500                 SWRAP_UNLOCK_SI(si);
7501         }
7502         errno = saved_errno;
7503
7504         return ret;
7505 }
7506
7507 #if defined(HAVE_RECVMMSG_SSIZE_T_CONST_TIMEOUT)
7508 /* FreeBSD */
7509 ssize_t recvmmsg(int sockfd, struct mmsghdr *msgvec, size_t vlen, int flags, const struct timespec *timeout)
7510 #elif defined(HAVE_RECVMMSG_CONST_TIMEOUT)
7511 /* Linux legacy glibc < 2.21 */
7512 int recvmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, const struct timespec *timeout)
7513 #else
7514 /* Linux glibc >= 2.21 */
7515 int recvmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, struct timespec *timeout)
7516 #endif
7517 {
7518         return swrap_recvmmsg(sockfd, msgvec, vlen, flags, timeout);
7519 }
7520 #endif /* HAVE_RECVMMSG */
7521
7522 /****************************************************************************
7523  *   SENDMSG
7524  ***************************************************************************/
7525
7526 static ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags)
7527 {
7528         struct msghdr msg;
7529         struct iovec tmp;
7530         struct sockaddr_un un_addr;
7531         const struct sockaddr_un *to_un = NULL;
7532         const struct sockaddr *to = NULL;
7533         ssize_t ret;
7534         int rc;
7535         struct socket_info *si = find_socket_info(s);
7536         int bcast = 0;
7537
7538         if (!si) {
7539                 int scm_rights_pipe_fd = -1;
7540
7541                 rc = swrap_sendmsg_before_unix(omsg, &msg,
7542                                                &scm_rights_pipe_fd);
7543                 if (rc < 0) {
7544                         return rc;
7545                 }
7546                 ret = libc_sendmsg(s, &msg, flags);
7547                 return swrap_sendmsg_after_unix(&msg, ret, scm_rights_pipe_fd);
7548         }
7549
7550         ZERO_STRUCT(un_addr);
7551
7552         tmp.iov_base = NULL;
7553         tmp.iov_len = 0;
7554
7555         ZERO_STRUCT(msg);
7556
7557         SWRAP_LOCK_SI(si);
7558
7559         if (si->connected == 0) {
7560                 msg.msg_name = omsg->msg_name;             /* optional address */
7561                 msg.msg_namelen = omsg->msg_namelen;       /* size of address */
7562         }
7563         msg.msg_iov = omsg->msg_iov;               /* scatter/gather array */
7564         msg.msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
7565
7566         SWRAP_UNLOCK_SI(si);
7567
7568 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7569         if (omsg != NULL && omsg->msg_controllen > 0 && omsg->msg_control != NULL) {
7570                 uint8_t *cmbuf = NULL;
7571                 size_t cmlen = 0;
7572
7573                 rc = swrap_sendmsg_filter_cmsghdr(omsg, &cmbuf, &cmlen);
7574                 if (rc < 0) {
7575                         return rc;
7576                 }
7577
7578                 if (cmlen == 0) {
7579                         msg.msg_controllen = 0;
7580                         msg.msg_control = NULL;
7581                 } else {
7582                         msg.msg_control = cmbuf;
7583                         msg.msg_controllen = cmlen;
7584                 }
7585         }
7586         msg.msg_flags = omsg->msg_flags;           /* flags on received message */
7587 #endif
7588         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
7589         if (rc < 0) {
7590                 int saved_errno = errno;
7591 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7592                 SAFE_FREE(msg.msg_control);
7593 #endif
7594                 errno = saved_errno;
7595                 return -1;
7596         }
7597
7598         if (bcast) {
7599                 struct stat st;
7600                 unsigned int iface;
7601                 unsigned int prt = ntohs(((const struct sockaddr_in *)(const void *)to)->sin_port);
7602                 char type;
7603                 size_t i, len = 0;
7604                 uint8_t *buf;
7605                 off_t ofs = 0;
7606                 size_t avail = 0;
7607                 size_t remain;
7608                 char *swrap_dir = NULL;
7609
7610                 for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
7611                         avail += msg.msg_iov[i].iov_len;
7612                 }
7613
7614                 len = avail;
7615                 remain = avail;
7616
7617                 /* we capture it as one single packet */
7618                 buf = (uint8_t *)malloc(remain);
7619                 if (!buf) {
7620                         int saved_errno = errno;
7621 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7622                         SAFE_FREE(msg.msg_control);
7623 #endif
7624                         errno = saved_errno;
7625                         return -1;
7626                 }
7627
7628                 for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
7629                         size_t this_time = MIN(remain, (size_t)msg.msg_iov[i].iov_len);
7630                         memcpy(buf + ofs,
7631                                msg.msg_iov[i].iov_base,
7632                                this_time);
7633                         ofs += this_time;
7634                         remain -= this_time;
7635                 }
7636
7637                 type = SOCKET_TYPE_CHAR_UDP;
7638
7639                 swrap_dir = socket_wrapper_dir();
7640                 if (swrap_dir == NULL) {
7641                         int saved_errno = errno;
7642 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7643                         SAFE_FREE(msg.msg_control);
7644 #endif
7645                         SAFE_FREE(buf);
7646                         errno = saved_errno;
7647                         return -1;
7648                 }
7649
7650                 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
7651                         swrap_un_path(&un_addr, swrap_dir, type, iface, prt);
7652                         if (stat(un_addr.sun_path, &st) != 0) continue;
7653
7654                         msg.msg_name = &un_addr;           /* optional address */
7655                         msg.msg_namelen = sizeof(un_addr); /* size of address */
7656
7657                         /* ignore the any errors in broadcast sends */
7658                         libc_sendmsg(s, &msg, flags);
7659                 }
7660
7661                 SAFE_FREE(swrap_dir);
7662
7663                 SWRAP_LOCK_SI(si);
7664
7665                 swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
7666                 free(buf);
7667
7668                 SWRAP_UNLOCK_SI(si);
7669
7670                 return len;
7671         }
7672
7673         ret = libc_sendmsg(s, &msg, flags);
7674
7675         swrap_sendmsg_after(s, si, &msg, to, ret);
7676
7677 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7678         {
7679                 int saved_errno = errno;
7680                 SAFE_FREE(msg.msg_control);
7681                 errno = saved_errno;
7682         }
7683 #endif
7684
7685         return ret;
7686 }
7687
7688 ssize_t sendmsg(int s, const struct msghdr *omsg, int flags)
7689 {
7690         return swrap_sendmsg(s, omsg, flags);
7691 }
7692
7693 /****************************************************************************
7694  *   SENDMMSG
7695  ***************************************************************************/
7696
7697 #ifdef HAVE_SENDMMSG
7698 #if defined(HAVE_SENDMMSG_SSIZE_T)
7699 /* FreeBSD */
7700 static ssize_t swrap_sendmmsg(int s, struct mmsghdr *omsgvec, size_t _vlen, int flags)
7701 #else
7702 /* Linux */
7703 static int swrap_sendmmsg(int s, struct mmsghdr *omsgvec, unsigned int _vlen, int flags)
7704 #endif
7705 {
7706         struct socket_info *si = find_socket_info(s);
7707 #define __SWRAP_SENDMMSG_MAX_VLEN 16
7708         struct mmsghdr msgvec[__SWRAP_SENDMMSG_MAX_VLEN] = {};
7709         struct {
7710                 struct iovec iov;
7711                 struct sockaddr_un un_addr;
7712                 const struct sockaddr_un *to_un;
7713                 const struct sockaddr *to;
7714                 int bcast;
7715         } tmp[__SWRAP_SENDMMSG_MAX_VLEN] = {};
7716         int vlen;
7717         int i;
7718         char *swrap_dir = NULL;
7719         int connected = 0;
7720         int found_bcast = 0;
7721         int ret;
7722         int rc;
7723         int saved_errno;
7724
7725         if (_vlen > __SWRAP_SENDMMSG_MAX_VLEN) {
7726                 vlen = __SWRAP_SENDMMSG_MAX_VLEN;
7727         } else {
7728                 vlen = _vlen;
7729         }
7730
7731         if (!si) {
7732                 int scm_rights_pipe_fd[__SWRAP_SENDMMSG_MAX_VLEN];
7733
7734                 for (i = 0; i < __SWRAP_SENDMMSG_MAX_VLEN; i++) {
7735                         scm_rights_pipe_fd[i] = -1;
7736                 }
7737
7738                 for (i = 0; i < vlen; i++) {
7739                         struct msghdr *omsg = &omsgvec[i].msg_hdr;
7740                         struct msghdr *msg = &msgvec[i].msg_hdr;
7741
7742                         rc = swrap_sendmsg_before_unix(omsg, msg,
7743                                                        &scm_rights_pipe_fd[i]);
7744                         if (rc < 0) {
7745                                 ret = rc;
7746                                 goto fail_libc;
7747                         }
7748                 }
7749
7750                 ret = libc_sendmmsg(s, msgvec, vlen, flags);
7751                 if (ret < 0) {
7752                         goto fail_libc;
7753                 }
7754
7755                 for (i = 0; i < ret; i++) {
7756                         omsgvec[i].msg_len = msgvec[i].msg_len;
7757                 }
7758
7759 fail_libc:
7760                 saved_errno = errno;
7761                 for (i = 0; i < vlen; i++) {
7762                         struct msghdr *msg = &msgvec[i].msg_hdr;
7763
7764                         swrap_sendmsg_after_unix(msg, ret,
7765                                                  scm_rights_pipe_fd[i]);
7766                 }
7767                 errno = saved_errno;
7768
7769                 return ret;
7770         }
7771
7772         SWRAP_LOCK_SI(si);
7773         connected = si->connected;
7774         SWRAP_UNLOCK_SI(si);
7775
7776         for (i = 0; i < vlen; i++) {
7777                 struct msghdr *omsg = &omsgvec[i].msg_hdr;
7778                 struct msghdr *msg = &msgvec[i].msg_hdr;
7779
7780                 if (connected == 0) {
7781                         msg->msg_name = omsg->msg_name;             /* optional address */
7782                         msg->msg_namelen = omsg->msg_namelen;       /* size of address */
7783                 }
7784                 msg->msg_iov = omsg->msg_iov;               /* scatter/gather array */
7785                 msg->msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
7786
7787 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7788                 if (omsg->msg_controllen > 0 && omsg->msg_control != NULL) {
7789                         uint8_t *cmbuf = NULL;
7790                         size_t cmlen = 0;
7791
7792                         rc = swrap_sendmsg_filter_cmsghdr(omsg, &cmbuf, &cmlen);
7793                         if (rc < 0) {
7794                                 ret = rc;
7795                                 goto fail_swrap;
7796                         }
7797
7798                         if (cmlen != 0) {
7799                                 msg->msg_control = cmbuf;
7800                                 msg->msg_controllen = cmlen;
7801                         }
7802                 }
7803                 msg->msg_flags = omsg->msg_flags;           /* flags on received message */
7804 #endif
7805
7806                 rc = swrap_sendmsg_before(s, si, msg,
7807                                           &tmp[i].iov,
7808                                           &tmp[i].un_addr,
7809                                           &tmp[i].to_un,
7810                                           &tmp[i].to,
7811                                           &tmp[i].bcast);
7812                 if (rc < 0) {
7813                         ret = rc;
7814                         goto fail_swrap;
7815                 }
7816
7817                 if (tmp[i].bcast) {
7818                         found_bcast = 1;
7819                 }
7820         }
7821
7822         if (found_bcast) {
7823
7824                 swrap_dir = socket_wrapper_dir();
7825                 if (swrap_dir == NULL) {
7826                         ret = -1;
7827                         goto fail_swrap;
7828                 }
7829
7830                 for (i = 0; i < vlen; i++) {
7831                         struct msghdr *msg = &msgvec[i].msg_hdr;
7832                         struct sockaddr_un *un_addr = &tmp[i].un_addr;
7833                         const struct sockaddr *to = tmp[i].to;
7834                         struct stat st;
7835                         unsigned int iface;
7836                         unsigned int prt = ntohs(((const struct sockaddr_in *)(const void *)to)->sin_port);
7837                         char type;
7838                         size_t l, len = 0;
7839                         uint8_t *buf;
7840                         off_t ofs = 0;
7841                         size_t avail = 0;
7842                         size_t remain;
7843
7844                         for (l = 0; l < (size_t)msg->msg_iovlen; l++) {
7845                                 avail += msg->msg_iov[l].iov_len;
7846                         }
7847
7848                         len = avail;
7849                         remain = avail;
7850
7851                         /* we capture it as one single packet */
7852                         buf = (uint8_t *)malloc(remain);
7853                         if (!buf) {
7854                                 ret = -1;
7855                                 goto fail_swrap;
7856                         }
7857
7858                         for (l = 0; l < (size_t)msg->msg_iovlen; l++) {
7859                                 size_t this_time = MIN(remain, (size_t)msg->msg_iov[l].iov_len);
7860                                 memcpy(buf + ofs,
7861                                        msg->msg_iov[l].iov_base,
7862                                        this_time);
7863                                 ofs += this_time;
7864                                 remain -= this_time;
7865                         }
7866
7867                         type = SOCKET_TYPE_CHAR_UDP;
7868
7869                         for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
7870                                 swrap_un_path(un_addr, swrap_dir, type, iface, prt);
7871                                 if (stat(un_addr->sun_path, &st) != 0) continue;
7872
7873                                 msg->msg_name = un_addr;             /* optional address */
7874                                 msg->msg_namelen = sizeof(*un_addr); /* size of address */
7875
7876                                 /*
7877                                  * ignore the any errors in broadcast sends and
7878                                  * do a single sendmsg instead of sendmmsg
7879                                  */
7880                                 libc_sendmsg(s, msg, flags);
7881                         }
7882
7883                         SWRAP_LOCK_SI(si);
7884                         swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
7885                         SWRAP_UNLOCK_SI(si);
7886
7887                         SAFE_FREE(buf);
7888
7889                         msgvec[i].msg_len = len;
7890                 }
7891
7892                 ret = vlen;
7893                 goto bcast_done;
7894         }
7895
7896         ret = libc_sendmmsg(s, msgvec, vlen, flags);
7897         if (ret < 0) {
7898                 goto fail_swrap;
7899         }
7900
7901 bcast_done:
7902         for (i = 0; i < ret; i++) {
7903                 omsgvec[i].msg_len = msgvec[i].msg_len;
7904         }
7905
7906 fail_swrap:
7907         saved_errno = errno;
7908         for (i = 0; i < vlen; i++) {
7909                 struct msghdr *msg = &msgvec[i].msg_hdr;
7910
7911                 if (i == 0 || i < ret) {
7912                         swrap_sendmsg_after(s, si, msg, tmp[i].to, ret);
7913                 }
7914 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7915                 SAFE_FREE(msg->msg_control);
7916 #endif
7917         }
7918         SAFE_FREE(swrap_dir);
7919         errno = saved_errno;
7920
7921         return ret;
7922 }
7923
7924 #if defined(HAVE_SENDMMSG_SSIZE_T)
7925 /* FreeBSD */
7926 ssize_t sendmmsg(int s, struct mmsghdr *msgvec, size_t vlen, int flags)
7927 #else
7928 /* Linux */
7929 int sendmmsg(int s, struct mmsghdr *msgvec, unsigned int vlen, int flags)
7930 #endif
7931 {
7932         return swrap_sendmmsg(s, msgvec, vlen, flags);
7933 }
7934 #endif /* HAVE_SENDMMSG */
7935
7936 /****************************************************************************
7937  *   READV
7938  ***************************************************************************/
7939
7940 static ssize_t swrap_readv(int s, const struct iovec *vector, int count)
7941 {
7942         struct socket_info *si;
7943         struct msghdr msg;
7944         struct iovec tmp;
7945         struct swrap_address saddr = {
7946                 .sa_socklen = sizeof(struct sockaddr_storage)
7947         };
7948         ssize_t ret;
7949         int rc;
7950
7951         si = find_socket_info(s);
7952         if (si == NULL) {
7953                 return libc_readv(s, vector, count);
7954         }
7955
7956         tmp.iov_base = NULL;
7957         tmp.iov_len = 0;
7958
7959         ZERO_STRUCT(msg);
7960         msg.msg_name = &saddr.sa.s; /* optional address */
7961         msg.msg_namelen = saddr.sa_socklen;      /* size of address */
7962         msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
7963         msg.msg_iovlen = count;        /* # elements in msg_iov */
7964 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7965         msg.msg_control = NULL;        /* ancillary data, see below */
7966         msg.msg_controllen = 0;        /* ancillary data buffer len */
7967         msg.msg_flags = 0;             /* flags on received message */
7968 #endif
7969
7970         rc = swrap_recvmsg_before(s, si, &msg, &tmp);
7971         if (rc < 0) {
7972                 if (rc == -ENOTSOCK) {
7973                         return libc_readv(s, vector, count);
7974                 }
7975                 return -1;
7976         }
7977
7978         ret = libc_readv(s, msg.msg_iov, msg.msg_iovlen);
7979
7980         rc = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
7981         if (rc != 0) {
7982                 return rc;
7983         }
7984
7985         return ret;
7986 }
7987
7988 ssize_t readv(int s, const struct iovec *vector, int count)
7989 {
7990         return swrap_readv(s, vector, count);
7991 }
7992
7993 /****************************************************************************
7994  *   WRITEV
7995  ***************************************************************************/
7996
7997 static ssize_t swrap_writev(int s, const struct iovec *vector, int count)
7998 {
7999         struct msghdr msg;
8000         struct iovec tmp;
8001         struct sockaddr_un un_addr;
8002         ssize_t ret;
8003         int rc;
8004         struct socket_info *si = find_socket_info(s);
8005
8006         if (!si) {
8007                 return libc_writev(s, vector, count);
8008         }
8009
8010         tmp.iov_base = NULL;
8011         tmp.iov_len = 0;
8012
8013         ZERO_STRUCT(msg);
8014         msg.msg_name = NULL;           /* optional address */
8015         msg.msg_namelen = 0;           /* size of address */
8016         msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
8017         msg.msg_iovlen = count;        /* # elements in msg_iov */
8018 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
8019         msg.msg_control = NULL;        /* ancillary data, see below */
8020         msg.msg_controllen = 0;        /* ancillary data buffer len */
8021         msg.msg_flags = 0;             /* flags on received message */
8022 #endif
8023
8024         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
8025         if (rc < 0) {
8026                 if (rc == -ENOTSOCK) {
8027                         return libc_readv(s, vector, count);
8028                 }
8029                 return -1;
8030         }
8031
8032         ret = libc_writev(s, msg.msg_iov, msg.msg_iovlen);
8033
8034         swrap_sendmsg_after(s, si, &msg, NULL, ret);
8035
8036         return ret;
8037 }
8038
8039 ssize_t writev(int s, const struct iovec *vector, int count)
8040 {
8041         return swrap_writev(s, vector, count);
8042 }
8043
8044 /****************************
8045  * CLOSE
8046  ***************************/
8047
8048 static int swrap_remove_wrapper(const char *__func_name,
8049                                 int (*__close_fd_fn)(int fd),
8050                                 int fd)
8051 {
8052         struct socket_info *si = NULL;
8053         int si_index;
8054         int ret_errno = errno;
8055         int ret;
8056
8057         swrap_mutex_lock(&socket_reset_mutex);
8058
8059         si_index = find_socket_info_index(fd);
8060         if (si_index == -1) {
8061                 swrap_mutex_unlock(&socket_reset_mutex);
8062                 return __close_fd_fn(fd);
8063         }
8064
8065         swrap_log(SWRAP_LOG_TRACE, __func_name, "Remove wrapper for fd=%d", fd);
8066         reset_socket_info_index(fd);
8067
8068         si = swrap_get_socket_info(si_index);
8069
8070         swrap_mutex_lock(&first_free_mutex);
8071         SWRAP_LOCK_SI(si);
8072
8073         ret = __close_fd_fn(fd);
8074         if (ret == -1) {
8075                 ret_errno = errno;
8076         }
8077
8078         swrap_dec_refcount(si);
8079
8080         if (swrap_get_refcount(si) > 0) {
8081                 /* there are still references left */
8082                 goto out;
8083         }
8084
8085         if (si->fd_passed) {
8086                 goto set_next_free;
8087         }
8088
8089         if (si->myname.sa_socklen > 0 && si->peername.sa_socklen > 0) {
8090                 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0);
8091         }
8092
8093         if (si->myname.sa_socklen > 0 && si->peername.sa_socklen > 0) {
8094                 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0);
8095                 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0);
8096         }
8097
8098         if (si->un_addr.sun_path[0] != '\0') {
8099                 unlink(si->un_addr.sun_path);
8100         }
8101
8102 set_next_free:
8103         swrap_set_next_free(si, first_free);
8104         first_free = si_index;
8105
8106 out:
8107         SWRAP_UNLOCK_SI(si);
8108         swrap_mutex_unlock(&first_free_mutex);
8109         swrap_mutex_unlock(&socket_reset_mutex);
8110
8111         errno = ret_errno;
8112         return ret;
8113 }
8114
8115 static int swrap_noop_close(int fd)
8116 {
8117         (void)fd; /* unused */
8118         return 0;
8119 }
8120
8121 static void swrap_remove_stale(int fd)
8122 {
8123         swrap_remove_wrapper(__func__, swrap_noop_close, fd);
8124 }
8125
8126 /*
8127  * This allows socket_wrapper aware applications to
8128  * indicate that the given fd does not belong to
8129  * an inet socket.
8130  *
8131  * We already overload a lot of unrelated functions
8132  * like eventfd(), timerfd_create(), ... in order to
8133  * call swrap_remove_stale() on the returned fd, but
8134  * we'll never be able to handle all possible syscalls.
8135  *
8136  * socket_wrapper_indicate_no_inet_fd() gives them a way
8137  * to do the same.
8138  *
8139  * We don't export swrap_remove_stale() in order to
8140  * make it easier to analyze SOCKET_WRAPPER_DEBUGLEVEL=3
8141  * log files.
8142  */
8143 void socket_wrapper_indicate_no_inet_fd(int fd)
8144 {
8145         swrap_remove_wrapper(__func__, swrap_noop_close, fd);
8146 }
8147
8148 static int swrap_close(int fd)
8149 {
8150         return swrap_remove_wrapper(__func__, libc_close, fd);
8151 }
8152
8153 int close(int fd)
8154 {
8155         return swrap_close(fd);
8156 }
8157
8158 #ifdef HAVE___CLOSE_NOCANCEL
8159
8160 static int swrap___close_nocancel(int fd)
8161 {
8162         return swrap_remove_wrapper(__func__, libc___close_nocancel, fd);
8163 }
8164
8165 int __close_nocancel(int fd);
8166 int __close_nocancel(int fd)
8167 {
8168         return swrap___close_nocancel(fd);
8169 }
8170
8171 #endif /* HAVE___CLOSE_NOCANCEL */
8172
8173 /****************************
8174  * DUP
8175  ***************************/
8176
8177 static int swrap_dup(int fd)
8178 {
8179         struct socket_info *si;
8180         int dup_fd, idx;
8181
8182         idx = find_socket_info_index(fd);
8183         if (idx == -1) {
8184                 return libc_dup(fd);
8185         }
8186
8187         si = swrap_get_socket_info(idx);
8188
8189         dup_fd = libc_dup(fd);
8190         if (dup_fd == -1) {
8191                 int saved_errno = errno;
8192                 errno = saved_errno;
8193                 return -1;
8194         }
8195
8196         if ((size_t)dup_fd >= socket_fds_max) {
8197                 SWRAP_LOG(SWRAP_LOG_ERROR,
8198                           "The max socket index limit of %zu has been reached, "
8199                           "trying to add %d",
8200                           socket_fds_max,
8201                           dup_fd);
8202                 libc_close(dup_fd);
8203                 errno = EMFILE;
8204                 return -1;
8205         }
8206
8207         SWRAP_LOCK_SI(si);
8208
8209         swrap_inc_refcount(si);
8210
8211         SWRAP_UNLOCK_SI(si);
8212
8213         /* Make sure we don't have an entry for the fd */
8214         swrap_remove_stale(dup_fd);
8215
8216         set_socket_info_index(dup_fd, idx);
8217
8218         return dup_fd;
8219 }
8220
8221 int dup(int fd)
8222 {
8223         return swrap_dup(fd);
8224 }
8225
8226 /****************************
8227  * DUP2
8228  ***************************/
8229
8230 static int swrap_dup2(int fd, int newfd)
8231 {
8232         struct socket_info *si;
8233         int dup_fd, idx;
8234
8235         idx = find_socket_info_index(fd);
8236         if (idx == -1) {
8237                 return libc_dup2(fd, newfd);
8238         }
8239
8240         si = swrap_get_socket_info(idx);
8241
8242         if (fd == newfd) {
8243                 /*
8244                  * According to the manpage:
8245                  *
8246                  * "If oldfd is a valid file descriptor, and newfd has the same
8247                  * value as oldfd, then dup2() does nothing, and returns newfd."
8248                  */
8249                 return newfd;
8250         }
8251
8252         if ((size_t)newfd >= socket_fds_max) {
8253                 SWRAP_LOG(SWRAP_LOG_ERROR,
8254                           "The max socket index limit of %zu has been reached, "
8255                           "trying to add %d",
8256                           socket_fds_max,
8257                           newfd);
8258                 errno = EMFILE;
8259                 return -1;
8260         }
8261
8262         if (find_socket_info(newfd)) {
8263                 /* dup2() does an implicit close of newfd, which we
8264                  * need to emulate */
8265                 swrap_close(newfd);
8266         }
8267
8268         dup_fd = libc_dup2(fd, newfd);
8269         if (dup_fd == -1) {
8270                 int saved_errno = errno;
8271                 errno = saved_errno;
8272                 return -1;
8273         }
8274
8275         SWRAP_LOCK_SI(si);
8276
8277         swrap_inc_refcount(si);
8278
8279         SWRAP_UNLOCK_SI(si);
8280
8281         /* Make sure we don't have an entry for the fd */
8282         swrap_remove_stale(dup_fd);
8283
8284         set_socket_info_index(dup_fd, idx);
8285
8286         return dup_fd;
8287 }
8288
8289 int dup2(int fd, int newfd)
8290 {
8291         return swrap_dup2(fd, newfd);
8292 }
8293
8294 /****************************
8295  * FCNTL
8296  ***************************/
8297
8298 static int swrap_vfcntl(int fd, int cmd, va_list va)
8299 {
8300         struct socket_info *si;
8301         int rc, dup_fd, idx;
8302
8303         idx = find_socket_info_index(fd);
8304         if (idx == -1) {
8305                 return libc_vfcntl(fd, cmd, va);
8306         }
8307
8308         si = swrap_get_socket_info(idx);
8309
8310         switch (cmd) {
8311         case F_DUPFD:
8312                 dup_fd = libc_vfcntl(fd, cmd, va);
8313                 if (dup_fd == -1) {
8314                         int saved_errno = errno;
8315                         errno = saved_errno;
8316                         return -1;
8317                 }
8318
8319                 /* Make sure we don't have an entry for the fd */
8320                 swrap_remove_stale(dup_fd);
8321
8322                 if ((size_t)dup_fd >= socket_fds_max) {
8323                         SWRAP_LOG(SWRAP_LOG_ERROR,
8324                           "The max socket index limit of %zu has been reached, "
8325                           "trying to add %d",
8326                           socket_fds_max,
8327                           dup_fd);
8328                         libc_close(dup_fd);
8329                         errno = EMFILE;
8330                         return -1;
8331                 }
8332
8333                 SWRAP_LOCK_SI(si);
8334
8335                 swrap_inc_refcount(si);
8336
8337                 SWRAP_UNLOCK_SI(si);
8338
8339
8340                 set_socket_info_index(dup_fd, idx);
8341
8342                 rc = dup_fd;
8343                 break;
8344         default:
8345                 rc = libc_vfcntl(fd, cmd, va);
8346                 break;
8347         }
8348
8349         return rc;
8350 }
8351
8352 int fcntl(int fd, int cmd, ...)
8353 {
8354         va_list va;
8355         int rc;
8356
8357         va_start(va, cmd);
8358
8359         rc = swrap_vfcntl(fd, cmd, va);
8360
8361         va_end(va);
8362
8363         return rc;
8364 }
8365
8366 /****************************
8367  * EVENTFD
8368  ***************************/
8369
8370 #ifdef HAVE_EVENTFD
8371 static int swrap_eventfd(int count, int flags)
8372 {
8373         int fd;
8374
8375         fd = libc_eventfd(count, flags);
8376         if (fd != -1) {
8377                 swrap_remove_stale(fd);
8378         }
8379
8380         return fd;
8381 }
8382
8383 #ifdef HAVE_EVENTFD_UNSIGNED_INT
8384 int eventfd(unsigned int count, int flags)
8385 #else
8386 int eventfd(int count, int flags)
8387 #endif
8388 {
8389         return swrap_eventfd(count, flags);
8390 }
8391 #endif
8392
8393 #ifdef HAVE_PLEDGE
8394 int pledge(const char *promises, const char *paths[])
8395 {
8396         (void)promises; /* unused */
8397         (void)paths; /* unused */
8398
8399         return 0;
8400 }
8401 #endif /* HAVE_PLEDGE */
8402
8403 #ifdef HAVE_SYSCALL
8404 static bool swrap_is_swrap_related_syscall(long int sysno)
8405 {
8406         switch (sysno) {
8407 #ifdef SYS_close
8408         case SYS_close:
8409                 return true;
8410 #endif /* SYS_close */
8411
8412 #ifdef SYS_recvmmsg
8413         case SYS_recvmmsg:
8414                 return true;
8415 #endif /* SYS_recvmmsg */
8416
8417 #ifdef SYS_sendmmsg
8418         case SYS_sendmmsg:
8419                 return true;
8420 #endif /* SYS_sendmmsg */
8421
8422         default:
8423                 return false;
8424         }
8425 }
8426
8427 static long int swrap_syscall(long int sysno, va_list vp)
8428 {
8429         long int rc;
8430
8431         switch (sysno) {
8432 #ifdef SYS_close
8433         case SYS_close:
8434                 {
8435                         int fd = (int)va_arg(vp, int);
8436
8437                         SWRAP_LOG(SWRAP_LOG_TRACE,
8438                                   "calling swrap_close syscall %lu",
8439                                   sysno);
8440                         rc = swrap_close(fd);
8441                 }
8442                 break;
8443 #endif /* SYS_close */
8444
8445 #ifdef SYS_recvmmsg
8446         case SYS_recvmmsg:
8447                 {
8448                         int fd = (int)va_arg(vp, int);
8449                         struct mmsghdr *msgvec = va_arg(vp, struct mmsghdr *);
8450                         unsigned int vlen = va_arg(vp, unsigned int);
8451                         int flags = va_arg(vp, int);
8452                         struct timespec *timeout = va_arg(vp, struct timespec *);
8453
8454                         SWRAP_LOG(SWRAP_LOG_TRACE,
8455                                   "calling swrap_recvmmsg syscall %lu",
8456                                   sysno);
8457                         rc = swrap_recvmmsg(fd, msgvec, vlen, flags, timeout);
8458                 }
8459                 break;
8460 #endif /* SYS_recvmmsg */
8461
8462 #ifdef SYS_sendmmsg
8463         case SYS_sendmmsg:
8464                 {
8465                         int fd = (int)va_arg(vp, int);
8466                         struct mmsghdr *msgvec = va_arg(vp, struct mmsghdr *);
8467                         unsigned int vlen = va_arg(vp, unsigned int);
8468                         int flags = va_arg(vp, int);
8469
8470                         SWRAP_LOG(SWRAP_LOG_TRACE,
8471                                   "calling swrap_sendmmsg syscall %lu",
8472                                   sysno);
8473                         rc = swrap_sendmmsg(fd, msgvec, vlen, flags);
8474                 }
8475                 break;
8476 #endif /* SYS_sendmmsg */
8477
8478         default:
8479                 rc = -1;
8480                 errno = ENOSYS;
8481                 break;
8482         }
8483
8484         return rc;
8485 }
8486
8487 #ifdef HAVE_SYSCALL_INT
8488 int syscall(int sysno, ...)
8489 #else
8490 long int syscall(long int sysno, ...)
8491 #endif
8492 {
8493 #ifdef HAVE_SYSCALL_INT
8494         int rc;
8495 #else
8496         long int rc;
8497 #endif
8498         va_list va;
8499
8500         va_start(va, sysno);
8501
8502         /*
8503          * We should only handle the syscall numbers
8504          * we care about...
8505          */
8506         if (!swrap_is_swrap_related_syscall(sysno)) {
8507                 rc = libc_vsyscall(sysno, va);
8508                 va_end(va);
8509                 return rc;
8510         }
8511
8512         if (!socket_wrapper_enabled()) {
8513                 rc = libc_vsyscall(sysno, va);
8514                 va_end(va);
8515                 return rc;
8516         }
8517
8518         rc = swrap_syscall(sysno, va);
8519         va_end(va);
8520
8521         return rc;
8522 }
8523 #endif /* HAVE_SYSCALL */
8524
8525 static void swrap_thread_prepare(void)
8526 {
8527         /*
8528          * This function should only be called here!!
8529          *
8530          * We bind all symobls to avoid deadlocks of the fork is
8531          * interrupted by a signal handler using a symbol of this
8532          * library.
8533          */
8534         swrap_bind_symbol_all();
8535
8536         SWRAP_LOCK_ALL;
8537 }
8538
8539 static void swrap_thread_parent(void)
8540 {
8541         SWRAP_UNLOCK_ALL;
8542 }
8543
8544 static void swrap_thread_child(void)
8545 {
8546         SWRAP_REINIT_ALL;
8547 }
8548
8549 /****************************
8550  * CONSTRUCTOR
8551  ***************************/
8552 void swrap_constructor(void)
8553 {
8554         if (PIPE_BUF < sizeof(struct swrap_unix_scm_rights)) {
8555                 SWRAP_LOG(SWRAP_LOG_ERROR,
8556                           "PIPE_BUF=%zu < "
8557                           "sizeof(struct swrap_unix_scm_rights)=%zu\n"
8558                           "sizeof(struct swrap_unix_scm_rights_payload)=%zu "
8559                           "sizeof(struct socket_info)=%zu",
8560                           (size_t)PIPE_BUF,
8561                           sizeof(struct swrap_unix_scm_rights),
8562                           sizeof(struct swrap_unix_scm_rights_payload),
8563                           sizeof(struct socket_info));
8564                 exit(-1);
8565         }
8566
8567         SWRAP_REINIT_ALL;
8568
8569         /*
8570         * If we hold a lock and the application forks, then the child
8571         * is not able to unlock the mutex and we are in a deadlock.
8572         * This should prevent such deadlocks.
8573         */
8574         pthread_atfork(&swrap_thread_prepare,
8575                        &swrap_thread_parent,
8576                        &swrap_thread_child);
8577 }
8578
8579 /****************************
8580  * DESTRUCTOR
8581  ***************************/
8582
8583 /*
8584  * This function is called when the library is unloaded and makes sure that
8585  * sockets get closed and the unix file for the socket are unlinked.
8586  */
8587 void swrap_destructor(void)
8588 {
8589         size_t i;
8590
8591         if (socket_fds_idx != NULL) {
8592                 for (i = 0; i < socket_fds_max; ++i) {
8593                         if (socket_fds_idx[i] != -1) {
8594                                 swrap_close(i);
8595                         }
8596                 }
8597                 SAFE_FREE(socket_fds_idx);
8598         }
8599
8600         SAFE_FREE(sockets);
8601
8602         if (swrap.libc.handle != NULL
8603 #ifdef RTLD_NEXT
8604             && swrap.libc.handle != RTLD_NEXT
8605 #endif
8606                         ) {
8607                 dlclose(swrap.libc.handle);
8608         }
8609         if (swrap.libc.socket_handle
8610 #ifdef RTLD_NEXT
8611             && swrap.libc.socket_handle != RTLD_NEXT
8612 #endif
8613                         ) {
8614                 dlclose(swrap.libc.socket_handle);
8615         }
8616 }
8617
8618 #if defined(HAVE__SOCKET) && defined(HAVE__CLOSE)
8619 /*
8620  * On FreeBSD 12 (and maybe other platforms)
8621  * system libraries like libresolv prefix there
8622  * syscalls with '_' in order to always use
8623  * the symbols from libc.
8624  *
8625  * In the interaction with resolv_wrapper,
8626  * we need to inject socket wrapper into libresolv,
8627  * which means we need to private all socket
8628  * related syscalls also with the '_' prefix.
8629  *
8630  * This is tested in Samba's 'make test',
8631  * there we noticed that providing '_read',
8632  * '_open' and '_close' would cause errors, which
8633  * means we skip '_read', '_write' and
8634  * all non socket related calls without
8635  * further analyzing the problem.
8636  */
8637 #define SWRAP_SYMBOL_ALIAS(__sym, __aliassym) \
8638         extern typeof(__sym) __aliassym __attribute__ ((alias(#__sym)))
8639
8640 #ifdef HAVE_ACCEPT4
8641 SWRAP_SYMBOL_ALIAS(accept4, _accept4);
8642 #endif
8643 SWRAP_SYMBOL_ALIAS(accept, _accept);
8644 SWRAP_SYMBOL_ALIAS(bind, _bind);
8645 SWRAP_SYMBOL_ALIAS(connect, _connect);
8646 SWRAP_SYMBOL_ALIAS(dup, _dup);
8647 SWRAP_SYMBOL_ALIAS(dup2, _dup2);
8648 SWRAP_SYMBOL_ALIAS(fcntl, _fcntl);
8649 SWRAP_SYMBOL_ALIAS(getpeername, _getpeername);
8650 SWRAP_SYMBOL_ALIAS(getsockname, _getsockname);
8651 SWRAP_SYMBOL_ALIAS(getsockopt, _getsockopt);
8652 SWRAP_SYMBOL_ALIAS(ioctl, _ioctl);
8653 SWRAP_SYMBOL_ALIAS(listen, _listen);
8654 SWRAP_SYMBOL_ALIAS(readv, _readv);
8655 SWRAP_SYMBOL_ALIAS(recv, _recv);
8656 SWRAP_SYMBOL_ALIAS(recvfrom, _recvfrom);
8657 SWRAP_SYMBOL_ALIAS(recvmsg, _recvmsg);
8658 SWRAP_SYMBOL_ALIAS(send, _send);
8659 SWRAP_SYMBOL_ALIAS(sendmsg, _sendmsg);
8660 SWRAP_SYMBOL_ALIAS(sendto, _sendto);
8661 SWRAP_SYMBOL_ALIAS(setsockopt, _setsockopt);
8662 SWRAP_SYMBOL_ALIAS(socket, _socket);
8663 SWRAP_SYMBOL_ALIAS(socketpair, _socketpair);
8664 SWRAP_SYMBOL_ALIAS(writev, _writev);
8665
8666 #endif /* SOCKET_WRAPPER_EXPORT_UNDERSCORE_SYMBOLS */