Provide a compatible declaration of CMSG_ALIGN
[vlendec/samba-autobuild/.git] / lib / socket_wrapper / socket_wrapper.c
1 /*
2  * Copyright (C) Jelmer Vernooij 2005,2008 <jelmer@samba.org>
3  * Copyright (C) Stefan Metzmacher 2006-2009 <metze@samba.org>
4  * Copyright (C) Andreas Schneider 2013 <asn@samba.org>
5  *
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * 3. Neither the name of the author nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  */
36
37 /*
38    Socket wrapper library. Passes all socket communication over
39    unix domain sockets if the environment variable SOCKET_WRAPPER_DIR
40    is set.
41 */
42
43 #include "config.h"
44
45 #include <sys/types.h>
46 #include <sys/time.h>
47 #include <sys/stat.h>
48 #include <sys/socket.h>
49 #include <sys/ioctl.h>
50 #ifdef HAVE_SYS_FILIO_H
51 #include <sys/filio.h>
52 #endif
53 #ifdef HAVE_SYS_SIGNALFD_H
54 #include <sys/signalfd.h>
55 #endif
56 #ifdef HAVE_SYS_EVENTFD_H
57 #include <sys/eventfd.h>
58 #endif
59 #ifdef HAVE_SYS_TIMERFD_H
60 #include <sys/timerfd.h>
61 #endif
62 #include <sys/uio.h>
63 #include <errno.h>
64 #include <sys/un.h>
65 #include <netinet/in.h>
66 #include <netinet/tcp.h>
67 #include <arpa/inet.h>
68 #include <fcntl.h>
69 #include <stdlib.h>
70 #include <string.h>
71 #include <stdio.h>
72 #include <stdint.h>
73 #include <stdarg.h>
74 #include <stdbool.h>
75 #include <unistd.h>
76 #ifdef HAVE_GNU_LIB_NAMES_H
77 #include <gnu/lib-names.h>
78 #endif
79 #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
3087         memcpy(name, si->peername, len);
3088         *addrlen = si->peername_len;
3089
3090         return 0;
3091 }
3092
3093 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3094 int getpeername(int s, struct sockaddr *name, Psocklen_t addrlen)
3095 #else
3096 int getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
3097 #endif
3098 {
3099         return swrap_getpeername(s, name, (socklen_t *)addrlen);
3100 }
3101
3102 /****************************************************************************
3103  *   GETSOCKNAME
3104  ***************************************************************************/
3105
3106 static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
3107 {
3108         struct socket_info *si = find_socket_info(s);
3109         socklen_t len;
3110
3111         if (!si) {
3112                 return libc_getsockname(s, name, addrlen);
3113         }
3114
3115         len = MIN(*addrlen, si->myname_len);
3116         if (len == 0) {
3117                 return 0;
3118         }
3119
3120         memcpy(name, si->myname, len);
3121         *addrlen = si->myname_len;
3122
3123         return 0;
3124 }
3125
3126 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3127 int getsockname(int s, struct sockaddr *name, Psocklen_t addrlen)
3128 #else
3129 int getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
3130 #endif
3131 {
3132         return swrap_getsockname(s, name, (socklen_t *)addrlen);
3133 }
3134
3135 /****************************************************************************
3136  *   GETSOCKOPT
3137  ***************************************************************************/
3138
3139 #ifndef SO_PROTOCOL
3140 # ifdef SO_PROTOTYPE /* The Solaris name */
3141 #  define SO_PROTOCOL SO_PROTOTYPE
3142 # endif /* SO_PROTOTYPE */
3143 #endif /* SO_PROTOCOL */
3144
3145 static int swrap_getsockopt(int s, int level, int optname,
3146                             void *optval, socklen_t *optlen)
3147 {
3148         struct socket_info *si = find_socket_info(s);
3149
3150         if (!si) {
3151                 return libc_getsockopt(s,
3152                                        level,
3153                                        optname,
3154                                        optval,
3155                                        optlen);
3156         }
3157
3158         if (level == SOL_SOCKET) {
3159                 switch (optname) {
3160 #ifdef SO_DOMAIN
3161                 case SO_DOMAIN:
3162                         if (optval == NULL || optlen == NULL ||
3163                             *optlen < (socklen_t)sizeof(int)) {
3164                                 errno = EINVAL;
3165                                 return -1;
3166                         }
3167
3168                         *optlen = sizeof(int);
3169                         *(int *)optval = si->family;
3170                         return 0;
3171 #endif /* SO_DOMAIN */
3172
3173 #ifdef SO_PROTOCOL
3174                 case SO_PROTOCOL:
3175                         if (optval == NULL || optlen == NULL ||
3176                             *optlen < (socklen_t)sizeof(int)) {
3177                                 errno = EINVAL;
3178                                 return -1;
3179                         }
3180
3181                         *optlen = sizeof(int);
3182                         *(int *)optval = si->protocol;
3183                         return 0;
3184 #endif /* SO_PROTOCOL */
3185                 case SO_TYPE:
3186                         if (optval == NULL || optlen == NULL ||
3187                             *optlen < (socklen_t)sizeof(int)) {
3188                                 errno = EINVAL;
3189                                 return -1;
3190                         }
3191
3192                         *optlen = sizeof(int);
3193                         *(int *)optval = si->type;
3194                         return 0;
3195                 default:
3196                         return libc_getsockopt(s,
3197                                                level,
3198                                                optname,
3199                                                optval,
3200                                                optlen);
3201                 }
3202         }
3203
3204         errno = ENOPROTOOPT;
3205         return -1;
3206 }
3207
3208 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3209 int getsockopt(int s, int level, int optname, void *optval, Psocklen_t optlen)
3210 #else
3211 int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
3212 #endif
3213 {
3214         return swrap_getsockopt(s, level, optname, optval, (socklen_t *)optlen);
3215 }
3216
3217 /****************************************************************************
3218  *   SETSOCKOPT
3219  ***************************************************************************/
3220
3221 static int swrap_setsockopt(int s, int level, int optname,
3222                             const void *optval, socklen_t optlen)
3223 {
3224         struct socket_info *si = find_socket_info(s);
3225
3226         if (!si) {
3227                 return libc_setsockopt(s,
3228                                        level,
3229                                        optname,
3230                                        optval,
3231                                        optlen);
3232         }
3233
3234         if (level == SOL_SOCKET) {
3235                 return libc_setsockopt(s,
3236                                        level,
3237                                        optname,
3238                                        optval,
3239                                        optlen);
3240         }
3241
3242         switch (si->family) {
3243         case AF_INET:
3244                 if (level == IPPROTO_IP) {
3245 #ifdef IP_PKTINFO
3246                         if (optname == IP_PKTINFO) {
3247                                 si->pktinfo = AF_INET;
3248                         }
3249 #endif /* IP_PKTINFO */
3250                 }
3251                 return 0;
3252 #ifdef HAVE_IPV6
3253         case AF_INET6:
3254                 if (level == IPPROTO_IPV6) {
3255 #ifdef IPV6_RECVPKTINFO
3256                         if (optname == IPV6_RECVPKTINFO) {
3257                                 si->pktinfo = AF_INET6;
3258                         }
3259 #endif /* IPV6_PKTINFO */
3260                 }
3261                 return 0;
3262 #endif
3263         default:
3264                 errno = ENOPROTOOPT;
3265                 return -1;
3266         }
3267 }
3268
3269 int setsockopt(int s, int level, int optname,
3270                const void *optval, socklen_t optlen)
3271 {
3272         return swrap_setsockopt(s, level, optname, optval, optlen);
3273 }
3274
3275 /****************************************************************************
3276  *   IOCTL
3277  ***************************************************************************/
3278
3279 static int swrap_vioctl(int s, unsigned long int r, va_list va)
3280 {
3281         struct socket_info *si = find_socket_info(s);
3282         va_list ap;
3283         int value;
3284         int rc;
3285
3286         if (!si) {
3287                 return libc_vioctl(s, r, va);
3288         }
3289
3290         va_copy(ap, va);
3291
3292         rc = libc_vioctl(s, r, va);
3293
3294         switch (r) {
3295         case FIONREAD:
3296                 value = *((int *)va_arg(ap, int *));
3297
3298                 if (rc == -1 && errno != EAGAIN && errno != ENOBUFS) {
3299                         swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
3300                 } else if (value == 0) { /* END OF FILE */
3301                         swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
3302                 }
3303                 break;
3304         }
3305
3306         va_end(ap);
3307
3308         return rc;
3309 }
3310
3311 #ifdef HAVE_IOCTL_INT
3312 int ioctl(int s, int r, ...)
3313 #else
3314 int ioctl(int s, unsigned long int r, ...)
3315 #endif
3316 {
3317         va_list va;
3318         int rc;
3319
3320         va_start(va, r);
3321
3322         rc = swrap_vioctl(s, (unsigned long int) r, va);
3323
3324         va_end(va);
3325
3326         return rc;
3327 }
3328
3329 /*****************
3330  * CMSG
3331  *****************/
3332
3333 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3334
3335 #ifndef CMSG_ALIGN
3336 # ifdef _ALIGN /* BSD */
3337 #define CMSG_ALIGN _ALIGN
3338 # else
3339 #define CMSG_ALIGN(len) (((len) + sizeof(size_t) - 1) & ~(sizeof(size_t) - 1))
3340 # endif /* _ALIGN */
3341 #endif /* CMSG_ALIGN */
3342
3343 /**
3344  * @brief Add a cmsghdr to a msghdr.
3345  *
3346  * This is an function to add any type of cmsghdr. It will operate on the
3347  * msg->msg_control and msg->msg_controllen you pass in by adapting them to
3348  * the buffer position after the added cmsg element. Hence, this function is
3349  * intended to be used with an intermediate msghdr and not on the original
3350  * one handed in by the client.
3351  *
3352  * @param[in]  msg      The msghdr to which to add the cmsg.
3353  *
3354  * @param[in]  level    The cmsg level to set.
3355  *
3356  * @param[in]  type     The cmsg type to set.
3357  *
3358  * @param[in]  data     The cmsg data to set.
3359  *
3360  * @param[in]  len      the length of the data to set.
3361  */
3362 static void swrap_msghdr_add_cmsghdr(struct msghdr *msg,
3363                                      int level,
3364                                      int type,
3365                                      const void *data,
3366                                      size_t len)
3367 {
3368         size_t cmlen = CMSG_LEN(len);
3369         size_t cmspace = CMSG_SPACE(len);
3370         uint8_t cmbuf[cmspace];
3371         struct cmsghdr *cm = (struct cmsghdr *)cmbuf;
3372         uint8_t *p;
3373
3374         memset(cmbuf, 0, cmspace);
3375
3376         if (msg->msg_controllen < cmlen) {
3377                 cmlen = msg->msg_controllen;
3378                 msg->msg_flags |= MSG_CTRUNC;
3379         }
3380
3381         if (msg->msg_controllen < cmspace) {
3382                 cmspace = msg->msg_controllen;
3383         }
3384
3385         /*
3386          * We copy the full input data into an intermediate cmsghdr first
3387          * in order to more easily cope with truncation.
3388          */
3389         cm->cmsg_len = cmlen;
3390         cm->cmsg_level = level;
3391         cm->cmsg_type = type;
3392         memcpy(CMSG_DATA(cm), data, len);
3393
3394         /*
3395          * We now copy the possibly truncated buffer.
3396          * We copy cmlen bytes, but consume cmspace bytes,
3397          * leaving the possible padding uninitialiazed.
3398          */
3399         p = (uint8_t *)msg->msg_control;
3400         memcpy(p, cm, cmlen);
3401         p += cmspace;
3402         msg->msg_control = p;
3403         msg->msg_controllen -= cmspace;
3404
3405         return;
3406 }
3407
3408 static int swrap_msghdr_add_pktinfo(struct socket_info *si,
3409                                     struct msghdr *msg)
3410 {
3411         /* Add packet info */
3412         switch (si->pktinfo) {
3413 #if defined(IP_PKTINFO) && (defined(HAVE_STRUCT_IN_PKTINFO) || defined(IP_RECVDSTADDR))
3414         case AF_INET: {
3415                 struct sockaddr_in *sin;
3416 #if defined(HAVE_STRUCT_IN_PKTINFO)
3417                 struct in_pktinfo pkt;
3418 #elif defined(IP_RECVDSTADDR)
3419                 struct in_addr pkt;
3420 #endif
3421
3422                 if (si->bindname_len == sizeof(struct sockaddr_in)) {
3423                         sin = (struct sockaddr_in*)si->bindname;
3424                 } else {
3425                         if (si->myname_len != sizeof(struct sockaddr_in)) {
3426                                 return 0;
3427                         }
3428                         sin = (struct sockaddr_in*)si->myname;
3429                 }
3430
3431                 ZERO_STRUCT(pkt);
3432
3433 #if defined(HAVE_STRUCT_IN_PKTINFO)
3434                 pkt.ipi_ifindex = socket_wrapper_default_iface();
3435                 pkt.ipi_addr.s_addr = sin->sin_addr.s_addr;
3436 #elif defined(IP_RECVDSTADDR)
3437                 pkt = sin->sin_addr;
3438 #endif
3439
3440                 swrap_msghdr_add_cmsghdr(msg, IPPROTO_IP, IP_PKTINFO,
3441                                          &pkt, sizeof(pkt));
3442
3443                 break;
3444         }
3445 #endif /* IP_PKTINFO */
3446 #if defined(HAVE_IPV6)
3447         case AF_INET6: {
3448 #if defined(IPV6_PKTINFO) && defined(HAVE_STRUCT_IN6_PKTINFO)
3449                 struct sockaddr_in6 *sin6;
3450                 struct in6_pktinfo pkt6;
3451
3452                 if (si->bindname_len == sizeof(struct sockaddr_in6)) {
3453                         sin6 = (struct sockaddr_in6*)si->bindname;
3454                 } else {
3455                         if (si->myname_len != sizeof(struct sockaddr_in6)) {
3456                                 return 0;
3457                         }
3458                         sin6 = (struct sockaddr_in6*)si->myname;
3459                 }
3460
3461                 ZERO_STRUCT(pkt6);
3462
3463                 pkt6.ipi6_ifindex = socket_wrapper_default_iface();
3464                 pkt6.ipi6_addr = sin6->sin6_addr;
3465
3466                 swrap_msghdr_add_cmsghdr(msg, IPPROTO_IPV6, IPV6_PKTINFO,
3467                                         &pkt6, sizeof(pkt6));
3468 #endif /* HAVE_STRUCT_IN6_PKTINFO */
3469
3470                 break;
3471         }
3472 #endif /* IPV6_PKTINFO */
3473         default:
3474                 return -1;
3475         }
3476
3477         return 0;
3478 }
3479
3480 static int swrap_msghdr_add_socket_info(struct socket_info *si,
3481                                         struct msghdr *omsg)
3482 {
3483         int rc = 0;
3484
3485         if (si->pktinfo > 0) {
3486                 rc = swrap_msghdr_add_pktinfo(si, omsg);
3487         }
3488
3489         return rc;
3490 }
3491
3492 static int swrap_sendmsg_copy_cmsg(struct cmsghdr *cmsg,
3493                                    uint8_t **cm_data,
3494                                    size_t *cm_data_space);
3495 static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr *cmsg,
3496                                             uint8_t **cm_data,
3497                                             size_t *cm_data_space);
3498
3499 static int swrap_sendmsg_filter_cmsghdr(struct msghdr *msg,
3500                                         uint8_t **cm_data,
3501                                         size_t *cm_data_space) {
3502         struct cmsghdr *cmsg;
3503         int rc = -1;
3504
3505         /* Nothing to do */
3506         if (msg->msg_controllen == 0 || msg->msg_control == NULL) {
3507                 return 0;
3508         }
3509
3510         for (cmsg = CMSG_FIRSTHDR(msg);
3511              cmsg != NULL;
3512              cmsg = CMSG_NXTHDR(msg, cmsg)) {
3513                 switch (cmsg->cmsg_level) {
3514                 case IPPROTO_IP:
3515                         rc = swrap_sendmsg_filter_cmsg_socket(cmsg,
3516                                                               cm_data,
3517                                                               cm_data_space);
3518                         break;
3519                 default:
3520                         rc = swrap_sendmsg_copy_cmsg(cmsg,
3521                                                      cm_data,
3522                                                      cm_data_space);
3523                         break;
3524                 }
3525         }
3526
3527         return rc;
3528 }
3529
3530 static int swrap_sendmsg_copy_cmsg(struct cmsghdr *cmsg,
3531                                    uint8_t **cm_data,
3532                                    size_t *cm_data_space)
3533 {
3534         size_t cmspace;
3535         uint8_t *p;
3536
3537         cmspace =
3538                 (*cm_data_space) +
3539                 CMSG_SPACE(cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr)));
3540
3541         p = realloc((*cm_data), cmspace);
3542         if (p == NULL) {
3543                 return -1;
3544         }
3545         (*cm_data) = p;
3546
3547         p = (*cm_data) + (*cm_data_space);
3548         *cm_data_space = cmspace;
3549
3550         memcpy(p, cmsg, cmsg->cmsg_len);
3551
3552         return 0;
3553 }
3554
3555 static int swrap_sendmsg_filter_cmsg_pktinfo(struct cmsghdr *cmsg,
3556                                             uint8_t **cm_data,
3557                                             size_t *cm_data_space);
3558
3559
3560 static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr *cmsg,
3561                                             uint8_t **cm_data,
3562                                             size_t *cm_data_space)
3563 {
3564         int rc = -1;
3565
3566         switch(cmsg->cmsg_type) {
3567 #ifdef IP_PKTINFO
3568         case IP_PKTINFO:
3569                 rc = swrap_sendmsg_filter_cmsg_pktinfo(cmsg,
3570                                                        cm_data,
3571                                                        cm_data_space);
3572                 break;
3573 #endif
3574 #ifdef IPV6_PKTINFO
3575         case IPV6_PKTINFO:
3576                 rc = swrap_sendmsg_filter_cmsg_pktinfo(cmsg,
3577                                                        cm_data,
3578                                                        cm_data_space);
3579                 break;
3580 #endif
3581         default:
3582                 break;
3583         }
3584
3585         return rc;
3586 }
3587
3588 static int swrap_sendmsg_filter_cmsg_pktinfo(struct cmsghdr *cmsg,
3589                                              uint8_t **cm_data,
3590                                              size_t *cm_data_space)
3591 {
3592         (void)cmsg; /* unused */
3593         (void)cm_data; /* unused */
3594         (void)cm_data_space; /* unused */
3595
3596         /*
3597          * Passing a IP pktinfo to a unix socket might be rejected by the
3598          * Kernel, at least on FreeBSD. So skip this cmsg.
3599          */
3600         return 0;
3601 }
3602 #endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
3603
3604 static ssize_t swrap_sendmsg_before(int fd,
3605                                     struct socket_info *si,
3606                                     struct msghdr *msg,
3607                                     struct iovec *tmp_iov,
3608                                     struct sockaddr_un *tmp_un,
3609                                     const struct sockaddr_un **to_un,
3610                                     const struct sockaddr **to,
3611                                     int *bcast)
3612 {
3613         size_t i, len = 0;
3614         ssize_t ret;
3615
3616         if (to_un) {
3617                 *to_un = NULL;
3618         }
3619         if (to) {
3620                 *to = NULL;
3621         }
3622         if (bcast) {
3623                 *bcast = 0;
3624         }
3625
3626         switch (si->type) {
3627         case SOCK_STREAM:
3628                 if (!si->connected) {
3629                         errno = ENOTCONN;
3630                         return -1;
3631                 }
3632
3633                 if (msg->msg_iovlen == 0) {
3634                         break;
3635                 }
3636
3637                 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3638                         size_t nlen;
3639                         nlen = len + msg->msg_iov[i].iov_len;
3640                         if (nlen > SOCKET_MAX_PACKET) {
3641                                 break;
3642                         }
3643                 }
3644                 msg->msg_iovlen = i;
3645                 if (msg->msg_iovlen == 0) {
3646                         *tmp_iov = msg->msg_iov[0];
3647                         tmp_iov->iov_len = MIN(tmp_iov->iov_len, SOCKET_MAX_PACKET);
3648                         msg->msg_iov = tmp_iov;
3649                         msg->msg_iovlen = 1;
3650                 }
3651                 break;
3652
3653         case SOCK_DGRAM:
3654                 if (si->connected) {
3655                         if (msg->msg_name) {
3656                                 errno = EISCONN;
3657                                 return -1;
3658                         }
3659                 } else {
3660                         const struct sockaddr *msg_name;
3661                         msg_name = (const struct sockaddr *)msg->msg_name;
3662
3663                         if (msg_name == NULL) {
3664                                 errno = ENOTCONN;
3665                                 return -1;
3666                         }
3667
3668
3669                         ret = sockaddr_convert_to_un(si, msg_name, msg->msg_namelen,
3670                                                      tmp_un, 0, bcast);
3671                         if (ret == -1) return -1;
3672
3673                         if (to_un) {
3674                                 *to_un = tmp_un;
3675                         }
3676                         if (to) {
3677                                 *to = msg_name;
3678                         }
3679                         msg->msg_name = tmp_un;
3680                         msg->msg_namelen = sizeof(*tmp_un);
3681                 }
3682
3683                 if (si->bound == 0) {
3684                         ret = swrap_auto_bind(fd, si, si->family);
3685                         if (ret == -1) {
3686                                 if (errno == ENOTSOCK) {
3687                                         swrap_remove_stale(fd);
3688                                         return -ENOTSOCK;
3689                                 } else {
3690                                         SWRAP_LOG(SWRAP_LOG_ERROR, "swrap_sendmsg_before failed");
3691                                         return -1;
3692                                 }
3693                         }
3694                 }
3695
3696                 if (!si->defer_connect) {
3697                         break;
3698                 }
3699
3700                 ret = sockaddr_convert_to_un(si, si->peername, si->peername_len,
3701                                              tmp_un, 0, NULL);
3702                 if (ret == -1) return -1;
3703
3704                 ret = libc_connect(fd,
3705                                    (struct sockaddr *)(void *)tmp_un,
3706                                    sizeof(*tmp_un));
3707
3708                 /* to give better errors */
3709                 if (ret == -1 && errno == ENOENT) {
3710                         errno = EHOSTUNREACH;
3711                 }
3712
3713                 if (ret == -1) {
3714                         return ret;
3715                 }
3716
3717                 si->defer_connect = 0;
3718                 break;
3719         default:
3720                 errno = EHOSTUNREACH;
3721                 return -1;
3722         }
3723
3724 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3725         if (msg->msg_controllen > 0 && msg->msg_control != NULL) {
3726                 uint8_t *cmbuf = NULL;
3727                 size_t cmlen = 0;
3728
3729                 ret = swrap_sendmsg_filter_cmsghdr(msg, &cmbuf, &cmlen);
3730                 if (ret < 0) {
3731                         free(cmbuf);
3732                         return -1;
3733                 }
3734
3735                 if (cmlen == 0) {
3736                         msg->msg_controllen = 0;
3737                         msg->msg_control = NULL;
3738                 } else if (cmlen < msg->msg_controllen && cmbuf != NULL) {
3739                         memcpy(msg->msg_control, cmbuf, cmlen);
3740                         msg->msg_controllen = cmlen;
3741                 }
3742                 free(cmbuf);
3743         }
3744 #endif
3745
3746         return 0;
3747 }
3748
3749 static void swrap_sendmsg_after(int fd,
3750                                 struct socket_info *si,
3751                                 struct msghdr *msg,
3752                                 const struct sockaddr *to,
3753                                 ssize_t ret)
3754 {
3755         int saved_errno = errno;
3756         size_t i, len = 0;
3757         uint8_t *buf;
3758         off_t ofs = 0;
3759         size_t avail = 0;
3760         size_t remain;
3761
3762         /* to give better errors */
3763         if (ret == -1) {
3764                 if (saved_errno == ENOENT) {
3765                         saved_errno = EHOSTUNREACH;
3766                 } else if (saved_errno == ENOTSOCK) {
3767                         /* If the fd is not a socket, remove it */
3768                         swrap_remove_stale(fd);
3769                 }
3770         }
3771
3772         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3773                 avail += msg->msg_iov[i].iov_len;
3774         }
3775
3776         if (ret == -1) {
3777                 remain = MIN(80, avail);
3778         } else {
3779                 remain = ret;
3780         }
3781
3782         /* we capture it as one single packet */
3783         buf = (uint8_t *)malloc(remain);
3784         if (!buf) {
3785                 /* we just not capture the packet */
3786                 errno = saved_errno;
3787                 return;
3788         }
3789
3790         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3791                 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
3792                 memcpy(buf + ofs,
3793                        msg->msg_iov[i].iov_base,
3794                        this_time);
3795                 ofs += this_time;
3796                 remain -= this_time;
3797         }
3798         len = ofs;
3799
3800         switch (si->type) {
3801         case SOCK_STREAM:
3802                 if (ret == -1) {
3803                         swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
3804                         swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
3805                 } else {
3806                         swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
3807                 }
3808                 break;
3809
3810         case SOCK_DGRAM:
3811                 if (si->connected) {
3812                         to = si->peername;
3813                 }
3814                 if (ret == -1) {
3815                         swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
3816                         swrap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);
3817                 } else {
3818                         swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
3819                 }
3820                 break;
3821         }
3822
3823         free(buf);
3824         errno = saved_errno;
3825 }
3826
3827 static int swrap_recvmsg_before(int fd,
3828                                 struct socket_info *si,
3829                                 struct msghdr *msg,
3830                                 struct iovec *tmp_iov)
3831 {
3832         size_t i, len = 0;
3833         ssize_t ret;
3834
3835         (void)fd; /* unused */
3836
3837         switch (si->type) {
3838         case SOCK_STREAM:
3839                 if (!si->connected) {
3840                         errno = ENOTCONN;
3841                         return -1;
3842                 }
3843
3844                 if (msg->msg_iovlen == 0) {
3845                         break;
3846                 }
3847
3848                 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3849                         size_t nlen;
3850                         nlen = len + msg->msg_iov[i].iov_len;
3851                         if (nlen > SOCKET_MAX_PACKET) {
3852                                 break;
3853                         }
3854                 }
3855                 msg->msg_iovlen = i;
3856                 if (msg->msg_iovlen == 0) {
3857                         *tmp_iov = msg->msg_iov[0];
3858                         tmp_iov->iov_len = MIN(tmp_iov->iov_len, SOCKET_MAX_PACKET);
3859                         msg->msg_iov = tmp_iov;
3860                         msg->msg_iovlen = 1;
3861                 }
3862                 break;
3863
3864         case SOCK_DGRAM:
3865                 if (msg->msg_name == NULL) {
3866                         errno = EINVAL;
3867                         return -1;
3868                 }
3869
3870                 if (msg->msg_iovlen == 0) {
3871                         break;
3872                 }
3873
3874                 if (si->bound == 0) {
3875                         ret = swrap_auto_bind(fd, si, si->family);
3876                         if (ret == -1) {
3877                                 /*
3878                                  * When attempting to read or write to a
3879                                  * descriptor, if an underlying autobind fails
3880                                  * because it's not a socket, stop intercepting
3881                                  * uses of that descriptor.
3882                                  */
3883                                 if (errno == ENOTSOCK) {
3884                                         swrap_remove_stale(fd);
3885                                         return -ENOTSOCK;
3886                                 } else {
3887                                         SWRAP_LOG(SWRAP_LOG_ERROR,
3888                                                   "swrap_recvmsg_before failed");
3889                                         return -1;
3890                                 }
3891                         }
3892                 }
3893                 break;
3894         default:
3895                 errno = EHOSTUNREACH;
3896                 return -1;
3897         }
3898
3899         return 0;
3900 }
3901
3902 static int swrap_recvmsg_after(int fd,
3903                                struct socket_info *si,
3904                                struct msghdr *msg,
3905                                const struct sockaddr_un *un_addr,
3906                                socklen_t un_addrlen,
3907                                ssize_t ret)
3908 {
3909         int saved_errno = errno;
3910         size_t i;
3911         uint8_t *buf = NULL;
3912         off_t ofs = 0;
3913         size_t avail = 0;
3914         size_t remain;
3915         int rc;
3916
3917         /* to give better errors */
3918         if (ret == -1) {
3919                 if (saved_errno == ENOENT) {
3920                         saved_errno = EHOSTUNREACH;
3921                 } else if (saved_errno == ENOTSOCK) {
3922                         /* If the fd is not a socket, remove it */
3923                         swrap_remove_stale(fd);
3924                 }
3925         }
3926
3927         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3928                 avail += msg->msg_iov[i].iov_len;
3929         }
3930
3931         if (avail == 0) {
3932                 rc = 0;
3933                 goto done;
3934         }
3935
3936         if (ret == -1) {
3937                 remain = MIN(80, avail);
3938         } else {
3939                 remain = ret;
3940         }
3941
3942         /* we capture it as one single packet */
3943         buf = (uint8_t *)malloc(remain);
3944         if (buf == NULL) {
3945                 /* we just not capture the packet */
3946                 errno = saved_errno;
3947                 return -1;
3948         }
3949
3950         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3951                 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
3952                 memcpy(buf + ofs,
3953                        msg->msg_iov[i].iov_base,
3954                        this_time);
3955                 ofs += this_time;
3956                 remain -= this_time;
3957         }
3958
3959         switch (si->type) {
3960         case SOCK_STREAM:
3961                 if (ret == -1 && saved_errno != EAGAIN && saved_errno != ENOBUFS) {
3962                         swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
3963                 } else if (ret == 0) { /* END OF FILE */
3964                         swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
3965                 } else if (ret > 0) {
3966                         swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
3967                 }
3968                 break;
3969
3970         case SOCK_DGRAM:
3971                 if (ret == -1) {
3972                         break;
3973                 }
3974
3975                 if (un_addr != NULL) {
3976                         rc = sockaddr_convert_from_un(si,
3977                                                       un_addr,
3978                                                       un_addrlen,
3979                                                       si->family,
3980                                                       msg->msg_name,
3981                                                       &msg->msg_namelen);
3982                         if (rc == -1) {
3983                                 goto done;
3984                         }
3985
3986                         swrap_dump_packet(si,
3987                                           msg->msg_name,
3988                                           SWRAP_RECVFROM,
3989                                           buf,
3990                                           ret);
3991                 } else {
3992                         swrap_dump_packet(si,
3993                                           msg->msg_name,
3994                                           SWRAP_RECV,
3995                                           buf,
3996                                           ret);
3997                 }
3998
3999                 break;
4000         }
4001
4002         rc = 0;
4003 done:
4004         free(buf);
4005         errno = saved_errno;
4006
4007 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4008         if (rc == 0 &&
4009             msg->msg_controllen > 0 &&
4010             msg->msg_control != NULL) {
4011                 rc = swrap_msghdr_add_socket_info(si, msg);
4012                 if (rc < 0) {
4013                         return -1;
4014                 }
4015         }
4016 #endif
4017
4018         return rc;
4019 }
4020
4021 /****************************************************************************
4022  *   RECVFROM
4023  ***************************************************************************/
4024
4025 static ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags,
4026                               struct sockaddr *from, socklen_t *fromlen)
4027 {
4028         struct sockaddr_un from_addr;
4029         socklen_t from_addrlen = sizeof(from_addr);
4030         ssize_t ret;
4031         struct socket_info *si = find_socket_info(s);
4032         struct sockaddr_storage ss;
4033         socklen_t ss_len = sizeof(ss);
4034         struct msghdr msg;
4035         struct iovec tmp;
4036         int tret;
4037
4038         if (!si) {
4039                 return libc_recvfrom(s,
4040                                      buf,
4041                                      len,
4042                                      flags,
4043                                      from,
4044                                      fromlen);
4045         }
4046
4047         tmp.iov_base = buf;
4048         tmp.iov_len = len;
4049
4050         ZERO_STRUCT(msg);
4051         if (from != NULL && fromlen != NULL) {
4052                 msg.msg_name = from;   /* optional address */
4053                 msg.msg_namelen = *fromlen; /* size of address */
4054         } else {
4055                 msg.msg_name = (struct sockaddr *)(void *)&ss; /* optional address */
4056                 msg.msg_namelen = ss_len; /* size of address */
4057         }
4058         msg.msg_iov = &tmp;            /* scatter/gather array */
4059         msg.msg_iovlen = 1;            /* # elements in msg_iov */
4060 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4061         msg.msg_control = NULL;        /* ancillary data, see below */
4062         msg.msg_controllen = 0;        /* ancillary data buffer len */
4063         msg.msg_flags = 0;             /* flags on received message */
4064 #endif
4065
4066         tret = swrap_recvmsg_before(s, si, &msg, &tmp);
4067         if (tret < 0) {
4068                 return -1;
4069         }
4070
4071         buf = msg.msg_iov[0].iov_base;
4072         len = msg.msg_iov[0].iov_len;
4073
4074         /* irix 6.4 forgets to null terminate the sun_path string :-( */
4075         memset(&from_addr, 0, sizeof(from_addr));
4076         ret = libc_recvfrom(s,
4077                             buf,
4078                             len,
4079                             flags,
4080                             (struct sockaddr *)(void *)&from_addr,
4081                             &from_addrlen);
4082         if (ret == -1) {
4083                 return ret;
4084         }
4085
4086         tret = swrap_recvmsg_after(s,
4087                                    si,
4088                                    &msg,
4089                                    &from_addr,
4090                                    from_addrlen,
4091                                    ret);
4092         if (tret != 0) {
4093                 return tret;
4094         }
4095
4096         if (from != NULL && fromlen != NULL) {
4097                 *fromlen = msg.msg_namelen;
4098         }
4099
4100         return ret;
4101 }
4102
4103 #ifdef HAVE_ACCEPT_PSOCKLEN_T
4104 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
4105                  struct sockaddr *from, Psocklen_t fromlen)
4106 #else
4107 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
4108                  struct sockaddr *from, socklen_t *fromlen)
4109 #endif
4110 {
4111         return swrap_recvfrom(s, buf, len, flags, from, (socklen_t *)fromlen);
4112 }
4113
4114 /****************************************************************************
4115  *   SENDTO
4116  ***************************************************************************/
4117
4118 static ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags,
4119                             const struct sockaddr *to, socklen_t tolen)
4120 {
4121         struct msghdr msg;
4122         struct iovec tmp;
4123         struct sockaddr_un un_addr;
4124         const struct sockaddr_un *to_un = NULL;
4125         ssize_t ret;
4126         int rc;
4127         struct socket_info *si = find_socket_info(s);
4128         int bcast = 0;
4129
4130         if (!si) {
4131                 return libc_sendto(s, buf, len, flags, to, tolen);
4132         }
4133
4134         tmp.iov_base = discard_const_p(char, buf);
4135         tmp.iov_len = len;
4136
4137         ZERO_STRUCT(msg);
4138         msg.msg_name = discard_const_p(struct sockaddr, to); /* optional address */
4139         msg.msg_namelen = tolen;       /* size of address */
4140         msg.msg_iov = &tmp;            /* scatter/gather array */
4141         msg.msg_iovlen = 1;            /* # elements in msg_iov */
4142 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
4143         msg.msg_control = NULL;        /* ancillary data, see below */
4144         msg.msg_controllen = 0;        /* ancillary data buffer len */
4145         msg.msg_flags = 0;             /* flags on received message */
4146 #endif
4147
4148         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
4149         if (rc < 0) {
4150                 return -1;
4151         }
4152
4153         buf = msg.msg_iov[0].iov_base;
4154         len = msg.msg_iov[0].iov_len;
4155
4156         if (bcast) {
4157                 struct stat st;
4158                 unsigned int iface;
4159                 unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port);
4160                 char type;
4161
4162                 type = SOCKET_TYPE_CHAR_UDP;
4163
4164                 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
4165                         snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT,
4166                                  socket_wrapper_dir(), type, iface, prt);
4167                         if (stat(un_addr.sun_path, &st) != 0) continue;
4168
4169                         /* ignore the any errors in broadcast sends */
4170                         libc_sendto(s,
4171                                     buf,
4172                                     len,
4173                                     flags,
4174                                     (struct sockaddr *)(void *)&un_addr,
4175                                     sizeof(un_addr));
4176                 }
4177
4178                 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
4179
4180                 return len;
4181         }
4182
4183         ret = libc_sendto(s,
4184                           buf,
4185                           len,
4186                           flags,
4187                           (struct sockaddr *)msg.msg_name,
4188                           msg.msg_namelen);
4189
4190         swrap_sendmsg_after(s, si, &msg, to, ret);
4191
4192         return ret;
4193 }
4194
4195 ssize_t sendto(int s, const void *buf, size_t len, int flags,
4196                const struct sockaddr *to, socklen_t tolen)
4197 {
4198         return swrap_sendto(s, buf, len, flags, to, tolen);
4199 }
4200
4201 /****************************************************************************
4202  *   READV
4203  ***************************************************************************/
4204
4205 static ssize_t swrap_recv(int s, void *buf, size_t len, int flags)
4206 {
4207         struct socket_info *si;
4208         struct msghdr msg;
4209         struct sockaddr_storage ss;
4210         socklen_t ss_len = sizeof(ss);
4211         struct iovec tmp;
4212         ssize_t ret;
4213         int tret;
4214
4215         si = find_socket_info(s);
4216         if (si == NULL) {
4217                 return libc_recv(s, buf, len, flags);
4218         }
4219
4220         tmp.iov_base = buf;
4221         tmp.iov_len = len;
4222
4223         ZERO_STRUCT(msg);
4224         msg.msg_name = (struct sockaddr *)(void *)&ss; /* optional address */
4225         msg.msg_namelen = ss_len;      /* size of address */
4226         msg.msg_iov = &tmp;            /* scatter/gather array */
4227         msg.msg_iovlen = 1;            /* # elements in msg_iov */
4228 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4229         msg.msg_control = NULL;        /* ancillary data, see below */
4230         msg.msg_controllen = 0;        /* ancillary data buffer len */
4231         msg.msg_flags = 0;             /* flags on received message */
4232 #endif
4233
4234         tret = swrap_recvmsg_before(s, si, &msg, &tmp);
4235         if (tret < 0) {
4236                 return -1;
4237         }
4238
4239         buf = msg.msg_iov[0].iov_base;
4240         len = msg.msg_iov[0].iov_len;
4241
4242         ret = libc_recv(s, buf, len, flags);
4243
4244         tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
4245         if (tret != 0) {
4246                 return tret;
4247         }
4248
4249         return ret;
4250 }
4251
4252 ssize_t recv(int s, void *buf, size_t len, int flags)
4253 {
4254         return swrap_recv(s, buf, len, flags);
4255 }
4256
4257 /****************************************************************************
4258  *   READ
4259  ***************************************************************************/
4260
4261 static ssize_t swrap_read(int s, void *buf, size_t len)
4262 {
4263         struct socket_info *si;
4264         struct msghdr msg;
4265         struct iovec tmp;
4266         struct sockaddr_storage ss;
4267         socklen_t ss_len = sizeof(ss);
4268         ssize_t ret;
4269         int tret;
4270
4271         si = find_socket_info(s);
4272         if (si == NULL) {
4273                 return libc_read(s, buf, len);
4274         }
4275
4276         tmp.iov_base = buf;
4277         tmp.iov_len = len;
4278
4279         ZERO_STRUCT(msg);
4280         msg.msg_name = (struct sockaddr *)(void *)&ss; /* optional address */
4281         msg.msg_namelen = ss_len;      /* size of address */
4282         msg.msg_iov = &tmp;            /* scatter/gather array */
4283         msg.msg_iovlen = 1;            /* # elements in msg_iov */
4284 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4285         msg.msg_control = NULL;        /* ancillary data, see below */
4286         msg.msg_controllen = 0;        /* ancillary data buffer len */
4287         msg.msg_flags = 0;             /* flags on received message */
4288 #endif
4289
4290         tret = swrap_recvmsg_before(s, si, &msg, &tmp);
4291         if (tret < 0) {
4292                 if (tret == -ENOTSOCK) {
4293                         return libc_read(s, buf, len);
4294                 }
4295                 return -1;
4296         }
4297
4298         buf = msg.msg_iov[0].iov_base;
4299         len = msg.msg_iov[0].iov_len;
4300
4301         ret = libc_read(s, buf, len);
4302
4303         tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
4304         if (tret != 0) {
4305                 return tret;
4306         }
4307
4308         return ret;
4309 }
4310
4311 ssize_t read(int s, void *buf, size_t len)
4312 {
4313         return swrap_read(s, buf, len);
4314 }
4315
4316 /****************************************************************************
4317  *   SEND
4318  ***************************************************************************/
4319
4320 static ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
4321 {
4322         struct msghdr msg;
4323         struct iovec tmp;
4324         struct sockaddr_un un_addr;
4325         ssize_t ret;
4326         int rc;
4327         struct socket_info *si = find_socket_info(s);
4328
4329         if (!si) {
4330                 return libc_send(s, buf, len, flags);
4331         }
4332
4333         tmp.iov_base = discard_const_p(char, buf);
4334         tmp.iov_len = len;
4335
4336         ZERO_STRUCT(msg);
4337         msg.msg_name = NULL;           /* optional address */
4338         msg.msg_namelen = 0;           /* size of address */
4339         msg.msg_iov = &tmp;            /* scatter/gather array */
4340         msg.msg_iovlen = 1;            /* # elements in msg_iov */
4341 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
4342         msg.msg_control = NULL;        /* ancillary data, see below */
4343         msg.msg_controllen = 0;        /* ancillary data buffer len */
4344         msg.msg_flags = 0;             /* flags on received message */
4345 #endif
4346
4347         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
4348         if (rc < 0) {
4349                 return -1;
4350         }
4351
4352         buf = msg.msg_iov[0].iov_base;
4353         len = msg.msg_iov[0].iov_len;
4354
4355         ret = libc_send(s, buf, len, flags);
4356
4357         swrap_sendmsg_after(s, si, &msg, NULL, ret);
4358
4359         return ret;
4360 }
4361
4362 ssize_t send(int s, const void *buf, size_t len, int flags)
4363 {
4364         return swrap_send(s, buf, len, flags);
4365 }
4366
4367 /****************************************************************************
4368  *   RECVMSG
4369  ***************************************************************************/
4370
4371 static ssize_t swrap_recvmsg(int s, struct msghdr *omsg, int flags)
4372 {
4373         struct sockaddr_un from_addr;
4374         socklen_t from_addrlen = sizeof(from_addr);
4375         struct socket_info *si;
4376         struct msghdr msg;
4377         struct iovec tmp;
4378 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4379         size_t msg_ctrllen_filled;
4380         size_t msg_ctrllen_left;
4381 #endif
4382
4383         ssize_t ret;
4384         int rc;
4385
4386         si = find_socket_info(s);
4387         if (si == NULL) {
4388                 return libc_recvmsg(s, omsg, flags);
4389         }
4390
4391         tmp.iov_base = NULL;
4392         tmp.iov_len = 0;
4393
4394         ZERO_STRUCT(msg);
4395         msg.msg_name = (struct sockaddr *)&from_addr; /* optional address */
4396         msg.msg_namelen = from_addrlen;            /* size of address */
4397         msg.msg_iov = omsg->msg_iov;               /* scatter/gather array */
4398         msg.msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
4399 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4400         msg_ctrllen_filled = 0;
4401         msg_ctrllen_left = omsg->msg_controllen;
4402
4403         msg.msg_control = omsg->msg_control;       /* ancillary data, see below */
4404         msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
4405         msg.msg_flags = omsg->msg_flags;           /* flags on received message */
4406 #endif
4407
4408         rc = swrap_recvmsg_before(s, si, &msg, &tmp);
4409         if (rc < 0) {
4410                 return -1;
4411         }
4412
4413         ret = libc_recvmsg(s, &msg, flags);
4414
4415         msg.msg_name = omsg->msg_name;
4416         msg.msg_namelen = omsg->msg_namelen;
4417
4418 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4419         msg_ctrllen_filled += msg.msg_controllen;
4420         msg_ctrllen_left -= msg.msg_controllen;
4421
4422         if (omsg->msg_control != NULL) {
4423                 uint8_t *p;
4424
4425                 p = omsg->msg_control;
4426                 p += msg_ctrllen_filled;
4427
4428                 msg.msg_control = p;
4429                 msg.msg_controllen = msg_ctrllen_left;
4430         } else {
4431                 msg.msg_control = NULL;
4432                 msg.msg_controllen = 0;
4433         }
4434 #endif
4435
4436         rc = swrap_recvmsg_after(s, si, &msg, &from_addr, from_addrlen, ret);
4437         if (rc != 0) {
4438                 return rc;
4439         }
4440
4441 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4442         if (omsg->msg_control != NULL) {
4443                 /* msg.msg_controllen = space left */
4444                 msg_ctrllen_left = msg.msg_controllen;
4445                 msg_ctrllen_filled = omsg->msg_controllen - msg_ctrllen_left;
4446         }
4447
4448         /* Update the original message length */
4449         omsg->msg_controllen = msg_ctrllen_filled;
4450         omsg->msg_flags = msg.msg_flags;
4451 #endif
4452         omsg->msg_iovlen = msg.msg_iovlen;
4453
4454         return ret;
4455 }
4456
4457 ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)
4458 {
4459         return swrap_recvmsg(sockfd, msg, flags);
4460 }
4461
4462 /****************************************************************************
4463  *   SENDMSG
4464  ***************************************************************************/
4465
4466 static ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags)
4467 {
4468         struct msghdr msg;
4469         struct iovec tmp;
4470         struct sockaddr_un un_addr;
4471         const struct sockaddr_un *to_un = NULL;
4472         const struct sockaddr *to = NULL;
4473         ssize_t ret;
4474         int rc;
4475         struct socket_info *si = find_socket_info(s);
4476         int bcast = 0;
4477
4478         if (!si) {
4479                 return libc_sendmsg(s, omsg, flags);
4480         }
4481
4482         ZERO_STRUCT(un_addr);
4483
4484         tmp.iov_base = NULL;
4485         tmp.iov_len = 0;
4486
4487         ZERO_STRUCT(msg);
4488         msg.msg_name = omsg->msg_name;             /* optional address */
4489         msg.msg_namelen = omsg->msg_namelen;       /* size of address */
4490         msg.msg_iov = omsg->msg_iov;               /* scatter/gather array */
4491         msg.msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
4492 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4493         if (msg.msg_controllen > 0 && msg.msg_control != NULL) {
4494                 /* omsg is a const so use a local buffer for modifications */
4495                 uint8_t cmbuf[omsg->msg_controllen];
4496
4497                 memcpy(cmbuf, omsg->msg_control, omsg->msg_controllen);
4498
4499                 msg.msg_control = cmbuf;       /* ancillary data, see below */
4500                 msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
4501         }
4502         msg.msg_flags = omsg->msg_flags;           /* flags on received message */
4503 #endif
4504
4505         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
4506         if (rc < 0) {
4507                 return -1;
4508         }
4509
4510         if (bcast) {
4511                 struct stat st;
4512                 unsigned int iface;
4513                 unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port);
4514                 char type;
4515                 size_t i, len = 0;
4516                 uint8_t *buf;
4517                 off_t ofs = 0;
4518                 size_t avail = 0;
4519                 size_t remain;
4520
4521                 for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
4522                         avail += msg.msg_iov[i].iov_len;
4523                 }
4524
4525                 len = avail;
4526                 remain = avail;
4527
4528                 /* we capture it as one single packet */
4529                 buf = (uint8_t *)malloc(remain);
4530                 if (!buf) {
4531                         return -1;
4532                 }
4533
4534                 for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
4535                         size_t this_time = MIN(remain, (size_t)msg.msg_iov[i].iov_len);
4536                         memcpy(buf + ofs,
4537                                msg.msg_iov[i].iov_base,
4538                                this_time);
4539                         ofs += this_time;
4540                         remain -= this_time;
4541                 }
4542
4543                 type = SOCKET_TYPE_CHAR_UDP;
4544
4545                 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
4546                         snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT,
4547                                  socket_wrapper_dir(), type, iface, prt);
4548                         if (stat(un_addr.sun_path, &st) != 0) continue;
4549
4550                         msg.msg_name = &un_addr;           /* optional address */
4551                         msg.msg_namelen = sizeof(un_addr); /* size of address */
4552
4553                         /* ignore the any errors in broadcast sends */
4554                         libc_sendmsg(s, &msg, flags);
4555                 }
4556
4557                 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
4558                 free(buf);
4559
4560                 return len;
4561         }
4562
4563         ret = libc_sendmsg(s, &msg, flags);
4564
4565         swrap_sendmsg_after(s, si, &msg, to, ret);
4566
4567         return ret;
4568 }
4569
4570 ssize_t sendmsg(int s, const struct msghdr *omsg, int flags)
4571 {
4572         return swrap_sendmsg(s, omsg, flags);
4573 }
4574
4575 /****************************************************************************
4576  *   READV
4577  ***************************************************************************/
4578
4579 static ssize_t swrap_readv(int s, const struct iovec *vector, int count)
4580 {
4581         struct socket_info *si;
4582         struct msghdr msg;
4583         struct iovec tmp;
4584         struct sockaddr_storage ss;
4585         socklen_t ss_len = sizeof(ss);
4586         ssize_t ret;
4587         int rc;
4588
4589         si = find_socket_info(s);
4590         if (si == NULL) {
4591                 return libc_readv(s, vector, count);
4592         }
4593
4594         tmp.iov_base = NULL;
4595         tmp.iov_len = 0;
4596
4597         ZERO_STRUCT(msg);
4598         msg.msg_name = (struct sockaddr *)(void *)&ss; /* optional address */
4599         msg.msg_namelen = ss_len;      /* size of address */
4600         msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
4601         msg.msg_iovlen = count;        /* # elements in msg_iov */
4602 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4603         msg.msg_control = NULL;        /* ancillary data, see below */
4604         msg.msg_controllen = 0;        /* ancillary data buffer len */
4605         msg.msg_flags = 0;             /* flags on received message */
4606 #endif
4607
4608         rc = swrap_recvmsg_before(s, si, &msg, &tmp);
4609         if (rc < 0) {
4610                 if (rc == -ENOTSOCK) {
4611                         return libc_readv(s, vector, count);
4612                 }
4613                 return -1;
4614         }
4615
4616         ret = libc_readv(s, msg.msg_iov, msg.msg_iovlen);
4617
4618         rc = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
4619         if (rc != 0) {
4620                 return rc;
4621         }
4622
4623         return ret;
4624 }
4625
4626 ssize_t readv(int s, const struct iovec *vector, int count)
4627 {
4628         return swrap_readv(s, vector, count);
4629 }
4630
4631 /****************************************************************************
4632  *   WRITEV
4633  ***************************************************************************/
4634
4635 static ssize_t swrap_writev(int s, const struct iovec *vector, int count)
4636 {
4637         struct msghdr msg;
4638         struct iovec tmp;
4639         struct sockaddr_un un_addr;
4640         ssize_t ret;
4641         int rc;
4642         struct socket_info *si = find_socket_info(s);
4643
4644         if (!si) {
4645                 return libc_writev(s, vector, count);
4646         }
4647
4648         tmp.iov_base = NULL;
4649         tmp.iov_len = 0;
4650
4651         ZERO_STRUCT(msg);
4652         msg.msg_name = NULL;           /* optional address */
4653         msg.msg_namelen = 0;           /* size of address */
4654         msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
4655         msg.msg_iovlen = count;        /* # elements in msg_iov */
4656 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
4657         msg.msg_control = NULL;        /* ancillary data, see below */
4658         msg.msg_controllen = 0;        /* ancillary data buffer len */
4659         msg.msg_flags = 0;             /* flags on received message */
4660 #endif
4661
4662         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
4663         if (rc < 0) {
4664                 if (rc == -ENOTSOCK) {
4665                         return libc_readv(s, vector, count);
4666                 }
4667                 return -1;
4668         }
4669
4670         ret = libc_writev(s, msg.msg_iov, msg.msg_iovlen);
4671
4672         swrap_sendmsg_after(s, si, &msg, NULL, ret);
4673
4674         return ret;
4675 }
4676
4677 ssize_t writev(int s, const struct iovec *vector, int count)
4678 {
4679         return swrap_writev(s, vector, count);
4680 }
4681
4682 /****************************
4683  * CLOSE
4684  ***************************/
4685
4686 static int swrap_close(int fd)
4687 {
4688         struct socket_info *si = find_socket_info(fd);
4689         struct socket_info_fd *fi;
4690         int ret;
4691
4692         if (!si) {
4693                 return libc_close(fd);
4694         }
4695
4696         for (fi = si->fds; fi; fi = fi->next) {
4697                 if (fi->fd == fd) {
4698                         SWRAP_DLIST_REMOVE(si->fds, fi);
4699                         free(fi);
4700                         break;
4701                 }
4702         }
4703
4704         if (si->fds) {
4705                 /* there are still references left */
4706                 return libc_close(fd);
4707         }
4708
4709         SWRAP_DLIST_REMOVE(sockets, si);
4710
4711         if (si->myname && si->peername) {
4712                 swrap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0);
4713         }
4714
4715         ret = libc_close(fd);
4716
4717         if (si->myname && si->peername) {
4718                 swrap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0);
4719                 swrap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0);
4720         }
4721
4722         if (si->bindname != NULL) {
4723                 free(si->bindname);
4724         }
4725
4726         if (si->myname) free(si->myname);
4727         if (si->peername) free(si->peername);
4728         if (si->tmp_path) {
4729                 unlink(si->tmp_path);
4730                 free(si->tmp_path);
4731         }
4732         free(si);
4733
4734         return ret;
4735 }
4736
4737 int close(int fd)
4738 {
4739         return swrap_close(fd);
4740 }
4741
4742 /****************************
4743  * DUP
4744  ***************************/
4745
4746 static int swrap_dup(int fd)
4747 {
4748         struct socket_info *si;
4749         struct socket_info_fd *fi;
4750
4751         si = find_socket_info(fd);
4752
4753         if (!si) {
4754                 return libc_dup(fd);
4755         }
4756
4757         fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
4758         if (fi == NULL) {
4759                 errno = ENOMEM;
4760                 return -1;
4761         }
4762
4763         fi->fd = libc_dup(fd);
4764         if (fi->fd == -1) {
4765                 int saved_errno = errno;
4766                 free(fi);
4767                 errno = saved_errno;
4768                 return -1;
4769         }
4770
4771         /* Make sure we don't have an entry for the fd */
4772         swrap_remove_stale(fi->fd);
4773
4774         SWRAP_DLIST_ADD(si->fds, fi);
4775         return fi->fd;
4776 }
4777
4778 int dup(int fd)
4779 {
4780         return swrap_dup(fd);
4781 }
4782
4783 /****************************
4784  * DUP2
4785  ***************************/
4786
4787 static int swrap_dup2(int fd, int newfd)
4788 {
4789         struct socket_info *si;
4790         struct socket_info_fd *fi;
4791
4792         si = find_socket_info(fd);
4793
4794         if (!si) {
4795                 return libc_dup2(fd, newfd);
4796         }
4797
4798         if (find_socket_info(newfd)) {
4799                 /* dup2() does an implicit close of newfd, which we
4800                  * need to emulate */
4801                 swrap_close(newfd);
4802         }
4803
4804         fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
4805         if (fi == NULL) {
4806                 errno = ENOMEM;
4807                 return -1;
4808         }
4809
4810         fi->fd = libc_dup2(fd, newfd);
4811         if (fi->fd == -1) {
4812                 int saved_errno = errno;
4813                 free(fi);
4814                 errno = saved_errno;
4815                 return -1;
4816         }
4817
4818         /* Make sure we don't have an entry for the fd */
4819         swrap_remove_stale(fi->fd);
4820
4821         SWRAP_DLIST_ADD(si->fds, fi);
4822         return fi->fd;
4823 }
4824
4825 int dup2(int fd, int newfd)
4826 {
4827         return swrap_dup2(fd, newfd);
4828 }
4829
4830 /****************************
4831  * DUP2
4832  ***************************/
4833
4834 #ifdef HAVE_EVENTFD
4835 static int swrap_eventfd(int count, int flags)
4836 {
4837         int fd;
4838
4839         fd = libc_eventfd(count, flags);
4840         if (fd != -1) {
4841                 swrap_remove_stale(fd);
4842         }
4843
4844         return fd;
4845 }
4846
4847 int eventfd(int count, int flags)
4848 {
4849         return swrap_eventfd(count, flags);
4850 }
4851 #endif
4852
4853 /****************************
4854  * DESTRUCTOR
4855  ***************************/
4856
4857 /*
4858  * This function is called when the library is unloaded and makes sure that
4859  * sockets get closed and the unix file for the socket are unlinked.
4860  */
4861 void swrap_destructor(void)
4862 {
4863         struct socket_info *s = sockets;
4864
4865         while (s != NULL) {
4866                 struct socket_info_fd *f = s->fds;
4867                 if (f != NULL) {
4868                         swrap_close(f->fd);
4869                 }
4870                 s = sockets;
4871         }
4872 }