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