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