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