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