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