swrap: Suppress intentional fall through warning
[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                     return -1;
3178                 }
3179
3180                 memset(&in, 0, sizeof(in));
3181                 in.sin_family = AF_INET;
3182                 in.sin_addr.s_addr = htonl(127<<24 |
3183                                            socket_wrapper_default_iface());
3184
3185                 si->myname = (struct swrap_address) {
3186                         .sa_socklen = sizeof(in),
3187                 };
3188                 memcpy(&si->myname.sa.in, &in, si->myname.sa_socklen);
3189                 break;
3190         }
3191 #ifdef HAVE_IPV6
3192         case AF_INET6: {
3193                 struct sockaddr_in6 in6;
3194
3195                 if (si->family != family) {
3196                         errno = ENETUNREACH;
3197                         return -1;
3198                 }
3199
3200                 switch (si->type) {
3201                 case SOCK_STREAM:
3202                         type = SOCKET_TYPE_CHAR_TCP_V6;
3203                         break;
3204                 case SOCK_DGRAM:
3205                         type = SOCKET_TYPE_CHAR_UDP_V6;
3206                         break;
3207                 default:
3208                         errno = ESOCKTNOSUPPORT;
3209                         return -1;
3210                 }
3211
3212                 memset(&in6, 0, sizeof(in6));
3213                 in6.sin6_family = AF_INET6;
3214                 in6.sin6_addr = *swrap_ipv6();
3215                 in6.sin6_addr.s6_addr[15] = socket_wrapper_default_iface();
3216
3217                 si->myname = (struct swrap_address) {
3218                         .sa_socklen = sizeof(in6),
3219                 };
3220                 memcpy(&si->myname.sa.in6, &in6, si->myname.sa_socklen);
3221                 break;
3222         }
3223 #endif
3224         default:
3225                 errno = ESOCKTNOSUPPORT;
3226                 return -1;
3227         }
3228
3229         if (autobind_start > 60000) {
3230                 autobind_start = 10000;
3231         }
3232
3233         for (i = 0; i < SOCKET_MAX_SOCKETS; i++) {
3234                 port = autobind_start + i;
3235                 snprintf(un_addr.sa.un.sun_path, sizeof(un_addr.sa.un.sun_path),
3236                          "%s/"SOCKET_FORMAT, socket_wrapper_dir(),
3237                          type, socket_wrapper_default_iface(), port);
3238                 if (stat(un_addr.sa.un.sun_path, &st) == 0) continue;
3239
3240                 ret = libc_bind(fd, &un_addr.sa.s, un_addr.sa_socklen);
3241                 if (ret == -1) {
3242                         return ret;
3243                 }
3244
3245                 si->un_addr = un_addr.sa.un;
3246
3247                 si->bound = 1;
3248                 autobind_start = port + 1;
3249                 break;
3250         }
3251         if (i == SOCKET_MAX_SOCKETS) {
3252                 SWRAP_LOG(SWRAP_LOG_ERROR, "Too many open unix sockets (%u) for "
3253                                            "interface "SOCKET_FORMAT,
3254                                            SOCKET_MAX_SOCKETS,
3255                                            type,
3256                                            socket_wrapper_default_iface(),
3257                                            0);
3258                 errno = ENFILE;
3259                 return -1;
3260         }
3261
3262         si->family = family;
3263         set_port(si->family, port, &si->myname);
3264
3265         return 0;
3266 }
3267
3268 /****************************************************************************
3269  *   CONNECT
3270  ***************************************************************************/
3271
3272 static int swrap_connect(int s, const struct sockaddr *serv_addr,
3273                          socklen_t addrlen)
3274 {
3275         int ret;
3276         struct swrap_address un_addr = {
3277                 .sa_socklen = sizeof(struct sockaddr_un),
3278         };
3279         struct socket_info *si = find_socket_info(s);
3280         int bcast = 0;
3281
3282         if (!si) {
3283                 return libc_connect(s, serv_addr, addrlen);
3284         }
3285
3286         if (si->bound == 0) {
3287                 ret = swrap_auto_bind(s, si, serv_addr->sa_family);
3288                 if (ret == -1) {
3289                         return -1;
3290                 }
3291         }
3292
3293         if (si->family != serv_addr->sa_family) {
3294                 errno = EINVAL;
3295                 return -1;
3296         }
3297
3298         ret = sockaddr_convert_to_un(si, serv_addr,
3299                                      addrlen, &un_addr.sa.un, 0, &bcast);
3300         if (ret == -1) {
3301                 return -1;
3302         }
3303
3304         if (bcast) {
3305                 errno = ENETUNREACH;
3306                 return -1;
3307         }
3308
3309         if (si->type == SOCK_DGRAM) {
3310                 si->defer_connect = 1;
3311                 ret = 0;
3312         } else {
3313                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0);
3314
3315                 ret = libc_connect(s,
3316                                    &un_addr.sa.s,
3317                                    un_addr.sa_socklen);
3318         }
3319
3320         SWRAP_LOG(SWRAP_LOG_TRACE,
3321                   "connect() path=%s, fd=%d",
3322                   un_addr.sa.un.sun_path, s);
3323
3324
3325         /* to give better errors */
3326         if (ret == -1 && errno == ENOENT) {
3327                 errno = EHOSTUNREACH;
3328         }
3329
3330         if (ret == 0) {
3331                 si->peername = (struct swrap_address) {
3332                         .sa_socklen = addrlen,
3333                 };
3334
3335                 memcpy(&si->peername.sa.ss, serv_addr, addrlen);
3336                 si->connected = 1;
3337
3338                 /*
3339                  * When we connect() on a socket than we have to bind the
3340                  * outgoing connection on the interface we use for the
3341                  * transport. We already bound it on the right interface
3342                  * but here we have to update the name so getsockname()
3343                  * returns correct information.
3344                  */
3345                 if (si->bindname.sa_socklen > 0) {
3346                         si->myname = (struct swrap_address) {
3347                                 .sa_socklen = si->bindname.sa_socklen,
3348                         };
3349
3350                         memcpy(&si->myname.sa.ss,
3351                                &si->bindname.sa.ss,
3352                                si->bindname.sa_socklen);
3353
3354                         /* Cleanup bindname */
3355                         si->bindname = (struct swrap_address) {
3356                                 .sa_socklen = 0,
3357                         };
3358                 }
3359
3360                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0);
3361                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0);
3362         } else {
3363                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0);
3364         }
3365
3366         return ret;
3367 }
3368
3369 int connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen)
3370 {
3371         return swrap_connect(s, serv_addr, addrlen);
3372 }
3373
3374 /****************************************************************************
3375  *   BIND
3376  ***************************************************************************/
3377
3378 static int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
3379 {
3380         int ret;
3381         struct swrap_address un_addr = {
3382                 .sa_socklen = sizeof(struct sockaddr_un),
3383         };
3384         struct socket_info *si = find_socket_info(s);
3385         int bind_error = 0;
3386 #if 0 /* FIXME */
3387         bool in_use;
3388 #endif
3389
3390         if (!si) {
3391                 return libc_bind(s, myaddr, addrlen);
3392         }
3393
3394         switch (si->family) {
3395         case AF_INET: {
3396                 const struct sockaddr_in *sin;
3397                 if (addrlen < sizeof(struct sockaddr_in)) {
3398                         bind_error = EINVAL;
3399                         break;
3400                 }
3401
3402                 sin = (const struct sockaddr_in *)(const void *)myaddr;
3403
3404                 if (sin->sin_family != AF_INET) {
3405                         bind_error = EAFNOSUPPORT;
3406                 }
3407
3408                 /* special case for AF_UNSPEC */
3409                 if (sin->sin_family == AF_UNSPEC &&
3410                     (sin->sin_addr.s_addr == htonl(INADDR_ANY)))
3411                 {
3412                         bind_error = 0;
3413                 }
3414
3415                 break;
3416         }
3417 #ifdef HAVE_IPV6
3418         case AF_INET6: {
3419                 const struct sockaddr_in6 *sin6;
3420                 if (addrlen < sizeof(struct sockaddr_in6)) {
3421                         bind_error = EINVAL;
3422                         break;
3423                 }
3424
3425                 sin6 = (const struct sockaddr_in6 *)(const void *)myaddr;
3426
3427                 if (sin6->sin6_family != AF_INET6) {
3428                         bind_error = EAFNOSUPPORT;
3429                 }
3430
3431                 break;
3432         }
3433 #endif
3434         default:
3435                 bind_error = EINVAL;
3436                 break;
3437         }
3438
3439         if (bind_error != 0) {
3440                 errno = bind_error;
3441                 return -1;
3442         }
3443
3444 #if 0 /* FIXME */
3445         in_use = check_addr_port_in_use(myaddr, addrlen);
3446         if (in_use) {
3447                 errno = EADDRINUSE;
3448                 return -1;
3449         }
3450 #endif
3451
3452         si->myname.sa_socklen = addrlen;
3453         memcpy(&si->myname.sa.ss, myaddr, addrlen);
3454
3455         ret = sockaddr_convert_to_un(si,
3456                                      myaddr,
3457                                      addrlen,
3458                                      &un_addr.sa.un,
3459                                      1,
3460                                      &si->bcast);
3461         if (ret == -1) {
3462                 return -1;
3463         }
3464
3465         unlink(un_addr.sa.un.sun_path);
3466
3467         ret = libc_bind(s, &un_addr.sa.s, un_addr.sa_socklen);
3468
3469         SWRAP_LOG(SWRAP_LOG_TRACE,
3470                   "bind() path=%s, fd=%d",
3471                   un_addr.sa.un.sun_path, s);
3472
3473         if (ret == 0) {
3474                 si->bound = 1;
3475         }
3476
3477         return ret;
3478 }
3479
3480 int bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
3481 {
3482         return swrap_bind(s, myaddr, addrlen);
3483 }
3484
3485 /****************************************************************************
3486  *   BINDRESVPORT
3487  ***************************************************************************/
3488
3489 #ifdef HAVE_BINDRESVPORT
3490 static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen);
3491
3492 static int swrap_bindresvport_sa(int sd, struct sockaddr *sa)
3493 {
3494         struct swrap_address myaddr = {
3495                 .sa_socklen = sizeof(struct sockaddr_storage),
3496         };
3497         socklen_t salen;
3498         static uint16_t port;
3499         uint16_t i;
3500         int rc = -1;
3501         int af;
3502
3503 #define SWRAP_STARTPORT 600
3504 #define SWRAP_ENDPORT (IPPORT_RESERVED - 1)
3505 #define SWRAP_NPORTS (SWRAP_ENDPORT - SWRAP_STARTPORT + 1)
3506
3507         if (port == 0) {
3508                 port = (getpid() % SWRAP_NPORTS) + SWRAP_STARTPORT;
3509         }
3510
3511         if (sa == NULL) {
3512                 salen = myaddr.sa_socklen;
3513                 sa = &myaddr.sa.s;
3514
3515                 rc = swrap_getsockname(sd, &myaddr.sa.s, &salen);
3516                 if (rc < 0) {
3517                         return -1;
3518                 }
3519
3520                 af = sa->sa_family;
3521                 memset(&myaddr.sa.ss, 0, salen);
3522         } else {
3523                 af = sa->sa_family;
3524         }
3525
3526         for (i = 0; i < SWRAP_NPORTS; i++, port++) {
3527                 switch(af) {
3528                 case AF_INET: {
3529                         struct sockaddr_in *sinp = (struct sockaddr_in *)(void *)sa;
3530
3531                         salen = sizeof(struct sockaddr_in);
3532                         sinp->sin_port = htons(port);
3533                         break;
3534                 }
3535                 case AF_INET6: {
3536                         struct sockaddr_in6 *sin6p = (struct sockaddr_in6 *)(void *)sa;
3537
3538                         salen = sizeof(struct sockaddr_in6);
3539                         sin6p->sin6_port = htons(port);
3540                         break;
3541                 }
3542                 default:
3543                         errno = EAFNOSUPPORT;
3544                         return -1;
3545                 }
3546                 sa->sa_family = af;
3547
3548                 if (port > SWRAP_ENDPORT) {
3549                         port = SWRAP_STARTPORT;
3550                 }
3551
3552                 rc = swrap_bind(sd, (struct sockaddr *)sa, salen);
3553                 if (rc == 0 || errno != EADDRINUSE) {
3554                         break;
3555                 }
3556         }
3557
3558         return rc;
3559 }
3560
3561 int bindresvport(int sockfd, struct sockaddr_in *sinp)
3562 {
3563         return swrap_bindresvport_sa(sockfd, (struct sockaddr *)sinp);
3564 }
3565 #endif
3566
3567 /****************************************************************************
3568  *   LISTEN
3569  ***************************************************************************/
3570
3571 static int swrap_listen(int s, int backlog)
3572 {
3573         int ret;
3574         struct socket_info *si = find_socket_info(s);
3575
3576         if (!si) {
3577                 return libc_listen(s, backlog);
3578         }
3579
3580         if (si->bound == 0) {
3581                 ret = swrap_auto_bind(s, si, si->family);
3582                 if (ret == -1) {
3583                         errno = EADDRINUSE;
3584                         return ret;
3585                 }
3586         }
3587
3588         ret = libc_listen(s, backlog);
3589
3590         return ret;
3591 }
3592
3593 int listen(int s, int backlog)
3594 {
3595         return swrap_listen(s, backlog);
3596 }
3597
3598 /****************************************************************************
3599  *   FOPEN
3600  ***************************************************************************/
3601
3602 static FILE *swrap_fopen(const char *name, const char *mode)
3603 {
3604         FILE *fp;
3605
3606         fp = libc_fopen(name, mode);
3607         if (fp != NULL) {
3608                 int fd = fileno(fp);
3609
3610                 swrap_remove_stale(fd);
3611         }
3612
3613         return fp;
3614 }
3615
3616 FILE *fopen(const char *name, const char *mode)
3617 {
3618         return swrap_fopen(name, mode);
3619 }
3620
3621 /****************************************************************************
3622  *   FOPEN64
3623  ***************************************************************************/
3624
3625 #ifdef HAVE_FOPEN64
3626 static FILE *swrap_fopen64(const char *name, const char *mode)
3627 {
3628         FILE *fp;
3629
3630         fp = libc_fopen64(name, mode);
3631         if (fp != NULL) {
3632                 int fd = fileno(fp);
3633
3634                 swrap_remove_stale(fd);
3635         }
3636
3637         return fp;
3638 }
3639
3640 FILE *fopen64(const char *name, const char *mode)
3641 {
3642         return swrap_fopen64(name, mode);
3643 }
3644 #endif /* HAVE_FOPEN64 */
3645
3646 /****************************************************************************
3647  *   OPEN
3648  ***************************************************************************/
3649
3650 static int swrap_vopen(const char *pathname, int flags, va_list ap)
3651 {
3652         int ret;
3653
3654         ret = libc_vopen(pathname, flags, ap);
3655         if (ret != -1) {
3656                 /*
3657                  * There are methods for closing descriptors (libc-internal code
3658                  * paths, direct syscalls) which close descriptors in ways that
3659                  * we can't intercept, so try to recover when we notice that
3660                  * that's happened
3661                  */
3662                 swrap_remove_stale(ret);
3663         }
3664         return ret;
3665 }
3666
3667 int open(const char *pathname, int flags, ...)
3668 {
3669         va_list ap;
3670         int fd;
3671
3672         va_start(ap, flags);
3673         fd = swrap_vopen(pathname, flags, ap);
3674         va_end(ap);
3675
3676         return fd;
3677 }
3678
3679 /****************************************************************************
3680  *   OPEN64
3681  ***************************************************************************/
3682
3683 #ifdef HAVE_OPEN64
3684 static int swrap_vopen64(const char *pathname, int flags, va_list ap)
3685 {
3686         int ret;
3687
3688         ret = libc_vopen64(pathname, flags, ap);
3689         if (ret != -1) {
3690                 /*
3691                  * There are methods for closing descriptors (libc-internal code
3692                  * paths, direct syscalls) which close descriptors in ways that
3693                  * we can't intercept, so try to recover when we notice that
3694                  * that's happened
3695                  */
3696                 swrap_remove_stale(ret);
3697         }
3698         return ret;
3699 }
3700
3701 int open64(const char *pathname, int flags, ...)
3702 {
3703         va_list ap;
3704         int fd;
3705
3706         va_start(ap, flags);
3707         fd = swrap_vopen64(pathname, flags, ap);
3708         va_end(ap);
3709
3710         return fd;
3711 }
3712 #endif /* HAVE_OPEN64 */
3713
3714 /****************************************************************************
3715  *   OPENAT
3716  ***************************************************************************/
3717
3718 static int swrap_vopenat(int dirfd, const char *path, int flags, va_list ap)
3719 {
3720         int ret;
3721
3722         ret = libc_vopenat(dirfd, path, flags, ap);
3723         if (ret != -1) {
3724                 /*
3725                  * There are methods for closing descriptors (libc-internal code
3726                  * paths, direct syscalls) which close descriptors in ways that
3727                  * we can't intercept, so try to recover when we notice that
3728                  * that's happened
3729                  */
3730                 swrap_remove_stale(ret);
3731         }
3732
3733         return ret;
3734 }
3735
3736 int openat(int dirfd, const char *path, int flags, ...)
3737 {
3738         va_list ap;
3739         int fd;
3740
3741         va_start(ap, flags);
3742         fd = swrap_vopenat(dirfd, path, flags, ap);
3743         va_end(ap);
3744
3745         return fd;
3746 }
3747
3748 /****************************************************************************
3749  *   GETPEERNAME
3750  ***************************************************************************/
3751
3752 static int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
3753 {
3754         struct socket_info *si = find_socket_info(s);
3755         socklen_t len;
3756
3757         if (!si) {
3758                 return libc_getpeername(s, name, addrlen);
3759         }
3760
3761         if (si->peername.sa_socklen == 0)
3762         {
3763                 errno = ENOTCONN;
3764                 return -1;
3765         }
3766
3767         len = MIN(*addrlen, si->peername.sa_socklen);
3768         if (len == 0) {
3769                 return 0;
3770         }
3771
3772         memcpy(name, &si->peername.sa.ss, len);
3773         *addrlen = si->peername.sa_socklen;
3774
3775         return 0;
3776 }
3777
3778 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3779 int getpeername(int s, struct sockaddr *name, Psocklen_t addrlen)
3780 #else
3781 int getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
3782 #endif
3783 {
3784         return swrap_getpeername(s, name, (socklen_t *)addrlen);
3785 }
3786
3787 /****************************************************************************
3788  *   GETSOCKNAME
3789  ***************************************************************************/
3790
3791 static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
3792 {
3793         struct socket_info *si = find_socket_info(s);
3794         socklen_t len;
3795
3796         if (!si) {
3797                 return libc_getsockname(s, name, addrlen);
3798         }
3799
3800         len = MIN(*addrlen, si->myname.sa_socklen);
3801         if (len == 0) {
3802                 return 0;
3803         }
3804
3805         memcpy(name, &si->myname.sa.ss, len);
3806         *addrlen = si->myname.sa_socklen;
3807
3808         return 0;
3809 }
3810
3811 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3812 int getsockname(int s, struct sockaddr *name, Psocklen_t addrlen)
3813 #else
3814 int getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
3815 #endif
3816 {
3817         return swrap_getsockname(s, name, (socklen_t *)addrlen);
3818 }
3819
3820 /****************************************************************************
3821  *   GETSOCKOPT
3822  ***************************************************************************/
3823
3824 #ifndef SO_PROTOCOL
3825 # ifdef SO_PROTOTYPE /* The Solaris name */
3826 #  define SO_PROTOCOL SO_PROTOTYPE
3827 # endif /* SO_PROTOTYPE */
3828 #endif /* SO_PROTOCOL */
3829
3830 static int swrap_getsockopt(int s, int level, int optname,
3831                             void *optval, socklen_t *optlen)
3832 {
3833         struct socket_info *si = find_socket_info(s);
3834
3835         if (!si) {
3836                 return libc_getsockopt(s,
3837                                        level,
3838                                        optname,
3839                                        optval,
3840                                        optlen);
3841         }
3842
3843         if (level == SOL_SOCKET) {
3844                 switch (optname) {
3845 #ifdef SO_DOMAIN
3846                 case SO_DOMAIN:
3847                         if (optval == NULL || optlen == NULL ||
3848                             *optlen < (socklen_t)sizeof(int)) {
3849                                 errno = EINVAL;
3850                                 return -1;
3851                         }
3852
3853                         *optlen = sizeof(int);
3854                         *(int *)optval = si->family;
3855                         return 0;
3856 #endif /* SO_DOMAIN */
3857
3858 #ifdef SO_PROTOCOL
3859                 case SO_PROTOCOL:
3860                         if (optval == NULL || optlen == NULL ||
3861                             *optlen < (socklen_t)sizeof(int)) {
3862                                 errno = EINVAL;
3863                                 return -1;
3864                         }
3865
3866                         *optlen = sizeof(int);
3867                         *(int *)optval = si->protocol;
3868                         return 0;
3869 #endif /* SO_PROTOCOL */
3870                 case SO_TYPE:
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->type;
3879                         return 0;
3880                 default:
3881                         return libc_getsockopt(s,
3882                                                level,
3883                                                optname,
3884                                                optval,
3885                                                optlen);
3886                 }
3887         } else if (level == IPPROTO_TCP) {
3888                 switch (optname) {
3889 #ifdef TCP_NODELAY
3890                 case TCP_NODELAY:
3891                         /*
3892                          * This enables sending packets directly out over TCP.
3893                          * As a unix socket is doing that any way, report it as
3894                          * enabled.
3895                          */
3896                         if (optval == NULL || optlen == NULL ||
3897                             *optlen < (socklen_t)sizeof(int)) {
3898                                 errno = EINVAL;
3899                                 return -1;
3900                         }
3901
3902                         *optlen = sizeof(int);
3903                         *(int *)optval = si->tcp_nodelay;
3904
3905                         return 0;
3906 #endif /* TCP_NODELAY */
3907                 default:
3908                         break;
3909                 }
3910         }
3911
3912         errno = ENOPROTOOPT;
3913         return -1;
3914 }
3915
3916 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3917 int getsockopt(int s, int level, int optname, void *optval, Psocklen_t optlen)
3918 #else
3919 int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
3920 #endif
3921 {
3922         return swrap_getsockopt(s, level, optname, optval, (socklen_t *)optlen);
3923 }
3924
3925 /****************************************************************************
3926  *   SETSOCKOPT
3927  ***************************************************************************/
3928
3929 static int swrap_setsockopt(int s, int level, int optname,
3930                             const void *optval, socklen_t optlen)
3931 {
3932         struct socket_info *si = find_socket_info(s);
3933
3934         if (!si) {
3935                 return libc_setsockopt(s,
3936                                        level,
3937                                        optname,
3938                                        optval,
3939                                        optlen);
3940         }
3941
3942         if (level == SOL_SOCKET) {
3943                 return libc_setsockopt(s,
3944                                        level,
3945                                        optname,
3946                                        optval,
3947                                        optlen);
3948         } else if (level == IPPROTO_TCP) {
3949                 switch (optname) {
3950 #ifdef TCP_NODELAY
3951                 case TCP_NODELAY: {
3952                         int i;
3953
3954                         /*
3955                          * This enables sending packets directly out over TCP.
3956                          * A unix socket is doing that any way.
3957                          */
3958                         if (optval == NULL || optlen == 0 ||
3959                             optlen < (socklen_t)sizeof(int)) {
3960                                 errno = EINVAL;
3961                                 return -1;
3962                         }
3963
3964                         i = *discard_const_p(int, optval);
3965                         if (i != 0 && i != 1) {
3966                                 errno = EINVAL;
3967                                 return -1;
3968                         }
3969                         si->tcp_nodelay = i;
3970
3971                         return 0;
3972                 }
3973 #endif /* TCP_NODELAY */
3974                 default:
3975                         break;
3976                 }
3977         }
3978
3979         switch (si->family) {
3980         case AF_INET:
3981                 if (level == IPPROTO_IP) {
3982 #ifdef IP_PKTINFO
3983                         if (optname == IP_PKTINFO) {
3984                                 si->pktinfo = AF_INET;
3985                         }
3986 #endif /* IP_PKTINFO */
3987                 }
3988                 return 0;
3989 #ifdef HAVE_IPV6
3990         case AF_INET6:
3991                 if (level == IPPROTO_IPV6) {
3992 #ifdef IPV6_RECVPKTINFO
3993                         if (optname == IPV6_RECVPKTINFO) {
3994                                 si->pktinfo = AF_INET6;
3995                         }
3996 #endif /* IPV6_PKTINFO */
3997                 }
3998                 return 0;
3999 #endif
4000         default:
4001                 errno = ENOPROTOOPT;
4002                 return -1;
4003         }
4004 }
4005
4006 int setsockopt(int s, int level, int optname,
4007                const void *optval, socklen_t optlen)
4008 {
4009         return swrap_setsockopt(s, level, optname, optval, optlen);
4010 }
4011
4012 /****************************************************************************
4013  *   IOCTL
4014  ***************************************************************************/
4015
4016 static int swrap_vioctl(int s, unsigned long int r, va_list va)
4017 {
4018         struct socket_info *si = find_socket_info(s);
4019         va_list ap;
4020         int value;
4021         int rc;
4022
4023         if (!si) {
4024                 return libc_vioctl(s, r, va);
4025         }
4026
4027         va_copy(ap, va);
4028
4029         rc = libc_vioctl(s, r, va);
4030
4031         switch (r) {
4032         case FIONREAD:
4033                 value = *((int *)va_arg(ap, int *));
4034
4035                 if (rc == -1 && errno != EAGAIN && errno != ENOBUFS) {
4036                         swrap_pcap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
4037                 } else if (value == 0) { /* END OF FILE */
4038                         swrap_pcap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
4039                 }
4040                 break;
4041         }
4042
4043         va_end(ap);
4044
4045         return rc;
4046 }
4047
4048 #ifdef HAVE_IOCTL_INT
4049 int ioctl(int s, int r, ...)
4050 #else
4051 int ioctl(int s, unsigned long int r, ...)
4052 #endif
4053 {
4054         va_list va;
4055         int rc;
4056
4057         va_start(va, r);
4058
4059         rc = swrap_vioctl(s, (unsigned long int) r, va);
4060
4061         va_end(va);
4062
4063         return rc;
4064 }
4065
4066 /*****************
4067  * CMSG
4068  *****************/
4069
4070 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4071
4072 #ifndef CMSG_ALIGN
4073 # ifdef _ALIGN /* BSD */
4074 #define CMSG_ALIGN _ALIGN
4075 # else
4076 #define CMSG_ALIGN(len) (((len) + sizeof(size_t) - 1) & ~(sizeof(size_t) - 1))
4077 # endif /* _ALIGN */
4078 #endif /* CMSG_ALIGN */
4079
4080 /**
4081  * @brief Add a cmsghdr to a msghdr.
4082  *
4083  * This is an function to add any type of cmsghdr. It will operate on the
4084  * msg->msg_control and msg->msg_controllen you pass in by adapting them to
4085  * the buffer position after the added cmsg element. Hence, this function is
4086  * intended to be used with an intermediate msghdr and not on the original
4087  * one handed in by the client.
4088  *
4089  * @param[in]  msg      The msghdr to which to add the cmsg.
4090  *
4091  * @param[in]  level    The cmsg level to set.
4092  *
4093  * @param[in]  type     The cmsg type to set.
4094  *
4095  * @param[in]  data     The cmsg data to set.
4096  *
4097  * @param[in]  len      the length of the data to set.
4098  */
4099 static void swrap_msghdr_add_cmsghdr(struct msghdr *msg,
4100                                      int level,
4101                                      int type,
4102                                      const void *data,
4103                                      size_t len)
4104 {
4105         size_t cmlen = CMSG_LEN(len);
4106         size_t cmspace = CMSG_SPACE(len);
4107         uint8_t cmbuf[cmspace];
4108         void *cast_ptr = (void *)cmbuf;
4109         struct cmsghdr *cm = (struct cmsghdr *)cast_ptr;
4110         uint8_t *p;
4111
4112         memset(cmbuf, 0, cmspace);
4113
4114         if (msg->msg_controllen < cmlen) {
4115                 cmlen = msg->msg_controllen;
4116                 msg->msg_flags |= MSG_CTRUNC;
4117         }
4118
4119         if (msg->msg_controllen < cmspace) {
4120                 cmspace = msg->msg_controllen;
4121         }
4122
4123         /*
4124          * We copy the full input data into an intermediate cmsghdr first
4125          * in order to more easily cope with truncation.
4126          */
4127         cm->cmsg_len = cmlen;
4128         cm->cmsg_level = level;
4129         cm->cmsg_type = type;
4130         memcpy(CMSG_DATA(cm), data, len);
4131
4132         /*
4133          * We now copy the possibly truncated buffer.
4134          * We copy cmlen bytes, but consume cmspace bytes,
4135          * leaving the possible padding uninitialiazed.
4136          */
4137         p = (uint8_t *)msg->msg_control;
4138         memcpy(p, cm, cmlen);
4139         p += cmspace;
4140         msg->msg_control = p;
4141         msg->msg_controllen -= cmspace;
4142
4143         return;
4144 }
4145
4146 static int swrap_msghdr_add_pktinfo(struct socket_info *si,
4147                                     struct msghdr *msg)
4148 {
4149         /* Add packet info */
4150         switch (si->pktinfo) {
4151 #if defined(IP_PKTINFO) && (defined(HAVE_STRUCT_IN_PKTINFO) || defined(IP_RECVDSTADDR))
4152         case AF_INET: {
4153                 struct sockaddr_in *sin;
4154 #if defined(HAVE_STRUCT_IN_PKTINFO)
4155                 struct in_pktinfo pkt;
4156 #elif defined(IP_RECVDSTADDR)
4157                 struct in_addr pkt;
4158 #endif
4159
4160                 if (si->bindname.sa_socklen == sizeof(struct sockaddr_in)) {
4161                         sin = &si->bindname.sa.in;
4162                 } else {
4163                         if (si->myname.sa_socklen != sizeof(struct sockaddr_in)) {
4164                                 return 0;
4165                         }
4166                         sin = &si->myname.sa.in;
4167                 }
4168
4169                 ZERO_STRUCT(pkt);
4170
4171 #if defined(HAVE_STRUCT_IN_PKTINFO)
4172                 pkt.ipi_ifindex = socket_wrapper_default_iface();
4173                 pkt.ipi_addr.s_addr = sin->sin_addr.s_addr;
4174 #elif defined(IP_RECVDSTADDR)
4175                 pkt = sin->sin_addr;
4176 #endif
4177
4178                 swrap_msghdr_add_cmsghdr(msg, IPPROTO_IP, IP_PKTINFO,
4179                                          &pkt, sizeof(pkt));
4180
4181                 break;
4182         }
4183 #endif /* IP_PKTINFO */
4184 #if defined(HAVE_IPV6)
4185         case AF_INET6: {
4186 #if defined(IPV6_PKTINFO) && defined(HAVE_STRUCT_IN6_PKTINFO)
4187                 struct sockaddr_in6 *sin6;
4188                 struct in6_pktinfo pkt6;
4189
4190                 if (si->bindname.sa_socklen == sizeof(struct sockaddr_in6)) {
4191                         sin6 = &si->bindname.sa.in6;
4192                 } else {
4193                         if (si->myname.sa_socklen != sizeof(struct sockaddr_in6)) {
4194                                 return 0;
4195                         }
4196                         sin6 = &si->myname.sa.in6;
4197                 }
4198
4199                 ZERO_STRUCT(pkt6);
4200
4201                 pkt6.ipi6_ifindex = socket_wrapper_default_iface();
4202                 pkt6.ipi6_addr = sin6->sin6_addr;
4203
4204                 swrap_msghdr_add_cmsghdr(msg, IPPROTO_IPV6, IPV6_PKTINFO,
4205                                         &pkt6, sizeof(pkt6));
4206 #endif /* HAVE_STRUCT_IN6_PKTINFO */
4207
4208                 break;
4209         }
4210 #endif /* IPV6_PKTINFO */
4211         default:
4212                 return -1;
4213         }
4214
4215         return 0;
4216 }
4217
4218 static int swrap_msghdr_add_socket_info(struct socket_info *si,
4219                                         struct msghdr *omsg)
4220 {
4221         int rc = 0;
4222
4223         if (si->pktinfo > 0) {
4224                 rc = swrap_msghdr_add_pktinfo(si, omsg);
4225         }
4226
4227         return rc;
4228 }
4229
4230 static int swrap_sendmsg_copy_cmsg(struct cmsghdr *cmsg,
4231                                    uint8_t **cm_data,
4232                                    size_t *cm_data_space);
4233 static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr *cmsg,
4234                                             uint8_t **cm_data,
4235                                             size_t *cm_data_space);
4236
4237 static int swrap_sendmsg_filter_cmsghdr(struct msghdr *msg,
4238                                         uint8_t **cm_data,
4239                                         size_t *cm_data_space) {
4240         struct cmsghdr *cmsg;
4241         int rc = -1;
4242
4243         /* Nothing to do */
4244         if (msg->msg_controllen == 0 || msg->msg_control == NULL) {
4245                 return 0;
4246         }
4247
4248         for (cmsg = CMSG_FIRSTHDR(msg);
4249              cmsg != NULL;
4250              cmsg = CMSG_NXTHDR(msg, cmsg)) {
4251                 switch (cmsg->cmsg_level) {
4252                 case IPPROTO_IP:
4253                         rc = swrap_sendmsg_filter_cmsg_socket(cmsg,
4254                                                               cm_data,
4255                                                               cm_data_space);
4256                         break;
4257                 default:
4258                         rc = swrap_sendmsg_copy_cmsg(cmsg,
4259                                                      cm_data,
4260                                                      cm_data_space);
4261                         break;
4262                 }
4263         }
4264
4265         return rc;
4266 }
4267
4268 static int swrap_sendmsg_copy_cmsg(struct cmsghdr *cmsg,
4269                                    uint8_t **cm_data,
4270                                    size_t *cm_data_space)
4271 {
4272         size_t cmspace;
4273         uint8_t *p;
4274
4275         cmspace = *cm_data_space + CMSG_ALIGN(cmsg->cmsg_len);
4276
4277         p = realloc((*cm_data), cmspace);
4278         if (p == NULL) {
4279                 return -1;
4280         }
4281         (*cm_data) = p;
4282
4283         p = (*cm_data) + (*cm_data_space);
4284         *cm_data_space = cmspace;
4285
4286         memcpy(p, cmsg, cmsg->cmsg_len);
4287
4288         return 0;
4289 }
4290
4291 static int swrap_sendmsg_filter_cmsg_pktinfo(struct cmsghdr *cmsg,
4292                                             uint8_t **cm_data,
4293                                             size_t *cm_data_space);
4294
4295
4296 static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr *cmsg,
4297                                             uint8_t **cm_data,
4298                                             size_t *cm_data_space)
4299 {
4300         int rc = -1;
4301
4302         switch(cmsg->cmsg_type) {
4303 #ifdef IP_PKTINFO
4304         case IP_PKTINFO:
4305                 rc = swrap_sendmsg_filter_cmsg_pktinfo(cmsg,
4306                                                        cm_data,
4307                                                        cm_data_space);
4308                 break;
4309 #endif
4310 #ifdef IPV6_PKTINFO
4311         case IPV6_PKTINFO:
4312                 rc = swrap_sendmsg_filter_cmsg_pktinfo(cmsg,
4313                                                        cm_data,
4314                                                        cm_data_space);
4315                 break;
4316 #endif
4317         default:
4318                 break;
4319         }
4320
4321         return rc;
4322 }
4323
4324 static int swrap_sendmsg_filter_cmsg_pktinfo(struct cmsghdr *cmsg,
4325                                              uint8_t **cm_data,
4326                                              size_t *cm_data_space)
4327 {
4328         (void)cmsg; /* unused */
4329         (void)cm_data; /* unused */
4330         (void)cm_data_space; /* unused */
4331
4332         /*
4333          * Passing a IP pktinfo to a unix socket might be rejected by the
4334          * Kernel, at least on FreeBSD. So skip this cmsg.
4335          */
4336         return 0;
4337 }
4338 #endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
4339
4340 static ssize_t swrap_sendmsg_before(int fd,
4341                                     struct socket_info *si,
4342                                     struct msghdr *msg,
4343                                     struct iovec *tmp_iov,
4344                                     struct sockaddr_un *tmp_un,
4345                                     const struct sockaddr_un **to_un,
4346                                     const struct sockaddr **to,
4347                                     int *bcast)
4348 {
4349         size_t i, len = 0;
4350         ssize_t ret;
4351
4352         if (to_un) {
4353                 *to_un = NULL;
4354         }
4355         if (to) {
4356                 *to = NULL;
4357         }
4358         if (bcast) {
4359                 *bcast = 0;
4360         }
4361
4362         switch (si->type) {
4363         case SOCK_STREAM: {
4364                 unsigned long mtu;
4365
4366                 if (!si->connected) {
4367                         errno = ENOTCONN;
4368                         return -1;
4369                 }
4370
4371                 if (msg->msg_iovlen == 0) {
4372                         break;
4373                 }
4374
4375                 mtu = socket_wrapper_mtu();
4376                 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
4377                         size_t nlen;
4378                         nlen = len + msg->msg_iov[i].iov_len;
4379                         if (nlen > mtu) {
4380                                 break;
4381                         }
4382                 }
4383                 msg->msg_iovlen = i;
4384                 if (msg->msg_iovlen == 0) {
4385                         *tmp_iov = msg->msg_iov[0];
4386                         tmp_iov->iov_len = MIN((size_t)tmp_iov->iov_len,
4387                                                (size_t)mtu);
4388                         msg->msg_iov = tmp_iov;
4389                         msg->msg_iovlen = 1;
4390                 }
4391                 break;
4392         }
4393         case SOCK_DGRAM:
4394                 if (si->connected) {
4395                         if (msg->msg_name != NULL) {
4396                                 /*
4397                                  * We are dealing with unix sockets and if we
4398                                  * are connected, we should only talk to the
4399                                  * connected unix path. Using the fd to send
4400                                  * to another server would be hard to achieve.
4401                                  */
4402                                 msg->msg_name = NULL;
4403                                 msg->msg_namelen = 0;
4404                         }
4405                 } else {
4406                         const struct sockaddr *msg_name;
4407                         msg_name = (const struct sockaddr *)msg->msg_name;
4408
4409                         if (msg_name == NULL) {
4410                                 errno = ENOTCONN;
4411                                 return -1;
4412                         }
4413
4414
4415                         ret = sockaddr_convert_to_un(si, msg_name, msg->msg_namelen,
4416                                                      tmp_un, 0, bcast);
4417                         if (ret == -1) {
4418                                 return -1;
4419                         }
4420
4421                         if (to_un) {
4422                                 *to_un = tmp_un;
4423                         }
4424                         if (to) {
4425                                 *to = msg_name;
4426                         }
4427                         msg->msg_name = tmp_un;
4428                         msg->msg_namelen = sizeof(*tmp_un);
4429                 }
4430
4431                 if (si->bound == 0) {
4432                         ret = swrap_auto_bind(fd, si, si->family);
4433                         if (ret == -1) {
4434                                 if (errno == ENOTSOCK) {
4435                                         swrap_remove_stale(fd);
4436                                         return -ENOTSOCK;
4437                                 } else {
4438                                         SWRAP_LOG(SWRAP_LOG_ERROR, "swrap_sendmsg_before failed");
4439                                         return -1;
4440                                 }
4441                         }
4442                 }
4443
4444                 if (!si->defer_connect) {
4445                         break;
4446                 }
4447
4448                 ret = sockaddr_convert_to_un(si,
4449                                              &si->peername.sa.s,
4450                                              si->peername.sa_socklen,
4451                                              tmp_un,
4452                                              0,
4453                                              NULL);
4454                 if (ret == -1) {
4455                         return -1;
4456                 }
4457
4458                 ret = libc_connect(fd,
4459                                    (struct sockaddr *)(void *)tmp_un,
4460                                    sizeof(*tmp_un));
4461
4462                 /* to give better errors */
4463                 if (ret == -1 && errno == ENOENT) {
4464                         errno = EHOSTUNREACH;
4465                 }
4466
4467                 if (ret == -1) {
4468                         return ret;
4469                 }
4470
4471                 si->defer_connect = 0;
4472                 break;
4473         default:
4474                 errno = EHOSTUNREACH;
4475                 return -1;
4476         }
4477
4478 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4479         if (msg->msg_controllen > 0 && msg->msg_control != NULL) {
4480                 uint8_t *cmbuf = NULL;
4481                 size_t cmlen = 0;
4482
4483                 ret = swrap_sendmsg_filter_cmsghdr(msg, &cmbuf, &cmlen);
4484                 if (ret < 0) {
4485                         free(cmbuf);
4486                         return -1;
4487                 }
4488
4489                 if (cmlen == 0) {
4490                         msg->msg_controllen = 0;
4491                         msg->msg_control = NULL;
4492                 } else if (cmlen < msg->msg_controllen && cmbuf != NULL) {
4493                         memcpy(msg->msg_control, cmbuf, cmlen);
4494                         msg->msg_controllen = cmlen;
4495                 }
4496                 free(cmbuf);
4497         }
4498 #endif
4499
4500         return 0;
4501 }
4502
4503 static void swrap_sendmsg_after(int fd,
4504                                 struct socket_info *si,
4505                                 struct msghdr *msg,
4506                                 const struct sockaddr *to,
4507                                 ssize_t ret)
4508 {
4509         int saved_errno = errno;
4510         size_t i, len = 0;
4511         uint8_t *buf;
4512         off_t ofs = 0;
4513         size_t avail = 0;
4514         size_t remain;
4515
4516         /* to give better errors */
4517         if (ret == -1) {
4518                 if (saved_errno == ENOENT) {
4519                         saved_errno = EHOSTUNREACH;
4520                 } else if (saved_errno == ENOTSOCK) {
4521                         /* If the fd is not a socket, remove it */
4522                         swrap_remove_stale(fd);
4523                 }
4524         }
4525
4526         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
4527                 avail += msg->msg_iov[i].iov_len;
4528         }
4529
4530         if (ret == -1) {
4531                 remain = MIN(80, avail);
4532         } else {
4533                 remain = ret;
4534         }
4535
4536         /* we capture it as one single packet */
4537         buf = (uint8_t *)malloc(remain);
4538         if (!buf) {
4539                 /* we just not capture the packet */
4540                 errno = saved_errno;
4541                 return;
4542         }
4543
4544         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
4545                 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
4546                 memcpy(buf + ofs,
4547                        msg->msg_iov[i].iov_base,
4548                        this_time);
4549                 ofs += this_time;
4550                 remain -= this_time;
4551         }
4552         len = ofs;
4553
4554         switch (si->type) {
4555         case SOCK_STREAM:
4556                 if (ret == -1) {
4557                         swrap_pcap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
4558                         swrap_pcap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
4559                 } else {
4560                         swrap_pcap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
4561                 }
4562                 break;
4563
4564         case SOCK_DGRAM:
4565                 if (si->connected) {
4566                         to = &si->peername.sa.s;
4567                 }
4568                 if (ret == -1) {
4569                         swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
4570                         swrap_pcap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);
4571                 } else {
4572                         swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
4573                 }
4574                 break;
4575         }
4576
4577         free(buf);
4578         errno = saved_errno;
4579 }
4580
4581 static int swrap_recvmsg_before(int fd,
4582                                 struct socket_info *si,
4583                                 struct msghdr *msg,
4584                                 struct iovec *tmp_iov)
4585 {
4586         size_t i, len = 0;
4587         ssize_t ret;
4588
4589         (void)fd; /* unused */
4590
4591         switch (si->type) {
4592         case SOCK_STREAM: {
4593                 unsigned int mtu;
4594                 if (!si->connected) {
4595                         errno = ENOTCONN;
4596                         return -1;
4597                 }
4598
4599                 if (msg->msg_iovlen == 0) {
4600                         break;
4601                 }
4602
4603                 mtu = socket_wrapper_mtu();
4604                 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
4605                         size_t nlen;
4606                         nlen = len + msg->msg_iov[i].iov_len;
4607                         if (nlen > mtu) {
4608                                 break;
4609                         }
4610                 }
4611                 msg->msg_iovlen = i;
4612                 if (msg->msg_iovlen == 0) {
4613                         *tmp_iov = msg->msg_iov[0];
4614                         tmp_iov->iov_len = MIN((size_t)tmp_iov->iov_len,
4615                                                (size_t)mtu);
4616                         msg->msg_iov = tmp_iov;
4617                         msg->msg_iovlen = 1;
4618                 }
4619                 break;
4620         }
4621         case SOCK_DGRAM:
4622                 if (msg->msg_name == NULL) {
4623                         errno = EINVAL;
4624                         return -1;
4625                 }
4626
4627                 if (msg->msg_iovlen == 0) {
4628                         break;
4629                 }
4630
4631                 if (si->bound == 0) {
4632                         ret = swrap_auto_bind(fd, si, si->family);
4633                         if (ret == -1) {
4634                                 /*
4635                                  * When attempting to read or write to a
4636                                  * descriptor, if an underlying autobind fails
4637                                  * because it's not a socket, stop intercepting
4638                                  * uses of that descriptor.
4639                                  */
4640                                 if (errno == ENOTSOCK) {
4641                                         swrap_remove_stale(fd);
4642                                         return -ENOTSOCK;
4643                                 } else {
4644                                         SWRAP_LOG(SWRAP_LOG_ERROR,
4645                                                   "swrap_recvmsg_before failed");
4646                                         return -1;
4647                                 }
4648                         }
4649                 }
4650                 break;
4651         default:
4652                 errno = EHOSTUNREACH;
4653                 return -1;
4654         }
4655
4656         return 0;
4657 }
4658
4659 static int swrap_recvmsg_after(int fd,
4660                                struct socket_info *si,
4661                                struct msghdr *msg,
4662                                const struct sockaddr_un *un_addr,
4663                                socklen_t un_addrlen,
4664                                ssize_t ret)
4665 {
4666         int saved_errno = errno;
4667         size_t i;
4668         uint8_t *buf = NULL;
4669         off_t ofs = 0;
4670         size_t avail = 0;
4671         size_t remain;
4672         int rc;
4673
4674         /* to give better errors */
4675         if (ret == -1) {
4676                 if (saved_errno == ENOENT) {
4677                         saved_errno = EHOSTUNREACH;
4678                 } else if (saved_errno == ENOTSOCK) {
4679                         /* If the fd is not a socket, remove it */
4680                         swrap_remove_stale(fd);
4681                 }
4682         }
4683
4684         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
4685                 avail += msg->msg_iov[i].iov_len;
4686         }
4687
4688         /* Convert the socket address before we leave */
4689         if (si->type == SOCK_DGRAM && un_addr != NULL) {
4690                 rc = sockaddr_convert_from_un(si,
4691                                               un_addr,
4692                                               un_addrlen,
4693                                               si->family,
4694                                               msg->msg_name,
4695                                               &msg->msg_namelen);
4696                 if (rc == -1) {
4697                         goto done;
4698                 }
4699         }
4700
4701         if (avail == 0) {
4702                 rc = 0;
4703                 goto done;
4704         }
4705
4706         if (ret == -1) {
4707                 remain = MIN(80, avail);
4708         } else {
4709                 remain = ret;
4710         }
4711
4712         /* we capture it as one single packet */
4713         buf = (uint8_t *)malloc(remain);
4714         if (buf == NULL) {
4715                 /* we just not capture the packet */
4716                 errno = saved_errno;
4717                 return -1;
4718         }
4719
4720         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
4721                 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
4722                 memcpy(buf + ofs,
4723                        msg->msg_iov[i].iov_base,
4724                        this_time);
4725                 ofs += this_time;
4726                 remain -= this_time;
4727         }
4728
4729         switch (si->type) {
4730         case SOCK_STREAM:
4731                 if (ret == -1 && saved_errno != EAGAIN && saved_errno != ENOBUFS) {
4732                         swrap_pcap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
4733                 } else if (ret == 0) { /* END OF FILE */
4734                         swrap_pcap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
4735                 } else if (ret > 0) {
4736                         swrap_pcap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
4737                 }
4738                 break;
4739
4740         case SOCK_DGRAM:
4741                 if (ret == -1) {
4742                         break;
4743                 }
4744
4745                 if (un_addr != NULL) {
4746                         swrap_pcap_dump_packet(si,
4747                                           msg->msg_name,
4748                                           SWRAP_RECVFROM,
4749                                           buf,
4750                                           ret);
4751                 } else {
4752                         swrap_pcap_dump_packet(si,
4753                                           msg->msg_name,
4754                                           SWRAP_RECV,
4755                                           buf,
4756                                           ret);
4757                 }
4758
4759                 break;
4760         }
4761
4762         rc = 0;
4763 done:
4764         free(buf);
4765         errno = saved_errno;
4766
4767 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4768         if (rc == 0 &&
4769             msg->msg_controllen > 0 &&
4770             msg->msg_control != NULL) {
4771                 rc = swrap_msghdr_add_socket_info(si, msg);
4772                 if (rc < 0) {
4773                         return -1;
4774                 }
4775         }
4776 #endif
4777
4778         return rc;
4779 }
4780
4781 /****************************************************************************
4782  *   RECVFROM
4783  ***************************************************************************/
4784
4785 static ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags,
4786                               struct sockaddr *from, socklen_t *fromlen)
4787 {
4788         struct swrap_address from_addr = {
4789                 .sa_socklen = sizeof(struct sockaddr_un),
4790         };
4791         ssize_t ret;
4792         struct socket_info *si = find_socket_info(s);
4793         struct swrap_address saddr = {
4794                 .sa_socklen = sizeof(struct sockaddr_storage),
4795         };
4796         struct msghdr msg;
4797         struct iovec tmp;
4798         int tret;
4799
4800         if (!si) {
4801                 return libc_recvfrom(s,
4802                                      buf,
4803                                      len,
4804                                      flags,
4805                                      from,
4806                                      fromlen);
4807         }
4808
4809         tmp.iov_base = buf;
4810         tmp.iov_len = len;
4811
4812         ZERO_STRUCT(msg);
4813         if (from != NULL && fromlen != NULL) {
4814                 msg.msg_name = from;   /* optional address */
4815                 msg.msg_namelen = *fromlen; /* size of address */
4816         } else {
4817                 msg.msg_name = &saddr.sa.s; /* optional address */
4818                 msg.msg_namelen = saddr.sa_socklen; /* size of address */
4819         }
4820         msg.msg_iov = &tmp;            /* scatter/gather array */
4821         msg.msg_iovlen = 1;            /* # elements in msg_iov */
4822 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4823         msg.msg_control = NULL;        /* ancillary data, see below */
4824         msg.msg_controllen = 0;        /* ancillary data buffer len */
4825         msg.msg_flags = 0;             /* flags on received message */
4826 #endif
4827
4828         tret = swrap_recvmsg_before(s, si, &msg, &tmp);
4829         if (tret < 0) {
4830                 return -1;
4831         }
4832
4833         buf = msg.msg_iov[0].iov_base;
4834         len = msg.msg_iov[0].iov_len;
4835
4836         ret = libc_recvfrom(s,
4837                             buf,
4838                             len,
4839                             flags,
4840                             &from_addr.sa.s,
4841                             &from_addr.sa_socklen);
4842         if (ret == -1) {
4843                 return ret;
4844         }
4845
4846         tret = swrap_recvmsg_after(s,
4847                                    si,
4848                                    &msg,
4849                                    &from_addr.sa.un,
4850                                    from_addr.sa_socklen,
4851                                    ret);
4852         if (tret != 0) {
4853                 return tret;
4854         }
4855
4856         if (from != NULL && fromlen != NULL) {
4857                 *fromlen = msg.msg_namelen;
4858         }
4859
4860         return ret;
4861 }
4862
4863 #ifdef HAVE_ACCEPT_PSOCKLEN_T
4864 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
4865                  struct sockaddr *from, Psocklen_t fromlen)
4866 #else
4867 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
4868                  struct sockaddr *from, socklen_t *fromlen)
4869 #endif
4870 {
4871         return swrap_recvfrom(s, buf, len, flags, from, (socklen_t *)fromlen);
4872 }
4873
4874 /****************************************************************************
4875  *   SENDTO
4876  ***************************************************************************/
4877
4878 static ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags,
4879                             const struct sockaddr *to, socklen_t tolen)
4880 {
4881         struct msghdr msg;
4882         struct iovec tmp;
4883         struct swrap_address un_addr = {
4884                 .sa_socklen = sizeof(struct sockaddr_un),
4885         };
4886         const struct sockaddr_un *to_un = NULL;
4887         ssize_t ret;
4888         int rc;
4889         struct socket_info *si = find_socket_info(s);
4890         int bcast = 0;
4891
4892         if (!si) {
4893                 return libc_sendto(s, buf, len, flags, to, tolen);
4894         }
4895
4896         tmp.iov_base = discard_const_p(char, buf);
4897         tmp.iov_len = len;
4898
4899         ZERO_STRUCT(msg);
4900         msg.msg_name = discard_const_p(struct sockaddr, to); /* optional address */
4901         msg.msg_namelen = tolen;       /* size of address */
4902         msg.msg_iov = &tmp;            /* scatter/gather array */
4903         msg.msg_iovlen = 1;            /* # elements in msg_iov */
4904 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
4905         msg.msg_control = NULL;        /* ancillary data, see below */
4906         msg.msg_controllen = 0;        /* ancillary data buffer len */
4907         msg.msg_flags = 0;             /* flags on received message */
4908 #endif
4909
4910         rc = swrap_sendmsg_before(s,
4911                                   si,
4912                                   &msg,
4913                                   &tmp,
4914                                   &un_addr.sa.un,
4915                                   &to_un,
4916                                   &to,
4917                                   &bcast);
4918         if (rc < 0) {
4919                 return -1;
4920         }
4921
4922         buf = msg.msg_iov[0].iov_base;
4923         len = msg.msg_iov[0].iov_len;
4924
4925         if (bcast) {
4926                 struct stat st;
4927                 unsigned int iface;
4928                 unsigned int prt = ntohs(((const struct sockaddr_in *)(const void *)to)->sin_port);
4929                 char type;
4930
4931                 type = SOCKET_TYPE_CHAR_UDP;
4932
4933                 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
4934                         snprintf(un_addr.sa.un.sun_path,
4935                                  sizeof(un_addr.sa.un.sun_path),
4936                                  "%s/"SOCKET_FORMAT,
4937                                  socket_wrapper_dir(), type, iface, prt);
4938                         if (stat(un_addr.sa.un.sun_path, &st) != 0) continue;
4939
4940                         /* ignore the any errors in broadcast sends */
4941                         libc_sendto(s,
4942                                     buf,
4943                                     len,
4944                                     flags,
4945                                     &un_addr.sa.s,
4946                                     un_addr.sa_socklen);
4947                 }
4948
4949                 swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
4950
4951                 return len;
4952         }
4953
4954         /*
4955          * If it is a dgram socket and we are connected, don't include the
4956          * 'to' address.
4957          */
4958         if (si->type == SOCK_DGRAM && si->connected) {
4959                 ret = libc_sendto(s,
4960                                   buf,
4961                                   len,
4962                                   flags,
4963                                   NULL,
4964                                   0);
4965         } else {
4966                 ret = libc_sendto(s,
4967                                   buf,
4968                                   len,
4969                                   flags,
4970                                   (struct sockaddr *)msg.msg_name,
4971                                   msg.msg_namelen);
4972         }
4973
4974         swrap_sendmsg_after(s, si, &msg, to, ret);
4975
4976         return ret;
4977 }
4978
4979 ssize_t sendto(int s, const void *buf, size_t len, int flags,
4980                const struct sockaddr *to, socklen_t tolen)
4981 {
4982         return swrap_sendto(s, buf, len, flags, to, tolen);
4983 }
4984
4985 /****************************************************************************
4986  *   READV
4987  ***************************************************************************/
4988
4989 static ssize_t swrap_recv(int s, void *buf, size_t len, int flags)
4990 {
4991         struct socket_info *si;
4992         struct msghdr msg;
4993         struct swrap_address saddr = {
4994                 .sa_socklen = sizeof(struct sockaddr_storage),
4995         };
4996         struct iovec tmp;
4997         ssize_t ret;
4998         int tret;
4999
5000         si = find_socket_info(s);
5001         if (si == NULL) {
5002                 return libc_recv(s, buf, len, flags);
5003         }
5004
5005         tmp.iov_base = buf;
5006         tmp.iov_len = len;
5007
5008         ZERO_STRUCT(msg);
5009         msg.msg_name = &saddr.sa.s;    /* optional address */
5010         msg.msg_namelen = saddr.sa_socklen; /* size of address */
5011         msg.msg_iov = &tmp;            /* scatter/gather array */
5012         msg.msg_iovlen = 1;            /* # elements in msg_iov */
5013 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5014         msg.msg_control = NULL;        /* ancillary data, see below */
5015         msg.msg_controllen = 0;        /* ancillary data buffer len */
5016         msg.msg_flags = 0;             /* flags on received message */
5017 #endif
5018
5019         tret = swrap_recvmsg_before(s, si, &msg, &tmp);
5020         if (tret < 0) {
5021                 return -1;
5022         }
5023
5024         buf = msg.msg_iov[0].iov_base;
5025         len = msg.msg_iov[0].iov_len;
5026
5027         ret = libc_recv(s, buf, len, flags);
5028
5029         tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
5030         if (tret != 0) {
5031                 return tret;
5032         }
5033
5034         return ret;
5035 }
5036
5037 ssize_t recv(int s, void *buf, size_t len, int flags)
5038 {
5039         return swrap_recv(s, buf, len, flags);
5040 }
5041
5042 /****************************************************************************
5043  *   READ
5044  ***************************************************************************/
5045
5046 static ssize_t swrap_read(int s, void *buf, size_t len)
5047 {
5048         struct socket_info *si;
5049         struct msghdr msg;
5050         struct iovec tmp;
5051         struct swrap_address saddr = {
5052                 .sa_socklen = sizeof(struct sockaddr_storage),
5053         };
5054         ssize_t ret;
5055         int tret;
5056
5057         si = find_socket_info(s);
5058         if (si == NULL) {
5059                 return libc_read(s, buf, len);
5060         }
5061
5062         tmp.iov_base = buf;
5063         tmp.iov_len = len;
5064
5065         ZERO_STRUCT(msg);
5066         msg.msg_name = &saddr.sa.ss;   /* optional address */
5067         msg.msg_namelen = saddr.sa_socklen; /* size of address */
5068         msg.msg_iov = &tmp;            /* scatter/gather array */
5069         msg.msg_iovlen = 1;            /* # elements in msg_iov */
5070 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5071         msg.msg_control = NULL;        /* ancillary data, see below */
5072         msg.msg_controllen = 0;        /* ancillary data buffer len */
5073         msg.msg_flags = 0;             /* flags on received message */
5074 #endif
5075
5076         tret = swrap_recvmsg_before(s, si, &msg, &tmp);
5077         if (tret < 0) {
5078                 if (tret == -ENOTSOCK) {
5079                         return libc_read(s, buf, len);
5080                 }
5081                 return -1;
5082         }
5083
5084         buf = msg.msg_iov[0].iov_base;
5085         len = msg.msg_iov[0].iov_len;
5086
5087         ret = libc_read(s, buf, len);
5088
5089         tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
5090         if (tret != 0) {
5091                 return tret;
5092         }
5093
5094         return ret;
5095 }
5096
5097 ssize_t read(int s, void *buf, size_t len)
5098 {
5099         return swrap_read(s, buf, len);
5100 }
5101
5102 /****************************************************************************
5103  *   WRITE
5104  ***************************************************************************/
5105
5106 static ssize_t swrap_write(int s, const void *buf, size_t len)
5107 {
5108         struct msghdr msg;
5109         struct iovec tmp;
5110         struct sockaddr_un un_addr;
5111         ssize_t ret;
5112         int rc;
5113         struct socket_info *si;
5114
5115         si = find_socket_info(s);
5116         if (si == NULL) {
5117                 return libc_write(s, buf, len);
5118         }
5119
5120         tmp.iov_base = discard_const_p(char, buf);
5121         tmp.iov_len = len;
5122
5123         ZERO_STRUCT(msg);
5124         msg.msg_name = NULL;           /* optional address */
5125         msg.msg_namelen = 0;           /* size of address */
5126         msg.msg_iov = &tmp;            /* scatter/gather array */
5127         msg.msg_iovlen = 1;            /* # elements in msg_iov */
5128 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
5129         msg.msg_control = NULL;        /* ancillary data, see below */
5130         msg.msg_controllen = 0;        /* ancillary data buffer len */
5131         msg.msg_flags = 0;             /* flags on received message */
5132 #endif
5133
5134         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
5135         if (rc < 0) {
5136                 return -1;
5137         }
5138
5139         buf = msg.msg_iov[0].iov_base;
5140         len = msg.msg_iov[0].iov_len;
5141
5142         ret = libc_write(s, buf, len);
5143
5144         swrap_sendmsg_after(s, si, &msg, NULL, ret);
5145
5146         return ret;
5147 }
5148
5149 ssize_t write(int s, const void *buf, size_t len)
5150 {
5151         return swrap_write(s, buf, len);
5152 }
5153
5154 /****************************************************************************
5155  *   SEND
5156  ***************************************************************************/
5157
5158 static ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
5159 {
5160         struct msghdr msg;
5161         struct iovec tmp;
5162         struct sockaddr_un un_addr;
5163         ssize_t ret;
5164         int rc;
5165         struct socket_info *si = find_socket_info(s);
5166
5167         if (!si) {
5168                 return libc_send(s, buf, len, flags);
5169         }
5170
5171         tmp.iov_base = discard_const_p(char, buf);
5172         tmp.iov_len = len;
5173
5174         ZERO_STRUCT(msg);
5175         msg.msg_name = NULL;           /* optional address */
5176         msg.msg_namelen = 0;           /* size of address */
5177         msg.msg_iov = &tmp;            /* scatter/gather array */
5178         msg.msg_iovlen = 1;            /* # elements in msg_iov */
5179 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
5180         msg.msg_control = NULL;        /* ancillary data, see below */
5181         msg.msg_controllen = 0;        /* ancillary data buffer len */
5182         msg.msg_flags = 0;             /* flags on received message */
5183 #endif
5184
5185         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
5186         if (rc < 0) {
5187                 return -1;
5188         }
5189
5190         buf = msg.msg_iov[0].iov_base;
5191         len = msg.msg_iov[0].iov_len;
5192
5193         ret = libc_send(s, buf, len, flags);
5194
5195         swrap_sendmsg_after(s, si, &msg, NULL, ret);
5196
5197         return ret;
5198 }
5199
5200 ssize_t send(int s, const void *buf, size_t len, int flags)
5201 {
5202         return swrap_send(s, buf, len, flags);
5203 }
5204
5205 /****************************************************************************
5206  *   RECVMSG
5207  ***************************************************************************/
5208
5209 static ssize_t swrap_recvmsg(int s, struct msghdr *omsg, int flags)
5210 {
5211         struct swrap_address from_addr = {
5212                 .sa_socklen = sizeof(struct sockaddr_un),
5213         };
5214         struct swrap_address convert_addr = {
5215                 .sa_socklen = sizeof(struct sockaddr_storage),
5216         };
5217         struct socket_info *si;
5218         struct msghdr msg;
5219         struct iovec tmp;
5220 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5221         size_t msg_ctrllen_filled;
5222         size_t msg_ctrllen_left;
5223 #endif
5224
5225         ssize_t ret;
5226         int rc;
5227
5228         si = find_socket_info(s);
5229         if (si == NULL) {
5230                 return libc_recvmsg(s, omsg, flags);
5231         }
5232
5233         tmp.iov_base = NULL;
5234         tmp.iov_len = 0;
5235
5236         ZERO_STRUCT(msg);
5237         msg.msg_name = &from_addr.sa;              /* optional address */
5238         msg.msg_namelen = from_addr.sa_socklen;    /* size of address */
5239         msg.msg_iov = omsg->msg_iov;               /* scatter/gather array */
5240         msg.msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
5241 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5242         msg_ctrllen_filled = 0;
5243         msg_ctrllen_left = omsg->msg_controllen;
5244
5245         msg.msg_control = omsg->msg_control;       /* ancillary data, see below */
5246         msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
5247         msg.msg_flags = omsg->msg_flags;           /* flags on received message */
5248 #endif
5249
5250         rc = swrap_recvmsg_before(s, si, &msg, &tmp);
5251         if (rc < 0) {
5252                 return -1;
5253         }
5254
5255         ret = libc_recvmsg(s, &msg, flags);
5256
5257 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5258         msg_ctrllen_filled += msg.msg_controllen;
5259         msg_ctrllen_left -= msg.msg_controllen;
5260
5261         if (omsg->msg_control != NULL) {
5262                 uint8_t *p;
5263
5264                 p = omsg->msg_control;
5265                 p += msg_ctrllen_filled;
5266
5267                 msg.msg_control = p;
5268                 msg.msg_controllen = msg_ctrllen_left;
5269         } else {
5270                 msg.msg_control = NULL;
5271                 msg.msg_controllen = 0;
5272         }
5273 #endif
5274
5275         /*
5276          * We convert the unix address to a IP address so we need a buffer
5277          * which can store the address in case of SOCK_DGRAM, see below.
5278          */
5279         msg.msg_name = &convert_addr.sa;
5280         msg.msg_namelen = convert_addr.sa_socklen;
5281
5282         rc = swrap_recvmsg_after(s,
5283                                  si,
5284                                  &msg,
5285                                  &from_addr.sa.un,
5286                                  from_addr.sa_socklen,
5287                                  ret);
5288         if (rc != 0) {
5289                 return rc;
5290         }
5291
5292 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5293         if (omsg->msg_control != NULL) {
5294                 /* msg.msg_controllen = space left */
5295                 msg_ctrllen_left = msg.msg_controllen;
5296                 msg_ctrllen_filled = omsg->msg_controllen - msg_ctrllen_left;
5297         }
5298
5299         /* Update the original message length */
5300         omsg->msg_controllen = msg_ctrllen_filled;
5301         omsg->msg_flags = msg.msg_flags;
5302 #endif
5303         omsg->msg_iovlen = msg.msg_iovlen;
5304
5305         /*
5306          * From the manpage:
5307          *
5308          * The  msg_name  field  points  to a caller-allocated buffer that is
5309          * used to return the source address if the socket is unconnected.  The
5310          * caller should set msg_namelen to the size of this buffer before this
5311          * call; upon return from a successful call, msg_name will contain the
5312          * length of the returned address.  If the application  does  not  need
5313          * to know the source address, msg_name can be specified as NULL.
5314          */
5315         if (si->type == SOCK_STREAM) {
5316                 omsg->msg_namelen = 0;
5317         } else if (omsg->msg_name != NULL &&
5318                    omsg->msg_namelen != 0 &&
5319                    omsg->msg_namelen >= msg.msg_namelen) {
5320                 memcpy(omsg->msg_name, msg.msg_name, msg.msg_namelen);
5321                 omsg->msg_namelen = msg.msg_namelen;
5322         }
5323
5324         return ret;
5325 }
5326
5327 ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)
5328 {
5329         return swrap_recvmsg(sockfd, msg, flags);
5330 }
5331
5332 /****************************************************************************
5333  *   SENDMSG
5334  ***************************************************************************/
5335
5336 static ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags)
5337 {
5338         struct msghdr msg;
5339         struct iovec tmp;
5340         struct sockaddr_un un_addr;
5341         const struct sockaddr_un *to_un = NULL;
5342         const struct sockaddr *to = NULL;
5343         ssize_t ret;
5344         int rc;
5345         struct socket_info *si = find_socket_info(s);
5346         int bcast = 0;
5347
5348         if (!si) {
5349                 return libc_sendmsg(s, omsg, flags);
5350         }
5351
5352         ZERO_STRUCT(un_addr);
5353
5354         tmp.iov_base = NULL;
5355         tmp.iov_len = 0;
5356
5357         ZERO_STRUCT(msg);
5358
5359         if (si->connected == 0) {
5360                 msg.msg_name = omsg->msg_name;             /* optional address */
5361                 msg.msg_namelen = omsg->msg_namelen;       /* size of address */
5362         }
5363         msg.msg_iov = omsg->msg_iov;               /* scatter/gather array */
5364         msg.msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
5365 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5366         if (msg.msg_controllen > 0 && msg.msg_control != NULL) {
5367                 /* omsg is a const so use a local buffer for modifications */
5368                 uint8_t cmbuf[omsg->msg_controllen];
5369
5370                 memcpy(cmbuf, omsg->msg_control, omsg->msg_controllen);
5371
5372                 msg.msg_control = cmbuf;       /* ancillary data, see below */
5373                 msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
5374         }
5375         msg.msg_flags = omsg->msg_flags;           /* flags on received message */
5376 #endif
5377
5378         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
5379         if (rc < 0) {
5380                 return -1;
5381         }
5382
5383         if (bcast) {
5384                 struct stat st;
5385                 unsigned int iface;
5386                 unsigned int prt = ntohs(((const struct sockaddr_in *)(const void *)to)->sin_port);
5387                 char type;
5388                 size_t i, len = 0;
5389                 uint8_t *buf;
5390                 off_t ofs = 0;
5391                 size_t avail = 0;
5392                 size_t remain;
5393
5394                 for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
5395                         avail += msg.msg_iov[i].iov_len;
5396                 }
5397
5398                 len = avail;
5399                 remain = avail;
5400
5401                 /* we capture it as one single packet */
5402                 buf = (uint8_t *)malloc(remain);
5403                 if (!buf) {
5404                         return -1;
5405                 }
5406
5407                 for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
5408                         size_t this_time = MIN(remain, (size_t)msg.msg_iov[i].iov_len);
5409                         memcpy(buf + ofs,
5410                                msg.msg_iov[i].iov_base,
5411                                this_time);
5412                         ofs += this_time;
5413                         remain -= this_time;
5414                 }
5415
5416                 type = SOCKET_TYPE_CHAR_UDP;
5417
5418                 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
5419                         snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT,
5420                                  socket_wrapper_dir(), type, iface, prt);
5421                         if (stat(un_addr.sun_path, &st) != 0) continue;
5422
5423                         msg.msg_name = &un_addr;           /* optional address */
5424                         msg.msg_namelen = sizeof(un_addr); /* size of address */
5425
5426                         /* ignore the any errors in broadcast sends */
5427                         libc_sendmsg(s, &msg, flags);
5428                 }
5429
5430                 swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
5431                 free(buf);
5432
5433                 return len;
5434         }
5435
5436         ret = libc_sendmsg(s, &msg, flags);
5437
5438         swrap_sendmsg_after(s, si, &msg, to, ret);
5439
5440         return ret;
5441 }
5442
5443 ssize_t sendmsg(int s, const struct msghdr *omsg, int flags)
5444 {
5445         return swrap_sendmsg(s, omsg, flags);
5446 }
5447
5448 /****************************************************************************
5449  *   READV
5450  ***************************************************************************/
5451
5452 static ssize_t swrap_readv(int s, const struct iovec *vector, int count)
5453 {
5454         struct socket_info *si;
5455         struct msghdr msg;
5456         struct iovec tmp;
5457         struct swrap_address saddr = {
5458                 .sa_socklen = sizeof(struct sockaddr_storage)
5459         };
5460         ssize_t ret;
5461         int rc;
5462
5463         si = find_socket_info(s);
5464         if (si == NULL) {
5465                 return libc_readv(s, vector, count);
5466         }
5467
5468         tmp.iov_base = NULL;
5469         tmp.iov_len = 0;
5470
5471         ZERO_STRUCT(msg);
5472         msg.msg_name = &saddr.sa.s; /* optional address */
5473         msg.msg_namelen = saddr.sa_socklen;      /* size of address */
5474         msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
5475         msg.msg_iovlen = count;        /* # elements in msg_iov */
5476 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5477         msg.msg_control = NULL;        /* ancillary data, see below */
5478         msg.msg_controllen = 0;        /* ancillary data buffer len */
5479         msg.msg_flags = 0;             /* flags on received message */
5480 #endif
5481
5482         rc = swrap_recvmsg_before(s, si, &msg, &tmp);
5483         if (rc < 0) {
5484                 if (rc == -ENOTSOCK) {
5485                         return libc_readv(s, vector, count);
5486                 }
5487                 return -1;
5488         }
5489
5490         ret = libc_readv(s, msg.msg_iov, msg.msg_iovlen);
5491
5492         rc = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
5493         if (rc != 0) {
5494                 return rc;
5495         }
5496
5497         return ret;
5498 }
5499
5500 ssize_t readv(int s, const struct iovec *vector, int count)
5501 {
5502         return swrap_readv(s, vector, count);
5503 }
5504
5505 /****************************************************************************
5506  *   WRITEV
5507  ***************************************************************************/
5508
5509 static ssize_t swrap_writev(int s, const struct iovec *vector, int count)
5510 {
5511         struct msghdr msg;
5512         struct iovec tmp;
5513         struct sockaddr_un un_addr;
5514         ssize_t ret;
5515         int rc;
5516         struct socket_info *si = find_socket_info(s);
5517
5518         if (!si) {
5519                 return libc_writev(s, vector, count);
5520         }
5521
5522         tmp.iov_base = NULL;
5523         tmp.iov_len = 0;
5524
5525         ZERO_STRUCT(msg);
5526         msg.msg_name = NULL;           /* optional address */
5527         msg.msg_namelen = 0;           /* size of address */
5528         msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
5529         msg.msg_iovlen = count;        /* # elements in msg_iov */
5530 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
5531         msg.msg_control = NULL;        /* ancillary data, see below */
5532         msg.msg_controllen = 0;        /* ancillary data buffer len */
5533         msg.msg_flags = 0;             /* flags on received message */
5534 #endif
5535
5536         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
5537         if (rc < 0) {
5538                 if (rc == -ENOTSOCK) {
5539                         return libc_readv(s, vector, count);
5540                 }
5541                 return -1;
5542         }
5543
5544         ret = libc_writev(s, msg.msg_iov, msg.msg_iovlen);
5545
5546         swrap_sendmsg_after(s, si, &msg, NULL, ret);
5547
5548         return ret;
5549 }
5550
5551 ssize_t writev(int s, const struct iovec *vector, int count)
5552 {
5553         return swrap_writev(s, vector, count);
5554 }
5555
5556 /****************************
5557  * CLOSE
5558  ***************************/
5559
5560 static int swrap_close(int fd)
5561 {
5562         struct socket_info_fd *fi = find_socket_info_fd(fd);
5563         struct socket_info *si = NULL;
5564         int si_index;
5565         int ret;
5566
5567         if (fi == NULL) {
5568                 return libc_close(fd);
5569         }
5570
5571         si_index = fi->si_index;
5572
5573         SWRAP_DLIST_REMOVE(socket_fds, fi);
5574         free(fi);
5575
5576         ret = libc_close(fd);
5577
5578         si = &sockets[si_index];
5579         si->refcount--;
5580
5581         if (si->refcount > 0) {
5582                 /* there are still references left */
5583                 return ret;
5584         }
5585
5586         if (si->myname.sa_socklen > 0 && si->peername.sa_socklen > 0) {
5587                 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0);
5588         }
5589
5590         if (si->myname.sa_socklen > 0 && si->peername.sa_socklen > 0) {
5591                 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0);
5592                 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0);
5593         }
5594
5595         if (si->un_addr.sun_path[0] != '\0') {
5596                 unlink(si->un_addr.sun_path);
5597         }
5598
5599         si->next_free = first_free;
5600         first_free = si_index;
5601
5602         return ret;
5603 }
5604
5605 int close(int fd)
5606 {
5607         return swrap_close(fd);
5608 }
5609
5610 /****************************
5611  * DUP
5612  ***************************/
5613
5614 static int swrap_dup(int fd)
5615 {
5616         struct socket_info *si;
5617         struct socket_info_fd *src_fi, *fi;
5618
5619         src_fi = find_socket_info_fd(fd);
5620         if (src_fi == NULL) {
5621                 return libc_dup(fd);
5622         }
5623
5624         si = &sockets[src_fi->si_index];
5625
5626         fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
5627         if (fi == NULL) {
5628                 errno = ENOMEM;
5629                 return -1;
5630         }
5631
5632         fi->fd = libc_dup(fd);
5633         if (fi->fd == -1) {
5634                 int saved_errno = errno;
5635                 free(fi);
5636                 errno = saved_errno;
5637                 return -1;
5638         }
5639
5640         si->refcount++;
5641         fi->si_index = src_fi->si_index;
5642
5643         /* Make sure we don't have an entry for the fd */
5644         swrap_remove_stale(fi->fd);
5645
5646         SWRAP_DLIST_ADD_AFTER(socket_fds, fi, src_fi);
5647         return fi->fd;
5648 }
5649
5650 int dup(int fd)
5651 {
5652         return swrap_dup(fd);
5653 }
5654
5655 /****************************
5656  * DUP2
5657  ***************************/
5658
5659 static int swrap_dup2(int fd, int newfd)
5660 {
5661         struct socket_info *si;
5662         struct socket_info_fd *src_fi, *fi;
5663
5664         src_fi = find_socket_info_fd(fd);
5665         if (src_fi == NULL) {
5666                 return libc_dup2(fd, newfd);
5667         }
5668
5669         si = &sockets[src_fi->si_index];
5670
5671         if (fd == newfd) {
5672                 /*
5673                  * According to the manpage:
5674                  *
5675                  * "If oldfd is a valid file descriptor, and newfd has the same
5676                  * value as oldfd, then dup2() does nothing, and returns newfd."
5677                  */
5678                 return newfd;
5679         }
5680
5681         if (find_socket_info(newfd)) {
5682                 /* dup2() does an implicit close of newfd, which we
5683                  * need to emulate */
5684                 swrap_close(newfd);
5685         }
5686
5687         fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
5688         if (fi == NULL) {
5689                 errno = ENOMEM;
5690                 return -1;
5691         }
5692
5693         fi->fd = libc_dup2(fd, newfd);
5694         if (fi->fd == -1) {
5695                 int saved_errno = errno;
5696                 free(fi);
5697                 errno = saved_errno;
5698                 return -1;
5699         }
5700
5701         si->refcount++;
5702         fi->si_index = src_fi->si_index;
5703
5704         /* Make sure we don't have an entry for the fd */
5705         swrap_remove_stale(fi->fd);
5706
5707         SWRAP_DLIST_ADD_AFTER(socket_fds, fi, src_fi);
5708         return fi->fd;
5709 }
5710
5711 int dup2(int fd, int newfd)
5712 {
5713         return swrap_dup2(fd, newfd);
5714 }
5715
5716 /****************************
5717  * FCNTL
5718  ***************************/
5719
5720 static int swrap_vfcntl(int fd, int cmd, va_list va)
5721 {
5722         struct socket_info_fd *src_fi, *fi;
5723         struct socket_info *si;
5724         int rc;
5725
5726         src_fi = find_socket_info_fd(fd);
5727         if (src_fi == NULL) {
5728                 return libc_vfcntl(fd, cmd, va);
5729         }
5730
5731         si = &sockets[src_fi->si_index];
5732
5733         switch (cmd) {
5734         case F_DUPFD:
5735                 fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
5736                 if (fi == NULL) {
5737                         errno = ENOMEM;
5738                         return -1;
5739                 }
5740
5741                 fi->fd = libc_vfcntl(fd, cmd, va);
5742                 if (fi->fd == -1) {
5743                         int saved_errno = errno;
5744                         free(fi);
5745                         errno = saved_errno;
5746                         return -1;
5747                 }
5748
5749                 si->refcount++;
5750                 fi->si_index = src_fi->si_index;
5751
5752                 /* Make sure we don't have an entry for the fd */
5753                 swrap_remove_stale(fi->fd);
5754
5755                 SWRAP_DLIST_ADD_AFTER(socket_fds, fi, src_fi);
5756
5757                 rc = fi->fd;
5758                 break;
5759         default:
5760                 rc = libc_vfcntl(fd, cmd, va);
5761                 break;
5762         }
5763
5764         return rc;
5765 }
5766
5767 int fcntl(int fd, int cmd, ...)
5768 {
5769         va_list va;
5770         int rc;
5771
5772         va_start(va, cmd);
5773
5774         rc = swrap_vfcntl(fd, cmd, va);
5775
5776         va_end(va);
5777
5778         return rc;
5779 }
5780
5781 /****************************
5782  * EVENTFD
5783  ***************************/
5784
5785 #ifdef HAVE_EVENTFD
5786 static int swrap_eventfd(int count, int flags)
5787 {
5788         int fd;
5789
5790         fd = libc_eventfd(count, flags);
5791         if (fd != -1) {
5792                 swrap_remove_stale(fd);
5793         }
5794
5795         return fd;
5796 }
5797
5798 #ifdef HAVE_EVENTFD_UNSIGNED_INT
5799 int eventfd(unsigned int count, int flags)
5800 #else
5801 int eventfd(int count, int flags)
5802 #endif
5803 {
5804         return swrap_eventfd(count, flags);
5805 }
5806 #endif
5807
5808 #ifdef HAVE_PLEDGE
5809 int pledge(const char *promises, const char *paths[])
5810 {
5811         (void)promises; /* unused */
5812         (void)paths; /* unused */
5813
5814         return 0;
5815 }
5816 #endif /* HAVE_PLEDGE */
5817
5818 static void swrap_thread_prepare(void)
5819 {
5820         SWRAP_LOCK_ALL;
5821 }
5822
5823 static void swrap_thread_parent(void)
5824 {
5825         SWRAP_UNLOCK_ALL;
5826 }
5827
5828 static void swrap_thread_child(void)
5829 {
5830         SWRAP_UNLOCK_ALL;
5831 }
5832
5833 /****************************
5834  * CONSTRUCTOR
5835  ***************************/
5836 void swrap_constructor(void)
5837 {
5838         /*
5839         * If we hold a lock and the application forks, then the child
5840         * is not able to unlock the mutex and we are in a deadlock.
5841         * This should prevent such deadlocks.
5842         */
5843         pthread_atfork(&swrap_thread_prepare,
5844                        &swrap_thread_parent,
5845                        &swrap_thread_child);
5846 }
5847
5848 /****************************
5849  * DESTRUCTOR
5850  ***************************/
5851
5852 /*
5853  * This function is called when the library is unloaded and makes sure that
5854  * sockets get closed and the unix file for the socket are unlinked.
5855  */
5856 void swrap_destructor(void)
5857 {
5858         struct socket_info_fd *s = socket_fds;
5859
5860         while (s != NULL) {
5861                 swrap_close(s->fd);
5862                 s = socket_fds;
5863         }
5864
5865         free(sockets);
5866
5867         if (swrap.libc.handle != NULL) {
5868                 dlclose(swrap.libc.handle);
5869         }
5870         if (swrap.libc.socket_handle) {
5871                 dlclose(swrap.libc.socket_handle);
5872         }
5873 }