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