swrap: Use swrap_recvmsg_* in swrap_recvfrom().
[socket_wrapper.git] / src / socket_wrapper.c
1 /*
2  * Copyright (C) Jelmer Vernooij 2005,2008 <jelmer@samba.org>
3  * Copyright (C) Stefan Metzmacher 2006-2009 <metze@samba.org>
4  * Copyright (C) Andreas Schneider 2013 <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 #include <sys/uio.h>
54 #include <errno.h>
55 #include <sys/un.h>
56 #include <netinet/in.h>
57 #include <netinet/tcp.h>
58 #include <arpa/inet.h>
59 #include <fcntl.h>
60 #include <stdlib.h>
61 #include <string.h>
62 #include <stdio.h>
63 #include <stdint.h>
64 #include <stdarg.h>
65 #include <stdbool.h>
66 #include <unistd.h>
67
68 enum swrap_dbglvl_e {
69         SWRAP_LOG_ERROR = 0,
70         SWRAP_LOG_WARN,
71         SWRAP_LOG_DEBUG,
72         SWRAP_LOG_TRACE
73 };
74
75 /* GCC have printf type attribute check. */
76 #ifdef HAVE_FUNCTION_ATTRIBUTE_FORMAT
77 #define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
78 #else
79 #define PRINTF_ATTRIBUTE(a,b)
80 #endif /* HAVE_FUNCTION_ATTRIBUTE_FORMAT */
81
82 #ifdef HAVE_DESTRUCTOR_ATTRIBUTE
83 #define DESTRUCTOR_ATTRIBUTE __attribute__ ((destructor))
84 #else
85 #define DESTRUCTOR_ATTRIBUTE
86 #endif
87
88 #ifdef HAVE_GCC_THREAD_LOCAL_STORAGE
89 # define SWRAP_THREAD __thread
90 #else
91 # define SWRAP_THREAD
92 #endif
93
94 #ifndef MIN
95 #define MIN(a,b) ((a)<(b)?(a):(b))
96 #endif
97
98 #if SIZEOF_PID_T == 8
99 # define SPRIpid PRIu64
100 #elif SIZEOF_UID_T == 4
101 # define SPRIpid PRIu32
102 #else
103 # define SPRIpid "%d"       /* Sane default for most platforms */
104 #endif /* SIZEOF_UID_T */
105
106 #ifndef ZERO_STRUCT
107 #define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
108 #endif
109
110 #ifndef discard_const
111 #define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
112 #endif
113
114 #ifndef discard_const_p
115 #define discard_const_p(type, ptr) ((type *)discard_const(ptr))
116 #endif
117
118 #define SWRAP_DLIST_ADD(list,item) do { \
119         if (!(list)) { \
120                 (item)->prev    = NULL; \
121                 (item)->next    = NULL; \
122                 (list)          = (item); \
123         } else { \
124                 (item)->prev    = NULL; \
125                 (item)->next    = (list); \
126                 (list)->prev    = (item); \
127                 (list)          = (item); \
128         } \
129 } while (0)
130
131 #define SWRAP_DLIST_REMOVE(list,item) do { \
132         if ((list) == (item)) { \
133                 (list)          = (item)->next; \
134                 if (list) { \
135                         (list)->prev    = NULL; \
136                 } \
137         } else { \
138                 if ((item)->prev) { \
139                         (item)->prev->next      = (item)->next; \
140                 } \
141                 if ((item)->next) { \
142                         (item)->next->prev      = (item)->prev; \
143                 } \
144         } \
145         (item)->prev    = NULL; \
146         (item)->next    = NULL; \
147 } while (0)
148
149 #if defined(HAVE_GETTIMEOFDAY_TZ) || defined(HAVE_GETTIMEOFDAY_TZ_VOID)
150 #define swrapGetTimeOfDay(tval) gettimeofday(tval,NULL)
151 #else
152 #define swrapGetTimeOfDay(tval) gettimeofday(tval)
153 #endif
154
155 /* we need to use a very terse format here as IRIX 6.4 silently
156    truncates names to 16 chars, so if we use a longer name then we
157    can't tell which port a packet came from with recvfrom()
158
159    with this format we have 8 chars left for the directory name
160 */
161 #define SOCKET_FORMAT "%c%02X%04X"
162 #define SOCKET_TYPE_CHAR_TCP            'T'
163 #define SOCKET_TYPE_CHAR_UDP            'U'
164 #define SOCKET_TYPE_CHAR_TCP_V6         'X'
165 #define SOCKET_TYPE_CHAR_UDP_V6         'Y'
166
167 /*
168  * Cut down to 1500 byte packets for stream sockets,
169  * which makes it easier to format PCAP capture files
170  * (as the caller will simply continue from here)
171  */
172 #define SOCKET_MAX_PACKET 1500
173
174 #define SOCKET_MAX_SOCKETS 1024
175
176 /* This limit is to avoid broadcast sendto() needing to stat too many
177  * files.  It may be raised (with a performance cost) to up to 254
178  * without changing the format above */
179 #define MAX_WRAPPED_INTERFACES 40
180
181 struct socket_info_fd {
182         struct socket_info_fd *prev, *next;
183         int fd;
184 };
185
186 struct socket_info
187 {
188         struct socket_info_fd *fds;
189
190         int family;
191         int type;
192         int protocol;
193         int bound;
194         int bcast;
195         int is_server;
196         int connected;
197         int defer_connect;
198
199         char *tmp_path;
200
201         struct sockaddr *myname;
202         socklen_t myname_len;
203
204         struct sockaddr *peername;
205         socklen_t peername_len;
206
207         struct {
208                 unsigned long pck_snd;
209                 unsigned long pck_rcv;
210         } io;
211
212         struct socket_info *prev, *next;
213 };
214
215 /*
216  * File descriptors are shared between threads so we should share socket
217  * information too.
218  */
219 struct socket_info *sockets;
220
221 /* Function prototypes */
222
223 void swrap_destructor(void) DESTRUCTOR_ATTRIBUTE;
224
225 #ifdef NDEBUG
226 # define SWRAP_LOG(...)
227 #else
228
229 static void swrap_log(enum swrap_dbglvl_e dbglvl, const char *format, ...) PRINTF_ATTRIBUTE(2, 3);
230 # define SWRAP_LOG(dbglvl, ...) swrap_log((dbglvl), __VA_ARGS__)
231
232 static void swrap_log(enum swrap_dbglvl_e dbglvl, const char *format, ...)
233 {
234         char buffer[1024];
235         va_list va;
236         const char *d;
237         unsigned int lvl = 0;
238
239         d = getenv("SOCKET_WRAPPER_DEBUGLEVEL");
240         if (d != NULL) {
241                 lvl = atoi(d);
242         }
243
244         va_start(va, format);
245         vsnprintf(buffer, sizeof(buffer), format, va);
246         va_end(va);
247
248         if (lvl >= dbglvl) {
249                 switch (dbglvl) {
250                         case SWRAP_LOG_ERROR:
251                                 fprintf(stderr,
252                                         "SWRAP_ERROR("SPRIpid"): %s\n",
253                                         getpid(), buffer);
254                                 break;
255                         case SWRAP_LOG_WARN:
256                                 fprintf(stderr,
257                                         "SWRAP_WARN("SPRIpid"): %s\n",
258                                         getpid(), buffer);
259                                 break;
260                         case SWRAP_LOG_DEBUG:
261                                 fprintf(stderr,
262                                         "SWRAP_DEBUG("SPRIpid"): %s\n",
263                                         getpid(), buffer);
264                                 break;
265                         case SWRAP_LOG_TRACE:
266                                 fprintf(stderr,
267                                         "SWRAP_TRACE("SPRIpid"): %s\n",
268                                         getpid(), buffer);
269                                 break;
270                 }
271         }
272 }
273 #endif
274
275 /*********************************************************
276  * SWRAP LOADING LIBC FUNCTIONS
277  *********************************************************/
278
279 #include <dlfcn.h>
280
281 struct swrap_libc_fns {
282         int (*libc_accept)(int sockfd,
283                            struct sockaddr *addr,
284                            socklen_t *addrlen);
285         int (*libc_bind)(int sockfd,
286                          const struct sockaddr *addr,
287                          socklen_t addrlen);
288         int (*libc_close)(int fd);
289         int (*libc_connect)(int sockfd,
290                             const struct sockaddr *addr,
291                             socklen_t addrlen);
292         int (*libc_dup)(int fd);
293         int (*libc_dup2)(int oldfd, int newfd);
294         int (*libc_getpeername)(int sockfd,
295                                 struct sockaddr *addr,
296                                 socklen_t *addrlen);
297         int (*libc_getsockname)(int sockfd,
298                                 struct sockaddr *addr,
299                                 socklen_t *addrlen);
300         int (*libc_getsockopt)(int sockfd,
301                                int level,
302                                int optname,
303                                void *optval,
304                                socklen_t *optlen);
305         int (*libc_ioctl)(int d, unsigned long int request, ...);
306         int (*libc_listen)(int sockfd, int backlog);
307         int (*libc_read)(int fd, void *buf, size_t count);
308         ssize_t (*libc_readv)(int fd, const struct iovec *iov, int iovcnt);
309         int (*libc_recv)(int sockfd, void *buf, size_t len, int flags);
310         int (*libc_recvfrom)(int sockfd,
311                              void *buf,
312                              size_t len,
313                              int flags,
314                              struct sockaddr *src_addr,
315                              socklen_t *addrlen);
316         int (*libc_send)(int sockfd, const void *buf, size_t len, int flags);
317         int (*libc_sendmsg)(int sockfd, const struct msghdr *msg, int flags);
318         int (*libc_sendto)(int sockfd,
319                            const void *buf,
320                            size_t len,
321                            int flags,
322                            const  struct sockaddr *dst_addr,
323                            socklen_t addrlen);
324         int (*libc_setsockopt)(int sockfd,
325                                int level,
326                                int optname,
327                                const void *optval,
328                                socklen_t optlen);
329         int (*libc_socket)(int domain, int type, int protocol);
330         ssize_t (*libc_writev)(int fd, const struct iovec *iov, int iovcnt);
331 };
332
333 struct swrap {
334         void *libc_handle;
335         void *libsocket_handle;
336
337         bool initialised;
338         bool enabled;
339
340         char *socket_dir;
341
342         struct swrap_libc_fns fns;
343 };
344
345 static struct swrap swrap;
346
347 /* prototypes */
348 static const char *socket_wrapper_dir(void);
349
350 #define LIBC_NAME "libc.so"
351
352 enum swrap_lib {
353     SWRAP_LIBC,
354     SWRAP_LIBNSL,
355     SWRAP_LIBSOCKET,
356 };
357
358 #ifndef NDEBUG
359 static const char *swrap_str_lib(enum swrap_lib lib)
360 {
361         switch (lib) {
362         case SWRAP_LIBC:
363                 return "libc";
364         case SWRAP_LIBNSL:
365                 return "libnsl";
366         case SWRAP_LIBSOCKET:
367                 return "libsocket";
368         }
369
370         /* Compiler would warn us about unhandled enum value if we get here */
371         return "unknown";
372 }
373 #endif
374
375 static void *swrap_load_lib_handle(enum swrap_lib lib)
376 {
377         int flags = RTLD_LAZY;
378         void *handle = NULL;
379         int i;
380
381 #ifdef HAVE_APPLE
382         return RTLD_NEXT;
383 #endif
384
385 #ifdef RTLD_DEEPBIND
386         flags |= RTLD_DEEPBIND;
387 #endif
388
389         switch (lib) {
390         case SWRAP_LIBNSL:
391                 /* FALL TROUGH */
392         case SWRAP_LIBSOCKET:
393 #ifdef HAVE_LIBSOCKET
394                 handle = swrap.libsocket_handle;
395                 if (handle == NULL) {
396                         for (handle = NULL, i = 10; handle == NULL && i >= 0; i--) {
397                                 char soname[256] = {0};
398
399                                 snprintf(soname, sizeof(soname), "libsocket.so.%d", i);
400                                 handle = dlopen(soname, flags);
401                         }
402
403                         swrap.libsocket_handle = handle;
404                 }
405                 break;
406 #endif
407                 /* FALL TROUGH */
408         case SWRAP_LIBC:
409                 handle = swrap.libc_handle;
410                 if (handle == NULL) {
411                         for (handle = NULL, i = 10; handle == NULL && i >= 0; i--) {
412                                 char soname[256] = {0};
413
414                                 snprintf(soname, sizeof(soname), "libc.so.%d", i);
415                                 handle = dlopen(soname, flags);
416                         }
417
418                         swrap.libc_handle = handle;
419                 }
420                 break;
421         }
422
423         if (handle == NULL) {
424                 SWRAP_LOG(SWRAP_LOG_ERROR,
425                           "Failed to dlopen library: %s\n",
426                           dlerror());
427                 exit(-1);
428         }
429
430         return handle;
431 }
432
433 static void *_swrap_load_lib_function(enum swrap_lib lib, const char *fn_name)
434 {
435         void *handle;
436         void *func;
437
438         handle = swrap_load_lib_handle(lib);
439
440         func = dlsym(handle, fn_name);
441         if (func == NULL) {
442                 SWRAP_LOG(SWRAP_LOG_ERROR,
443                                 "Failed to find %s: %s\n",
444                                 fn_name, dlerror());
445                 exit(-1);
446         }
447
448         SWRAP_LOG(SWRAP_LOG_TRACE,
449                         "Loaded %s from %s",
450                         fn_name, swrap_str_lib(lib));
451         return func;
452 }
453
454 #define swrap_load_lib_function(lib, fn_name) \
455         if (swrap.fns.libc_##fn_name == NULL) { \
456                 *(void **) (&swrap.fns.libc_##fn_name) = \
457                         _swrap_load_lib_function(lib, #fn_name); \
458         }
459
460
461 /*
462  * IMPORTANT
463  *
464  * Functions expeciall from libc need to be loaded individually, you can't load
465  * all at once or gdb will segfault at startup. The same applies to valgrind and
466  * has probably something todo with with the linker.
467  * So we need load each function at the point it is called the first time.
468  */
469 static int libc_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
470 {
471         swrap_load_lib_function(SWRAP_LIBSOCKET, accept);
472
473         return swrap.fns.libc_accept(sockfd, addr, addrlen);
474 }
475
476 static int libc_bind(int sockfd,
477                      const struct sockaddr *addr,
478                      socklen_t addrlen)
479 {
480         swrap_load_lib_function(SWRAP_LIBSOCKET, bind);
481
482         return swrap.fns.libc_bind(sockfd, addr, addrlen);
483 }
484
485 static int libc_close(int fd)
486 {
487         swrap_load_lib_function(SWRAP_LIBC, close);
488
489         return swrap.fns.libc_close(fd);
490 }
491
492 static int libc_connect(int sockfd,
493                         const struct sockaddr *addr,
494                         socklen_t addrlen)
495 {
496         swrap_load_lib_function(SWRAP_LIBSOCKET, connect);
497
498         return swrap.fns.libc_connect(sockfd, addr, addrlen);
499 }
500
501 static int libc_dup(int fd)
502 {
503         swrap_load_lib_function(SWRAP_LIBC, dup);
504
505         return swrap.fns.libc_dup(fd);
506 }
507
508 static int libc_dup2(int oldfd, int newfd)
509 {
510         swrap_load_lib_function(SWRAP_LIBC, dup2);
511
512         return swrap.fns.libc_dup2(oldfd, newfd);
513 }
514
515 static int libc_getpeername(int sockfd,
516                             struct sockaddr *addr,
517                             socklen_t *addrlen)
518 {
519         swrap_load_lib_function(SWRAP_LIBSOCKET, getpeername);
520
521         return swrap.fns.libc_getpeername(sockfd, addr, addrlen);
522 }
523
524 static int libc_getsockname(int sockfd,
525                             struct sockaddr *addr,
526                             socklen_t *addrlen)
527 {
528         swrap_load_lib_function(SWRAP_LIBSOCKET, getsockname);
529
530         return swrap.fns.libc_getsockname(sockfd, addr, addrlen);
531 }
532
533 static int libc_getsockopt(int sockfd,
534                            int level,
535                            int optname,
536                            void *optval,
537                            socklen_t *optlen)
538 {
539         swrap_load_lib_function(SWRAP_LIBSOCKET, getsockopt);
540
541         return swrap.fns.libc_getsockopt(sockfd, level, optname, optval, optlen);
542 }
543
544 static int libc_vioctl(int d, unsigned long int request, va_list ap)
545 {
546         long int args[4];
547         int rc;
548         int i;
549
550         swrap_load_lib_function(SWRAP_LIBC, ioctl);
551
552         for (i = 0; i < 4; i++) {
553                 args[i] = va_arg(ap, long int);
554         }
555
556         rc = swrap.fns.libc_ioctl(d,
557                                   request,
558                                   args[0],
559                                   args[1],
560                                   args[2],
561                                   args[3]);
562
563         return rc;
564 }
565
566 static int libc_listen(int sockfd, int backlog)
567 {
568         swrap_load_lib_function(SWRAP_LIBSOCKET, listen);
569
570         return swrap.fns.libc_listen(sockfd, backlog);
571 }
572
573 static int libc_read(int fd, void *buf, size_t count)
574 {
575         swrap_load_lib_function(SWRAP_LIBC, read);
576
577         return swrap.fns.libc_read(fd, buf, count);
578 }
579
580 static ssize_t libc_readv(int fd, const struct iovec *iov, int iovcnt)
581 {
582         swrap_load_lib_function(SWRAP_LIBSOCKET, readv);
583
584         return swrap.fns.libc_readv(fd, iov, iovcnt);
585 }
586
587 static int libc_recv(int sockfd, void *buf, size_t len, int flags)
588 {
589         swrap_load_lib_function(SWRAP_LIBSOCKET, recv);
590
591         return swrap.fns.libc_recv(sockfd, buf, len, flags);
592 }
593
594 static int libc_recvfrom(int sockfd,
595                          void *buf,
596                          size_t len,
597                          int flags,
598                          struct sockaddr *src_addr,
599                          socklen_t *addrlen)
600 {
601         swrap_load_lib_function(SWRAP_LIBSOCKET, recvfrom);
602
603         return swrap.fns.libc_recvfrom(sockfd, buf, len, flags, src_addr, addrlen);
604 }
605
606 static int libc_send(int sockfd, const void *buf, size_t len, int flags)
607 {
608         swrap_load_lib_function(SWRAP_LIBSOCKET, send);
609
610         return swrap.fns.libc_send(sockfd, buf, len, flags);
611 }
612
613 static int libc_sendmsg(int sockfd, const struct msghdr *msg, int flags)
614 {
615         swrap_load_lib_function(SWRAP_LIBSOCKET, sendmsg);
616
617         return swrap.fns.libc_sendmsg(sockfd, msg, flags);
618 }
619
620 static int libc_sendto(int sockfd,
621                        const void *buf,
622                        size_t len,
623                        int flags,
624                        const  struct sockaddr *dst_addr,
625                        socklen_t addrlen)
626 {
627         swrap_load_lib_function(SWRAP_LIBSOCKET, sendto);
628
629         return swrap.fns.libc_sendto(sockfd, buf, len, flags, dst_addr, addrlen);
630 }
631
632 static int libc_setsockopt(int sockfd,
633                            int level,
634                            int optname,
635                            const void *optval,
636                            socklen_t optlen)
637 {
638         swrap_load_lib_function(SWRAP_LIBSOCKET, setsockopt);
639
640         return swrap.fns.libc_setsockopt(sockfd, level, optname, optval, optlen);
641 }
642
643 static int libc_socket(int domain, int type, int protocol)
644 {
645         swrap_load_lib_function(SWRAP_LIBSOCKET, socket);
646
647         return swrap.fns.libc_socket(domain, type, protocol);
648 }
649
650 static ssize_t libc_writev(int fd, const struct iovec *iov, int iovcnt)
651 {
652         swrap_load_lib_function(SWRAP_LIBSOCKET, writev);
653
654         return swrap.fns.libc_writev(fd, iov, iovcnt);
655 }
656
657 /*********************************************************
658  * SWRAP HELPER FUNCTIONS
659  *********************************************************/
660
661 #ifdef HAVE_IPV6
662 /*
663  * FD00::5357:5FXX
664  */
665 static const struct in6_addr *swrap_ipv6(void)
666 {
667         static struct in6_addr v;
668         static int initialized;
669         int ret;
670
671         if (initialized) {
672                 return &v;
673         }
674         initialized = 1;
675
676         ret = inet_pton(AF_INET6, "FD00::5357:5F00", &v);
677         if (ret <= 0) {
678                 abort();
679         }
680
681         return &v;
682 }
683 #endif
684
685 static struct sockaddr *sockaddr_dup(const void *data, socklen_t len)
686 {
687         struct sockaddr *ret = (struct sockaddr *)malloc(len);
688         memcpy(ret, data, len);
689         return ret;
690 }
691
692 static void set_port(int family, int prt, struct sockaddr *addr)
693 {
694         switch (family) {
695         case AF_INET:
696                 ((struct sockaddr_in *)addr)->sin_port = htons(prt);
697                 break;
698 #ifdef HAVE_IPV6
699         case AF_INET6:
700                 ((struct sockaddr_in6 *)addr)->sin6_port = htons(prt);
701                 break;
702 #endif
703         }
704 }
705
706 static size_t socket_length(int family)
707 {
708         switch (family) {
709         case AF_INET:
710                 return sizeof(struct sockaddr_in);
711 #ifdef HAVE_IPV6
712         case AF_INET6:
713                 return sizeof(struct sockaddr_in6);
714 #endif
715         }
716         return 0;
717 }
718
719 static const char *socket_wrapper_dir(void)
720 {
721         const char *s = getenv("SOCKET_WRAPPER_DIR");
722         if (s == NULL) {
723                 return NULL;
724         }
725         if (strncmp(s, "./", 2) == 0) {
726                 s += 2;
727         }
728
729         SWRAP_LOG(SWRAP_LOG_TRACE, "socket_wrapper_dir: %s", s);
730         return s;
731 }
732
733 static unsigned int socket_wrapper_default_iface(void)
734 {
735         const char *s = getenv("SOCKET_WRAPPER_DEFAULT_IFACE");
736         if (s) {
737                 unsigned int iface;
738                 if (sscanf(s, "%u", &iface) == 1) {
739                         if (iface >= 1 && iface <= MAX_WRAPPED_INTERFACES) {
740                                 return iface;
741                         }
742                 }
743         }
744
745         return 1;/* 127.0.0.1 */
746 }
747
748 static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, socklen_t *len)
749 {
750         unsigned int iface;
751         unsigned int prt;
752         const char *p;
753         char type;
754
755         p = strrchr(un->sun_path, '/');
756         if (p) p++; else p = un->sun_path;
757
758         if (sscanf(p, SOCKET_FORMAT, &type, &iface, &prt) != 3) {
759                 errno = EINVAL;
760                 return -1;
761         }
762
763         SWRAP_LOG(SWRAP_LOG_TRACE, "type %c iface %u port %u",
764                         type, iface, prt);
765
766         if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
767                 errno = EINVAL;
768                 return -1;
769         }
770
771         if (prt > 0xFFFF) {
772                 errno = EINVAL;
773                 return -1;
774         }
775
776         switch(type) {
777         case SOCKET_TYPE_CHAR_TCP:
778         case SOCKET_TYPE_CHAR_UDP: {
779                 struct sockaddr_in *in2 = (struct sockaddr_in *)(void *)in;
780
781                 if ((*len) < sizeof(*in2)) {
782                     errno = EINVAL;
783                     return -1;
784                 }
785
786                 memset(in2, 0, sizeof(*in2));
787                 in2->sin_family = AF_INET;
788                 in2->sin_addr.s_addr = htonl((127<<24) | iface);
789                 in2->sin_port = htons(prt);
790
791                 *len = sizeof(*in2);
792                 break;
793         }
794 #ifdef HAVE_IPV6
795         case SOCKET_TYPE_CHAR_TCP_V6:
796         case SOCKET_TYPE_CHAR_UDP_V6: {
797                 struct sockaddr_in6 *in2 = (struct sockaddr_in6 *)(void *)in;
798
799                 if ((*len) < sizeof(*in2)) {
800                         errno = EINVAL;
801                         return -1;
802                 }
803
804                 memset(in2, 0, sizeof(*in2));
805                 in2->sin6_family = AF_INET6;
806                 in2->sin6_addr = *swrap_ipv6();
807                 in2->sin6_addr.s6_addr[15] = iface;
808                 in2->sin6_port = htons(prt);
809
810                 *len = sizeof(*in2);
811                 break;
812         }
813 #endif
814         default:
815                 errno = EINVAL;
816                 return -1;
817         }
818
819         return 0;
820 }
821
822 static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un,
823                                 int *bcast)
824 {
825         char type = '\0';
826         unsigned int prt;
827         unsigned int iface;
828         int is_bcast = 0;
829
830         if (bcast) *bcast = 0;
831
832         switch (inaddr->sa_family) {
833         case AF_INET: {
834                 const struct sockaddr_in *in = 
835                     (const struct sockaddr_in *)(const void *)inaddr;
836                 unsigned int addr = ntohl(in->sin_addr.s_addr);
837                 char u_type = '\0';
838                 char b_type = '\0';
839                 char a_type = '\0';
840
841                 switch (si->type) {
842                 case SOCK_STREAM:
843                         u_type = SOCKET_TYPE_CHAR_TCP;
844                         break;
845                 case SOCK_DGRAM:
846                         u_type = SOCKET_TYPE_CHAR_UDP;
847                         a_type = SOCKET_TYPE_CHAR_UDP;
848                         b_type = SOCKET_TYPE_CHAR_UDP;
849                         break;
850                 default:
851                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
852                         errno = ESOCKTNOSUPPORT;
853                         return -1;
854                 }
855
856                 prt = ntohs(in->sin_port);
857                 if (a_type && addr == 0xFFFFFFFF) {
858                         /* 255.255.255.255 only udp */
859                         is_bcast = 2;
860                         type = a_type;
861                         iface = socket_wrapper_default_iface();
862                 } else if (b_type && addr == 0x7FFFFFFF) {
863                         /* 127.255.255.255 only udp */
864                         is_bcast = 1;
865                         type = b_type;
866                         iface = socket_wrapper_default_iface();
867                 } else if ((addr & 0xFFFFFF00) == 0x7F000000) {
868                         /* 127.0.0.X */
869                         is_bcast = 0;
870                         type = u_type;
871                         iface = (addr & 0x000000FF);
872                 } else {
873                         errno = ENETUNREACH;
874                         return -1;
875                 }
876                 if (bcast) *bcast = is_bcast;
877                 break;
878         }
879 #ifdef HAVE_IPV6
880         case AF_INET6: {
881                 const struct sockaddr_in6 *in = 
882                     (const struct sockaddr_in6 *)(const void *)inaddr;
883                 struct in6_addr cmp1, cmp2;
884
885                 switch (si->type) {
886                 case SOCK_STREAM:
887                         type = SOCKET_TYPE_CHAR_TCP_V6;
888                         break;
889                 case SOCK_DGRAM:
890                         type = SOCKET_TYPE_CHAR_UDP_V6;
891                         break;
892                 default:
893                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
894                         errno = ESOCKTNOSUPPORT;
895                         return -1;
896                 }
897
898                 /* XXX no multicast/broadcast */
899
900                 prt = ntohs(in->sin6_port);
901
902                 cmp1 = *swrap_ipv6();
903                 cmp2 = in->sin6_addr;
904                 cmp2.s6_addr[15] = 0;
905                 if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
906                         iface = in->sin6_addr.s6_addr[15];
907                 } else {
908                         errno = ENETUNREACH;
909                         return -1;
910                 }
911
912                 break;
913         }
914 #endif
915         default:
916                 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family!\n");
917                 errno = ENETUNREACH;
918                 return -1;
919         }
920
921         if (prt == 0) {
922                 SWRAP_LOG(SWRAP_LOG_WARN, "Port not set\n");
923                 errno = EINVAL;
924                 return -1;
925         }
926
927         if (is_bcast) {
928                 snprintf(un->sun_path, sizeof(un->sun_path), "%s/EINVAL", 
929                          socket_wrapper_dir());
930                 SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
931                 /* the caller need to do more processing */
932                 return 0;
933         }
934
935         snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, 
936                  socket_wrapper_dir(), type, iface, prt);
937         SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
938
939         return 0;
940 }
941
942 static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un,
943                                int *bcast)
944 {
945         char type = '\0';
946         unsigned int prt;
947         unsigned int iface;
948         struct stat st;
949         int is_bcast = 0;
950
951         if (bcast) *bcast = 0;
952
953         switch (si->family) {
954         case AF_INET: {
955                 const struct sockaddr_in *in = 
956                     (const struct sockaddr_in *)(const void *)inaddr;
957                 unsigned int addr = ntohl(in->sin_addr.s_addr);
958                 char u_type = '\0';
959                 char d_type = '\0';
960                 char b_type = '\0';
961                 char a_type = '\0';
962
963                 prt = ntohs(in->sin_port);
964
965                 switch (si->type) {
966                 case SOCK_STREAM:
967                         u_type = SOCKET_TYPE_CHAR_TCP;
968                         d_type = SOCKET_TYPE_CHAR_TCP;
969                         break;
970                 case SOCK_DGRAM:
971                         u_type = SOCKET_TYPE_CHAR_UDP;
972                         d_type = SOCKET_TYPE_CHAR_UDP;
973                         a_type = SOCKET_TYPE_CHAR_UDP;
974                         b_type = SOCKET_TYPE_CHAR_UDP;
975                         break;
976                 default:
977                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
978                         errno = ESOCKTNOSUPPORT;
979                         return -1;
980                 }
981
982                 if (addr == 0) {
983                         /* 0.0.0.0 */
984                         is_bcast = 0;
985                         type = d_type;
986                         iface = socket_wrapper_default_iface();
987                 } else if (a_type && addr == 0xFFFFFFFF) {
988                         /* 255.255.255.255 only udp */
989                         is_bcast = 2;
990                         type = a_type;
991                         iface = socket_wrapper_default_iface();
992                 } else if (b_type && addr == 0x7FFFFFFF) {
993                         /* 127.255.255.255 only udp */
994                         is_bcast = 1;
995                         type = b_type;
996                         iface = socket_wrapper_default_iface();
997                 } else if ((addr & 0xFFFFFF00) == 0x7F000000) {
998                         /* 127.0.0.X */
999                         is_bcast = 0;
1000                         type = u_type;
1001                         iface = (addr & 0x000000FF);
1002                 } else {
1003                         errno = EADDRNOTAVAIL;
1004                         return -1;
1005                 }
1006                 break;
1007         }
1008 #ifdef HAVE_IPV6
1009         case AF_INET6: {
1010                 const struct sockaddr_in6 *in = 
1011                     (const struct sockaddr_in6 *)(const void *)inaddr;
1012                 struct in6_addr cmp1, cmp2;
1013
1014                 switch (si->type) {
1015                 case SOCK_STREAM:
1016                         type = SOCKET_TYPE_CHAR_TCP_V6;
1017                         break;
1018                 case SOCK_DGRAM:
1019                         type = SOCKET_TYPE_CHAR_UDP_V6;
1020                         break;
1021                 default:
1022                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1023                         errno = ESOCKTNOSUPPORT;
1024                         return -1;
1025                 }
1026
1027                 /* XXX no multicast/broadcast */
1028
1029                 prt = ntohs(in->sin6_port);
1030
1031                 cmp1 = *swrap_ipv6();
1032                 cmp2 = in->sin6_addr;
1033                 cmp2.s6_addr[15] = 0;
1034                 if (IN6_IS_ADDR_UNSPECIFIED(&in->sin6_addr)) {
1035                         iface = socket_wrapper_default_iface();
1036                 } else if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
1037                         iface = in->sin6_addr.s6_addr[15];
1038                 } else {
1039                         errno = EADDRNOTAVAIL;
1040                         return -1;
1041                 }
1042
1043                 break;
1044         }
1045 #endif
1046         default:
1047                 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n");
1048                 errno = EADDRNOTAVAIL;
1049                 return -1;
1050         }
1051
1052
1053         if (bcast) *bcast = is_bcast;
1054
1055         if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
1056                 errno = EINVAL;
1057                 return -1;
1058         }
1059
1060         if (prt == 0) {
1061                 /* handle auto-allocation of ephemeral ports */
1062                 for (prt = 5001; prt < 10000; prt++) {
1063                         snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, 
1064                                  socket_wrapper_dir(), type, iface, prt);
1065                         if (stat(un->sun_path, &st) == 0) continue;
1066
1067                         set_port(si->family, prt, si->myname);
1068                         break;
1069                 }
1070                 if (prt == 10000) {
1071                         errno = ENFILE;
1072                         return -1;
1073                 }
1074         }
1075
1076         snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, 
1077                  socket_wrapper_dir(), type, iface, prt);
1078         SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
1079         return 0;
1080 }
1081
1082 static struct socket_info *find_socket_info(int fd)
1083 {
1084         struct socket_info *i;
1085
1086         for (i = sockets; i; i = i->next) {
1087                 struct socket_info_fd *f;
1088                 for (f = i->fds; f; f = f->next) {
1089                         if (f->fd == fd) {
1090                                 return i;
1091                         }
1092                 }
1093         }
1094
1095         return NULL;
1096 }
1097
1098 static int sockaddr_convert_to_un(struct socket_info *si,
1099                                   const struct sockaddr *in_addr,
1100                                   socklen_t in_len,
1101                                   struct sockaddr_un *out_addr,
1102                                   int alloc_sock,
1103                                   int *bcast)
1104 {
1105         struct sockaddr *out = (struct sockaddr *)(void *)out_addr;
1106
1107         (void) in_len; /* unused */
1108
1109         if (out_addr == NULL) {
1110                 return 0;
1111         }
1112
1113         out->sa_family = AF_UNIX;
1114 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
1115         out->sa_len = sizeof(*out_addr);
1116 #endif
1117
1118         switch (in_addr->sa_family) {
1119         case AF_INET:
1120 #ifdef HAVE_IPV6
1121         case AF_INET6:
1122 #endif
1123                 switch (si->type) {
1124                 case SOCK_STREAM:
1125                 case SOCK_DGRAM:
1126                         break;
1127                 default:
1128                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1129                         errno = ESOCKTNOSUPPORT;
1130                         return -1;
1131                 }
1132                 if (alloc_sock) {
1133                         return convert_in_un_alloc(si, in_addr, out_addr, bcast);
1134                 } else {
1135                         return convert_in_un_remote(si, in_addr, out_addr, bcast);
1136                 }
1137         default:
1138                 break;
1139         }
1140
1141         errno = EAFNOSUPPORT;
1142         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n");
1143         return -1;
1144 }
1145
1146 static int sockaddr_convert_from_un(const struct socket_info *si, 
1147                                     const struct sockaddr_un *in_addr, 
1148                                     socklen_t un_addrlen,
1149                                     int family,
1150                                     struct sockaddr *out_addr,
1151                                     socklen_t *out_addrlen)
1152 {
1153         int ret;
1154
1155         if (out_addr == NULL || out_addrlen == NULL) 
1156                 return 0;
1157
1158         if (un_addrlen == 0) {
1159                 *out_addrlen = 0;
1160                 return 0;
1161         }
1162
1163         switch (family) {
1164         case AF_INET:
1165 #ifdef HAVE_IPV6
1166         case AF_INET6:
1167 #endif
1168                 switch (si->type) {
1169                 case SOCK_STREAM:
1170                 case SOCK_DGRAM:
1171                         break;
1172                 default:
1173                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1174                         errno = ESOCKTNOSUPPORT;
1175                         return -1;
1176                 }
1177                 ret = convert_un_in(in_addr, out_addr, out_addrlen);
1178 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
1179                 out_addr->sa_len = *out_addrlen;
1180 #endif
1181                 return ret;
1182         default:
1183                 break;
1184         }
1185
1186         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n");
1187         errno = EAFNOSUPPORT;
1188         return -1;
1189 }
1190
1191 enum swrap_packet_type {
1192         SWRAP_CONNECT_SEND,
1193         SWRAP_CONNECT_UNREACH,
1194         SWRAP_CONNECT_RECV,
1195         SWRAP_CONNECT_ACK,
1196         SWRAP_ACCEPT_SEND,
1197         SWRAP_ACCEPT_RECV,
1198         SWRAP_ACCEPT_ACK,
1199         SWRAP_RECVFROM,
1200         SWRAP_SENDTO,
1201         SWRAP_SENDTO_UNREACH,
1202         SWRAP_PENDING_RST,
1203         SWRAP_RECV,
1204         SWRAP_RECV_RST,
1205         SWRAP_SEND,
1206         SWRAP_SEND_RST,
1207         SWRAP_CLOSE_SEND,
1208         SWRAP_CLOSE_RECV,
1209         SWRAP_CLOSE_ACK,
1210 };
1211
1212 struct swrap_file_hdr {
1213         uint32_t        magic;
1214         uint16_t        version_major;
1215         uint16_t        version_minor;
1216         int32_t         timezone;
1217         uint32_t        sigfigs;
1218         uint32_t        frame_max_len;
1219 #define SWRAP_FRAME_LENGTH_MAX 0xFFFF
1220         uint32_t        link_type;
1221 };
1222 #define SWRAP_FILE_HDR_SIZE 24
1223
1224 struct swrap_packet_frame {
1225         uint32_t seconds;
1226         uint32_t micro_seconds;
1227         uint32_t recorded_length;
1228         uint32_t full_length;
1229 };
1230 #define SWRAP_PACKET_FRAME_SIZE 16
1231
1232 union swrap_packet_ip {
1233         struct {
1234                 uint8_t         ver_hdrlen;
1235                 uint8_t         tos;
1236                 uint16_t        packet_length;
1237                 uint16_t        identification;
1238                 uint8_t         flags;
1239                 uint8_t         fragment;
1240                 uint8_t         ttl;
1241                 uint8_t         protocol;
1242                 uint16_t        hdr_checksum;
1243                 uint32_t        src_addr;
1244                 uint32_t        dest_addr;
1245         } v4;
1246 #define SWRAP_PACKET_IP_V4_SIZE 20
1247         struct {
1248                 uint8_t         ver_prio;
1249                 uint8_t         flow_label_high;
1250                 uint16_t        flow_label_low;
1251                 uint16_t        payload_length;
1252                 uint8_t         next_header;
1253                 uint8_t         hop_limit;
1254                 uint8_t         src_addr[16];
1255                 uint8_t         dest_addr[16];
1256         } v6;
1257 #define SWRAP_PACKET_IP_V6_SIZE 40
1258 };
1259 #define SWRAP_PACKET_IP_SIZE 40
1260
1261 union swrap_packet_payload {
1262         struct {
1263                 uint16_t        source_port;
1264                 uint16_t        dest_port;
1265                 uint32_t        seq_num;
1266                 uint32_t        ack_num;
1267                 uint8_t         hdr_length;
1268                 uint8_t         control;
1269                 uint16_t        window;
1270                 uint16_t        checksum;
1271                 uint16_t        urg;
1272         } tcp;
1273 #define SWRAP_PACKET_PAYLOAD_TCP_SIZE 20
1274         struct {
1275                 uint16_t        source_port;
1276                 uint16_t        dest_port;
1277                 uint16_t        length;
1278                 uint16_t        checksum;
1279         } udp;
1280 #define SWRAP_PACKET_PAYLOAD_UDP_SIZE 8
1281         struct {
1282                 uint8_t         type;
1283                 uint8_t         code;
1284                 uint16_t        checksum;
1285                 uint32_t        unused;
1286         } icmp4;
1287 #define SWRAP_PACKET_PAYLOAD_ICMP4_SIZE 8
1288         struct {
1289                 uint8_t         type;
1290                 uint8_t         code;
1291                 uint16_t        checksum;
1292                 uint32_t        unused;
1293         } icmp6;
1294 #define SWRAP_PACKET_PAYLOAD_ICMP6_SIZE 8
1295 };
1296 #define SWRAP_PACKET_PAYLOAD_SIZE 20
1297
1298 #define SWRAP_PACKET_MIN_ALLOC \
1299         (SWRAP_PACKET_FRAME_SIZE + \
1300          SWRAP_PACKET_IP_SIZE + \
1301          SWRAP_PACKET_PAYLOAD_SIZE)
1302
1303 static const char *socket_wrapper_pcap_file(void)
1304 {
1305         static int initialized = 0;
1306         static const char *s = NULL;
1307         static const struct swrap_file_hdr h;
1308         static const struct swrap_packet_frame f;
1309         static const union swrap_packet_ip i;
1310         static const union swrap_packet_payload p;
1311
1312         if (initialized == 1) {
1313                 return s;
1314         }
1315         initialized = 1;
1316
1317         /*
1318          * TODO: don't use the structs use plain buffer offsets
1319          *       and PUSH_U8(), PUSH_U16() and PUSH_U32()
1320          * 
1321          * for now make sure we disable PCAP support
1322          * if the struct has alignment!
1323          */
1324         if (sizeof(h) != SWRAP_FILE_HDR_SIZE) {
1325                 return NULL;
1326         }
1327         if (sizeof(f) != SWRAP_PACKET_FRAME_SIZE) {
1328                 return NULL;
1329         }
1330         if (sizeof(i) != SWRAP_PACKET_IP_SIZE) {
1331                 return NULL;
1332         }
1333         if (sizeof(i.v4) != SWRAP_PACKET_IP_V4_SIZE) {
1334                 return NULL;
1335         }
1336         if (sizeof(i.v6) != SWRAP_PACKET_IP_V6_SIZE) {
1337                 return NULL;
1338         }
1339         if (sizeof(p) != SWRAP_PACKET_PAYLOAD_SIZE) {
1340                 return NULL;
1341         }
1342         if (sizeof(p.tcp) != SWRAP_PACKET_PAYLOAD_TCP_SIZE) {
1343                 return NULL;
1344         }
1345         if (sizeof(p.udp) != SWRAP_PACKET_PAYLOAD_UDP_SIZE) {
1346                 return NULL;
1347         }
1348         if (sizeof(p.icmp4) != SWRAP_PACKET_PAYLOAD_ICMP4_SIZE) {
1349                 return NULL;
1350         }
1351         if (sizeof(p.icmp6) != SWRAP_PACKET_PAYLOAD_ICMP6_SIZE) {
1352                 return NULL;
1353         }
1354
1355         s = getenv("SOCKET_WRAPPER_PCAP_FILE");
1356         if (s == NULL) {
1357                 return NULL;
1358         }
1359         if (strncmp(s, "./", 2) == 0) {
1360                 s += 2;
1361         }
1362         return s;
1363 }
1364
1365 static uint8_t *swrap_packet_init(struct timeval *tval,
1366                                   const struct sockaddr *src,
1367                                   const struct sockaddr *dest,
1368                                   int socket_type,
1369                                   const uint8_t *payload,
1370                                   size_t payload_len,
1371                                   unsigned long tcp_seqno,
1372                                   unsigned long tcp_ack,
1373                                   unsigned char tcp_ctl,
1374                                   int unreachable,
1375                                   size_t *_packet_len)
1376 {
1377         uint8_t *base;
1378         uint8_t *buf;
1379         struct swrap_packet_frame *frame;
1380         union swrap_packet_ip *ip;
1381         union swrap_packet_payload *pay;
1382         size_t packet_len;
1383         size_t alloc_len;
1384         size_t nonwire_len = sizeof(*frame);
1385         size_t wire_hdr_len = 0;
1386         size_t wire_len = 0;
1387         size_t ip_hdr_len = 0;
1388         size_t icmp_hdr_len = 0;
1389         size_t icmp_truncate_len = 0;
1390         uint8_t protocol = 0, icmp_protocol = 0;
1391         const struct sockaddr_in *src_in = NULL;
1392         const struct sockaddr_in *dest_in = NULL;
1393 #ifdef HAVE_IPV6
1394         const struct sockaddr_in6 *src_in6 = NULL;
1395         const struct sockaddr_in6 *dest_in6 = NULL;
1396 #endif
1397         uint16_t src_port;
1398         uint16_t dest_port;
1399
1400         switch (src->sa_family) {
1401         case AF_INET:
1402                 src_in = (const struct sockaddr_in *)src;
1403                 dest_in = (const struct sockaddr_in *)dest;
1404                 src_port = src_in->sin_port;
1405                 dest_port = dest_in->sin_port;
1406                 ip_hdr_len = sizeof(ip->v4);
1407                 break;
1408 #ifdef HAVE_IPV6
1409         case AF_INET6:
1410                 src_in6 = (const struct sockaddr_in6 *)src;
1411                 dest_in6 = (const struct sockaddr_in6 *)dest;
1412                 src_port = src_in6->sin6_port;
1413                 dest_port = dest_in6->sin6_port;
1414                 ip_hdr_len = sizeof(ip->v6);
1415                 break;
1416 #endif
1417         default:
1418                 return NULL;
1419         }
1420
1421         switch (socket_type) {
1422         case SOCK_STREAM:
1423                 protocol = 0x06; /* TCP */
1424                 wire_hdr_len = ip_hdr_len + sizeof(pay->tcp);
1425                 wire_len = wire_hdr_len + payload_len;
1426                 break;
1427
1428         case SOCK_DGRAM:
1429                 protocol = 0x11; /* UDP */
1430                 wire_hdr_len = ip_hdr_len + sizeof(pay->udp);
1431                 wire_len = wire_hdr_len + payload_len;
1432                 break;
1433
1434         default:
1435                 return NULL;
1436         }
1437
1438         if (unreachable) {
1439                 icmp_protocol = protocol;
1440                 switch (src->sa_family) {
1441                 case AF_INET:
1442                         protocol = 0x01; /* ICMPv4 */
1443                         icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp4);
1444                         break;
1445 #ifdef HAVE_IPV6
1446                 case AF_INET6:
1447                         protocol = 0x3A; /* ICMPv6 */
1448                         icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp6);
1449                         break;
1450 #endif
1451                 }
1452                 if (wire_len > 64 ) {
1453                         icmp_truncate_len = wire_len - 64;
1454                 }
1455                 wire_hdr_len += icmp_hdr_len;
1456                 wire_len += icmp_hdr_len;
1457         }
1458
1459         packet_len = nonwire_len + wire_len;
1460         alloc_len = packet_len;
1461         if (alloc_len < SWRAP_PACKET_MIN_ALLOC) {
1462                 alloc_len = SWRAP_PACKET_MIN_ALLOC;
1463         }
1464
1465         base = (uint8_t *)malloc(alloc_len);
1466         if (!base) return NULL;
1467
1468         buf = base;
1469
1470         frame = (struct swrap_packet_frame *)buf;
1471         frame->seconds          = tval->tv_sec;
1472         frame->micro_seconds    = tval->tv_usec;
1473         frame->recorded_length  = wire_len - icmp_truncate_len;
1474         frame->full_length      = wire_len - icmp_truncate_len;
1475         buf += SWRAP_PACKET_FRAME_SIZE;
1476
1477         ip = (union swrap_packet_ip *)buf;
1478         switch (src->sa_family) {
1479         case AF_INET:
1480                 ip->v4.ver_hdrlen       = 0x45; /* version 4 and 5 * 32 bit words */
1481                 ip->v4.tos              = 0x00;
1482                 ip->v4.packet_length    = htons(wire_len - icmp_truncate_len);
1483                 ip->v4.identification   = htons(0xFFFF);
1484                 ip->v4.flags            = 0x40; /* BIT 1 set - means don't fraqment */
1485                 ip->v4.fragment         = htons(0x0000);
1486                 ip->v4.ttl              = 0xFF;
1487                 ip->v4.protocol         = protocol;
1488                 ip->v4.hdr_checksum     = htons(0x0000);
1489                 ip->v4.src_addr         = src_in->sin_addr.s_addr;
1490                 ip->v4.dest_addr        = dest_in->sin_addr.s_addr;
1491                 buf += SWRAP_PACKET_IP_V4_SIZE;
1492                 break;
1493 #ifdef HAVE_IPV6
1494         case AF_INET6:
1495                 ip->v6.ver_prio         = 0x60; /* version 4 and 5 * 32 bit words */
1496                 ip->v6.flow_label_high  = 0x00;
1497                 ip->v6.flow_label_low   = 0x0000;
1498                 ip->v6.payload_length   = htons(wire_len - icmp_truncate_len); /* TODO */
1499                 ip->v6.next_header      = protocol;
1500                 memcpy(ip->v6.src_addr, src_in6->sin6_addr.s6_addr, 16);
1501                 memcpy(ip->v6.dest_addr, dest_in6->sin6_addr.s6_addr, 16);
1502                 buf += SWRAP_PACKET_IP_V6_SIZE;
1503                 break;
1504 #endif
1505         }
1506
1507         if (unreachable) {
1508                 pay = (union swrap_packet_payload *)buf;
1509                 switch (src->sa_family) {
1510                 case AF_INET:
1511                         pay->icmp4.type         = 0x03; /* destination unreachable */
1512                         pay->icmp4.code         = 0x01; /* host unreachable */
1513                         pay->icmp4.checksum     = htons(0x0000);
1514                         pay->icmp4.unused       = htonl(0x00000000);
1515                         buf += SWRAP_PACKET_PAYLOAD_ICMP4_SIZE;
1516
1517                         /* set the ip header in the ICMP payload */
1518                         ip = (union swrap_packet_ip *)buf;
1519                         ip->v4.ver_hdrlen       = 0x45; /* version 4 and 5 * 32 bit words */
1520                         ip->v4.tos              = 0x00;
1521                         ip->v4.packet_length    = htons(wire_len - icmp_hdr_len);
1522                         ip->v4.identification   = htons(0xFFFF);
1523                         ip->v4.flags            = 0x40; /* BIT 1 set - means don't fraqment */
1524                         ip->v4.fragment         = htons(0x0000);
1525                         ip->v4.ttl              = 0xFF;
1526                         ip->v4.protocol         = icmp_protocol;
1527                         ip->v4.hdr_checksum     = htons(0x0000);
1528                         ip->v4.src_addr         = dest_in->sin_addr.s_addr;
1529                         ip->v4.dest_addr        = src_in->sin_addr.s_addr;
1530                         buf += SWRAP_PACKET_IP_V4_SIZE;
1531
1532                         src_port = dest_in->sin_port;
1533                         dest_port = src_in->sin_port;
1534                         break;
1535 #ifdef HAVE_IPV6
1536                 case AF_INET6:
1537                         pay->icmp6.type         = 0x01; /* destination unreachable */
1538                         pay->icmp6.code         = 0x03; /* address unreachable */
1539                         pay->icmp6.checksum     = htons(0x0000);
1540                         pay->icmp6.unused       = htonl(0x00000000);
1541                         buf += SWRAP_PACKET_PAYLOAD_ICMP6_SIZE;
1542
1543                         /* set the ip header in the ICMP payload */
1544                         ip = (union swrap_packet_ip *)buf;
1545                         ip->v6.ver_prio         = 0x60; /* version 4 and 5 * 32 bit words */
1546                         ip->v6.flow_label_high  = 0x00;
1547                         ip->v6.flow_label_low   = 0x0000;
1548                         ip->v6.payload_length   = htons(wire_len - icmp_truncate_len); /* TODO */
1549                         ip->v6.next_header      = protocol;
1550                         memcpy(ip->v6.src_addr, dest_in6->sin6_addr.s6_addr, 16);
1551                         memcpy(ip->v6.dest_addr, src_in6->sin6_addr.s6_addr, 16);
1552                         buf += SWRAP_PACKET_IP_V6_SIZE;
1553
1554                         src_port = dest_in6->sin6_port;
1555                         dest_port = src_in6->sin6_port;
1556                         break;
1557 #endif
1558                 }
1559         }
1560
1561         pay = (union swrap_packet_payload *)buf;
1562
1563         switch (socket_type) {
1564         case SOCK_STREAM:
1565                 pay->tcp.source_port    = src_port;
1566                 pay->tcp.dest_port      = dest_port;
1567                 pay->tcp.seq_num        = htonl(tcp_seqno);
1568                 pay->tcp.ack_num        = htonl(tcp_ack);
1569                 pay->tcp.hdr_length     = 0x50; /* 5 * 32 bit words */
1570                 pay->tcp.control        = tcp_ctl;
1571                 pay->tcp.window         = htons(0x7FFF);
1572                 pay->tcp.checksum       = htons(0x0000);
1573                 pay->tcp.urg            = htons(0x0000);
1574                 buf += SWRAP_PACKET_PAYLOAD_TCP_SIZE;
1575
1576                 break;
1577
1578         case SOCK_DGRAM:
1579                 pay->udp.source_port    = src_port;
1580                 pay->udp.dest_port      = dest_port;
1581                 pay->udp.length         = htons(8 + payload_len);
1582                 pay->udp.checksum       = htons(0x0000);
1583                 buf += SWRAP_PACKET_PAYLOAD_UDP_SIZE;
1584
1585                 break;
1586         }
1587
1588         if (payload && payload_len > 0) {
1589                 memcpy(buf, payload, payload_len);
1590         }
1591
1592         *_packet_len = packet_len - icmp_truncate_len;
1593         return base;
1594 }
1595
1596 static int swrap_get_pcap_fd(const char *fname)
1597 {
1598         static int fd = -1;
1599
1600         if (fd != -1) return fd;
1601
1602         fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0644);
1603         if (fd != -1) {
1604                 struct swrap_file_hdr file_hdr;
1605                 file_hdr.magic          = 0xA1B2C3D4;
1606                 file_hdr.version_major  = 0x0002;       
1607                 file_hdr.version_minor  = 0x0004;
1608                 file_hdr.timezone       = 0x00000000;
1609                 file_hdr.sigfigs        = 0x00000000;
1610                 file_hdr.frame_max_len  = SWRAP_FRAME_LENGTH_MAX;
1611                 file_hdr.link_type      = 0x0065; /* 101 RAW IP */
1612
1613                 if (write(fd, &file_hdr, sizeof(file_hdr)) != sizeof(file_hdr)) {
1614                         close(fd);
1615                         fd = -1;
1616                 }
1617                 return fd;
1618         }
1619
1620         fd = open(fname, O_WRONLY|O_APPEND, 0644);
1621
1622         return fd;
1623 }
1624
1625 static uint8_t *swrap_marshall_packet(struct socket_info *si,
1626                                       const struct sockaddr *addr,
1627                                       enum swrap_packet_type type,
1628                                       const void *buf, size_t len,
1629                                       size_t *packet_len)
1630 {
1631         const struct sockaddr *src_addr;
1632         const struct sockaddr *dest_addr;
1633         unsigned long tcp_seqno = 0;
1634         unsigned long tcp_ack = 0;
1635         unsigned char tcp_ctl = 0;
1636         int unreachable = 0;
1637
1638         struct timeval tv;
1639
1640         switch (si->family) {
1641         case AF_INET:
1642                 break;
1643 #ifdef HAVE_IPV6
1644         case AF_INET6:
1645                 break;
1646 #endif
1647         default:
1648                 return NULL;
1649         }
1650
1651         switch (type) {
1652         case SWRAP_CONNECT_SEND:
1653                 if (si->type != SOCK_STREAM) return NULL;
1654
1655                 src_addr = si->myname;
1656                 dest_addr = addr;
1657
1658                 tcp_seqno = si->io.pck_snd;
1659                 tcp_ack = si->io.pck_rcv;
1660                 tcp_ctl = 0x02; /* SYN */
1661
1662                 si->io.pck_snd += 1;
1663
1664                 break;
1665
1666         case SWRAP_CONNECT_RECV:
1667                 if (si->type != SOCK_STREAM) return NULL;
1668
1669                 dest_addr = si->myname;
1670                 src_addr = addr;
1671
1672                 tcp_seqno = si->io.pck_rcv;
1673                 tcp_ack = si->io.pck_snd;
1674                 tcp_ctl = 0x12; /** SYN,ACK */
1675
1676                 si->io.pck_rcv += 1;
1677
1678                 break;
1679
1680         case SWRAP_CONNECT_UNREACH:
1681                 if (si->type != SOCK_STREAM) return NULL;
1682
1683                 dest_addr = si->myname;
1684                 src_addr = addr;
1685
1686                 /* Unreachable: resend the data of SWRAP_CONNECT_SEND */
1687                 tcp_seqno = si->io.pck_snd - 1;
1688                 tcp_ack = si->io.pck_rcv;
1689                 tcp_ctl = 0x02; /* SYN */
1690                 unreachable = 1;
1691
1692                 break;
1693
1694         case SWRAP_CONNECT_ACK:
1695                 if (si->type != SOCK_STREAM) return NULL;
1696
1697                 src_addr = si->myname;
1698                 dest_addr = addr;
1699
1700                 tcp_seqno = si->io.pck_snd;
1701                 tcp_ack = si->io.pck_rcv;
1702                 tcp_ctl = 0x10; /* ACK */
1703
1704                 break;
1705
1706         case SWRAP_ACCEPT_SEND:
1707                 if (si->type != SOCK_STREAM) return NULL;
1708
1709                 dest_addr = si->myname;
1710                 src_addr = addr;
1711
1712                 tcp_seqno = si->io.pck_rcv;
1713                 tcp_ack = si->io.pck_snd;
1714                 tcp_ctl = 0x02; /* SYN */
1715
1716                 si->io.pck_rcv += 1;
1717
1718                 break;
1719
1720         case SWRAP_ACCEPT_RECV:
1721                 if (si->type != SOCK_STREAM) return NULL;
1722
1723                 src_addr = si->myname;
1724                 dest_addr = addr;
1725
1726                 tcp_seqno = si->io.pck_snd;
1727                 tcp_ack = si->io.pck_rcv;
1728                 tcp_ctl = 0x12; /* SYN,ACK */
1729
1730                 si->io.pck_snd += 1;
1731
1732                 break;
1733
1734         case SWRAP_ACCEPT_ACK:
1735                 if (si->type != SOCK_STREAM) return NULL;
1736
1737                 dest_addr = si->myname;
1738                 src_addr = addr;
1739
1740                 tcp_seqno = si->io.pck_rcv;
1741                 tcp_ack = si->io.pck_snd;
1742                 tcp_ctl = 0x10; /* ACK */
1743
1744                 break;
1745
1746         case SWRAP_SEND:
1747                 src_addr = si->myname;
1748                 dest_addr = si->peername;
1749
1750                 tcp_seqno = si->io.pck_snd;
1751                 tcp_ack = si->io.pck_rcv;
1752                 tcp_ctl = 0x18; /* PSH,ACK */
1753
1754                 si->io.pck_snd += len;
1755
1756                 break;
1757
1758         case SWRAP_SEND_RST:
1759                 dest_addr = si->myname;
1760                 src_addr = si->peername;
1761
1762                 if (si->type == SOCK_DGRAM) {
1763                         return swrap_marshall_packet(si, si->peername,
1764                                           SWRAP_SENDTO_UNREACH,
1765                                           buf, len, packet_len);
1766                 }
1767
1768                 tcp_seqno = si->io.pck_rcv;
1769                 tcp_ack = si->io.pck_snd;
1770                 tcp_ctl = 0x14; /** RST,ACK */
1771
1772                 break;
1773
1774         case SWRAP_PENDING_RST:
1775                 dest_addr = si->myname;
1776                 src_addr = si->peername;
1777
1778                 if (si->type == SOCK_DGRAM) {
1779                         return NULL;
1780                 }
1781
1782                 tcp_seqno = si->io.pck_rcv;
1783                 tcp_ack = si->io.pck_snd;
1784                 tcp_ctl = 0x14; /* RST,ACK */
1785
1786                 break;
1787
1788         case SWRAP_RECV:
1789                 dest_addr = si->myname;
1790                 src_addr = si->peername;
1791
1792                 tcp_seqno = si->io.pck_rcv;
1793                 tcp_ack = si->io.pck_snd;
1794                 tcp_ctl = 0x18; /* PSH,ACK */
1795
1796                 si->io.pck_rcv += len;
1797
1798                 break;
1799
1800         case SWRAP_RECV_RST:
1801                 dest_addr = si->myname;
1802                 src_addr = si->peername;
1803
1804                 if (si->type == SOCK_DGRAM) {
1805                         return NULL;
1806                 }
1807
1808                 tcp_seqno = si->io.pck_rcv;
1809                 tcp_ack = si->io.pck_snd;
1810                 tcp_ctl = 0x14; /* RST,ACK */
1811
1812                 break;
1813
1814         case SWRAP_SENDTO:
1815                 src_addr = si->myname;
1816                 dest_addr = addr;
1817
1818                 si->io.pck_snd += len;
1819
1820                 break;
1821
1822         case SWRAP_SENDTO_UNREACH:
1823                 dest_addr = si->myname;
1824                 src_addr = addr;
1825
1826                 unreachable = 1;
1827
1828                 break;
1829
1830         case SWRAP_RECVFROM:
1831                 dest_addr = si->myname;
1832                 src_addr = addr;
1833
1834                 si->io.pck_rcv += len;
1835
1836                 break;
1837
1838         case SWRAP_CLOSE_SEND:
1839                 if (si->type != SOCK_STREAM) return NULL;
1840
1841                 src_addr = si->myname;
1842                 dest_addr = si->peername;
1843
1844                 tcp_seqno = si->io.pck_snd;
1845                 tcp_ack = si->io.pck_rcv;
1846                 tcp_ctl = 0x11; /* FIN, ACK */
1847
1848                 si->io.pck_snd += 1;
1849
1850                 break;
1851
1852         case SWRAP_CLOSE_RECV:
1853                 if (si->type != SOCK_STREAM) return NULL;
1854
1855                 dest_addr = si->myname;
1856                 src_addr = si->peername;
1857
1858                 tcp_seqno = si->io.pck_rcv;
1859                 tcp_ack = si->io.pck_snd;
1860                 tcp_ctl = 0x11; /* FIN,ACK */
1861
1862                 si->io.pck_rcv += 1;
1863
1864                 break;
1865
1866         case SWRAP_CLOSE_ACK:
1867                 if (si->type != SOCK_STREAM) return NULL;
1868
1869                 src_addr = si->myname;
1870                 dest_addr = si->peername;
1871
1872                 tcp_seqno = si->io.pck_snd;
1873                 tcp_ack = si->io.pck_rcv;
1874                 tcp_ctl = 0x10; /* ACK */
1875
1876                 break;
1877         default:
1878                 return NULL;
1879         }
1880
1881         swrapGetTimeOfDay(&tv);
1882
1883         return swrap_packet_init(&tv, src_addr, dest_addr, si->type,
1884                                  (const uint8_t *)buf, len,
1885                                  tcp_seqno, tcp_ack, tcp_ctl, unreachable,
1886                                  packet_len);
1887 }
1888
1889 static void swrap_dump_packet(struct socket_info *si,
1890                               const struct sockaddr *addr,
1891                               enum swrap_packet_type type,
1892                               const void *buf, size_t len)
1893 {
1894         const char *file_name;
1895         uint8_t *packet;
1896         size_t packet_len = 0;
1897         int fd;
1898
1899         file_name = socket_wrapper_pcap_file();
1900         if (!file_name) {
1901                 return;
1902         }
1903
1904         packet = swrap_marshall_packet(si, addr, type, buf, len, &packet_len);
1905         if (!packet) {
1906                 return;
1907         }
1908
1909         fd = swrap_get_pcap_fd(file_name);
1910         if (fd != -1) {
1911                 if (write(fd, packet, packet_len) != (ssize_t)packet_len) {
1912                         free(packet);
1913                         return;
1914                 }
1915         }
1916
1917         free(packet);
1918 }
1919
1920 /****************************************************************************
1921  *   SOCKET
1922  ***************************************************************************/
1923
1924 static int swrap_socket(int family, int type, int protocol)
1925 {
1926         struct socket_info *si;
1927         struct socket_info_fd *fi;
1928         int fd;
1929         int real_type = type;
1930
1931         /*
1932          * Remove possible addition flags passed to socket() so
1933          * do not fail checking the type.
1934          * See https://lwn.net/Articles/281965/
1935          */
1936 #ifdef SOCK_CLOEXEC
1937         real_type &= ~SOCK_CLOEXEC;
1938 #endif
1939 #ifdef SOCK_NONBLOCK
1940         real_type &= ~SOCK_NONBLOCK;
1941 #endif
1942
1943         if (socket_wrapper_dir() == NULL) {
1944                 return libc_socket(family, type, protocol);
1945         }
1946
1947         switch (family) {
1948         case AF_INET:
1949 #ifdef HAVE_IPV6
1950         case AF_INET6:
1951 #endif
1952                 break;
1953         case AF_UNIX:
1954                 return libc_socket(family, type, protocol);
1955         default:
1956                 errno = EAFNOSUPPORT;
1957                 return -1;
1958         }
1959
1960         switch (real_type) {
1961         case SOCK_STREAM:
1962                 break;
1963         case SOCK_DGRAM:
1964                 break;
1965         default:
1966                 errno = EPROTONOSUPPORT;
1967                 return -1;
1968         }
1969
1970         switch (protocol) {
1971         case 0:
1972                 break;
1973         case 6:
1974                 if (real_type == SOCK_STREAM) {
1975                         break;
1976                 }
1977                 /*fall through*/
1978         case 17:
1979                 if (real_type == SOCK_DGRAM) {
1980                         break;
1981                 }
1982                 /*fall through*/
1983         default:
1984                 errno = EPROTONOSUPPORT;
1985                 return -1;
1986         }
1987
1988         /*
1989          * We must call libc_socket with type, from the caller, not the version
1990          * we removed SOCK_CLOEXEC and SOCK_NONBLOCK from
1991          */
1992         fd = libc_socket(AF_UNIX, type, 0);
1993
1994         if (fd == -1) return -1;
1995
1996         si = (struct socket_info *)malloc(sizeof(struct socket_info));
1997         memset(si, 0, sizeof(struct socket_info));
1998         if (si == NULL) {
1999                 errno = ENOMEM;
2000                 return -1;
2001         }
2002
2003         si->family = family;
2004
2005         /* however, the rest of the socket_wrapper code expects just
2006          * the type, not the flags */
2007         si->type = real_type;
2008         si->protocol = protocol;
2009
2010         fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
2011         if (fi == NULL) {
2012                 free(si);
2013                 errno = ENOMEM;
2014                 return -1;
2015         }
2016
2017         fi->fd = fd;
2018
2019         SWRAP_DLIST_ADD(si->fds, fi);
2020         SWRAP_DLIST_ADD(sockets, si);
2021
2022         return fd;
2023 }
2024
2025 int socket(int family, int type, int protocol)
2026 {
2027         return swrap_socket(family, type, protocol);
2028 }
2029
2030 /****************************************************************************
2031  *   ACCEPT
2032  ***************************************************************************/
2033
2034 static int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
2035 {
2036         struct socket_info *parent_si, *child_si;
2037         struct socket_info_fd *child_fi;
2038         int fd;
2039         struct sockaddr_un un_addr;
2040         socklen_t un_addrlen = sizeof(un_addr);
2041         struct sockaddr_un un_my_addr;
2042         socklen_t un_my_addrlen = sizeof(un_my_addr);
2043         struct sockaddr *my_addr;
2044         socklen_t my_addrlen, len;
2045         int ret;
2046
2047         parent_si = find_socket_info(s);
2048         if (!parent_si) {
2049                 return libc_accept(s, addr, addrlen);
2050         }
2051
2052         /* 
2053          * assume out sockaddr have the same size as the in parent
2054          * socket family
2055          */
2056         my_addrlen = socket_length(parent_si->family);
2057         if (my_addrlen <= 0) {
2058                 errno = EINVAL;
2059                 return -1;
2060         }
2061
2062         my_addr = (struct sockaddr *)malloc(my_addrlen);
2063         if (my_addr == NULL) {
2064                 return -1;
2065         }
2066
2067         memset(&un_addr, 0, sizeof(un_addr));
2068         memset(&un_my_addr, 0, sizeof(un_my_addr));
2069
2070         ret = libc_accept(s, (struct sockaddr *)(void *)&un_addr, &un_addrlen);
2071         if (ret == -1) {
2072                 free(my_addr);
2073                 return ret;
2074         }
2075
2076         fd = ret;
2077
2078         len = my_addrlen;
2079         ret = sockaddr_convert_from_un(parent_si, &un_addr, un_addrlen,
2080                                        parent_si->family, my_addr, &len);
2081         if (ret == -1) {
2082                 free(my_addr);
2083                 close(fd);
2084                 return ret;
2085         }
2086
2087         child_si = (struct socket_info *)malloc(sizeof(struct socket_info));
2088         memset(child_si, 0, sizeof(struct socket_info));
2089
2090         child_fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
2091         if (child_fi == NULL) {
2092                 free(child_si);
2093                 free(my_addr);
2094                 close(fd);
2095                 errno = ENOMEM;
2096                 return -1;
2097         }
2098
2099         child_fi->fd = fd;
2100
2101         SWRAP_DLIST_ADD(child_si->fds, child_fi);
2102
2103         child_si->family = parent_si->family;
2104         child_si->type = parent_si->type;
2105         child_si->protocol = parent_si->protocol;
2106         child_si->bound = 1;
2107         child_si->is_server = 1;
2108         child_si->connected = 1;
2109
2110         child_si->peername_len = len;
2111         child_si->peername = sockaddr_dup(my_addr, len);
2112
2113         if (addr != NULL && addrlen != NULL) {
2114                 size_t copy_len = MIN(*addrlen, len);
2115                 if (copy_len > 0) {
2116                         memcpy(addr, my_addr, copy_len);
2117                 }
2118                 *addrlen = len;
2119         }
2120
2121         ret = libc_getsockname(fd,
2122                                (struct sockaddr *)(void *)&un_my_addr,
2123                                &un_my_addrlen);
2124         if (ret == -1) {
2125                 free(child_fi);
2126                 free(child_si);
2127                 free(my_addr);
2128                 close(fd);
2129                 return ret;
2130         }
2131
2132         len = my_addrlen;
2133         ret = sockaddr_convert_from_un(child_si, &un_my_addr, un_my_addrlen,
2134                                        child_si->family, my_addr, &len);
2135         if (ret == -1) {
2136                 free(child_fi);
2137                 free(child_si);
2138                 free(my_addr);
2139                 close(fd);
2140                 return ret;
2141         }
2142
2143         SWRAP_LOG(SWRAP_LOG_TRACE,
2144                   "accept() path=%s, fd=%d",
2145                   un_my_addr.sun_path, s);
2146
2147         child_si->myname_len = len;
2148         child_si->myname = sockaddr_dup(my_addr, len);
2149         free(my_addr);
2150
2151         SWRAP_DLIST_ADD(sockets, child_si);
2152
2153         if (addr != NULL) {
2154                 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0);
2155                 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_RECV, NULL, 0);
2156                 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_ACK, NULL, 0);
2157         }
2158
2159         return fd;
2160 }
2161
2162 #ifdef HAVE_ACCEPT_PSOCKLEN_T
2163 int accept(int s, struct sockaddr *addr, Psocklen_t addrlen)
2164 #else
2165 int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
2166 #endif
2167 {
2168         return swrap_accept(s, addr, (socklen_t *)addrlen);
2169 }
2170
2171 static int autobind_start_init;
2172 static int autobind_start;
2173
2174 /* using sendto() or connect() on an unbound socket would give the
2175    recipient no way to reply, as unlike UDP and TCP, a unix domain
2176    socket can't auto-assign emphemeral port numbers, so we need to
2177    assign it here.
2178    Note: this might change the family from ipv6 to ipv4
2179 */
2180 static int swrap_auto_bind(int fd, struct socket_info *si, int family)
2181 {
2182         struct sockaddr_un un_addr;
2183         int i;
2184         char type;
2185         int ret;
2186         int port;
2187         struct stat st;
2188
2189         if (autobind_start_init != 1) {
2190                 autobind_start_init = 1;
2191                 autobind_start = getpid();
2192                 autobind_start %= 50000;
2193                 autobind_start += 10000;
2194         }
2195
2196         un_addr.sun_family = AF_UNIX;
2197
2198         switch (family) {
2199         case AF_INET: {
2200                 struct sockaddr_in in;
2201
2202                 switch (si->type) {
2203                 case SOCK_STREAM:
2204                         type = SOCKET_TYPE_CHAR_TCP;
2205                         break;
2206                 case SOCK_DGRAM:
2207                         type = SOCKET_TYPE_CHAR_UDP;
2208                         break;
2209                 default:
2210                     errno = ESOCKTNOSUPPORT;
2211                     return -1;
2212                 }
2213
2214                 memset(&in, 0, sizeof(in));
2215                 in.sin_family = AF_INET;
2216                 in.sin_addr.s_addr = htonl(127<<24 | 
2217                                            socket_wrapper_default_iface());
2218
2219                 si->myname_len = sizeof(in);
2220                 si->myname = sockaddr_dup(&in, si->myname_len);
2221                 break;
2222         }
2223 #ifdef HAVE_IPV6
2224         case AF_INET6: {
2225                 struct sockaddr_in6 in6;
2226
2227                 if (si->family != family) {
2228                         errno = ENETUNREACH;
2229                         return -1;
2230                 }
2231
2232                 switch (si->type) {
2233                 case SOCK_STREAM:
2234                         type = SOCKET_TYPE_CHAR_TCP_V6;
2235                         break;
2236                 case SOCK_DGRAM:
2237                         type = SOCKET_TYPE_CHAR_UDP_V6;
2238                         break;
2239                 default:
2240                         errno = ESOCKTNOSUPPORT;
2241                         return -1;
2242                 }
2243
2244                 memset(&in6, 0, sizeof(in6));
2245                 in6.sin6_family = AF_INET6;
2246                 in6.sin6_addr = *swrap_ipv6();
2247                 in6.sin6_addr.s6_addr[15] = socket_wrapper_default_iface();
2248                 si->myname_len = sizeof(in6);
2249                 si->myname = sockaddr_dup(&in6, si->myname_len);
2250                 break;
2251         }
2252 #endif
2253         default:
2254                 errno = ESOCKTNOSUPPORT;
2255                 return -1;
2256         }
2257
2258         if (autobind_start > 60000) {
2259                 autobind_start = 10000;
2260         }
2261
2262         for (i = 0; i < SOCKET_MAX_SOCKETS; i++) {
2263                 port = autobind_start + i;
2264                 snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), 
2265                          "%s/"SOCKET_FORMAT, socket_wrapper_dir(),
2266                          type, socket_wrapper_default_iface(), port);
2267                 if (stat(un_addr.sun_path, &st) == 0) continue;
2268
2269                 ret = libc_bind(fd, (struct sockaddr *)(void *)&un_addr,
2270                                 sizeof(un_addr));
2271                 if (ret == -1) return ret;
2272
2273                 si->tmp_path = strdup(un_addr.sun_path);
2274                 si->bound = 1;
2275                 autobind_start = port + 1;
2276                 break;
2277         }
2278         if (i == SOCKET_MAX_SOCKETS) {
2279                 SWRAP_LOG(SWRAP_LOG_ERROR, "Too many open unix sockets (%u) for "
2280                                            "interface "SOCKET_FORMAT,
2281                                            SOCKET_MAX_SOCKETS,
2282                                            type,
2283                                            socket_wrapper_default_iface(),
2284                                            0);
2285                 errno = ENFILE;
2286                 return -1;
2287         }
2288
2289         si->family = family;
2290         set_port(si->family, port, si->myname);
2291
2292         return 0;
2293 }
2294
2295 /****************************************************************************
2296  *   CONNECT
2297  ***************************************************************************/
2298
2299 static int swrap_connect(int s, const struct sockaddr *serv_addr,
2300                          socklen_t addrlen)
2301 {
2302         int ret;
2303         struct sockaddr_un un_addr;
2304         struct socket_info *si = find_socket_info(s);
2305         int bcast = 0;
2306
2307         if (!si) {
2308                 return libc_connect(s, serv_addr, addrlen);
2309         }
2310
2311         if (si->bound == 0) {
2312                 ret = swrap_auto_bind(s, si, serv_addr->sa_family);
2313                 if (ret == -1) return -1;
2314         }
2315
2316         if (si->family != serv_addr->sa_family) {
2317                 errno = EINVAL;
2318                 return -1;
2319         }
2320
2321         ret = sockaddr_convert_to_un(si, serv_addr,
2322                                      addrlen, &un_addr, 0, &bcast);
2323         if (ret == -1) return -1;
2324
2325         if (bcast) {
2326                 errno = ENETUNREACH;
2327                 return -1;
2328         }
2329
2330         if (si->type == SOCK_DGRAM) {
2331                 si->defer_connect = 1;
2332                 ret = 0;
2333         } else {
2334                 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0);
2335
2336                 ret = libc_connect(s,
2337                                    (struct sockaddr *)(void *)&un_addr,
2338                                    sizeof(struct sockaddr_un));
2339         }
2340
2341         SWRAP_LOG(SWRAP_LOG_TRACE,
2342                   "connect() path=%s, fd=%d",
2343                   un_addr.sun_path, s);
2344
2345
2346         /* to give better errors */
2347         if (ret == -1 && errno == ENOENT) {
2348                 errno = EHOSTUNREACH;
2349         }
2350
2351         if (ret == 0) {
2352                 si->peername_len = addrlen;
2353                 si->peername = sockaddr_dup(serv_addr, addrlen);
2354                 si->connected = 1;
2355
2356                 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0);
2357                 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0);
2358         } else {
2359                 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0);
2360         }
2361
2362         return ret;
2363 }
2364
2365 int connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen)
2366 {
2367         return swrap_connect(s, serv_addr, addrlen);
2368 }
2369
2370 /****************************************************************************
2371  *   BIND
2372  ***************************************************************************/
2373
2374 static int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
2375 {
2376         int ret;
2377         struct sockaddr_un un_addr;
2378         struct socket_info *si = find_socket_info(s);
2379
2380         if (!si) {
2381                 return libc_bind(s, myaddr, addrlen);
2382         }
2383
2384         si->myname_len = addrlen;
2385         si->myname = sockaddr_dup(myaddr, addrlen);
2386
2387         ret = sockaddr_convert_to_un(si, myaddr, addrlen, &un_addr, 1, &si->bcast);
2388         if (ret == -1) return -1;
2389
2390         unlink(un_addr.sun_path);
2391
2392         ret = libc_bind(s, (struct sockaddr *)(void *)&un_addr,
2393                         sizeof(struct sockaddr_un));
2394
2395         SWRAP_LOG(SWRAP_LOG_TRACE,
2396                   "bind() path=%s, fd=%d",
2397                   un_addr.sun_path, s);
2398
2399         if (ret == 0) {
2400                 si->bound = 1;
2401         }
2402
2403         return ret;
2404 }
2405
2406 int bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
2407 {
2408         return swrap_bind(s, myaddr, addrlen);
2409 }
2410
2411 /****************************************************************************
2412  *   LISTEN
2413  ***************************************************************************/
2414
2415 static int swrap_listen(int s, int backlog)
2416 {
2417         int ret;
2418         struct socket_info *si = find_socket_info(s);
2419
2420         if (!si) {
2421                 return libc_listen(s, backlog);
2422         }
2423
2424         ret = libc_listen(s, backlog);
2425
2426         return ret;
2427 }
2428
2429 int listen(int s, int backlog)
2430 {
2431         return swrap_listen(s, backlog);
2432 }
2433
2434 /****************************************************************************
2435  *   GETPEERNAME
2436  ***************************************************************************/
2437
2438 static int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
2439 {
2440         struct socket_info *si = find_socket_info(s);
2441
2442         if (!si) {
2443                 return libc_getpeername(s, name, addrlen);
2444         }
2445
2446         if (!si->peername)
2447         {
2448                 errno = ENOTCONN;
2449                 return -1;
2450         }
2451
2452         memcpy(name, si->peername, si->peername_len);
2453         *addrlen = si->peername_len;
2454
2455         return 0;
2456 }
2457
2458 #ifdef HAVE_ACCEPT_PSOCKLEN_T
2459 int getpeername(int s, struct sockaddr *name, Psocklen_t addrlen)
2460 #else
2461 int getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
2462 #endif
2463 {
2464         return swrap_getpeername(s, name, (socklen_t *)addrlen);
2465 }
2466
2467 /****************************************************************************
2468  *   GETSOCKNAME
2469  ***************************************************************************/
2470
2471 static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
2472 {
2473         struct socket_info *si = find_socket_info(s);
2474
2475         if (!si) {
2476                 return libc_getsockname(s, name, addrlen);
2477         }
2478
2479         memcpy(name, si->myname, si->myname_len);
2480         *addrlen = si->myname_len;
2481
2482         return 0;
2483 }
2484
2485 #ifdef HAVE_ACCEPT_PSOCKLEN_T
2486 int getsockname(int s, struct sockaddr *name, Psocklen_t addrlen)
2487 #else
2488 int getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
2489 #endif
2490 {
2491         return swrap_getsockname(s, name, (socklen_t *)addrlen);
2492 }
2493
2494 /****************************************************************************
2495  *   GETSOCKOPT
2496  ***************************************************************************/
2497
2498 static int swrap_getsockopt(int s, int level, int optname,
2499                             void *optval, socklen_t *optlen)
2500 {
2501         struct socket_info *si = find_socket_info(s);
2502
2503         if (!si) {
2504                 return libc_getsockopt(s,
2505                                        level,
2506                                        optname,
2507                                        optval,
2508                                        optlen);
2509         }
2510
2511         if (level == SOL_SOCKET) {
2512                 return libc_getsockopt(s,
2513                                        level,
2514                                        optname,
2515                                        optval,
2516                                        optlen);
2517         }
2518
2519         errno = ENOPROTOOPT;
2520         return -1;
2521 }
2522
2523 #ifdef HAVE_ACCEPT_PSOCKLEN_T
2524 int getsockopt(int s, int level, int optname, void *optval, Psocklen_t optlen)
2525 #else
2526 int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
2527 #endif
2528 {
2529         return swrap_getsockopt(s, level, optname, optval, (socklen_t *)optlen);
2530 }
2531
2532 /****************************************************************************
2533  *   SETSOCKOPT
2534  ***************************************************************************/
2535
2536 static int swrap_setsockopt(int s, int level, int optname,
2537                             const void *optval, socklen_t optlen)
2538 {
2539         struct socket_info *si = find_socket_info(s);
2540
2541         if (!si) {
2542                 return libc_setsockopt(s,
2543                                        level,
2544                                        optname,
2545                                        optval,
2546                                        optlen);
2547         }
2548
2549         if (level == SOL_SOCKET) {
2550                 return libc_setsockopt(s,
2551                                        level,
2552                                        optname,
2553                                        optval,
2554                                        optlen);
2555         }
2556
2557         switch (si->family) {
2558         case AF_INET:
2559                 return 0;
2560 #ifdef HAVE_IPV6
2561         case AF_INET6:
2562                 return 0;
2563 #endif
2564         default:
2565                 errno = ENOPROTOOPT;
2566                 return -1;
2567         }
2568 }
2569
2570 int setsockopt(int s, int level, int optname,
2571                const void *optval, socklen_t optlen)
2572 {
2573         return swrap_setsockopt(s, level, optname, optval, optlen);
2574 }
2575
2576 /****************************************************************************
2577  *   IOCTL
2578  ***************************************************************************/
2579
2580 static int swrap_vioctl(int s, unsigned long int r, va_list va)
2581 {
2582         struct socket_info *si = find_socket_info(s);
2583         va_list ap;
2584         int value;
2585         int rc;
2586
2587         if (!si) {
2588                 return libc_vioctl(s, r, va);
2589         }
2590
2591         va_copy(ap, va);
2592
2593         rc = libc_vioctl(s, r, va);
2594
2595         switch (r) {
2596         case FIONREAD:
2597                 value = *((int *)va_arg(ap, int *));
2598
2599                 if (rc == -1 && errno != EAGAIN && errno != ENOBUFS) {
2600                         swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
2601                 } else if (value == 0) { /* END OF FILE */
2602                         swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
2603                 }
2604                 break;
2605         }
2606
2607         va_end(ap);
2608
2609         return rc;
2610 }
2611
2612 #ifdef HAVE_IOCTL_INT
2613 int ioctl(int s, int r, ...)
2614 #else
2615 int ioctl(int s, unsigned long int r, ...)
2616 #endif
2617 {
2618         va_list va;
2619         int rc;
2620
2621         va_start(va, r);
2622
2623         rc = swrap_vioctl(s, (unsigned long int) r, va);
2624
2625         va_end(va);
2626
2627         return rc;
2628 }
2629
2630 static ssize_t swrap_sendmsg_before(int fd,
2631                                     struct socket_info *si,
2632                                     struct msghdr *msg,
2633                                     struct iovec *tmp_iov,
2634                                     struct sockaddr_un *tmp_un,
2635                                     const struct sockaddr_un **to_un,
2636                                     const struct sockaddr **to,
2637                                     int *bcast)
2638 {
2639         size_t i, len = 0;
2640         ssize_t ret;
2641
2642         if (to_un) {
2643                 *to_un = NULL;
2644         }
2645         if (to) {
2646                 *to = NULL;
2647         }
2648         if (bcast) {
2649                 *bcast = 0;
2650         }
2651
2652         switch (si->type) {
2653         case SOCK_STREAM:
2654                 if (!si->connected) {
2655                         errno = ENOTCONN;
2656                         return -1;
2657                 }
2658
2659                 if (msg->msg_iovlen == 0) {
2660                         break;
2661                 }
2662
2663                 for (i=0; i < msg->msg_iovlen; i++) {
2664                         size_t nlen;
2665                         nlen = len + msg->msg_iov[i].iov_len;
2666                         if (nlen > SOCKET_MAX_PACKET) {
2667                                 break;
2668                         }
2669                 }
2670                 msg->msg_iovlen = i;
2671                 if (msg->msg_iovlen == 0) {
2672                         *tmp_iov = msg->msg_iov[0];
2673                         tmp_iov->iov_len = MIN(tmp_iov->iov_len, SOCKET_MAX_PACKET);
2674                         msg->msg_iov = tmp_iov;
2675                         msg->msg_iovlen = 1;
2676                 }
2677                 break;
2678
2679         case SOCK_DGRAM:
2680                 if (si->connected) {
2681                         if (msg->msg_name) {
2682                                 errno = EISCONN;
2683                                 return -1;
2684                         }
2685                 } else {
2686                         const struct sockaddr *msg_name;
2687                         msg_name = (const struct sockaddr *)msg->msg_name;
2688
2689                         if (msg_name == NULL) {
2690                                 errno = ENOTCONN;
2691                                 return -1;
2692                         }
2693
2694
2695                         ret = sockaddr_convert_to_un(si, msg_name, msg->msg_namelen,
2696                                                      tmp_un, 0, bcast);
2697                         if (ret == -1) return -1;
2698
2699                         if (to_un) {
2700                                 *to_un = tmp_un;
2701                         }
2702                         if (to) {
2703                                 *to = msg_name;
2704                         }
2705                         msg->msg_name = tmp_un;
2706                         msg->msg_namelen = sizeof(*tmp_un);
2707                 }
2708
2709                 if (si->bound == 0) {
2710                         ret = swrap_auto_bind(fd, si, si->family);
2711                         if (ret == -1) return -1;
2712                 }
2713
2714                 if (!si->defer_connect) {
2715                         break;
2716                 }
2717
2718                 ret = sockaddr_convert_to_un(si, si->peername, si->peername_len,
2719                                              tmp_un, 0, NULL);
2720                 if (ret == -1) return -1;
2721
2722                 ret = libc_connect(fd,
2723                                    (struct sockaddr *)(void *)tmp_un,
2724                                    sizeof(*tmp_un));
2725
2726                 /* to give better errors */
2727                 if (ret == -1 && errno == ENOENT) {
2728                         errno = EHOSTUNREACH;
2729                 }
2730
2731                 if (ret == -1) {
2732                         return ret;
2733                 }
2734
2735                 si->defer_connect = 0;
2736                 break;
2737         default:
2738                 errno = EHOSTUNREACH;
2739                 return -1;
2740         }
2741
2742         return 0;
2743 }
2744
2745 static void swrap_sendmsg_after(struct socket_info *si,
2746                                 struct msghdr *msg,
2747                                 const struct sockaddr *to,
2748                                 ssize_t ret)
2749 {
2750         int saved_errno = errno;
2751         size_t i, len = 0;
2752         uint8_t *buf;
2753         off_t ofs = 0;
2754         size_t avail = 0;
2755         size_t remain;
2756
2757         /* to give better errors */
2758         if (ret == -1 && saved_errno == ENOENT) {
2759                 saved_errno = EHOSTUNREACH;
2760         }
2761
2762         for (i=0; i < msg->msg_iovlen; i++) {
2763                 avail += msg->msg_iov[i].iov_len;
2764         }
2765
2766         if (ret == -1) {
2767                 remain = MIN(80, avail);
2768         } else {
2769                 remain = ret;
2770         }
2771
2772         /* we capture it as one single packet */
2773         buf = (uint8_t *)malloc(remain);
2774         if (!buf) {
2775                 /* we just not capture the packet */
2776                 errno = saved_errno;
2777                 return;
2778         }
2779
2780         for (i=0; i < msg->msg_iovlen; i++) {
2781                 size_t this_time = MIN(remain, msg->msg_iov[i].iov_len);
2782                 memcpy(buf + ofs,
2783                        msg->msg_iov[i].iov_base,
2784                        this_time);
2785                 ofs += this_time;
2786                 remain -= this_time;
2787         }
2788         len = ofs;
2789
2790         switch (si->type) {
2791         case SOCK_STREAM:
2792                 if (ret == -1) {
2793                         swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
2794                         swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
2795                 } else {
2796                         swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
2797                 }
2798                 break;
2799
2800         case SOCK_DGRAM:
2801                 if (si->connected) {
2802                         to = si->peername;
2803                 }
2804                 if (ret == -1) {
2805                         swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
2806                         swrap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);
2807                 } else {
2808                         swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
2809                 }
2810                 break;
2811         }
2812
2813         free(buf);
2814         errno = saved_errno;
2815 }
2816
2817 static int swrap_recvmsg_before(int fd,
2818                                 struct socket_info *si,
2819                                 struct msghdr *msg,
2820                                 struct iovec *tmp_iov)
2821 {
2822         size_t i, len = 0;
2823         ssize_t ret;
2824
2825         switch (si->type) {
2826         case SOCK_STREAM:
2827                 if (!si->connected) {
2828                         errno = ENOTCONN;
2829                         return -1;
2830                 }
2831
2832                 if (msg->msg_iovlen == 0) {
2833                         break;
2834                 }
2835
2836                 for (i=0; i < msg->msg_iovlen; i++) {
2837                         size_t nlen;
2838                         nlen = len + msg->msg_iov[i].iov_len;
2839                         if (nlen > SOCKET_MAX_PACKET) {
2840                                 break;
2841                         }
2842                 }
2843                 msg->msg_iovlen = i;
2844                 if (msg->msg_iovlen == 0) {
2845                         *tmp_iov = msg->msg_iov[0];
2846                         tmp_iov->iov_len = MIN(tmp_iov->iov_len, SOCKET_MAX_PACKET);
2847                         msg->msg_iov = tmp_iov;
2848                         msg->msg_iovlen = 1;
2849                 }
2850                 break;
2851
2852         case SOCK_DGRAM:
2853                 if (si->bound == 0) {
2854                         ret = swrap_auto_bind(fd, si, si->family);
2855                         if (ret == -1) return -1;
2856                 }
2857                 break;
2858         default:
2859                 errno = EHOSTUNREACH;
2860                 return -1;
2861         }
2862
2863         return 0;
2864 }
2865
2866 static int swrap_recvmsg_after(struct socket_info *si,
2867                                struct msghdr *msg,
2868                                const struct sockaddr_un *un_addr,
2869                                socklen_t un_addrlen,
2870                                struct sockaddr *from,
2871                                socklen_t *fromlen,
2872                                ssize_t ret)
2873 {
2874         int saved_errno = errno;
2875         size_t i;
2876         uint8_t *buf;
2877         off_t ofs = 0;
2878         size_t avail = 0;
2879         size_t remain;
2880
2881         /* to give better errors */
2882         if (ret == -1 && saved_errno == ENOENT) {
2883                 saved_errno = EHOSTUNREACH;
2884         }
2885
2886         for (i=0; i < msg->msg_iovlen; i++) {
2887                 avail += msg->msg_iov[i].iov_len;
2888         }
2889
2890         if (ret == -1) {
2891                 remain = MIN(80, avail);
2892         } else {
2893                 remain = ret;
2894         }
2895
2896         /* we capture it as one single packet */
2897         buf = (uint8_t *)malloc(remain);
2898         if (!buf) {
2899                 /* we just not capture the packet */
2900                 errno = saved_errno;
2901                 return -1;
2902         }
2903
2904         for (i=0; i < msg->msg_iovlen; i++) {
2905                 size_t this_time = MIN(remain, msg->msg_iov[i].iov_len);
2906                 memcpy(buf + ofs,
2907                        msg->msg_iov[i].iov_base,
2908                        this_time);
2909                 ofs += this_time;
2910                 remain -= this_time;
2911         }
2912
2913         switch (si->type) {
2914         case SOCK_STREAM:
2915                 if (ret == -1 && saved_errno != EAGAIN && saved_errno != ENOBUFS) {
2916                         swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
2917                 } else if (ret == 0) { /* END OF FILE */
2918                         swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
2919                 } else if (ret > 0) {
2920                         swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
2921                 }
2922                 break;
2923
2924         case SOCK_DGRAM:
2925                 if (ret == -1) {
2926                         break;
2927                 }
2928
2929                 swrap_dump_packet(si, from, SWRAP_RECVFROM, buf, ret);
2930
2931                 if (sockaddr_convert_from_un(si, un_addr, un_addrlen,
2932                                              si->family, from, fromlen) == -1) {
2933                         return -1;
2934                 }
2935
2936                 break;
2937         }
2938
2939         free(buf);
2940         errno = saved_errno;
2941         return 0;
2942 }
2943
2944 /****************************************************************************
2945  *   RECVFROM
2946  ***************************************************************************/
2947
2948 static ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags,
2949                               struct sockaddr *from, socklen_t *fromlen)
2950 {
2951         struct sockaddr_un un_addr;
2952         socklen_t un_addrlen = sizeof(un_addr);
2953         ssize_t ret;
2954         struct socket_info *si = find_socket_info(s);
2955         struct sockaddr_storage ss;
2956         socklen_t ss_len = sizeof(ss);
2957         struct msghdr msg;
2958         struct iovec tmp;
2959         int tret;
2960
2961         if (!si) {
2962                 return libc_recvfrom(s,
2963                                      buf,
2964                                      len,
2965                                      flags,
2966                                      from,
2967                                      fromlen);
2968         }
2969
2970         if (!from) {
2971                 from = (struct sockaddr *)(void *)&ss;
2972                 fromlen = &ss_len;
2973         }
2974
2975         tmp.iov_base = buf;
2976         tmp.iov_len = len;
2977
2978         msg.msg_name = NULL;           /* optional address */
2979         msg.msg_namelen = 0;           /* size of address */
2980         msg.msg_iov = &tmp;            /* scatter/gather array */
2981         msg.msg_iovlen = 1;            /* # elements in msg_iov */
2982         msg.msg_control = NULL;        /* ancillary data, see below */
2983         msg.msg_controllen = 0;        /* ancillary data buffer len */
2984         msg.msg_flags = 0;             /* flags on received message */
2985
2986         tret = swrap_recvmsg_before(s, si, &msg, &tmp);
2987         if (tret == -1) return -1;
2988
2989         buf = msg.msg_iov[0].iov_base;
2990         len = msg.msg_iov[0].iov_len;
2991
2992         /* irix 6.4 forgets to null terminate the sun_path string :-( */
2993         memset(&un_addr, 0, sizeof(un_addr));
2994         ret = libc_recvfrom(s,
2995                             buf,
2996                             len,
2997                             flags,
2998                             (struct sockaddr *)(void *)&un_addr,
2999                             &un_addrlen);
3000         if (ret == -1) {
3001                 return ret;
3002         }
3003
3004         tret = swrap_recvmsg_after(si,
3005                                    &msg,
3006                                    &un_addr,
3007                                    un_addrlen,
3008                                    from,
3009                                    fromlen,
3010                                    ret);
3011         if (tret != 0) {
3012                 return tret;
3013         }
3014
3015         return ret;
3016 }
3017
3018 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3019 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
3020                  struct sockaddr *from, Psocklen_t fromlen)
3021 #else
3022 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
3023                  struct sockaddr *from, socklen_t *fromlen)
3024 #endif
3025 {
3026         return swrap_recvfrom(s, buf, len, flags, from, (socklen_t *)fromlen);
3027 }
3028
3029 /****************************************************************************
3030  *   SENDTO
3031  ***************************************************************************/
3032
3033 static ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags,
3034                             const struct sockaddr *to, socklen_t tolen)
3035 {
3036         struct msghdr msg;
3037         struct iovec tmp;
3038         struct sockaddr_un un_addr;
3039         const struct sockaddr_un *to_un = NULL;
3040         ssize_t ret;
3041         struct socket_info *si = find_socket_info(s);
3042         int bcast = 0;
3043
3044         if (!si) {
3045                 return libc_sendto(s, buf, len, flags, to, tolen);
3046         }
3047
3048         tmp.iov_base = discard_const_p(char, buf);
3049         tmp.iov_len = len;
3050
3051         ZERO_STRUCT(msg);
3052         msg.msg_name = discard_const_p(struct sockaddr, to); /* optional address */
3053         msg.msg_namelen = tolen;       /* size of address */
3054         msg.msg_iov = &tmp;            /* scatter/gather array */
3055         msg.msg_iovlen = 1;            /* # elements in msg_iov */
3056 #if 0 /* not available on solaris */
3057         msg.msg_control = NULL;        /* ancillary data, see below */
3058         msg.msg_controllen = 0;        /* ancillary data buffer len */
3059         msg.msg_flags = 0;             /* flags on received message */
3060 #endif
3061
3062         ret = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
3063         if (ret == -1) return -1;
3064
3065         buf = msg.msg_iov[0].iov_base;
3066         len = msg.msg_iov[0].iov_len;
3067
3068         if (bcast) {
3069                 struct stat st;
3070                 unsigned int iface;
3071                 unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port);
3072                 char type;
3073
3074                 type = SOCKET_TYPE_CHAR_UDP;
3075
3076                 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
3077                         snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT,
3078                                  socket_wrapper_dir(), type, iface, prt);
3079                         if (stat(un_addr.sun_path, &st) != 0) continue;
3080
3081                         /* ignore the any errors in broadcast sends */
3082                         libc_sendto(s,
3083                                     buf,
3084                                     len,
3085                                     flags,
3086                                     (struct sockaddr *)(void *)&un_addr,
3087                                     sizeof(un_addr));
3088                 }
3089
3090                 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
3091
3092                 return len;
3093         }
3094
3095         ret = libc_sendto(s,
3096                           buf,
3097                           len,
3098                           flags,
3099                           (struct sockaddr *)msg.msg_name,
3100                           msg.msg_namelen);
3101
3102         swrap_sendmsg_after(si, &msg, to, ret);
3103
3104         return ret;
3105 }
3106
3107 ssize_t sendto(int s, const void *buf, size_t len, int flags,
3108                const struct sockaddr *to, socklen_t tolen)
3109 {
3110         return swrap_sendto(s, buf, len, flags, to, tolen);
3111 }
3112
3113 /****************************************************************************
3114  *   READV
3115  ***************************************************************************/
3116
3117 static ssize_t swrap_recv(int s, void *buf, size_t len, int flags)
3118 {
3119         ssize_t ret;
3120         struct socket_info *si = find_socket_info(s);
3121
3122         if (!si) {
3123                 return libc_recv(s, buf, len, flags);
3124         }
3125
3126         if (si->type == SOCK_STREAM) {
3127                 len = MIN(len, SOCKET_MAX_PACKET);
3128         }
3129
3130         ret = libc_recv(s, buf, len, flags);
3131         if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
3132                 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
3133         } else if (ret == 0) { /* END OF FILE */
3134                 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
3135         } else if (ret > 0) {
3136                 swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
3137         }
3138
3139         return ret;
3140 }
3141
3142 ssize_t recv(int s, void *buf, size_t len, int flags)
3143 {
3144         return swrap_recv(s, buf, len, flags);
3145 }
3146
3147 /****************************************************************************
3148  *   READ
3149  ***************************************************************************/
3150
3151 static ssize_t swrap_read(int s, void *buf, size_t len)
3152 {
3153         ssize_t ret;
3154         struct socket_info *si = find_socket_info(s);
3155
3156         if (!si) {
3157                 return libc_read(s, buf, len);
3158         }
3159
3160         if (si->type == SOCK_STREAM) {
3161                 len = MIN(len, SOCKET_MAX_PACKET);
3162         }
3163
3164         ret = libc_read(s, buf, len);
3165         if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
3166                 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
3167         } else if (ret == 0) { /* END OF FILE */
3168                 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
3169         } else if (ret > 0) {
3170                 swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
3171         }
3172
3173         return ret;
3174 }
3175
3176 ssize_t read(int s, void *buf, size_t len)
3177 {
3178         return swrap_read(s, buf, len);
3179 }
3180
3181 /****************************************************************************
3182  *   SEND
3183  ***************************************************************************/
3184
3185 static ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
3186 {
3187         struct msghdr msg;
3188         struct iovec tmp;
3189         struct sockaddr_un un_addr;
3190         ssize_t ret;
3191         struct socket_info *si = find_socket_info(s);
3192
3193         if (!si) {
3194                 return libc_send(s, buf, len, flags);
3195         }
3196
3197         tmp.iov_base = discard_const_p(char, buf);
3198         tmp.iov_len = len;
3199
3200         ZERO_STRUCT(msg);
3201         msg.msg_name = NULL;           /* optional address */
3202         msg.msg_namelen = 0;           /* size of address */
3203         msg.msg_iov = &tmp;            /* scatter/gather array */
3204         msg.msg_iovlen = 1;            /* # elements in msg_iov */
3205 #if 0 /* not available on solaris */
3206         msg.msg_control = NULL;        /* ancillary data, see below */
3207         msg.msg_controllen = 0;        /* ancillary data buffer len */
3208         msg.msg_flags = 0;             /* flags on received message */
3209 #endif
3210
3211         ret = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
3212         if (ret == -1) return -1;
3213
3214         buf = msg.msg_iov[0].iov_base;
3215         len = msg.msg_iov[0].iov_len;
3216
3217         ret = libc_send(s, buf, len, flags);
3218
3219         swrap_sendmsg_after(si, &msg, NULL, ret);
3220
3221         return ret;
3222 }
3223
3224 ssize_t send(int s, const void *buf, size_t len, int flags)
3225 {
3226         return swrap_send(s, buf, len, flags);
3227 }
3228
3229 /****************************************************************************
3230  *   RECVMSG
3231  ***************************************************************************/
3232
3233 /* TODO */
3234
3235 /****************************************************************************
3236  *   SENDMSG
3237  ***************************************************************************/
3238
3239 static ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags)
3240 {
3241         struct msghdr msg;
3242         struct iovec tmp;
3243         struct sockaddr_un un_addr;
3244         const struct sockaddr_un *to_un = NULL;
3245         const struct sockaddr *to = NULL;
3246         ssize_t ret;
3247         struct socket_info *si = find_socket_info(s);
3248         int bcast = 0;
3249
3250         if (!si) {
3251                 return libc_sendmsg(s, omsg, flags);
3252         }
3253
3254         tmp.iov_base = NULL;
3255         tmp.iov_len = 0;
3256
3257         msg = *omsg;
3258 #if 0
3259         msg.msg_name = omsg->msg_name;             /* optional address */
3260         msg.msg_namelen = omsg->msg_namelen;       /* size of address */
3261         msg.msg_iov = omsg->msg_iov;               /* scatter/gather array */
3262         msg.msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
3263         /* the following is not available on solaris */
3264         msg.msg_control = omsg->msg_control;       /* ancillary data, see below */
3265         msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
3266         msg.msg_flags = omsg->msg_flags;           /* flags on received message */
3267 #endif
3268
3269         ret = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
3270         if (ret == -1) return -1;
3271
3272         if (bcast) {
3273                 struct stat st;
3274                 unsigned int iface;
3275                 unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port);
3276                 char type;
3277                 size_t i, len = 0;
3278                 uint8_t *buf;
3279                 off_t ofs = 0;
3280                 size_t avail = 0;
3281                 size_t remain;
3282
3283                 for (i=0; i < msg.msg_iovlen; i++) {
3284                         avail += msg.msg_iov[i].iov_len;
3285                 }
3286
3287                 len = avail;
3288                 remain = avail;
3289
3290                 /* we capture it as one single packet */
3291                 buf = (uint8_t *)malloc(remain);
3292                 if (!buf) {
3293                         return -1;
3294                 }
3295
3296                 for (i=0; i < msg.msg_iovlen; i++) {
3297                         size_t this_time = MIN(remain, msg.msg_iov[i].iov_len);
3298                         memcpy(buf + ofs,
3299                                msg.msg_iov[i].iov_base,
3300                                this_time);
3301                         ofs += this_time;
3302                         remain -= this_time;
3303                 }
3304
3305                 type = SOCKET_TYPE_CHAR_UDP;
3306
3307                 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
3308                         snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT,
3309                                  socket_wrapper_dir(), type, iface, prt);
3310                         if (stat(un_addr.sun_path, &st) != 0) continue;
3311
3312                         msg.msg_name = &un_addr;           /* optional address */
3313                         msg.msg_namelen = sizeof(un_addr); /* size of address */
3314
3315                         /* ignore the any errors in broadcast sends */
3316                         libc_sendmsg(s, &msg, flags);
3317                 }
3318
3319                 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
3320                 free(buf);
3321
3322                 return len;
3323         }
3324
3325         ret = libc_sendmsg(s, &msg, flags);
3326
3327         swrap_sendmsg_after(si, &msg, to, ret);
3328
3329         return ret;
3330 }
3331
3332 ssize_t sendmsg(int s, const struct msghdr *omsg, int flags)
3333 {
3334         return swrap_sendmsg(s, omsg, flags);
3335 }
3336
3337 /****************************************************************************
3338  *   READV
3339  ***************************************************************************/
3340
3341 static ssize_t swrap_readv(int s, const struct iovec *vector, int count)
3342 {
3343         ssize_t ret;
3344         struct socket_info *si = find_socket_info(s);
3345         struct iovec v;
3346
3347         if (!si) {
3348                 return libc_readv(s, vector, count);
3349         }
3350
3351         if (!si->connected) {
3352                 errno = ENOTCONN;
3353                 return -1;
3354         }
3355
3356         if (si->type == SOCK_STREAM && count > 0) {
3357                 int i;
3358                 size_t len = 0;
3359
3360                 for (i = 0; i < count; i++) {
3361                         size_t nlen;
3362                         nlen = len + vector[i].iov_len;
3363                         if (nlen > SOCKET_MAX_PACKET) {
3364                                 break;
3365                         }
3366                 }
3367                 count = i;
3368                 if (count == 0) {
3369                         v = vector[0];
3370                         v.iov_len = MIN(v.iov_len, SOCKET_MAX_PACKET);
3371                         vector = &v;
3372                         count = 1;
3373                 }
3374         }
3375
3376         ret = libc_readv(s, vector, count);
3377         if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
3378                 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
3379         } else if (ret == 0) { /* END OF FILE */
3380                 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
3381         } else if (ret > 0) {
3382                 uint8_t *buf;
3383                 off_t ofs = 0;
3384                 int i;
3385                 size_t remain = ret;
3386
3387                 /* we capture it as one single packet */
3388                 buf = (uint8_t *)malloc(ret);
3389                 if (!buf) {
3390                         /* we just not capture the packet */
3391                         errno = 0;
3392                         return ret;
3393                 }
3394
3395                 for (i=0; i < count; i++) {
3396                         size_t this_time = MIN(remain, vector[i].iov_len);
3397                         memcpy(buf + ofs,
3398                                vector[i].iov_base,
3399                                this_time);
3400                         ofs += this_time;
3401                         remain -= this_time;
3402                 }
3403
3404                 swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
3405                 free(buf);
3406         }
3407
3408         return ret;
3409 }
3410
3411 ssize_t readv(int s, const struct iovec *vector, int count)
3412 {
3413         return swrap_readv(s, vector, count);
3414 }
3415
3416 /****************************************************************************
3417  *   WRITEV
3418  ***************************************************************************/
3419
3420 static ssize_t swrap_writev(int s, const struct iovec *vector, int count)
3421 {
3422         struct msghdr msg;
3423         struct iovec tmp;
3424         struct sockaddr_un un_addr;
3425         ssize_t ret;
3426         struct socket_info *si = find_socket_info(s);
3427
3428         if (!si) {
3429                 return libc_writev(s, vector, count);
3430         }
3431
3432         tmp.iov_base = NULL;
3433         tmp.iov_len = 0;
3434
3435         ZERO_STRUCT(msg);
3436         msg.msg_name = NULL;           /* optional address */
3437         msg.msg_namelen = 0;           /* size of address */
3438         msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
3439         msg.msg_iovlen = count;        /* # elements in msg_iov */
3440 #if 0 /* not available on solaris */
3441         msg.msg_control = NULL;        /* ancillary data, see below */
3442         msg.msg_controllen = 0;        /* ancillary data buffer len */
3443         msg.msg_flags = 0;             /* flags on received message */
3444 #endif
3445
3446         ret = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
3447         if (ret == -1) return -1;
3448
3449         ret = libc_writev(s, msg.msg_iov, msg.msg_iovlen);
3450
3451         swrap_sendmsg_after(si, &msg, NULL, ret);
3452
3453         return ret;
3454 }
3455
3456 ssize_t writev(int s, const struct iovec *vector, int count)
3457 {
3458         return swrap_writev(s, vector, count);
3459 }
3460
3461 /****************************
3462  * CLOSE
3463  ***************************/
3464
3465 static int swrap_close(int fd)
3466 {
3467         struct socket_info *si = find_socket_info(fd);
3468         struct socket_info_fd *fi;
3469         int ret;
3470
3471         if (!si) {
3472                 return libc_close(fd);
3473         }
3474
3475         for (fi = si->fds; fi; fi = fi->next) {
3476                 if (fi->fd == fd) {
3477                         SWRAP_DLIST_REMOVE(si->fds, fi);
3478                         free(fi);
3479                         break;
3480                 }
3481         }
3482
3483         if (si->fds) {
3484                 /* there are still references left */
3485                 return libc_close(fd);
3486         }
3487
3488         SWRAP_DLIST_REMOVE(sockets, si);
3489
3490         if (si->myname && si->peername) {
3491                 swrap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0);
3492         }
3493
3494         ret = libc_close(fd);
3495
3496         if (si->myname && si->peername) {
3497                 swrap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0);
3498                 swrap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0);
3499         }
3500
3501         if (si->myname) free(si->myname);
3502         if (si->peername) free(si->peername);
3503         if (si->tmp_path) {
3504                 unlink(si->tmp_path);
3505                 free(si->tmp_path);
3506         }
3507         free(si);
3508
3509         return ret;
3510 }
3511
3512 int close(int fd)
3513 {
3514         return swrap_close(fd);
3515 }
3516
3517 /****************************
3518  * DUP
3519  ***************************/
3520
3521 static int swrap_dup(int fd)
3522 {
3523         struct socket_info *si;
3524         struct socket_info_fd *fi;
3525
3526         si = find_socket_info(fd);
3527
3528         if (!si) {
3529                 return libc_dup(fd);
3530         }
3531
3532         fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
3533         if (fi == NULL) {
3534                 errno = ENOMEM;
3535                 return -1;
3536         }
3537
3538         fi->fd = libc_dup(fd);
3539         if (fi->fd == -1) {
3540                 int saved_errno = errno;
3541                 free(fi);
3542                 errno = saved_errno;
3543                 return -1;
3544         }
3545
3546         SWRAP_DLIST_ADD(si->fds, fi);
3547         return fi->fd;
3548 }
3549
3550 int dup(int fd)
3551 {
3552         return swrap_dup(fd);
3553 }
3554
3555 /****************************
3556  * DUP2
3557  ***************************/
3558
3559 static int swrap_dup2(int fd, int newfd)
3560 {
3561         struct socket_info *si;
3562         struct socket_info_fd *fi;
3563
3564         si = find_socket_info(fd);
3565
3566         if (!si) {
3567                 return libc_dup2(fd, newfd);
3568         }
3569
3570         if (find_socket_info(newfd)) {
3571                 /* dup2() does an implicit close of newfd, which we
3572                  * need to emulate */
3573                 swrap_close(newfd);
3574         }
3575
3576         fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
3577         if (fi == NULL) {
3578                 errno = ENOMEM;
3579                 return -1;
3580         }
3581
3582         fi->fd = libc_dup2(fd, newfd);
3583         if (fi->fd == -1) {
3584                 int saved_errno = errno;
3585                 free(fi);
3586                 errno = saved_errno;
3587                 return -1;
3588         }
3589
3590         SWRAP_DLIST_ADD(si->fds, fi);
3591         return fi->fd;
3592 }
3593
3594 int dup2(int fd, int newfd)
3595 {
3596         return swrap_dup2(fd, newfd);
3597 }
3598
3599 /****************************
3600  * DESTRUCTOR
3601  ***************************/
3602
3603 /*
3604  * This function is called when the library is unloaded and makes sure that
3605  * sockets get closed and the unix file for the socket are unlinked.
3606  */
3607 void swrap_destructor(void)
3608 {
3609         struct socket_info *s = sockets;
3610
3611         while (s != NULL) {
3612                 struct socket_info_fd *f = s->fds;
3613                 if (f != NULL) {
3614                         swrap_close(f->fd);
3615                 }
3616                 s = sockets;
3617         }
3618 }