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