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