SO_PROTOCOL is platform-dependent
[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 #if 0 /* FIXME */
1271 static bool check_addr_port_in_use(const struct sockaddr *sa, socklen_t len)
1272 {
1273         struct socket_info *s;
1274
1275         /* first catch invalid input */
1276         switch (sa->sa_family) {
1277         case AF_INET:
1278                 if (len < sizeof(struct sockaddr_in)) {
1279                         return false;
1280                 }
1281                 break;
1282 #if HAVE_IPV6
1283         case AF_INET6:
1284                 if (len < sizeof(struct sockaddr_in6)) {
1285                         return false;
1286                 }
1287                 break;
1288 #endif
1289         default:
1290                 return false;
1291                 break;
1292         }
1293
1294         for (s = sockets; s != NULL; s = s->next) {
1295                 if (s->myname == NULL) {
1296                         continue;
1297                 }
1298                 if (s->myname->sa_family != sa->sa_family) {
1299                         continue;
1300                 }
1301                 switch (s->myname->sa_family) {
1302                 case AF_INET: {
1303                         struct sockaddr_in *sin1, *sin2;
1304
1305                         sin1 = (struct sockaddr_in *)s->myname;
1306                         sin2 = (struct sockaddr_in *)sa;
1307
1308                         if (sin1->sin_addr.s_addr == htonl(INADDR_ANY)) {
1309                                 continue;
1310                         }
1311                         if (sin1->sin_port != sin2->sin_port) {
1312                                 continue;
1313                         }
1314                         if (sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) {
1315                                 continue;
1316                         }
1317
1318                         /* found */
1319                         return true;
1320                         break;
1321                 }
1322 #if HAVE_IPV6
1323                 case AF_INET6: {
1324                         struct sockaddr_in6 *sin1, *sin2;
1325
1326                         sin1 = (struct sockaddr_in6 *)s->myname;
1327                         sin2 = (struct sockaddr_in6 *)sa;
1328
1329                         if (sin1->sin6_port != sin2->sin6_port) {
1330                                 continue;
1331                         }
1332                         if (!IN6_ARE_ADDR_EQUAL(&sin1->sin6_addr,
1333                                                 &sin2->sin6_addr))
1334                         {
1335                                 continue;
1336                         }
1337
1338                         /* found */
1339                         return true;
1340                         break;
1341                 }
1342 #endif
1343                 default:
1344                         continue;
1345                         break;
1346
1347                 }
1348         }
1349
1350         return false;
1351 }
1352 #endif
1353
1354 static void swrap_remove_stale(int fd)
1355 {
1356         struct socket_info *si = find_socket_info(fd);
1357         struct socket_info_fd *fi;
1358
1359         if (si != NULL) {
1360                 for (fi = si->fds; fi; fi = fi->next) {
1361                         if (fi->fd == fd) {
1362                                 SWRAP_LOG(SWRAP_LOG_TRACE, "remove stale wrapper for %d", fd);
1363                                 SWRAP_DLIST_REMOVE(si->fds, fi);
1364                                 free(fi);
1365                                 break;
1366                         }
1367                 }
1368
1369                 if (si->fds == NULL) {
1370                         SWRAP_DLIST_REMOVE(sockets, si);
1371                 }
1372         }
1373 }
1374
1375 static int sockaddr_convert_to_un(struct socket_info *si,
1376                                   const struct sockaddr *in_addr,
1377                                   socklen_t in_len,
1378                                   struct sockaddr_un *out_addr,
1379                                   int alloc_sock,
1380                                   int *bcast)
1381 {
1382         struct sockaddr *out = (struct sockaddr *)(void *)out_addr;
1383
1384         (void) in_len; /* unused */
1385
1386         if (out_addr == NULL) {
1387                 return 0;
1388         }
1389
1390         out->sa_family = AF_UNIX;
1391 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
1392         out->sa_len = sizeof(*out_addr);
1393 #endif
1394
1395         switch (in_addr->sa_family) {
1396         case AF_UNSPEC: {
1397                 const struct sockaddr_in *sin;
1398                 if (si->family != AF_INET) {
1399                         break;
1400                 }
1401                 if (in_len < sizeof(struct sockaddr_in)) {
1402                         break;
1403                 }
1404                 sin = (const struct sockaddr_in *)in_addr;
1405                 if(sin->sin_addr.s_addr != htonl(INADDR_ANY)) {
1406                         break;
1407                 }
1408
1409                 /*
1410                  * Note: in the special case of AF_UNSPEC and INADDR_ANY,
1411                  * AF_UNSPEC is mapped to AF_INET and must be treated here.
1412                  */
1413
1414                 /* FALL THROUGH */
1415         }
1416         case AF_INET:
1417 #ifdef HAVE_IPV6
1418         case AF_INET6:
1419 #endif
1420                 switch (si->type) {
1421                 case SOCK_STREAM:
1422                 case SOCK_DGRAM:
1423                         break;
1424                 default:
1425                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1426                         errno = ESOCKTNOSUPPORT;
1427                         return -1;
1428                 }
1429                 if (alloc_sock) {
1430                         return convert_in_un_alloc(si, in_addr, out_addr, bcast);
1431                 } else {
1432                         return convert_in_un_remote(si, in_addr, out_addr, bcast);
1433                 }
1434         default:
1435                 break;
1436         }
1437
1438         errno = EAFNOSUPPORT;
1439         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n");
1440         return -1;
1441 }
1442
1443 static int sockaddr_convert_from_un(const struct socket_info *si, 
1444                                     const struct sockaddr_un *in_addr, 
1445                                     socklen_t un_addrlen,
1446                                     int family,
1447                                     struct sockaddr *out_addr,
1448                                     socklen_t *out_addrlen)
1449 {
1450         int ret;
1451
1452         if (out_addr == NULL || out_addrlen == NULL) 
1453                 return 0;
1454
1455         if (un_addrlen == 0) {
1456                 *out_addrlen = 0;
1457                 return 0;
1458         }
1459
1460         switch (family) {
1461         case AF_INET:
1462 #ifdef HAVE_IPV6
1463         case AF_INET6:
1464 #endif
1465                 switch (si->type) {
1466                 case SOCK_STREAM:
1467                 case SOCK_DGRAM:
1468                         break;
1469                 default:
1470                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1471                         errno = ESOCKTNOSUPPORT;
1472                         return -1;
1473                 }
1474                 ret = convert_un_in(in_addr, out_addr, out_addrlen);
1475 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
1476                 out_addr->sa_len = *out_addrlen;
1477 #endif
1478                 return ret;
1479         default:
1480                 break;
1481         }
1482
1483         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n");
1484         errno = EAFNOSUPPORT;
1485         return -1;
1486 }
1487
1488 enum swrap_packet_type {
1489         SWRAP_CONNECT_SEND,
1490         SWRAP_CONNECT_UNREACH,
1491         SWRAP_CONNECT_RECV,
1492         SWRAP_CONNECT_ACK,
1493         SWRAP_ACCEPT_SEND,
1494         SWRAP_ACCEPT_RECV,
1495         SWRAP_ACCEPT_ACK,
1496         SWRAP_RECVFROM,
1497         SWRAP_SENDTO,
1498         SWRAP_SENDTO_UNREACH,
1499         SWRAP_PENDING_RST,
1500         SWRAP_RECV,
1501         SWRAP_RECV_RST,
1502         SWRAP_SEND,
1503         SWRAP_SEND_RST,
1504         SWRAP_CLOSE_SEND,
1505         SWRAP_CLOSE_RECV,
1506         SWRAP_CLOSE_ACK,
1507 };
1508
1509 struct swrap_file_hdr {
1510         uint32_t        magic;
1511         uint16_t        version_major;
1512         uint16_t        version_minor;
1513         int32_t         timezone;
1514         uint32_t        sigfigs;
1515         uint32_t        frame_max_len;
1516 #define SWRAP_FRAME_LENGTH_MAX 0xFFFF
1517         uint32_t        link_type;
1518 };
1519 #define SWRAP_FILE_HDR_SIZE 24
1520
1521 struct swrap_packet_frame {
1522         uint32_t seconds;
1523         uint32_t micro_seconds;
1524         uint32_t recorded_length;
1525         uint32_t full_length;
1526 };
1527 #define SWRAP_PACKET_FRAME_SIZE 16
1528
1529 union swrap_packet_ip {
1530         struct {
1531                 uint8_t         ver_hdrlen;
1532                 uint8_t         tos;
1533                 uint16_t        packet_length;
1534                 uint16_t        identification;
1535                 uint8_t         flags;
1536                 uint8_t         fragment;
1537                 uint8_t         ttl;
1538                 uint8_t         protocol;
1539                 uint16_t        hdr_checksum;
1540                 uint32_t        src_addr;
1541                 uint32_t        dest_addr;
1542         } v4;
1543 #define SWRAP_PACKET_IP_V4_SIZE 20
1544         struct {
1545                 uint8_t         ver_prio;
1546                 uint8_t         flow_label_high;
1547                 uint16_t        flow_label_low;
1548                 uint16_t        payload_length;
1549                 uint8_t         next_header;
1550                 uint8_t         hop_limit;
1551                 uint8_t         src_addr[16];
1552                 uint8_t         dest_addr[16];
1553         } v6;
1554 #define SWRAP_PACKET_IP_V6_SIZE 40
1555 };
1556 #define SWRAP_PACKET_IP_SIZE 40
1557
1558 union swrap_packet_payload {
1559         struct {
1560                 uint16_t        source_port;
1561                 uint16_t        dest_port;
1562                 uint32_t        seq_num;
1563                 uint32_t        ack_num;
1564                 uint8_t         hdr_length;
1565                 uint8_t         control;
1566                 uint16_t        window;
1567                 uint16_t        checksum;
1568                 uint16_t        urg;
1569         } tcp;
1570 #define SWRAP_PACKET_PAYLOAD_TCP_SIZE 20
1571         struct {
1572                 uint16_t        source_port;
1573                 uint16_t        dest_port;
1574                 uint16_t        length;
1575                 uint16_t        checksum;
1576         } udp;
1577 #define SWRAP_PACKET_PAYLOAD_UDP_SIZE 8
1578         struct {
1579                 uint8_t         type;
1580                 uint8_t         code;
1581                 uint16_t        checksum;
1582                 uint32_t        unused;
1583         } icmp4;
1584 #define SWRAP_PACKET_PAYLOAD_ICMP4_SIZE 8
1585         struct {
1586                 uint8_t         type;
1587                 uint8_t         code;
1588                 uint16_t        checksum;
1589                 uint32_t        unused;
1590         } icmp6;
1591 #define SWRAP_PACKET_PAYLOAD_ICMP6_SIZE 8
1592 };
1593 #define SWRAP_PACKET_PAYLOAD_SIZE 20
1594
1595 #define SWRAP_PACKET_MIN_ALLOC \
1596         (SWRAP_PACKET_FRAME_SIZE + \
1597          SWRAP_PACKET_IP_SIZE + \
1598          SWRAP_PACKET_PAYLOAD_SIZE)
1599
1600 static const char *socket_wrapper_pcap_file(void)
1601 {
1602         static int initialized = 0;
1603         static const char *s = NULL;
1604         static const struct swrap_file_hdr h;
1605         static const struct swrap_packet_frame f;
1606         static const union swrap_packet_ip i;
1607         static const union swrap_packet_payload p;
1608
1609         if (initialized == 1) {
1610                 return s;
1611         }
1612         initialized = 1;
1613
1614         /*
1615          * TODO: don't use the structs use plain buffer offsets
1616          *       and PUSH_U8(), PUSH_U16() and PUSH_U32()
1617          * 
1618          * for now make sure we disable PCAP support
1619          * if the struct has alignment!
1620          */
1621         if (sizeof(h) != SWRAP_FILE_HDR_SIZE) {
1622                 return NULL;
1623         }
1624         if (sizeof(f) != SWRAP_PACKET_FRAME_SIZE) {
1625                 return NULL;
1626         }
1627         if (sizeof(i) != SWRAP_PACKET_IP_SIZE) {
1628                 return NULL;
1629         }
1630         if (sizeof(i.v4) != SWRAP_PACKET_IP_V4_SIZE) {
1631                 return NULL;
1632         }
1633         if (sizeof(i.v6) != SWRAP_PACKET_IP_V6_SIZE) {
1634                 return NULL;
1635         }
1636         if (sizeof(p) != SWRAP_PACKET_PAYLOAD_SIZE) {
1637                 return NULL;
1638         }
1639         if (sizeof(p.tcp) != SWRAP_PACKET_PAYLOAD_TCP_SIZE) {
1640                 return NULL;
1641         }
1642         if (sizeof(p.udp) != SWRAP_PACKET_PAYLOAD_UDP_SIZE) {
1643                 return NULL;
1644         }
1645         if (sizeof(p.icmp4) != SWRAP_PACKET_PAYLOAD_ICMP4_SIZE) {
1646                 return NULL;
1647         }
1648         if (sizeof(p.icmp6) != SWRAP_PACKET_PAYLOAD_ICMP6_SIZE) {
1649                 return NULL;
1650         }
1651
1652         s = getenv("SOCKET_WRAPPER_PCAP_FILE");
1653         if (s == NULL) {
1654                 return NULL;
1655         }
1656         if (strncmp(s, "./", 2) == 0) {
1657                 s += 2;
1658         }
1659         return s;
1660 }
1661
1662 static uint8_t *swrap_packet_init(struct timeval *tval,
1663                                   const struct sockaddr *src,
1664                                   const struct sockaddr *dest,
1665                                   int socket_type,
1666                                   const uint8_t *payload,
1667                                   size_t payload_len,
1668                                   unsigned long tcp_seqno,
1669                                   unsigned long tcp_ack,
1670                                   unsigned char tcp_ctl,
1671                                   int unreachable,
1672                                   size_t *_packet_len)
1673 {
1674         uint8_t *base;
1675         uint8_t *buf;
1676         struct swrap_packet_frame *frame;
1677         union swrap_packet_ip *ip;
1678         union swrap_packet_payload *pay;
1679         size_t packet_len;
1680         size_t alloc_len;
1681         size_t nonwire_len = sizeof(*frame);
1682         size_t wire_hdr_len = 0;
1683         size_t wire_len = 0;
1684         size_t ip_hdr_len = 0;
1685         size_t icmp_hdr_len = 0;
1686         size_t icmp_truncate_len = 0;
1687         uint8_t protocol = 0, icmp_protocol = 0;
1688         const struct sockaddr_in *src_in = NULL;
1689         const struct sockaddr_in *dest_in = NULL;
1690 #ifdef HAVE_IPV6
1691         const struct sockaddr_in6 *src_in6 = NULL;
1692         const struct sockaddr_in6 *dest_in6 = NULL;
1693 #endif
1694         uint16_t src_port;
1695         uint16_t dest_port;
1696
1697         switch (src->sa_family) {
1698         case AF_INET:
1699                 src_in = (const struct sockaddr_in *)src;
1700                 dest_in = (const struct sockaddr_in *)dest;
1701                 src_port = src_in->sin_port;
1702                 dest_port = dest_in->sin_port;
1703                 ip_hdr_len = sizeof(ip->v4);
1704                 break;
1705 #ifdef HAVE_IPV6
1706         case AF_INET6:
1707                 src_in6 = (const struct sockaddr_in6 *)src;
1708                 dest_in6 = (const struct sockaddr_in6 *)dest;
1709                 src_port = src_in6->sin6_port;
1710                 dest_port = dest_in6->sin6_port;
1711                 ip_hdr_len = sizeof(ip->v6);
1712                 break;
1713 #endif
1714         default:
1715                 return NULL;
1716         }
1717
1718         switch (socket_type) {
1719         case SOCK_STREAM:
1720                 protocol = 0x06; /* TCP */
1721                 wire_hdr_len = ip_hdr_len + sizeof(pay->tcp);
1722                 wire_len = wire_hdr_len + payload_len;
1723                 break;
1724
1725         case SOCK_DGRAM:
1726                 protocol = 0x11; /* UDP */
1727                 wire_hdr_len = ip_hdr_len + sizeof(pay->udp);
1728                 wire_len = wire_hdr_len + payload_len;
1729                 break;
1730
1731         default:
1732                 return NULL;
1733         }
1734
1735         if (unreachable) {
1736                 icmp_protocol = protocol;
1737                 switch (src->sa_family) {
1738                 case AF_INET:
1739                         protocol = 0x01; /* ICMPv4 */
1740                         icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp4);
1741                         break;
1742 #ifdef HAVE_IPV6
1743                 case AF_INET6:
1744                         protocol = 0x3A; /* ICMPv6 */
1745                         icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp6);
1746                         break;
1747 #endif
1748                 }
1749                 if (wire_len > 64 ) {
1750                         icmp_truncate_len = wire_len - 64;
1751                 }
1752                 wire_hdr_len += icmp_hdr_len;
1753                 wire_len += icmp_hdr_len;
1754         }
1755
1756         packet_len = nonwire_len + wire_len;
1757         alloc_len = packet_len;
1758         if (alloc_len < SWRAP_PACKET_MIN_ALLOC) {
1759                 alloc_len = SWRAP_PACKET_MIN_ALLOC;
1760         }
1761
1762         base = (uint8_t *)malloc(alloc_len);
1763         if (base == NULL) {
1764                 return NULL;
1765         }
1766         memset(base, 0x0, alloc_len);
1767
1768         buf = base;
1769
1770         frame = (struct swrap_packet_frame *)buf;
1771         frame->seconds          = tval->tv_sec;
1772         frame->micro_seconds    = tval->tv_usec;
1773         frame->recorded_length  = wire_len - icmp_truncate_len;
1774         frame->full_length      = wire_len - icmp_truncate_len;
1775         buf += SWRAP_PACKET_FRAME_SIZE;
1776
1777         ip = (union swrap_packet_ip *)buf;
1778         switch (src->sa_family) {
1779         case AF_INET:
1780                 ip->v4.ver_hdrlen       = 0x45; /* version 4 and 5 * 32 bit words */
1781                 ip->v4.tos              = 0x00;
1782                 ip->v4.packet_length    = htons(wire_len - icmp_truncate_len);
1783                 ip->v4.identification   = htons(0xFFFF);
1784                 ip->v4.flags            = 0x40; /* BIT 1 set - means don't fragment */
1785                 ip->v4.fragment         = htons(0x0000);
1786                 ip->v4.ttl              = 0xFF;
1787                 ip->v4.protocol         = protocol;
1788                 ip->v4.hdr_checksum     = htons(0x0000);
1789                 ip->v4.src_addr         = src_in->sin_addr.s_addr;
1790                 ip->v4.dest_addr        = dest_in->sin_addr.s_addr;
1791                 buf += SWRAP_PACKET_IP_V4_SIZE;
1792                 break;
1793 #ifdef HAVE_IPV6
1794         case AF_INET6:
1795                 ip->v6.ver_prio         = 0x60; /* version 4 and 5 * 32 bit words */
1796                 ip->v6.flow_label_high  = 0x00;
1797                 ip->v6.flow_label_low   = 0x0000;
1798                 ip->v6.payload_length   = htons(wire_len - icmp_truncate_len); /* TODO */
1799                 ip->v6.next_header      = protocol;
1800                 memcpy(ip->v6.src_addr, src_in6->sin6_addr.s6_addr, 16);
1801                 memcpy(ip->v6.dest_addr, dest_in6->sin6_addr.s6_addr, 16);
1802                 buf += SWRAP_PACKET_IP_V6_SIZE;
1803                 break;
1804 #endif
1805         }
1806
1807         if (unreachable) {
1808                 pay = (union swrap_packet_payload *)buf;
1809                 switch (src->sa_family) {
1810                 case AF_INET:
1811                         pay->icmp4.type         = 0x03; /* destination unreachable */
1812                         pay->icmp4.code         = 0x01; /* host unreachable */
1813                         pay->icmp4.checksum     = htons(0x0000);
1814                         pay->icmp4.unused       = htonl(0x00000000);
1815                         buf += SWRAP_PACKET_PAYLOAD_ICMP4_SIZE;
1816
1817                         /* set the ip header in the ICMP payload */
1818                         ip = (union swrap_packet_ip *)buf;
1819                         ip->v4.ver_hdrlen       = 0x45; /* version 4 and 5 * 32 bit words */
1820                         ip->v4.tos              = 0x00;
1821                         ip->v4.packet_length    = htons(wire_len - icmp_hdr_len);
1822                         ip->v4.identification   = htons(0xFFFF);
1823                         ip->v4.flags            = 0x40; /* BIT 1 set - means don't fragment */
1824                         ip->v4.fragment         = htons(0x0000);
1825                         ip->v4.ttl              = 0xFF;
1826                         ip->v4.protocol         = icmp_protocol;
1827                         ip->v4.hdr_checksum     = htons(0x0000);
1828                         ip->v4.src_addr         = dest_in->sin_addr.s_addr;
1829                         ip->v4.dest_addr        = src_in->sin_addr.s_addr;
1830                         buf += SWRAP_PACKET_IP_V4_SIZE;
1831
1832                         src_port = dest_in->sin_port;
1833                         dest_port = src_in->sin_port;
1834                         break;
1835 #ifdef HAVE_IPV6
1836                 case AF_INET6:
1837                         pay->icmp6.type         = 0x01; /* destination unreachable */
1838                         pay->icmp6.code         = 0x03; /* address unreachable */
1839                         pay->icmp6.checksum     = htons(0x0000);
1840                         pay->icmp6.unused       = htonl(0x00000000);
1841                         buf += SWRAP_PACKET_PAYLOAD_ICMP6_SIZE;
1842
1843                         /* set the ip header in the ICMP payload */
1844                         ip = (union swrap_packet_ip *)buf;
1845                         ip->v6.ver_prio         = 0x60; /* version 4 and 5 * 32 bit words */
1846                         ip->v6.flow_label_high  = 0x00;
1847                         ip->v6.flow_label_low   = 0x0000;
1848                         ip->v6.payload_length   = htons(wire_len - icmp_truncate_len); /* TODO */
1849                         ip->v6.next_header      = protocol;
1850                         memcpy(ip->v6.src_addr, dest_in6->sin6_addr.s6_addr, 16);
1851                         memcpy(ip->v6.dest_addr, src_in6->sin6_addr.s6_addr, 16);
1852                         buf += SWRAP_PACKET_IP_V6_SIZE;
1853
1854                         src_port = dest_in6->sin6_port;
1855                         dest_port = src_in6->sin6_port;
1856                         break;
1857 #endif
1858                 }
1859         }
1860
1861         pay = (union swrap_packet_payload *)buf;
1862
1863         switch (socket_type) {
1864         case SOCK_STREAM:
1865                 pay->tcp.source_port    = src_port;
1866                 pay->tcp.dest_port      = dest_port;
1867                 pay->tcp.seq_num        = htonl(tcp_seqno);
1868                 pay->tcp.ack_num        = htonl(tcp_ack);
1869                 pay->tcp.hdr_length     = 0x50; /* 5 * 32 bit words */
1870                 pay->tcp.control        = tcp_ctl;
1871                 pay->tcp.window         = htons(0x7FFF);
1872                 pay->tcp.checksum       = htons(0x0000);
1873                 pay->tcp.urg            = htons(0x0000);
1874                 buf += SWRAP_PACKET_PAYLOAD_TCP_SIZE;
1875
1876                 break;
1877
1878         case SOCK_DGRAM:
1879                 pay->udp.source_port    = src_port;
1880                 pay->udp.dest_port      = dest_port;
1881                 pay->udp.length         = htons(8 + payload_len);
1882                 pay->udp.checksum       = htons(0x0000);
1883                 buf += SWRAP_PACKET_PAYLOAD_UDP_SIZE;
1884
1885                 break;
1886         }
1887
1888         if (payload && payload_len > 0) {
1889                 memcpy(buf, payload, payload_len);
1890         }
1891
1892         *_packet_len = packet_len - icmp_truncate_len;
1893         return base;
1894 }
1895
1896 static int swrap_get_pcap_fd(const char *fname)
1897 {
1898         static int fd = -1;
1899
1900         if (fd != -1) return fd;
1901
1902         fd = libc_open(fname, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0644);
1903         if (fd != -1) {
1904                 struct swrap_file_hdr file_hdr;
1905                 file_hdr.magic          = 0xA1B2C3D4;
1906                 file_hdr.version_major  = 0x0002;       
1907                 file_hdr.version_minor  = 0x0004;
1908                 file_hdr.timezone       = 0x00000000;
1909                 file_hdr.sigfigs        = 0x00000000;
1910                 file_hdr.frame_max_len  = SWRAP_FRAME_LENGTH_MAX;
1911                 file_hdr.link_type      = 0x0065; /* 101 RAW IP */
1912
1913                 if (write(fd, &file_hdr, sizeof(file_hdr)) != sizeof(file_hdr)) {
1914                         close(fd);
1915                         fd = -1;
1916                 }
1917                 return fd;
1918         }
1919
1920         fd = libc_open(fname, O_WRONLY|O_APPEND, 0644);
1921
1922         return fd;
1923 }
1924
1925 static uint8_t *swrap_marshall_packet(struct socket_info *si,
1926                                       const struct sockaddr *addr,
1927                                       enum swrap_packet_type type,
1928                                       const void *buf, size_t len,
1929                                       size_t *packet_len)
1930 {
1931         const struct sockaddr *src_addr;
1932         const struct sockaddr *dest_addr;
1933         unsigned long tcp_seqno = 0;
1934         unsigned long tcp_ack = 0;
1935         unsigned char tcp_ctl = 0;
1936         int unreachable = 0;
1937
1938         struct timeval tv;
1939
1940         switch (si->family) {
1941         case AF_INET:
1942                 break;
1943 #ifdef HAVE_IPV6
1944         case AF_INET6:
1945                 break;
1946 #endif
1947         default:
1948                 return NULL;
1949         }
1950
1951         switch (type) {
1952         case SWRAP_CONNECT_SEND:
1953                 if (si->type != SOCK_STREAM) return NULL;
1954
1955                 src_addr = si->myname;
1956                 dest_addr = addr;
1957
1958                 tcp_seqno = si->io.pck_snd;
1959                 tcp_ack = si->io.pck_rcv;
1960                 tcp_ctl = 0x02; /* SYN */
1961
1962                 si->io.pck_snd += 1;
1963
1964                 break;
1965
1966         case SWRAP_CONNECT_RECV:
1967                 if (si->type != SOCK_STREAM) return NULL;
1968
1969                 dest_addr = si->myname;
1970                 src_addr = addr;
1971
1972                 tcp_seqno = si->io.pck_rcv;
1973                 tcp_ack = si->io.pck_snd;
1974                 tcp_ctl = 0x12; /** SYN,ACK */
1975
1976                 si->io.pck_rcv += 1;
1977
1978                 break;
1979
1980         case SWRAP_CONNECT_UNREACH:
1981                 if (si->type != SOCK_STREAM) return NULL;
1982
1983                 dest_addr = si->myname;
1984                 src_addr = addr;
1985
1986                 /* Unreachable: resend the data of SWRAP_CONNECT_SEND */
1987                 tcp_seqno = si->io.pck_snd - 1;
1988                 tcp_ack = si->io.pck_rcv;
1989                 tcp_ctl = 0x02; /* SYN */
1990                 unreachable = 1;
1991
1992                 break;
1993
1994         case SWRAP_CONNECT_ACK:
1995                 if (si->type != SOCK_STREAM) return NULL;
1996
1997                 src_addr = si->myname;
1998                 dest_addr = addr;
1999
2000                 tcp_seqno = si->io.pck_snd;
2001                 tcp_ack = si->io.pck_rcv;
2002                 tcp_ctl = 0x10; /* ACK */
2003
2004                 break;
2005
2006         case SWRAP_ACCEPT_SEND:
2007                 if (si->type != SOCK_STREAM) return NULL;
2008
2009                 dest_addr = si->myname;
2010                 src_addr = addr;
2011
2012                 tcp_seqno = si->io.pck_rcv;
2013                 tcp_ack = si->io.pck_snd;
2014                 tcp_ctl = 0x02; /* SYN */
2015
2016                 si->io.pck_rcv += 1;
2017
2018                 break;
2019
2020         case SWRAP_ACCEPT_RECV:
2021                 if (si->type != SOCK_STREAM) return NULL;
2022
2023                 src_addr = si->myname;
2024                 dest_addr = addr;
2025
2026                 tcp_seqno = si->io.pck_snd;
2027                 tcp_ack = si->io.pck_rcv;
2028                 tcp_ctl = 0x12; /* SYN,ACK */
2029
2030                 si->io.pck_snd += 1;
2031
2032                 break;
2033
2034         case SWRAP_ACCEPT_ACK:
2035                 if (si->type != SOCK_STREAM) return NULL;
2036
2037                 dest_addr = si->myname;
2038                 src_addr = addr;
2039
2040                 tcp_seqno = si->io.pck_rcv;
2041                 tcp_ack = si->io.pck_snd;
2042                 tcp_ctl = 0x10; /* ACK */
2043
2044                 break;
2045
2046         case SWRAP_SEND:
2047                 src_addr = si->myname;
2048                 dest_addr = si->peername;
2049
2050                 tcp_seqno = si->io.pck_snd;
2051                 tcp_ack = si->io.pck_rcv;
2052                 tcp_ctl = 0x18; /* PSH,ACK */
2053
2054                 si->io.pck_snd += len;
2055
2056                 break;
2057
2058         case SWRAP_SEND_RST:
2059                 dest_addr = si->myname;
2060                 src_addr = si->peername;
2061
2062                 if (si->type == SOCK_DGRAM) {
2063                         return swrap_marshall_packet(si, si->peername,
2064                                           SWRAP_SENDTO_UNREACH,
2065                                           buf, len, packet_len);
2066                 }
2067
2068                 tcp_seqno = si->io.pck_rcv;
2069                 tcp_ack = si->io.pck_snd;
2070                 tcp_ctl = 0x14; /** RST,ACK */
2071
2072                 break;
2073
2074         case SWRAP_PENDING_RST:
2075                 dest_addr = si->myname;
2076                 src_addr = si->peername;
2077
2078                 if (si->type == SOCK_DGRAM) {
2079                         return NULL;
2080                 }
2081
2082                 tcp_seqno = si->io.pck_rcv;
2083                 tcp_ack = si->io.pck_snd;
2084                 tcp_ctl = 0x14; /* RST,ACK */
2085
2086                 break;
2087
2088         case SWRAP_RECV:
2089                 dest_addr = si->myname;
2090                 src_addr = si->peername;
2091
2092                 tcp_seqno = si->io.pck_rcv;
2093                 tcp_ack = si->io.pck_snd;
2094                 tcp_ctl = 0x18; /* PSH,ACK */
2095
2096                 si->io.pck_rcv += len;
2097
2098                 break;
2099
2100         case SWRAP_RECV_RST:
2101                 dest_addr = si->myname;
2102                 src_addr = si->peername;
2103
2104                 if (si->type == SOCK_DGRAM) {
2105                         return NULL;
2106                 }
2107
2108                 tcp_seqno = si->io.pck_rcv;
2109                 tcp_ack = si->io.pck_snd;
2110                 tcp_ctl = 0x14; /* RST,ACK */
2111
2112                 break;
2113
2114         case SWRAP_SENDTO:
2115                 src_addr = si->myname;
2116                 dest_addr = addr;
2117
2118                 si->io.pck_snd += len;
2119
2120                 break;
2121
2122         case SWRAP_SENDTO_UNREACH:
2123                 dest_addr = si->myname;
2124                 src_addr = addr;
2125
2126                 unreachable = 1;
2127
2128                 break;
2129
2130         case SWRAP_RECVFROM:
2131                 dest_addr = si->myname;
2132                 src_addr = addr;
2133
2134                 si->io.pck_rcv += len;
2135
2136                 break;
2137
2138         case SWRAP_CLOSE_SEND:
2139                 if (si->type != SOCK_STREAM) return NULL;
2140
2141                 src_addr = si->myname;
2142                 dest_addr = si->peername;
2143
2144                 tcp_seqno = si->io.pck_snd;
2145                 tcp_ack = si->io.pck_rcv;
2146                 tcp_ctl = 0x11; /* FIN, ACK */
2147
2148                 si->io.pck_snd += 1;
2149
2150                 break;
2151
2152         case SWRAP_CLOSE_RECV:
2153                 if (si->type != SOCK_STREAM) return NULL;
2154
2155                 dest_addr = si->myname;
2156                 src_addr = si->peername;
2157
2158                 tcp_seqno = si->io.pck_rcv;
2159                 tcp_ack = si->io.pck_snd;
2160                 tcp_ctl = 0x11; /* FIN,ACK */
2161
2162                 si->io.pck_rcv += 1;
2163
2164                 break;
2165
2166         case SWRAP_CLOSE_ACK:
2167                 if (si->type != SOCK_STREAM) return NULL;
2168
2169                 src_addr = si->myname;
2170                 dest_addr = si->peername;
2171
2172                 tcp_seqno = si->io.pck_snd;
2173                 tcp_ack = si->io.pck_rcv;
2174                 tcp_ctl = 0x10; /* ACK */
2175
2176                 break;
2177         default:
2178                 return NULL;
2179         }
2180
2181         swrapGetTimeOfDay(&tv);
2182
2183         return swrap_packet_init(&tv, src_addr, dest_addr, si->type,
2184                                  (const uint8_t *)buf, len,
2185                                  tcp_seqno, tcp_ack, tcp_ctl, unreachable,
2186                                  packet_len);
2187 }
2188
2189 static void swrap_dump_packet(struct socket_info *si,
2190                               const struct sockaddr *addr,
2191                               enum swrap_packet_type type,
2192                               const void *buf, size_t len)
2193 {
2194         const char *file_name;
2195         uint8_t *packet;
2196         size_t packet_len = 0;
2197         int fd;
2198
2199         file_name = socket_wrapper_pcap_file();
2200         if (!file_name) {
2201                 return;
2202         }
2203
2204         packet = swrap_marshall_packet(si, addr, type, buf, len, &packet_len);
2205         if (!packet) {
2206                 return;
2207         }
2208
2209         fd = swrap_get_pcap_fd(file_name);
2210         if (fd != -1) {
2211                 if (write(fd, packet, packet_len) != (ssize_t)packet_len) {
2212                         free(packet);
2213                         return;
2214                 }
2215         }
2216
2217         free(packet);
2218 }
2219
2220 /****************************************************************************
2221  *   SIGNALFD
2222  ***************************************************************************/
2223
2224 #ifdef HAVE_SIGNALFD
2225 static int swrap_signalfd(int fd, const sigset_t *mask, int flags)
2226 {
2227         int rc;
2228
2229         rc = libc_signalfd(fd, mask, flags);
2230         if (rc != -1) {
2231                 swrap_remove_stale(fd);
2232         }
2233
2234         return rc;
2235 }
2236
2237 int signalfd(int fd, const sigset_t *mask, int flags)
2238 {
2239         return swrap_signalfd(fd, mask, flags);
2240 }
2241 #endif
2242
2243 /****************************************************************************
2244  *   SOCKET
2245  ***************************************************************************/
2246
2247 static int swrap_socket(int family, int type, int protocol)
2248 {
2249         struct socket_info *si;
2250         struct socket_info_fd *fi;
2251         int fd;
2252         int real_type = type;
2253
2254         /*
2255          * Remove possible addition flags passed to socket() so
2256          * do not fail checking the type.
2257          * See https://lwn.net/Articles/281965/
2258          */
2259 #ifdef SOCK_CLOEXEC
2260         real_type &= ~SOCK_CLOEXEC;
2261 #endif
2262 #ifdef SOCK_NONBLOCK
2263         real_type &= ~SOCK_NONBLOCK;
2264 #endif
2265
2266         if (!socket_wrapper_enabled()) {
2267                 return libc_socket(family, type, protocol);
2268         }
2269
2270         switch (family) {
2271         case AF_INET:
2272 #ifdef HAVE_IPV6
2273         case AF_INET6:
2274 #endif
2275                 break;
2276         case AF_UNIX:
2277                 return libc_socket(family, type, protocol);
2278         default:
2279                 errno = EAFNOSUPPORT;
2280                 return -1;
2281         }
2282
2283         switch (real_type) {
2284         case SOCK_STREAM:
2285                 break;
2286         case SOCK_DGRAM:
2287                 break;
2288         default:
2289                 errno = EPROTONOSUPPORT;
2290                 return -1;
2291         }
2292
2293         switch (protocol) {
2294         case 0:
2295                 break;
2296         case 6:
2297                 if (real_type == SOCK_STREAM) {
2298                         break;
2299                 }
2300                 /*fall through*/
2301         case 17:
2302                 if (real_type == SOCK_DGRAM) {
2303                         break;
2304                 }
2305                 /*fall through*/
2306         default:
2307                 errno = EPROTONOSUPPORT;
2308                 return -1;
2309         }
2310
2311         /*
2312          * We must call libc_socket with type, from the caller, not the version
2313          * we removed SOCK_CLOEXEC and SOCK_NONBLOCK from
2314          */
2315         fd = libc_socket(AF_UNIX, type, 0);
2316
2317         if (fd == -1) {
2318                 return -1;
2319         }
2320
2321         /* Check if we have a stale fd and remove it */
2322         si = find_socket_info(fd);
2323         if (si != NULL) {
2324                 swrap_remove_stale(fd);
2325         }
2326
2327         si = (struct socket_info *)malloc(sizeof(struct socket_info));
2328         memset(si, 0, sizeof(struct socket_info));
2329         if (si == NULL) {
2330                 errno = ENOMEM;
2331                 return -1;
2332         }
2333
2334         si->family = family;
2335
2336         /* however, the rest of the socket_wrapper code expects just
2337          * the type, not the flags */
2338         si->type = real_type;
2339         si->protocol = protocol;
2340
2341         /*
2342          * Setup myname so getsockname() can succeed to find out the socket
2343          * type.
2344          */
2345         switch(si->family) {
2346         case AF_INET: {
2347                 struct sockaddr_in sin = {
2348                         .sin_family = AF_INET,
2349                 };
2350
2351                 si->myname_len = sizeof(struct sockaddr_in);
2352                 si->myname = sockaddr_dup(&sin, si->myname_len);
2353                 break;
2354         }
2355         case AF_INET6: {
2356                 struct sockaddr_in6 sin6 = {
2357                         .sin6_family = AF_INET6,
2358                 };
2359
2360                 si->myname_len = sizeof(struct sockaddr_in6);
2361                 si->myname = sockaddr_dup(&sin6, si->myname_len);
2362                 break;
2363         }
2364         default:
2365                 free(si);
2366                 errno = EINVAL;
2367                 return -1;
2368         }
2369
2370         fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
2371         if (fi == NULL) {
2372                 if (si->myname != NULL) {
2373                         free (si->myname);
2374                 }
2375                 free(si);
2376                 errno = ENOMEM;
2377                 return -1;
2378         }
2379
2380         fi->fd = fd;
2381
2382         SWRAP_DLIST_ADD(si->fds, fi);
2383         SWRAP_DLIST_ADD(sockets, si);
2384
2385         return fd;
2386 }
2387
2388 int socket(int family, int type, int protocol)
2389 {
2390         return swrap_socket(family, type, protocol);
2391 }
2392
2393 /****************************************************************************
2394  *   SOCKETPAIR
2395  ***************************************************************************/
2396
2397 static int swrap_socketpair(int family, int type, int protocol, int sv[2])
2398 {
2399         int rc;
2400
2401         rc = libc_socketpair(family, type, protocol, sv);
2402         if (rc != -1) {
2403                 swrap_remove_stale(sv[0]);
2404                 swrap_remove_stale(sv[1]);
2405         }
2406
2407         return rc;
2408 }
2409
2410 int socketpair(int family, int type, int protocol, int sv[2])
2411 {
2412         return swrap_socketpair(family, type, protocol, sv);
2413 }
2414
2415 /****************************************************************************
2416  *   SOCKETPAIR
2417  ***************************************************************************/
2418
2419 #ifdef HAVE_TIMERFD_CREATE
2420 static int swrap_timerfd_create(int clockid, int flags)
2421 {
2422         int fd;
2423
2424         fd = libc_timerfd_create(clockid, flags);
2425         if (fd != -1) {
2426                 swrap_remove_stale(fd);
2427         }
2428
2429         return fd;
2430 }
2431
2432 int timerfd_create(int clockid, int flags)
2433 {
2434         return swrap_timerfd_create(clockid, flags);
2435 }
2436 #endif
2437
2438 /****************************************************************************
2439  *   PIPE
2440  ***************************************************************************/
2441
2442 static int swrap_pipe(int pipefd[2])
2443 {
2444         int rc;
2445
2446         rc = libc_pipe(pipefd);
2447         if (rc != -1) {
2448                 swrap_remove_stale(pipefd[0]);
2449                 swrap_remove_stale(pipefd[1]);
2450         }
2451
2452         return rc;
2453 }
2454
2455 int pipe(int pipefd[2])
2456 {
2457         return swrap_pipe(pipefd);
2458 }
2459
2460 /****************************************************************************
2461  *   ACCEPT
2462  ***************************************************************************/
2463
2464 static int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
2465 {
2466         struct socket_info *parent_si, *child_si;
2467         struct socket_info_fd *child_fi;
2468         int fd;
2469         struct sockaddr_un un_addr;
2470         socklen_t un_addrlen = sizeof(un_addr);
2471         struct sockaddr_un un_my_addr;
2472         socklen_t un_my_addrlen = sizeof(un_my_addr);
2473         struct sockaddr *my_addr;
2474         socklen_t my_addrlen, len;
2475         int ret;
2476
2477         parent_si = find_socket_info(s);
2478         if (!parent_si) {
2479                 return libc_accept(s, addr, addrlen);
2480         }
2481
2482         /* 
2483          * assume out sockaddr have the same size as the in parent
2484          * socket family
2485          */
2486         my_addrlen = socket_length(parent_si->family);
2487         if (my_addrlen <= 0) {
2488                 errno = EINVAL;
2489                 return -1;
2490         }
2491
2492         my_addr = (struct sockaddr *)malloc(my_addrlen);
2493         if (my_addr == NULL) {
2494                 return -1;
2495         }
2496
2497         memset(&un_addr, 0, sizeof(un_addr));
2498         memset(&un_my_addr, 0, sizeof(un_my_addr));
2499
2500         ret = libc_accept(s, (struct sockaddr *)(void *)&un_addr, &un_addrlen);
2501         if (ret == -1) {
2502                 if (errno == ENOTSOCK) {
2503                         /* Remove stale fds */
2504                         swrap_remove_stale(s);
2505                 }
2506                 free(my_addr);
2507                 return ret;
2508         }
2509
2510         fd = ret;
2511
2512         len = my_addrlen;
2513         ret = sockaddr_convert_from_un(parent_si, &un_addr, un_addrlen,
2514                                        parent_si->family, my_addr, &len);
2515         if (ret == -1) {
2516                 free(my_addr);
2517                 close(fd);
2518                 return ret;
2519         }
2520
2521         child_si = (struct socket_info *)malloc(sizeof(struct socket_info));
2522         memset(child_si, 0, sizeof(struct socket_info));
2523
2524         child_fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
2525         if (child_fi == NULL) {
2526                 free(child_si);
2527                 free(my_addr);
2528                 close(fd);
2529                 errno = ENOMEM;
2530                 return -1;
2531         }
2532
2533         child_fi->fd = fd;
2534
2535         SWRAP_DLIST_ADD(child_si->fds, child_fi);
2536
2537         child_si->family = parent_si->family;
2538         child_si->type = parent_si->type;
2539         child_si->protocol = parent_si->protocol;
2540         child_si->bound = 1;
2541         child_si->is_server = 1;
2542         child_si->connected = 1;
2543
2544         child_si->peername_len = len;
2545         child_si->peername = sockaddr_dup(my_addr, len);
2546
2547         if (addr != NULL && addrlen != NULL) {
2548                 size_t copy_len = MIN(*addrlen, len);
2549                 if (copy_len > 0) {
2550                         memcpy(addr, my_addr, copy_len);
2551                 }
2552                 *addrlen = len;
2553         }
2554
2555         ret = libc_getsockname(fd,
2556                                (struct sockaddr *)(void *)&un_my_addr,
2557                                &un_my_addrlen);
2558         if (ret == -1) {
2559                 free(child_fi);
2560                 free(child_si);
2561                 free(my_addr);
2562                 close(fd);
2563                 return ret;
2564         }
2565
2566         len = my_addrlen;
2567         ret = sockaddr_convert_from_un(child_si, &un_my_addr, un_my_addrlen,
2568                                        child_si->family, my_addr, &len);
2569         if (ret == -1) {
2570                 free(child_fi);
2571                 free(child_si);
2572                 free(my_addr);
2573                 close(fd);
2574                 return ret;
2575         }
2576
2577         SWRAP_LOG(SWRAP_LOG_TRACE,
2578                   "accept() path=%s, fd=%d",
2579                   un_my_addr.sun_path, s);
2580
2581         child_si->myname_len = len;
2582         child_si->myname = sockaddr_dup(my_addr, len);
2583         free(my_addr);
2584
2585         SWRAP_DLIST_ADD(sockets, child_si);
2586
2587         if (addr != NULL) {
2588                 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0);
2589                 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_RECV, NULL, 0);
2590                 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_ACK, NULL, 0);
2591         }
2592
2593         return fd;
2594 }
2595
2596 #ifdef HAVE_ACCEPT_PSOCKLEN_T
2597 int accept(int s, struct sockaddr *addr, Psocklen_t addrlen)
2598 #else
2599 int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
2600 #endif
2601 {
2602         return swrap_accept(s, addr, (socklen_t *)addrlen);
2603 }
2604
2605 static int autobind_start_init;
2606 static int autobind_start;
2607
2608 /* using sendto() or connect() on an unbound socket would give the
2609    recipient no way to reply, as unlike UDP and TCP, a unix domain
2610    socket can't auto-assign ephemeral port numbers, so we need to
2611    assign it here.
2612    Note: this might change the family from ipv6 to ipv4
2613 */
2614 static int swrap_auto_bind(int fd, struct socket_info *si, int family)
2615 {
2616         struct sockaddr_un un_addr;
2617         int i;
2618         char type;
2619         int ret;
2620         int port;
2621         struct stat st;
2622
2623         if (autobind_start_init != 1) {
2624                 autobind_start_init = 1;
2625                 autobind_start = getpid();
2626                 autobind_start %= 50000;
2627                 autobind_start += 10000;
2628         }
2629
2630         un_addr.sun_family = AF_UNIX;
2631
2632         switch (family) {
2633         case AF_INET: {
2634                 struct sockaddr_in in;
2635
2636                 switch (si->type) {
2637                 case SOCK_STREAM:
2638                         type = SOCKET_TYPE_CHAR_TCP;
2639                         break;
2640                 case SOCK_DGRAM:
2641                         type = SOCKET_TYPE_CHAR_UDP;
2642                         break;
2643                 default:
2644                     errno = ESOCKTNOSUPPORT;
2645                     return -1;
2646                 }
2647
2648                 memset(&in, 0, sizeof(in));
2649                 in.sin_family = AF_INET;
2650                 in.sin_addr.s_addr = htonl(127<<24 | 
2651                                            socket_wrapper_default_iface());
2652
2653                 free(si->myname);
2654                 si->myname_len = sizeof(in);
2655                 si->myname = sockaddr_dup(&in, si->myname_len);
2656                 break;
2657         }
2658 #ifdef HAVE_IPV6
2659         case AF_INET6: {
2660                 struct sockaddr_in6 in6;
2661
2662                 if (si->family != family) {
2663                         errno = ENETUNREACH;
2664                         return -1;
2665                 }
2666
2667                 switch (si->type) {
2668                 case SOCK_STREAM:
2669                         type = SOCKET_TYPE_CHAR_TCP_V6;
2670                         break;
2671                 case SOCK_DGRAM:
2672                         type = SOCKET_TYPE_CHAR_UDP_V6;
2673                         break;
2674                 default:
2675                         errno = ESOCKTNOSUPPORT;
2676                         return -1;
2677                 }
2678
2679                 memset(&in6, 0, sizeof(in6));
2680                 in6.sin6_family = AF_INET6;
2681                 in6.sin6_addr = *swrap_ipv6();
2682                 in6.sin6_addr.s6_addr[15] = socket_wrapper_default_iface();
2683                 free(si->myname);
2684                 si->myname_len = sizeof(in6);
2685                 si->myname = sockaddr_dup(&in6, si->myname_len);
2686                 break;
2687         }
2688 #endif
2689         default:
2690                 errno = ESOCKTNOSUPPORT;
2691                 return -1;
2692         }
2693
2694         if (autobind_start > 60000) {
2695                 autobind_start = 10000;
2696         }
2697
2698         for (i = 0; i < SOCKET_MAX_SOCKETS; i++) {
2699                 port = autobind_start + i;
2700                 snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), 
2701                          "%s/"SOCKET_FORMAT, socket_wrapper_dir(),
2702                          type, socket_wrapper_default_iface(), port);
2703                 if (stat(un_addr.sun_path, &st) == 0) continue;
2704
2705                 ret = libc_bind(fd, (struct sockaddr *)(void *)&un_addr,
2706                                 sizeof(un_addr));
2707                 if (ret == -1) return ret;
2708
2709                 si->tmp_path = strdup(un_addr.sun_path);
2710                 si->bound = 1;
2711                 autobind_start = port + 1;
2712                 break;
2713         }
2714         if (i == SOCKET_MAX_SOCKETS) {
2715                 SWRAP_LOG(SWRAP_LOG_ERROR, "Too many open unix sockets (%u) for "
2716                                            "interface "SOCKET_FORMAT,
2717                                            SOCKET_MAX_SOCKETS,
2718                                            type,
2719                                            socket_wrapper_default_iface(),
2720                                            0);
2721                 errno = ENFILE;
2722                 return -1;
2723         }
2724
2725         si->family = family;
2726         set_port(si->family, port, si->myname);
2727
2728         return 0;
2729 }
2730
2731 /****************************************************************************
2732  *   CONNECT
2733  ***************************************************************************/
2734
2735 static int swrap_connect(int s, const struct sockaddr *serv_addr,
2736                          socklen_t addrlen)
2737 {
2738         int ret;
2739         struct sockaddr_un un_addr;
2740         struct socket_info *si = find_socket_info(s);
2741         int bcast = 0;
2742
2743         if (!si) {
2744                 return libc_connect(s, serv_addr, addrlen);
2745         }
2746
2747         if (si->bound == 0) {
2748                 ret = swrap_auto_bind(s, si, serv_addr->sa_family);
2749                 if (ret == -1) return -1;
2750         }
2751
2752         if (si->family != serv_addr->sa_family) {
2753                 errno = EINVAL;
2754                 return -1;
2755         }
2756
2757         ret = sockaddr_convert_to_un(si, serv_addr,
2758                                      addrlen, &un_addr, 0, &bcast);
2759         if (ret == -1) return -1;
2760
2761         if (bcast) {
2762                 errno = ENETUNREACH;
2763                 return -1;
2764         }
2765
2766         if (si->type == SOCK_DGRAM) {
2767                 si->defer_connect = 1;
2768                 ret = 0;
2769         } else {
2770                 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0);
2771
2772                 ret = libc_connect(s,
2773                                    (struct sockaddr *)(void *)&un_addr,
2774                                    sizeof(struct sockaddr_un));
2775         }
2776
2777         SWRAP_LOG(SWRAP_LOG_TRACE,
2778                   "connect() path=%s, fd=%d",
2779                   un_addr.sun_path, s);
2780
2781
2782         /* to give better errors */
2783         if (ret == -1 && errno == ENOENT) {
2784                 errno = EHOSTUNREACH;
2785         }
2786
2787         if (ret == 0) {
2788                 si->peername_len = addrlen;
2789                 si->peername = sockaddr_dup(serv_addr, addrlen);
2790                 si->connected = 1;
2791
2792                 /*
2793                  * When we connect() on a socket than we have to bind the
2794                  * outgoing connection on the interface we use for the
2795                  * transport. We already bound it on the right interface
2796                  * but here we have to update the name so getsockname()
2797                  * returns correct information.
2798                  */
2799                 if (si->bindname != NULL) {
2800                         free(si->myname);
2801
2802                         si->myname = si->bindname;
2803                         si->myname_len = si->bindname_len;
2804
2805                         si->bindname = NULL;
2806                         si->bindname_len = 0;
2807                 }
2808
2809                 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0);
2810                 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0);
2811         } else {
2812                 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0);
2813         }
2814
2815         return ret;
2816 }
2817
2818 int connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen)
2819 {
2820         return swrap_connect(s, serv_addr, addrlen);
2821 }
2822
2823 /****************************************************************************
2824  *   BIND
2825  ***************************************************************************/
2826
2827 static int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
2828 {
2829         int ret;
2830         struct sockaddr_un un_addr;
2831         struct socket_info *si = find_socket_info(s);
2832         int bind_error = 0;
2833 #if 0 /* FIXME */
2834         bool in_use;
2835 #endif
2836
2837         if (!si) {
2838                 return libc_bind(s, myaddr, addrlen);
2839         }
2840
2841         switch (si->family) {
2842         case AF_INET: {
2843                 const struct sockaddr_in *sin;
2844                 if (addrlen < sizeof(struct sockaddr_in)) {
2845                         bind_error = EINVAL;
2846                         break;
2847                 }
2848
2849                 sin = (const struct sockaddr_in *)myaddr;
2850
2851                 if (sin->sin_family != AF_INET) {
2852                         bind_error = EAFNOSUPPORT;
2853                 }
2854
2855                 /* special case for AF_UNSPEC */
2856                 if (sin->sin_family == AF_UNSPEC &&
2857                     (sin->sin_addr.s_addr == htonl(INADDR_ANY)))
2858                 {
2859                         bind_error = 0;
2860                 }
2861
2862                 break;
2863         }
2864 #ifdef HAVE_IPV6
2865         case AF_INET6: {
2866                 const struct sockaddr_in6 *sin6;
2867                 if (addrlen < sizeof(struct sockaddr_in6)) {
2868                         bind_error = EINVAL;
2869                         break;
2870                 }
2871
2872                 sin6 = (const struct sockaddr_in6 *)myaddr;
2873
2874                 if (sin6->sin6_family != AF_INET6) {
2875                         bind_error = EAFNOSUPPORT;
2876                 }
2877
2878                 break;
2879         }
2880 #endif
2881         default:
2882                 bind_error = EINVAL;
2883                 break;
2884         }
2885
2886         if (bind_error != 0) {
2887                 errno = bind_error;
2888                 return -1;
2889         }
2890
2891 #if 0 /* FIXME */
2892         in_use = check_addr_port_in_use(myaddr, addrlen);
2893         if (in_use) {
2894                 errno = EADDRINUSE;
2895                 return -1;
2896         }
2897 #endif
2898
2899         free(si->myname);
2900         si->myname_len = addrlen;
2901         si->myname = sockaddr_dup(myaddr, addrlen);
2902
2903         ret = sockaddr_convert_to_un(si, myaddr, addrlen, &un_addr, 1, &si->bcast);
2904         if (ret == -1) return -1;
2905
2906         unlink(un_addr.sun_path);
2907
2908         ret = libc_bind(s, (struct sockaddr *)(void *)&un_addr,
2909                         sizeof(struct sockaddr_un));
2910
2911         SWRAP_LOG(SWRAP_LOG_TRACE,
2912                   "bind() path=%s, fd=%d",
2913                   un_addr.sun_path, s);
2914
2915         if (ret == 0) {
2916                 si->bound = 1;
2917         }
2918
2919         return ret;
2920 }
2921
2922 int bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
2923 {
2924         return swrap_bind(s, myaddr, addrlen);
2925 }
2926
2927 /****************************************************************************
2928  *   BINDRESVPORT
2929  ***************************************************************************/
2930
2931 #ifdef HAVE_BINDRESVPORT
2932 static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen);
2933
2934 static int swrap_bindresvport_sa(int sd, struct sockaddr *sa)
2935 {
2936         struct sockaddr_storage myaddr;
2937         socklen_t salen;
2938         static uint16_t port;
2939         uint16_t i;
2940         int rc = -1;
2941         int af;
2942
2943 #define SWRAP_STARTPORT 600
2944 #define SWRAP_ENDPORT (IPPORT_RESERVED - 1)
2945 #define SWRAP_NPORTS (SWRAP_ENDPORT - SWRAP_STARTPORT + 1)
2946
2947         if (port == 0) {
2948                 port = (getpid() % SWRAP_NPORTS) + SWRAP_STARTPORT;
2949         }
2950
2951         if (sa == NULL) {
2952                 salen = sizeof(struct sockaddr);
2953                 sa = (struct sockaddr *)&myaddr;
2954
2955                 rc = swrap_getsockname(sd, (struct sockaddr *)&myaddr, &salen);
2956                 if (rc < 0) {
2957                         return -1;
2958                 }
2959
2960                 af = sa->sa_family;
2961                 memset(&myaddr, 0, salen);
2962         } else {
2963                 af = sa->sa_family;
2964         }
2965
2966         for (i = 0; i < SWRAP_NPORTS; i++, port++) {
2967                 switch(af) {
2968                 case AF_INET: {
2969                         struct sockaddr_in *sinp = (struct sockaddr_in *)sa;
2970
2971                         salen = sizeof(struct sockaddr_in);
2972                         sinp->sin_port = htons(port);
2973                         break;
2974                 }
2975                 case AF_INET6: {
2976                         struct sockaddr_in6 *sin6p = (struct sockaddr_in6 *)sa;
2977
2978                         salen = sizeof(struct sockaddr_in6);
2979                         sin6p->sin6_port = htons(port);
2980                         break;
2981                 }
2982                 default:
2983                         errno = EAFNOSUPPORT;
2984                         return -1;
2985                 }
2986                 sa->sa_family = af;
2987
2988                 if (port > SWRAP_ENDPORT) {
2989                         port = SWRAP_STARTPORT;
2990                 }
2991
2992                 rc = swrap_bind(sd, (struct sockaddr *)sa, salen);
2993                 if (rc == 0 || errno != EADDRINUSE) {
2994                         break;
2995                 }
2996         }
2997
2998         return rc;
2999 }
3000
3001 int bindresvport(int sockfd, struct sockaddr_in *sinp)
3002 {
3003         return swrap_bindresvport_sa(sockfd, (struct sockaddr *)sinp);
3004 }
3005 #endif
3006
3007 /****************************************************************************
3008  *   LISTEN
3009  ***************************************************************************/
3010
3011 static int swrap_listen(int s, int backlog)
3012 {
3013         int ret;
3014         struct socket_info *si = find_socket_info(s);
3015
3016         if (!si) {
3017                 return libc_listen(s, backlog);
3018         }
3019
3020         ret = libc_listen(s, backlog);
3021
3022         return ret;
3023 }
3024
3025 int listen(int s, int backlog)
3026 {
3027         return swrap_listen(s, backlog);
3028 }
3029
3030 /****************************************************************************
3031  *   OPEN
3032  ***************************************************************************/
3033
3034 static int swrap_vopen(const char *pathname, int flags, va_list ap)
3035 {
3036         int ret;
3037
3038         ret = libc_vopen(pathname, flags, ap);
3039         if (ret != -1) {
3040                 /*
3041                  * There are methods for closing descriptors (libc-internal code
3042                  * paths, direct syscalls) which close descriptors in ways that
3043                  * we can't intercept, so try to recover when we notice that
3044                  * that's happened
3045                  */
3046                 swrap_remove_stale(ret);
3047         }
3048         return ret;
3049 }
3050
3051 int open(const char *pathname, int flags, ...)
3052 {
3053         va_list ap;
3054         int fd;
3055
3056         va_start(ap, flags);
3057         fd = swrap_vopen(pathname, flags, ap);
3058         va_end(ap);
3059
3060         return fd;
3061 }
3062
3063 /****************************************************************************
3064  *   GETPEERNAME
3065  ***************************************************************************/
3066
3067 static int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
3068 {
3069         struct socket_info *si = find_socket_info(s);
3070         socklen_t len;
3071
3072         if (!si) {
3073                 return libc_getpeername(s, name, addrlen);
3074         }
3075
3076         if (!si->peername)
3077         {
3078                 errno = ENOTCONN;
3079                 return -1;
3080         }
3081
3082         len = MIN(*addrlen, si->peername_len);
3083         if (len == 0) {
3084                 return 0;
3085         }
3086