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