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