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