swrap: Treat the case of fd == newfd correctly in dup2()
[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         child_si->family = parent_si->family;
2686         child_si->type = parent_si->type;
2687         child_si->protocol = parent_si->protocol;
2688         child_si->bound = 1;
2689         child_si->is_server = 1;
2690         child_si->connected = 1;
2691
2692         child_si->peername = (struct swrap_address) {
2693                 .sa_socklen = in_addr.sa_socklen,
2694         };
2695         memcpy(&child_si->peername.sa.ss, &in_addr.sa.ss, in_addr.sa_socklen);
2696
2697         if (addr != NULL && addrlen != NULL) {
2698                 size_t copy_len = MIN(*addrlen, in_addr.sa_socklen);
2699                 if (copy_len > 0) {
2700                         memcpy(addr, &in_addr.sa.ss, copy_len);
2701                 }
2702                 *addrlen = in_addr.sa_socklen;
2703         }
2704
2705         ret = libc_getsockname(fd,
2706                                &un_my_addr.sa.s,
2707                                &un_my_addr.sa_socklen);
2708         if (ret == -1) {
2709                 free(child_fi);
2710                 free(child_si);
2711                 close(fd);
2712                 return ret;
2713         }
2714
2715         ret = sockaddr_convert_from_un(child_si,
2716                                        &un_my_addr.sa.un,
2717                                        un_my_addr.sa_socklen,
2718                                        child_si->family,
2719                                        &in_my_addr.sa.s,
2720                                        &in_my_addr.sa_socklen);
2721         if (ret == -1) {
2722                 free(child_fi);
2723                 free(child_si);
2724                 close(fd);
2725                 return ret;
2726         }
2727
2728         SWRAP_LOG(SWRAP_LOG_TRACE,
2729                   "accept() path=%s, fd=%d",
2730                   un_my_addr.sa.un.sun_path, s);
2731
2732         child_si->myname = (struct swrap_address) {
2733                 .sa_socklen = in_my_addr.sa_socklen,
2734         };
2735         memcpy(&child_si->myname.sa.ss, &in_my_addr.sa.ss, in_my_addr.sa_socklen);
2736
2737         SWRAP_DLIST_ADD(child_si->fds, child_fi);
2738         SWRAP_DLIST_ADD(sockets, child_si);
2739
2740         if (addr != NULL) {
2741                 swrap_pcap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0);
2742                 swrap_pcap_dump_packet(child_si, addr, SWRAP_ACCEPT_RECV, NULL, 0);
2743                 swrap_pcap_dump_packet(child_si, addr, SWRAP_ACCEPT_ACK, NULL, 0);
2744         }
2745
2746         return fd;
2747 }
2748
2749 #ifdef HAVE_ACCEPT4
2750 int accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags)
2751 {
2752         return swrap_accept(s, addr, (socklen_t *)addrlen, flags);
2753 }
2754 #endif
2755
2756 #ifdef HAVE_ACCEPT_PSOCKLEN_T
2757 int accept(int s, struct sockaddr *addr, Psocklen_t addrlen)
2758 #else
2759 int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
2760 #endif
2761 {
2762         return swrap_accept(s, addr, (socklen_t *)addrlen, 0);
2763 }
2764
2765 static int autobind_start_init;
2766 static int autobind_start;
2767
2768 /* using sendto() or connect() on an unbound socket would give the
2769    recipient no way to reply, as unlike UDP and TCP, a unix domain
2770    socket can't auto-assign ephemeral port numbers, so we need to
2771    assign it here.
2772    Note: this might change the family from ipv6 to ipv4
2773 */
2774 static int swrap_auto_bind(int fd, struct socket_info *si, int family)
2775 {
2776         struct swrap_address un_addr = {
2777                 .sa_socklen = sizeof(struct sockaddr_un),
2778         };
2779         int i;
2780         char type;
2781         int ret;
2782         int port;
2783         struct stat st;
2784
2785         if (autobind_start_init != 1) {
2786                 autobind_start_init = 1;
2787                 autobind_start = getpid();
2788                 autobind_start %= 50000;
2789                 autobind_start += 10000;
2790         }
2791
2792         un_addr.sa.un.sun_family = AF_UNIX;
2793
2794         switch (family) {
2795         case AF_INET: {
2796                 struct sockaddr_in in;
2797
2798                 switch (si->type) {
2799                 case SOCK_STREAM:
2800                         type = SOCKET_TYPE_CHAR_TCP;
2801                         break;
2802                 case SOCK_DGRAM:
2803                         type = SOCKET_TYPE_CHAR_UDP;
2804                         break;
2805                 default:
2806                     errno = ESOCKTNOSUPPORT;
2807                     return -1;
2808                 }
2809
2810                 memset(&in, 0, sizeof(in));
2811                 in.sin_family = AF_INET;
2812                 in.sin_addr.s_addr = htonl(127<<24 |
2813                                            socket_wrapper_default_iface());
2814
2815                 si->myname = (struct swrap_address) {
2816                         .sa_socklen = sizeof(in),
2817                 };
2818                 memcpy(&si->myname.sa.in, &in, si->myname.sa_socklen);
2819                 break;
2820         }
2821 #ifdef HAVE_IPV6
2822         case AF_INET6: {
2823                 struct sockaddr_in6 in6;
2824
2825                 if (si->family != family) {
2826                         errno = ENETUNREACH;
2827                         return -1;
2828                 }
2829
2830                 switch (si->type) {
2831                 case SOCK_STREAM:
2832                         type = SOCKET_TYPE_CHAR_TCP_V6;
2833                         break;
2834                 case SOCK_DGRAM:
2835                         type = SOCKET_TYPE_CHAR_UDP_V6;
2836                         break;
2837                 default:
2838                         errno = ESOCKTNOSUPPORT;
2839                         return -1;
2840                 }
2841
2842                 memset(&in6, 0, sizeof(in6));
2843                 in6.sin6_family = AF_INET6;
2844                 in6.sin6_addr = *swrap_ipv6();
2845                 in6.sin6_addr.s6_addr[15] = socket_wrapper_default_iface();
2846
2847                 si->myname = (struct swrap_address) {
2848                         .sa_socklen = sizeof(in6),
2849                 };
2850                 memcpy(&si->myname.sa.in6, &in6, si->myname.sa_socklen);
2851                 break;
2852         }
2853 #endif
2854         default:
2855                 errno = ESOCKTNOSUPPORT;
2856                 return -1;
2857         }
2858
2859         if (autobind_start > 60000) {
2860                 autobind_start = 10000;
2861         }
2862
2863         for (i = 0; i < SOCKET_MAX_SOCKETS; i++) {
2864                 port = autobind_start + i;
2865                 snprintf(un_addr.sa.un.sun_path, sizeof(un_addr.sa.un.sun_path),
2866                          "%s/"SOCKET_FORMAT, socket_wrapper_dir(),
2867                          type, socket_wrapper_default_iface(), port);
2868                 if (stat(un_addr.sa.un.sun_path, &st) == 0) continue;
2869
2870                 ret = libc_bind(fd, &un_addr.sa.s, un_addr.sa_socklen);
2871                 if (ret == -1) return ret;
2872
2873                 si->un_addr = un_addr.sa.un;
2874
2875                 si->bound = 1;
2876                 autobind_start = port + 1;
2877                 break;
2878         }
2879         if (i == SOCKET_MAX_SOCKETS) {
2880                 SWRAP_LOG(SWRAP_LOG_ERROR, "Too many open unix sockets (%u) for "
2881                                            "interface "SOCKET_FORMAT,
2882                                            SOCKET_MAX_SOCKETS,
2883                                            type,
2884                                            socket_wrapper_default_iface(),
2885                                            0);
2886                 errno = ENFILE;
2887                 return -1;
2888         }
2889
2890         si->family = family;
2891         set_port(si->family, port, &si->myname);
2892
2893         return 0;
2894 }
2895
2896 /****************************************************************************
2897  *   CONNECT
2898  ***************************************************************************/
2899
2900 static int swrap_connect(int s, const struct sockaddr *serv_addr,
2901                          socklen_t addrlen)
2902 {
2903         int ret;
2904         struct swrap_address un_addr = {
2905                 .sa_socklen = sizeof(struct sockaddr_un),
2906         };
2907         struct socket_info *si = find_socket_info(s);
2908         int bcast = 0;
2909
2910         if (!si) {
2911                 return libc_connect(s, serv_addr, addrlen);
2912         }
2913
2914         if (si->bound == 0) {
2915                 ret = swrap_auto_bind(s, si, serv_addr->sa_family);
2916                 if (ret == -1) return -1;
2917         }
2918
2919         if (si->family != serv_addr->sa_family) {
2920                 errno = EINVAL;
2921                 return -1;
2922         }
2923
2924         ret = sockaddr_convert_to_un(si, serv_addr,
2925                                      addrlen, &un_addr.sa.un, 0, &bcast);
2926         if (ret == -1) return -1;
2927
2928         if (bcast) {
2929                 errno = ENETUNREACH;
2930                 return -1;
2931         }
2932
2933         if (si->type == SOCK_DGRAM) {
2934                 si->defer_connect = 1;
2935                 ret = 0;
2936         } else {
2937                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0);
2938
2939                 ret = libc_connect(s,
2940                                    &un_addr.sa.s,
2941                                    un_addr.sa_socklen);
2942         }
2943
2944         SWRAP_LOG(SWRAP_LOG_TRACE,
2945                   "connect() path=%s, fd=%d",
2946                   un_addr.sa.un.sun_path, s);
2947
2948
2949         /* to give better errors */
2950         if (ret == -1 && errno == ENOENT) {
2951                 errno = EHOSTUNREACH;
2952         }
2953
2954         if (ret == 0) {
2955                 si->peername = (struct swrap_address) {
2956                         .sa_socklen = addrlen,
2957                 };
2958
2959                 memcpy(&si->peername.sa.ss, serv_addr, addrlen);
2960                 si->connected = 1;
2961
2962                 /*
2963                  * When we connect() on a socket than we have to bind the
2964                  * outgoing connection on the interface we use for the
2965                  * transport. We already bound it on the right interface
2966                  * but here we have to update the name so getsockname()
2967                  * returns correct information.
2968                  */
2969                 if (si->bindname.sa_socklen > 0) {
2970                         si->myname = (struct swrap_address) {
2971                                 .sa_socklen = si->bindname.sa_socklen,
2972                         };
2973
2974                         memcpy(&si->myname.sa.ss,
2975                                &si->bindname.sa.ss,
2976                                si->bindname.sa_socklen);
2977
2978                         /* Cleanup bindname */
2979                         si->bindname = (struct swrap_address) {
2980                                 .sa_socklen = 0,
2981                         };
2982                 }
2983
2984                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0);
2985                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0);
2986         } else {
2987                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0);
2988         }
2989
2990         return ret;
2991 }
2992
2993 int connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen)
2994 {
2995         return swrap_connect(s, serv_addr, addrlen);
2996 }
2997
2998 /****************************************************************************
2999  *   BIND
3000  ***************************************************************************/
3001
3002 static int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
3003 {
3004         int ret;
3005         struct swrap_address un_addr = {
3006                 .sa_socklen = sizeof(struct sockaddr_un),
3007         };
3008         struct socket_info *si = find_socket_info(s);
3009         int bind_error = 0;
3010 #if 0 /* FIXME */
3011         bool in_use;
3012 #endif
3013
3014         if (!si) {
3015                 return libc_bind(s, myaddr, addrlen);
3016         }
3017
3018         switch (si->family) {
3019         case AF_INET: {
3020                 const struct sockaddr_in *sin;
3021                 if (addrlen < sizeof(struct sockaddr_in)) {
3022                         bind_error = EINVAL;
3023                         break;
3024                 }
3025
3026                 sin = (const struct sockaddr_in *)(const void *)myaddr;
3027
3028                 if (sin->sin_family != AF_INET) {
3029                         bind_error = EAFNOSUPPORT;
3030                 }
3031
3032                 /* special case for AF_UNSPEC */
3033                 if (sin->sin_family == AF_UNSPEC &&
3034                     (sin->sin_addr.s_addr == htonl(INADDR_ANY)))
3035                 {
3036                         bind_error = 0;
3037                 }
3038
3039                 break;
3040         }
3041 #ifdef HAVE_IPV6
3042         case AF_INET6: {
3043                 const struct sockaddr_in6 *sin6;
3044                 if (addrlen < sizeof(struct sockaddr_in6)) {
3045                         bind_error = EINVAL;
3046                         break;
3047                 }
3048
3049                 sin6 = (const struct sockaddr_in6 *)(const void *)myaddr;
3050
3051                 if (sin6->sin6_family != AF_INET6) {
3052                         bind_error = EAFNOSUPPORT;
3053                 }
3054
3055                 break;
3056         }
3057 #endif
3058         default:
3059                 bind_error = EINVAL;
3060                 break;
3061         }
3062
3063         if (bind_error != 0) {
3064                 errno = bind_error;
3065                 return -1;
3066         }
3067
3068 #if 0 /* FIXME */
3069         in_use = check_addr_port_in_use(myaddr, addrlen);
3070         if (in_use) {
3071                 errno = EADDRINUSE;
3072                 return -1;
3073         }
3074 #endif
3075
3076         si->myname.sa_socklen = addrlen;
3077         memcpy(&si->myname.sa.ss, myaddr, addrlen);
3078
3079         ret = sockaddr_convert_to_un(si,
3080                                      myaddr,
3081                                      addrlen,
3082                                      &un_addr.sa.un,
3083                                      1,
3084                                      &si->bcast);
3085         if (ret == -1) return -1;
3086
3087         unlink(un_addr.sa.un.sun_path);
3088
3089         ret = libc_bind(s, &un_addr.sa.s, un_addr.sa_socklen);
3090
3091         SWRAP_LOG(SWRAP_LOG_TRACE,
3092                   "bind() path=%s, fd=%d",
3093                   un_addr.sa.un.sun_path, s);
3094
3095         if (ret == 0) {
3096                 si->bound = 1;
3097         }
3098
3099         return ret;
3100 }
3101
3102 int bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
3103 {
3104         return swrap_bind(s, myaddr, addrlen);
3105 }
3106
3107 /****************************************************************************
3108  *   BINDRESVPORT
3109  ***************************************************************************/
3110
3111 #ifdef HAVE_BINDRESVPORT
3112 static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen);
3113
3114 static int swrap_bindresvport_sa(int sd, struct sockaddr *sa)
3115 {
3116         struct swrap_address myaddr = {
3117                 .sa_socklen = sizeof(struct sockaddr_storage),
3118         };
3119         socklen_t salen;
3120         static uint16_t port;
3121         uint16_t i;
3122         int rc = -1;
3123         int af;
3124
3125 #define SWRAP_STARTPORT 600
3126 #define SWRAP_ENDPORT (IPPORT_RESERVED - 1)
3127 #define SWRAP_NPORTS (SWRAP_ENDPORT - SWRAP_STARTPORT + 1)
3128
3129         if (port == 0) {
3130                 port = (getpid() % SWRAP_NPORTS) + SWRAP_STARTPORT;
3131         }
3132
3133         if (sa == NULL) {
3134                 salen = myaddr.sa_socklen;
3135                 sa = &myaddr.sa.s;
3136
3137                 rc = swrap_getsockname(sd, &myaddr.sa.s, &salen);
3138                 if (rc < 0) {
3139                         return -1;
3140                 }
3141
3142                 af = sa->sa_family;
3143                 memset(&myaddr.sa.ss, 0, salen);
3144         } else {
3145                 af = sa->sa_family;
3146         }
3147
3148         for (i = 0; i < SWRAP_NPORTS; i++, port++) {
3149                 switch(af) {
3150                 case AF_INET: {
3151                         struct sockaddr_in *sinp = (struct sockaddr_in *)(void *)sa;
3152
3153                         salen = sizeof(struct sockaddr_in);
3154                         sinp->sin_port = htons(port);
3155                         break;
3156                 }
3157                 case AF_INET6: {
3158                         struct sockaddr_in6 *sin6p = (struct sockaddr_in6 *)(void *)sa;
3159
3160                         salen = sizeof(struct sockaddr_in6);
3161                         sin6p->sin6_port = htons(port);
3162                         break;
3163                 }
3164                 default:
3165                         errno = EAFNOSUPPORT;
3166                         return -1;
3167                 }
3168                 sa->sa_family = af;
3169
3170                 if (port > SWRAP_ENDPORT) {
3171                         port = SWRAP_STARTPORT;
3172                 }
3173
3174                 rc = swrap_bind(sd, (struct sockaddr *)sa, salen);
3175                 if (rc == 0 || errno != EADDRINUSE) {
3176                         break;
3177                 }
3178         }
3179
3180         return rc;
3181 }
3182
3183 int bindresvport(int sockfd, struct sockaddr_in *sinp)
3184 {
3185         return swrap_bindresvport_sa(sockfd, (struct sockaddr *)sinp);
3186 }
3187 #endif
3188
3189 /****************************************************************************
3190  *   LISTEN
3191  ***************************************************************************/
3192
3193 static int swrap_listen(int s, int backlog)
3194 {
3195         int ret;
3196         struct socket_info *si = find_socket_info(s);
3197
3198         if (!si) {
3199                 return libc_listen(s, backlog);
3200         }
3201
3202         if (si->bound == 0) {
3203                 ret = swrap_auto_bind(s, si, si->family);
3204                 if (ret == -1) {
3205                         errno = EADDRINUSE;
3206                         return ret;
3207                 }
3208         }
3209
3210         ret = libc_listen(s, backlog);
3211
3212         return ret;
3213 }
3214
3215 int listen(int s, int backlog)
3216 {
3217         return swrap_listen(s, backlog);
3218 }
3219
3220 /****************************************************************************
3221  *   FOPEN
3222  ***************************************************************************/
3223
3224 static FILE *swrap_fopen(const char *name, const char *mode)
3225 {
3226         FILE *fp;
3227
3228         fp = libc_fopen(name, mode);
3229         if (fp != NULL) {
3230                 int fd = fileno(fp);
3231
3232                 swrap_remove_stale(fd);
3233         }
3234
3235         return fp;
3236 }
3237
3238 FILE *fopen(const char *name, const char *mode)
3239 {
3240         return swrap_fopen(name, mode);
3241 }
3242
3243 /****************************************************************************
3244  *   OPEN
3245  ***************************************************************************/
3246
3247 static int swrap_vopen(const char *pathname, int flags, va_list ap)
3248 {
3249         int ret;
3250
3251         ret = libc_vopen(pathname, flags, ap);
3252         if (ret != -1) {
3253                 /*
3254                  * There are methods for closing descriptors (libc-internal code
3255                  * paths, direct syscalls) which close descriptors in ways that
3256                  * we can't intercept, so try to recover when we notice that
3257                  * that's happened
3258                  */
3259                 swrap_remove_stale(ret);
3260         }
3261         return ret;
3262 }
3263
3264 int open(const char *pathname, int flags, ...)
3265 {
3266         va_list ap;
3267         int fd;
3268
3269         va_start(ap, flags);
3270         fd = swrap_vopen(pathname, flags, ap);
3271         va_end(ap);
3272
3273         return fd;
3274 }
3275
3276 /****************************************************************************
3277  *   GETPEERNAME
3278  ***************************************************************************/
3279
3280 static int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
3281 {
3282         struct socket_info *si = find_socket_info(s);
3283         socklen_t len;
3284
3285         if (!si) {
3286                 return libc_getpeername(s, name, addrlen);
3287         }
3288
3289         if (si->peername.sa_socklen == 0)
3290         {
3291                 errno = ENOTCONN;
3292                 return -1;
3293         }
3294
3295         len = MIN(*addrlen, si->peername.sa_socklen);
3296         if (len == 0) {
3297                 return 0;
3298         }
3299
3300         memcpy(name, &si->peername.sa.ss, len);
3301         *addrlen = si->peername.sa_socklen;
3302
3303         return 0;
3304 }
3305
3306 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3307 int getpeername(int s, struct sockaddr *name, Psocklen_t addrlen)
3308 #else
3309 int getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
3310 #endif
3311 {
3312         return swrap_getpeername(s, name, (socklen_t *)addrlen);
3313 }
3314
3315 /****************************************************************************
3316  *   GETSOCKNAME
3317  ***************************************************************************/
3318
3319 static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
3320 {
3321         struct socket_info *si = find_socket_info(s);
3322         socklen_t len;
3323
3324         if (!si) {
3325                 return libc_getsockname(s, name, addrlen);
3326         }
3327
3328         len = MIN(*addrlen, si->myname.sa_socklen);
3329         if (len == 0) {
3330                 return 0;
3331         }
3332
3333         memcpy(name, &si->myname.sa.ss, len);
3334         *addrlen = si->myname.sa_socklen;
3335
3336         return 0;
3337 }
3338
3339 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3340 int getsockname(int s, struct sockaddr *name, Psocklen_t addrlen)
3341 #else
3342 int getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
3343 #endif
3344 {
3345         return swrap_getsockname(s, name, (socklen_t *)addrlen);
3346 }
3347
3348 /****************************************************************************
3349  *   GETSOCKOPT
3350  ***************************************************************************/
3351
3352 #ifndef SO_PROTOCOL
3353 # ifdef SO_PROTOTYPE /* The Solaris name */
3354 #  define SO_PROTOCOL SO_PROTOTYPE
3355 # endif /* SO_PROTOTYPE */
3356 #endif /* SO_PROTOCOL */
3357
3358 static int swrap_getsockopt(int s, int level, int optname,
3359                             void *optval, socklen_t *optlen)
3360 {
3361         struct socket_info *si = find_socket_info(s);
3362
3363         if (!si) {
3364                 return libc_getsockopt(s,
3365                                        level,
3366                                        optname,
3367                                        optval,
3368                                        optlen);
3369         }
3370
3371         if (level == SOL_SOCKET) {
3372                 switch (optname) {
3373 #ifdef SO_DOMAIN
3374                 case SO_DOMAIN:
3375                         if (optval == NULL || optlen == NULL ||
3376                             *optlen < (socklen_t)sizeof(int)) {
3377                                 errno = EINVAL;
3378                                 return -1;
3379                         }
3380
3381                         *optlen = sizeof(int);
3382                         *(int *)optval = si->family;
3383                         return 0;
3384 #endif /* SO_DOMAIN */
3385
3386 #ifdef SO_PROTOCOL
3387                 case SO_PROTOCOL:
3388                         if (optval == NULL || optlen == NULL ||
3389                             *optlen < (socklen_t)sizeof(int)) {
3390                                 errno = EINVAL;
3391                                 return -1;
3392                         }
3393
3394                         *optlen = sizeof(int);
3395                         *(int *)optval = si->protocol;
3396                         return 0;
3397 #endif /* SO_PROTOCOL */
3398                 case SO_TYPE:
3399                         if (optval == NULL || optlen == NULL ||
3400                             *optlen < (socklen_t)sizeof(int)) {
3401                                 errno = EINVAL;
3402                                 return -1;
3403                         }
3404
3405                         *optlen = sizeof(int);
3406                         *(int *)optval = si->type;
3407                         return 0;
3408                 default:
3409                         return libc_getsockopt(s,
3410                                                level,
3411                                                optname,
3412                                                optval,
3413                                                optlen);
3414                 }
3415         } else if (level == IPPROTO_TCP) {
3416                 switch (optname) {
3417 #ifdef TCP_NODELAY
3418                 case TCP_NODELAY:
3419                         /*
3420                          * This enables sending packets directly out over TCP.
3421                          * As a unix socket is doing that any way, report it as
3422                          * enabled.
3423                          */
3424                         if (optval == NULL || optlen == NULL ||
3425                             *optlen < (socklen_t)sizeof(int)) {
3426                                 errno = EINVAL;
3427                                 return -1;
3428                         }
3429
3430                         *optlen = sizeof(int);
3431                         *(int *)optval = si->tcp_nodelay;
3432
3433                         return 0;
3434 #endif /* TCP_NODELAY */
3435                 default:
3436                         break;
3437                 }
3438         }
3439
3440         errno = ENOPROTOOPT;
3441         return -1;
3442 }
3443
3444 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3445 int getsockopt(int s, int level, int optname, void *optval, Psocklen_t optlen)
3446 #else
3447 int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
3448 #endif
3449 {
3450         return swrap_getsockopt(s, level, optname, optval, (socklen_t *)optlen);
3451 }
3452
3453 /****************************************************************************
3454  *   SETSOCKOPT
3455  ***************************************************************************/
3456
3457 static int swrap_setsockopt(int s, int level, int optname,
3458                             const void *optval, socklen_t optlen)
3459 {
3460         struct socket_info *si = find_socket_info(s);
3461
3462         if (!si) {
3463                 return libc_setsockopt(s,
3464                                        level,
3465                                        optname,
3466                                        optval,
3467                                        optlen);
3468         }
3469
3470         if (level == SOL_SOCKET) {
3471                 return libc_setsockopt(s,
3472                                        level,
3473                                        optname,
3474                                        optval,
3475                                        optlen);
3476         } else if (level == IPPROTO_TCP) {
3477                 switch (optname) {
3478 #ifdef TCP_NODELAY
3479                 case TCP_NODELAY: {
3480                         int i;
3481
3482                         /*
3483                          * This enables sending packets directly out over TCP.
3484                          * A unix socket is doing that any way.
3485                          */
3486                         if (optval == NULL || optlen == 0 ||
3487                             optlen < (socklen_t)sizeof(int)) {
3488                                 errno = EINVAL;
3489                                 return -1;
3490                         }
3491
3492                         i = *discard_const_p(int, optval);
3493                         if (i != 0 && i != 1) {
3494                                 errno = EINVAL;
3495                                 return -1;
3496                         }
3497                         si->tcp_nodelay = i;
3498
3499                         return 0;
3500                 }
3501 #endif /* TCP_NODELAY */
3502                 default:
3503                         break;
3504                 }
3505         }
3506
3507         switch (si->family) {
3508         case AF_INET:
3509                 if (level == IPPROTO_IP) {
3510 #ifdef IP_PKTINFO
3511                         if (optname == IP_PKTINFO) {
3512                                 si->pktinfo = AF_INET;
3513                         }
3514 #endif /* IP_PKTINFO */
3515                 }
3516                 return 0;
3517 #ifdef HAVE_IPV6
3518         case AF_INET6:
3519                 if (level == IPPROTO_IPV6) {
3520 #ifdef IPV6_RECVPKTINFO
3521                         if (optname == IPV6_RECVPKTINFO) {
3522                                 si->pktinfo = AF_INET6;
3523                         }
3524 #endif /* IPV6_PKTINFO */
3525                 }
3526                 return 0;
3527 #endif
3528         default:
3529                 errno = ENOPROTOOPT;
3530                 return -1;
3531         }
3532 }
3533
3534 int setsockopt(int s, int level, int optname,
3535                const void *optval, socklen_t optlen)
3536 {
3537         return swrap_setsockopt(s, level, optname, optval, optlen);
3538 }
3539
3540 /****************************************************************************
3541  *   IOCTL
3542  ***************************************************************************/
3543
3544 static int swrap_vioctl(int s, unsigned long int r, va_list va)
3545 {
3546         struct socket_info *si = find_socket_info(s);
3547         va_list ap;
3548         int value;
3549         int rc;
3550
3551         if (!si) {
3552                 return libc_vioctl(s, r, va);
3553         }
3554
3555         va_copy(ap, va);
3556
3557         rc = libc_vioctl(s, r, va);
3558
3559         switch (r) {
3560         case FIONREAD:
3561                 value = *((int *)va_arg(ap, int *));
3562
3563                 if (rc == -1 && errno != EAGAIN && errno != ENOBUFS) {
3564                         swrap_pcap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
3565                 } else if (value == 0) { /* END OF FILE */
3566                         swrap_pcap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
3567                 }
3568                 break;
3569         }
3570
3571         va_end(ap);
3572
3573         return rc;
3574 }
3575
3576 #ifdef HAVE_IOCTL_INT
3577 int ioctl(int s, int r, ...)
3578 #else
3579 int ioctl(int s, unsigned long int r, ...)
3580 #endif
3581 {
3582         va_list va;
3583         int rc;
3584
3585         va_start(va, r);
3586
3587         rc = swrap_vioctl(s, (unsigned long int) r, va);
3588
3589         va_end(va);
3590
3591         return rc;
3592 }
3593
3594 /*****************
3595  * CMSG
3596  *****************/
3597
3598 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3599
3600 #ifndef CMSG_ALIGN
3601 # ifdef _ALIGN /* BSD */
3602 #define CMSG_ALIGN _ALIGN
3603 # else
3604 #define CMSG_ALIGN(len) (((len) + sizeof(size_t) - 1) & ~(sizeof(size_t) - 1))
3605 # endif /* _ALIGN */
3606 #endif /* CMSG_ALIGN */
3607
3608 /**
3609  * @brief Add a cmsghdr to a msghdr.
3610  *
3611  * This is an function to add any type of cmsghdr. It will operate on the
3612  * msg->msg_control and msg->msg_controllen you pass in by adapting them to
3613  * the buffer position after the added cmsg element. Hence, this function is
3614  * intended to be used with an intermediate msghdr and not on the original
3615  * one handed in by the client.
3616  *
3617  * @param[in]  msg      The msghdr to which to add the cmsg.
3618  *
3619  * @param[in]  level    The cmsg level to set.
3620  *
3621  * @param[in]  type     The cmsg type to set.
3622  *
3623  * @param[in]  data     The cmsg data to set.
3624  *
3625  * @param[in]  len      the length of the data to set.
3626  */
3627 static void swrap_msghdr_add_cmsghdr(struct msghdr *msg,
3628                                      int level,
3629                                      int type,
3630                                      const void *data,
3631                                      size_t len)
3632 {
3633         size_t cmlen = CMSG_LEN(len);
3634         size_t cmspace = CMSG_SPACE(len);
3635         uint8_t cmbuf[cmspace];
3636         void *cast_ptr = (void *)cmbuf;
3637         struct cmsghdr *cm = (struct cmsghdr *)cast_ptr;
3638         uint8_t *p;
3639
3640         memset(cmbuf, 0, cmspace);
3641
3642         if (msg->msg_controllen < cmlen) {
3643                 cmlen = msg->msg_controllen;
3644                 msg->msg_flags |= MSG_CTRUNC;
3645         }
3646
3647         if (msg->msg_controllen < cmspace) {
3648                 cmspace = msg->msg_controllen;
3649         }
3650
3651         /*
3652          * We copy the full input data into an intermediate cmsghdr first
3653          * in order to more easily cope with truncation.
3654          */
3655         cm->cmsg_len = cmlen;
3656         cm->cmsg_level = level;
3657         cm->cmsg_type = type;
3658         memcpy(CMSG_DATA(cm), data, len);
3659
3660         /*
3661          * We now copy the possibly truncated buffer.
3662          * We copy cmlen bytes, but consume cmspace bytes,
3663          * leaving the possible padding uninitialiazed.
3664          */
3665         p = (uint8_t *)msg->msg_control;
3666         memcpy(p, cm, cmlen);
3667         p += cmspace;
3668         msg->msg_control = p;
3669         msg->msg_controllen -= cmspace;
3670
3671         return;
3672 }
3673
3674 static int swrap_msghdr_add_pktinfo(struct socket_info *si,
3675                                     struct msghdr *msg)
3676 {
3677         /* Add packet info */
3678         switch (si->pktinfo) {
3679 #if defined(IP_PKTINFO) && (defined(HAVE_STRUCT_IN_PKTINFO) || defined(IP_RECVDSTADDR))
3680         case AF_INET: {
3681                 struct sockaddr_in *sin;
3682 #if defined(HAVE_STRUCT_IN_PKTINFO)
3683                 struct in_pktinfo pkt;
3684 #elif defined(IP_RECVDSTADDR)
3685                 struct in_addr pkt;
3686 #endif
3687
3688                 if (si->bindname.sa_socklen == sizeof(struct sockaddr_in)) {
3689                         sin = &si->bindname.sa.in;
3690                 } else {
3691                         if (si->myname.sa_socklen != sizeof(struct sockaddr_in)) {
3692                                 return 0;
3693                         }
3694                         sin = &si->myname.sa.in;
3695                 }
3696
3697                 ZERO_STRUCT(pkt);
3698
3699 #if defined(HAVE_STRUCT_IN_PKTINFO)
3700                 pkt.ipi_ifindex = socket_wrapper_default_iface();
3701                 pkt.ipi_addr.s_addr = sin->sin_addr.s_addr;
3702 #elif defined(IP_RECVDSTADDR)
3703                 pkt = sin->sin_addr;
3704 #endif
3705
3706                 swrap_msghdr_add_cmsghdr(msg, IPPROTO_IP, IP_PKTINFO,
3707                                          &pkt, sizeof(pkt));
3708
3709                 break;
3710         }
3711 #endif /* IP_PKTINFO */
3712 #if defined(HAVE_IPV6)
3713         case AF_INET6: {
3714 #if defined(IPV6_PKTINFO) && defined(HAVE_STRUCT_IN6_PKTINFO)
3715                 struct sockaddr_in6 *sin6;
3716                 struct in6_pktinfo pkt6;
3717
3718                 if (si->bindname.sa_socklen == sizeof(struct sockaddr_in6)) {
3719                         sin6 = &si->bindname.sa.in6;
3720                 } else {
3721                         if (si->myname.sa_socklen != sizeof(struct sockaddr_in6)) {
3722                                 return 0;
3723                         }
3724                         sin6 = &si->myname.sa.in6;
3725                 }
3726
3727                 ZERO_STRUCT(pkt6);
3728
3729                 pkt6.ipi6_ifindex = socket_wrapper_default_iface();
3730                 pkt6.ipi6_addr = sin6->sin6_addr;
3731
3732                 swrap_msghdr_add_cmsghdr(msg, IPPROTO_IPV6, IPV6_PKTINFO,
3733                                         &pkt6, sizeof(pkt6));
3734 #endif /* HAVE_STRUCT_IN6_PKTINFO */
3735
3736                 break;
3737         }
3738 #endif /* IPV6_PKTINFO */
3739         default:
3740                 return -1;
3741         }
3742
3743         return 0;
3744 }
3745
3746 static int swrap_msghdr_add_socket_info(struct socket_info *si,
3747                                         struct msghdr *omsg)
3748 {
3749         int rc = 0;
3750
3751         if (si->pktinfo > 0) {
3752                 rc = swrap_msghdr_add_pktinfo(si, omsg);
3753         }
3754
3755         return rc;
3756 }
3757
3758 static int swrap_sendmsg_copy_cmsg(struct cmsghdr *cmsg,
3759                                    uint8_t **cm_data,
3760                                    size_t *cm_data_space);
3761 static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr *cmsg,
3762                                             uint8_t **cm_data,
3763                                             size_t *cm_data_space);
3764
3765 static int swrap_sendmsg_filter_cmsghdr(struct msghdr *msg,
3766                                         uint8_t **cm_data,
3767                                         size_t *cm_data_space) {
3768         struct cmsghdr *cmsg;
3769         int rc = -1;
3770
3771         /* Nothing to do */
3772         if (msg->msg_controllen == 0 || msg->msg_control == NULL) {
3773                 return 0;
3774         }
3775
3776         for (cmsg = CMSG_FIRSTHDR(msg);
3777              cmsg != NULL;
3778              cmsg = CMSG_NXTHDR(msg, cmsg)) {
3779                 switch (cmsg->cmsg_level) {
3780                 case IPPROTO_IP:
3781                         rc = swrap_sendmsg_filter_cmsg_socket(cmsg,
3782                                                               cm_data,
3783                                                               cm_data_space);
3784                         break;
3785                 default:
3786                         rc = swrap_sendmsg_copy_cmsg(cmsg,
3787                                                      cm_data,
3788                                                      cm_data_space);
3789                         break;
3790                 }
3791         }
3792
3793         return rc;
3794 }
3795
3796 static int swrap_sendmsg_copy_cmsg(struct cmsghdr *cmsg,
3797                                    uint8_t **cm_data,
3798                                    size_t *cm_data_space)
3799 {
3800         size_t cmspace;
3801         uint8_t *p;
3802
3803         cmspace = *cm_data_space + CMSG_ALIGN(cmsg->cmsg_len);
3804
3805         p = realloc((*cm_data), cmspace);
3806         if (p == NULL) {
3807                 return -1;
3808         }
3809         (*cm_data) = p;
3810
3811         p = (*cm_data) + (*cm_data_space);
3812         *cm_data_space = cmspace;
3813
3814         memcpy(p, cmsg, cmsg->cmsg_len);
3815
3816         return 0;
3817 }
3818
3819 static int swrap_sendmsg_filter_cmsg_pktinfo(struct cmsghdr *cmsg,
3820                                             uint8_t **cm_data,
3821                                             size_t *cm_data_space);
3822
3823
3824 static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr *cmsg,
3825                                             uint8_t **cm_data,
3826                                             size_t *cm_data_space)
3827 {
3828         int rc = -1;
3829
3830         switch(cmsg->cmsg_type) {
3831 #ifdef IP_PKTINFO
3832         case IP_PKTINFO:
3833                 rc = swrap_sendmsg_filter_cmsg_pktinfo(cmsg,
3834                                                        cm_data,
3835                                                        cm_data_space);
3836                 break;
3837 #endif
3838 #ifdef IPV6_PKTINFO
3839         case IPV6_PKTINFO:
3840                 rc = swrap_sendmsg_filter_cmsg_pktinfo(cmsg,
3841                                                        cm_data,
3842                                                        cm_data_space);
3843                 break;
3844 #endif
3845         default:
3846                 break;
3847         }
3848
3849         return rc;
3850 }
3851
3852 static int swrap_sendmsg_filter_cmsg_pktinfo(struct cmsghdr *cmsg,
3853                                              uint8_t **cm_data,
3854                                              size_t *cm_data_space)
3855 {
3856         (void)cmsg; /* unused */
3857         (void)cm_data; /* unused */
3858         (void)cm_data_space; /* unused */
3859
3860         /*
3861          * Passing a IP pktinfo to a unix socket might be rejected by the
3862          * Kernel, at least on FreeBSD. So skip this cmsg.
3863          */
3864         return 0;
3865 }
3866 #endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
3867
3868 static ssize_t swrap_sendmsg_before(int fd,
3869                                     struct socket_info *si,
3870                                     struct msghdr *msg,
3871                                     struct iovec *tmp_iov,
3872                                     struct sockaddr_un *tmp_un,
3873                                     const struct sockaddr_un **to_un,
3874                                     const struct sockaddr **to,
3875                                     int *bcast)
3876 {
3877         size_t i, len = 0;
3878         ssize_t ret;
3879
3880         if (to_un) {
3881                 *to_un = NULL;
3882         }
3883         if (to) {
3884                 *to = NULL;
3885         }
3886         if (bcast) {
3887                 *bcast = 0;
3888         }
3889
3890         switch (si->type) {
3891         case SOCK_STREAM: {
3892                 unsigned long mtu;
3893
3894                 if (!si->connected) {
3895                         errno = ENOTCONN;
3896                         return -1;
3897                 }
3898
3899                 if (msg->msg_iovlen == 0) {
3900                         break;
3901                 }
3902
3903                 mtu = socket_wrapper_mtu();
3904                 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3905                         size_t nlen;
3906                         nlen = len + msg->msg_iov[i].iov_len;
3907                         if (nlen > mtu) {
3908                                 break;
3909                         }
3910                 }
3911                 msg->msg_iovlen = i;
3912                 if (msg->msg_iovlen == 0) {
3913                         *tmp_iov = msg->msg_iov[0];
3914                         tmp_iov->iov_len = MIN((size_t)tmp_iov->iov_len,
3915                                                (size_t)mtu);
3916                         msg->msg_iov = tmp_iov;
3917                         msg->msg_iovlen = 1;
3918                 }
3919                 break;
3920         }
3921         case SOCK_DGRAM:
3922                 if (si->connected) {
3923                         if (msg->msg_name != NULL) {
3924                                 /*
3925                                  * We are dealing with unix sockets and if we
3926                                  * are connected, we should only talk to the
3927                                  * connected unix path. Using the fd to send
3928                                  * to another server would be hard to achieve.
3929                                  */
3930                                 msg->msg_name = NULL;
3931                                 msg->msg_namelen = 0;
3932                         }
3933                 } else {
3934                         const struct sockaddr *msg_name;
3935                         msg_name = (const struct sockaddr *)msg->msg_name;
3936
3937                         if (msg_name == NULL) {
3938                                 errno = ENOTCONN;
3939                                 return -1;
3940                         }
3941
3942
3943                         ret = sockaddr_convert_to_un(si, msg_name, msg->msg_namelen,
3944                                                      tmp_un, 0, bcast);
3945                         if (ret == -1) return -1;
3946
3947                         if (to_un) {
3948                                 *to_un = tmp_un;
3949                         }
3950                         if (to) {
3951                                 *to = msg_name;
3952                         }
3953                         msg->msg_name = tmp_un;
3954                         msg->msg_namelen = sizeof(*tmp_un);
3955                 }
3956
3957                 if (si->bound == 0) {
3958                         ret = swrap_auto_bind(fd, si, si->family);
3959                         if (ret == -1) {
3960                                 if (errno == ENOTSOCK) {
3961                                         swrap_remove_stale(fd);
3962                                         return -ENOTSOCK;
3963                                 } else {
3964                                         SWRAP_LOG(SWRAP_LOG_ERROR, "swrap_sendmsg_before failed");
3965                                         return -1;
3966                                 }
3967                         }
3968                 }
3969
3970                 if (!si->defer_connect) {
3971                         break;
3972                 }
3973
3974                 ret = sockaddr_convert_to_un(si,
3975                                              &si->peername.sa.s,
3976                                              si->peername.sa_socklen,
3977                                              tmp_un,
3978                                              0,
3979                                              NULL);
3980                 if (ret == -1) return -1;
3981
3982                 ret = libc_connect(fd,
3983                                    (struct sockaddr *)(void *)tmp_un,
3984                                    sizeof(*tmp_un));
3985
3986                 /* to give better errors */
3987                 if (ret == -1 && errno == ENOENT) {
3988                         errno = EHOSTUNREACH;
3989                 }
3990
3991                 if (ret == -1) {
3992                         return ret;
3993                 }
3994
3995                 si->defer_connect = 0;
3996                 break;
3997         default:
3998                 errno = EHOSTUNREACH;
3999                 return -1;
4000         }
4001
4002 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4003         if (msg->msg_controllen > 0 && msg->msg_control != NULL) {
4004                 uint8_t *cmbuf = NULL;
4005                 size_t cmlen = 0;
4006
4007                 ret = swrap_sendmsg_filter_cmsghdr(msg, &cmbuf, &cmlen);
4008                 if (ret < 0) {
4009                         free(cmbuf);
4010                         return -1;
4011                 }
4012
4013                 if (cmlen == 0) {
4014                         msg->msg_controllen = 0;
4015                         msg->msg_control = NULL;
4016                 } else if (cmlen < msg->msg_controllen && cmbuf != NULL) {
4017                         memcpy(msg->msg_control, cmbuf, cmlen);
4018                         msg->msg_controllen = cmlen;
4019                 }
4020                 free(cmbuf);
4021         }
4022 #endif
4023
4024         return 0;
4025 }
4026
4027 static void swrap_sendmsg_after(int fd,
4028                                 struct socket_info *si,
4029                                 struct msghdr *msg,
4030                                 const struct sockaddr *to,
4031                                 ssize_t ret)
4032 {
4033         int saved_errno = errno;
4034         size_t i, len = 0;
4035         uint8_t *buf;
4036         off_t ofs = 0;
4037         size_t avail = 0;
4038         size_t remain;
4039
4040         /* to give better errors */
4041         if (ret == -1) {
4042                 if (saved_errno == ENOENT) {
4043                         saved_errno = EHOSTUNREACH;
4044                 } else if (saved_errno == ENOTSOCK) {
4045                         /* If the fd is not a socket, remove it */
4046                         swrap_remove_stale(fd);
4047                 }
4048         }
4049
4050         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
4051                 avail += msg->msg_iov[i].iov_len;
4052         }
4053
4054         if (ret == -1) {
4055                 remain = MIN(80, avail);
4056         } else {
4057                 remain = ret;
4058         }
4059
4060         /* we capture it as one single packet */
4061         buf = (uint8_t *)malloc(remain);
4062         if (!buf) {
4063                 /* we just not capture the packet */
4064                 errno = saved_errno;
4065                 return;
4066         }
4067
4068         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
4069                 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
4070                 memcpy(buf + ofs,
4071                        msg->msg_iov[i].iov_base,
4072                        this_time);
4073                 ofs += this_time;
4074                 remain -= this_time;
4075         }
4076         len = ofs;
4077
4078         switch (si->type) {
4079         case SOCK_STREAM:
4080                 if (ret == -1) {
4081                         swrap_pcap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
4082                         swrap_pcap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
4083                 } else {
4084                         swrap_pcap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
4085                 }
4086                 break;
4087
4088         case SOCK_DGRAM:
4089                 if (si->connected) {
4090                         to = &si->peername.sa.s;
4091                 }
4092                 if (ret == -1) {
4093                         swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
4094                         swrap_pcap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);
4095                 } else {
4096                         swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
4097                 }
4098                 break;
4099         }
4100
4101         free(buf);
4102         errno = saved_errno;
4103 }
4104
4105 static int swrap_recvmsg_before(int fd,
4106                                 struct socket_info *si,
4107                                 struct msghdr *msg,
4108                                 struct iovec *tmp_iov)
4109 {
4110         size_t i, len = 0;
4111         ssize_t ret;
4112
4113         (void)fd; /* unused */
4114
4115         switch (si->type) {
4116         case SOCK_STREAM: {
4117                 unsigned int mtu;
4118                 if (!si->connected) {
4119                         errno = ENOTCONN;
4120                         return -1;
4121                 }
4122
4123                 if (msg->msg_iovlen == 0) {
4124                         break;
4125                 }
4126
4127                 mtu = socket_wrapper_mtu();
4128                 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
4129                         size_t nlen;
4130                         nlen = len + msg->msg_iov[i].iov_len;
4131                         if (nlen > mtu) {
4132                                 break;
4133                         }
4134                 }
4135                 msg->msg_iovlen = i;
4136                 if (msg->msg_iovlen == 0) {
4137                         *tmp_iov = msg->msg_iov[0];
4138                         tmp_iov->iov_len = MIN((size_t)tmp_iov->iov_len,
4139                                                (size_t)mtu);
4140                         msg->msg_iov = tmp_iov;
4141                         msg->msg_iovlen = 1;
4142                 }
4143                 break;
4144         }
4145         case SOCK_DGRAM:
4146                 if (msg->msg_name == NULL) {
4147                         errno = EINVAL;
4148                         return -1;
4149                 }
4150
4151                 if (msg->msg_iovlen == 0) {
4152                         break;
4153                 }
4154
4155                 if (si->bound == 0) {
4156                         ret = swrap_auto_bind(fd, si, si->family);
4157                         if (ret == -1) {
4158                                 /*
4159                                  * When attempting to read or write to a
4160                                  * descriptor, if an underlying autobind fails
4161                                  * because it's not a socket, stop intercepting
4162                                  * uses of that descriptor.
4163                                  */
4164                                 if (errno == ENOTSOCK) {
4165                                         swrap_remove_stale(fd);
4166                                         return -ENOTSOCK;
4167                                 } else {
4168                                         SWRAP_LOG(SWRAP_LOG_ERROR,
4169                                                   "swrap_recvmsg_before failed");
4170                                         return -1;
4171                                 }
4172                         }
4173                 }
4174                 break;
4175         default:
4176                 errno = EHOSTUNREACH;
4177                 return -1;
4178         }
4179
4180         return 0;
4181 }
4182
4183 static int swrap_recvmsg_after(int fd,
4184                                struct socket_info *si,
4185                                struct msghdr *msg,
4186                                const struct sockaddr_un *un_addr,
4187                                socklen_t un_addrlen,
4188                                ssize_t ret)
4189 {
4190         int saved_errno = errno;
4191         size_t i;
4192         uint8_t *buf = NULL;
4193         off_t ofs = 0;
4194         size_t avail = 0;
4195         size_t remain;
4196         int rc;
4197
4198         /* to give better errors */
4199         if (ret == -1) {
4200                 if (saved_errno == ENOENT) {
4201                         saved_errno = EHOSTUNREACH;
4202                 } else if (saved_errno == ENOTSOCK) {
4203                         /* If the fd is not a socket, remove it */
4204                         swrap_remove_stale(fd);
4205                 }
4206         }
4207
4208         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
4209                 avail += msg->msg_iov[i].iov_len;
4210         }
4211
4212         /* Convert the socket address before we leave */
4213         if (si->type == SOCK_DGRAM && un_addr != NULL) {
4214                 rc = sockaddr_convert_from_un(si,
4215                                               un_addr,
4216                                               un_addrlen,
4217                                               si->family,
4218                                               msg->msg_name,
4219                                               &msg->msg_namelen);
4220                 if (rc == -1) {
4221                         goto done;
4222                 }
4223         }
4224
4225         if (avail == 0) {
4226                 rc = 0;
4227                 goto done;
4228         }
4229
4230         if (ret == -1) {
4231                 remain = MIN(80, avail);
4232         } else {
4233                 remain = ret;
4234         }
4235
4236         /* we capture it as one single packet */
4237         buf = (uint8_t *)malloc(remain);
4238         if (buf == NULL) {
4239                 /* we just not capture the packet */
4240                 errno = saved_errno;
4241                 return -1;
4242         }
4243
4244         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
4245                 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
4246                 memcpy(buf + ofs,
4247                        msg->msg_iov[i].iov_base,
4248                        this_time);
4249                 ofs += this_time;
4250                 remain -= this_time;
4251         }
4252
4253         switch (si->type) {
4254         case SOCK_STREAM:
4255                 if (ret == -1 && saved_errno != EAGAIN && saved_errno != ENOBUFS) {
4256                         swrap_pcap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
4257                 } else if (ret == 0) { /* END OF FILE */
4258                         swrap_pcap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
4259                 } else if (ret > 0) {
4260                         swrap_pcap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
4261                 }
4262                 break;
4263
4264         case SOCK_DGRAM:
4265                 if (ret == -1) {
4266                         break;
4267                 }
4268
4269                 if (un_addr != NULL) {
4270                         swrap_pcap_dump_packet(si,
4271                                           msg->msg_name,
4272                                           SWRAP_RECVFROM,
4273                                           buf,
4274                                           ret);
4275                 } else {
4276                         swrap_pcap_dump_packet(si,
4277                                           msg->msg_name,
4278                                           SWRAP_RECV,
4279                                           buf,
4280                                           ret);
4281                 }
4282
4283                 break;
4284         }
4285
4286         rc = 0;
4287 done:
4288         free(buf);
4289         errno = saved_errno;
4290
4291 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4292         if (rc == 0 &&
4293             msg->msg_controllen > 0 &&
4294             msg->msg_control != NULL) {
4295                 rc = swrap_msghdr_add_socket_info(si, msg);
4296                 if (rc < 0) {
4297                         return -1;
4298                 }
4299         }
4300 #endif
4301
4302         return rc;
4303 }
4304
4305 /****************************************************************************
4306  *   RECVFROM
4307  ***************************************************************************/
4308
4309 static ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags,
4310                               struct sockaddr *from, socklen_t *fromlen)
4311 {
4312         struct swrap_address from_addr = {
4313                 .sa_socklen = sizeof(struct sockaddr_un),
4314         };
4315         ssize_t ret;
4316         struct socket_info *si = find_socket_info(s);
4317         struct swrap_address saddr = {
4318                 .sa_socklen = sizeof(struct sockaddr_storage),
4319         };
4320         struct msghdr msg;
4321         struct iovec tmp;
4322         int tret;
4323
4324         if (!si) {
4325                 return libc_recvfrom(s,
4326                                      buf,
4327                                      len,
4328                                      flags,
4329                                      from,
4330                                      fromlen);
4331         }
4332
4333         tmp.iov_base = buf;
4334         tmp.iov_len = len;
4335
4336         ZERO_STRUCT(msg);
4337         if (from != NULL && fromlen != NULL) {
4338                 msg.msg_name = from;   /* optional address */
4339                 msg.msg_namelen = *fromlen; /* size of address */
4340         } else {
4341                 msg.msg_name = &saddr.sa.s; /* optional address */
4342                 msg.msg_namelen = saddr.sa_socklen; /* size of address */
4343         }
4344         msg.msg_iov = &tmp;            /* scatter/gather array */
4345         msg.msg_iovlen = 1;            /* # elements in msg_iov */
4346 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4347         msg.msg_control = NULL;        /* ancillary data, see below */
4348         msg.msg_controllen = 0;        /* ancillary data buffer len */
4349         msg.msg_flags = 0;             /* flags on received message */
4350 #endif
4351
4352         tret = swrap_recvmsg_before(s, si, &msg, &tmp);
4353         if (tret < 0) {
4354                 return -1;
4355         }
4356
4357         buf = msg.msg_iov[0].iov_base;
4358         len = msg.msg_iov[0].iov_len;
4359
4360         ret = libc_recvfrom(s,
4361                             buf,
4362                             len,
4363                             flags,
4364                             &from_addr.sa.s,
4365                             &from_addr.sa_socklen);
4366         if (ret == -1) {
4367                 return ret;
4368         }
4369
4370         tret = swrap_recvmsg_after(s,
4371                                    si,
4372                                    &msg,
4373                                    &from_addr.sa.un,
4374                                    from_addr.sa_socklen,
4375                                    ret);
4376         if (tret != 0) {
4377                 return tret;
4378         }
4379
4380         if (from != NULL && fromlen != NULL) {
4381                 *fromlen = msg.msg_namelen;
4382         }
4383
4384         return ret;
4385 }
4386
4387 #ifdef HAVE_ACCEPT_PSOCKLEN_T
4388 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
4389                  struct sockaddr *from, Psocklen_t fromlen)
4390 #else
4391 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
4392                  struct sockaddr *from, socklen_t *fromlen)
4393 #endif
4394 {
4395         return swrap_recvfrom(s, buf, len, flags, from, (socklen_t *)fromlen);
4396 }
4397
4398 /****************************************************************************
4399  *   SENDTO
4400  ***************************************************************************/
4401
4402 static ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags,
4403                             const struct sockaddr *to, socklen_t tolen)
4404 {
4405         struct msghdr msg;
4406         struct iovec tmp;
4407         struct swrap_address un_addr = {
4408                 .sa_socklen = sizeof(struct sockaddr_un),
4409         };
4410         const struct sockaddr_un *to_un = NULL;
4411         ssize_t ret;
4412         int rc;
4413         struct socket_info *si = find_socket_info(s);
4414         int bcast = 0;
4415
4416         if (!si) {
4417                 return libc_sendto(s, buf, len, flags, to, tolen);
4418         }
4419
4420         tmp.iov_base = discard_const_p(char, buf);
4421         tmp.iov_len = len;
4422
4423         ZERO_STRUCT(msg);
4424         msg.msg_name = discard_const_p(struct sockaddr, to); /* optional address */
4425         msg.msg_namelen = tolen;       /* size of address */
4426         msg.msg_iov = &tmp;            /* scatter/gather array */
4427         msg.msg_iovlen = 1;            /* # elements in msg_iov */
4428 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
4429         msg.msg_control = NULL;        /* ancillary data, see below */
4430         msg.msg_controllen = 0;        /* ancillary data buffer len */
4431         msg.msg_flags = 0;             /* flags on received message */
4432 #endif
4433
4434         rc = swrap_sendmsg_before(s,
4435                                   si,
4436                                   &msg,
4437                                   &tmp,
4438                                   &un_addr.sa.un,
4439                                   &to_un,
4440                                   &to,
4441                                   &bcast);
4442         if (rc < 0) {
4443                 return -1;
4444         }
4445
4446         buf = msg.msg_iov[0].iov_base;
4447         len = msg.msg_iov[0].iov_len;
4448
4449         if (bcast) {
4450                 struct stat st;
4451                 unsigned int iface;
4452                 unsigned int prt = ntohs(((const struct sockaddr_in *)(const void *)to)->sin_port);
4453                 char type;
4454
4455                 type = SOCKET_TYPE_CHAR_UDP;
4456
4457                 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
4458                         snprintf(un_addr.sa.un.sun_path,
4459                                  sizeof(un_addr.sa.un.sun_path),
4460                                  "%s/"SOCKET_FORMAT,
4461                                  socket_wrapper_dir(), type, iface, prt);
4462                         if (stat(un_addr.sa.un.sun_path, &st) != 0) continue;
4463
4464                         /* ignore the any errors in broadcast sends */
4465                         libc_sendto(s,
4466                                     buf,
4467                                     len,
4468                                     flags,
4469                                     &un_addr.sa.s,
4470                                     un_addr.sa_socklen);
4471                 }
4472
4473                 swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
4474
4475                 return len;
4476         }
4477
4478         /*
4479          * If it is a dgram socket and we are connected, don't include the
4480          * 'to' address.
4481          */
4482         if (si->type == SOCK_DGRAM && si->connected) {
4483                 ret = libc_sendto(s,
4484                                   buf,
4485                                   len,
4486                                   flags,
4487                                   NULL,
4488                                   0);
4489         } else {
4490                 ret = libc_sendto(s,
4491                                   buf,
4492                                   len,
4493                                   flags,
4494                                   (struct sockaddr *)msg.msg_name,
4495                                   msg.msg_namelen);
4496         }
4497
4498         swrap_sendmsg_after(s, si, &msg, to, ret);
4499
4500         return ret;
4501 }
4502
4503 ssize_t sendto(int s, const void *buf, size_t len, int flags,
4504                const struct sockaddr *to, socklen_t tolen)
4505 {
4506         return swrap_sendto(s, buf, len, flags, to, tolen);
4507 }
4508
4509 /****************************************************************************
4510  *   READV
4511  ***************************************************************************/
4512
4513 static ssize_t swrap_recv(int s, void *buf, size_t len, int flags)
4514 {
4515         struct socket_info *si;
4516         struct msghdr msg;
4517         struct swrap_address saddr = {
4518                 .sa_socklen = sizeof(struct sockaddr_storage),
4519         };
4520         struct iovec tmp;
4521         ssize_t ret;
4522         int tret;
4523
4524         si = find_socket_info(s);
4525         if (si == NULL) {
4526                 return libc_recv(s, buf, len, flags);
4527         }
4528
4529         tmp.iov_base = buf;
4530         tmp.iov_len = len;
4531
4532         ZERO_STRUCT(msg);
4533         msg.msg_name = &saddr.sa.s;    /* optional address */
4534         msg.msg_namelen = saddr.sa_socklen; /* size of address */
4535         msg.msg_iov = &tmp;            /* scatter/gather array */
4536         msg.msg_iovlen = 1;            /* # elements in msg_iov */
4537 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4538         msg.msg_control = NULL;        /* ancillary data, see below */
4539         msg.msg_controllen = 0;        /* ancillary data buffer len */
4540         msg.msg_flags = 0;             /* flags on received message */
4541 #endif
4542
4543         tret = swrap_recvmsg_before(s, si, &msg, &tmp);
4544         if (tret < 0) {
4545                 return -1;
4546         }
4547
4548         buf = msg.msg_iov[0].iov_base;
4549         len = msg.msg_iov[0].iov_len;
4550
4551         ret = libc_recv(s, buf, len, flags);
4552
4553         tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
4554         if (tret != 0) {
4555                 return tret;
4556         }
4557
4558         return ret;
4559 }
4560
4561 ssize_t recv(int s, void *buf, size_t len, int flags)
4562 {
4563         return swrap_recv(s, buf, len, flags);
4564 }
4565
4566 /****************************************************************************
4567  *   READ
4568  ***************************************************************************/
4569
4570 static ssize_t swrap_read(int s, void *buf, size_t len)
4571 {
4572         struct socket_info *si;
4573         struct msghdr msg;
4574         struct iovec tmp;
4575         struct swrap_address saddr = {
4576                 .sa_socklen = sizeof(struct sockaddr_storage),
4577         };
4578         ssize_t ret;
4579         int tret;
4580
4581         si = find_socket_info(s);
4582         if (si == NULL) {
4583                 return libc_read(s, buf, len);
4584         }
4585
4586         tmp.iov_base = buf;
4587         tmp.iov_len = len;
4588
4589         ZERO_STRUCT(msg);
4590         msg.msg_name = &saddr.sa.ss;   /* optional address */
4591         msg.msg_namelen = saddr.sa_socklen; /* size of address */
4592         msg.msg_iov = &tmp;            /* scatter/gather array */
4593         msg.msg_iovlen = 1;            /* # elements in msg_iov */
4594 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4595         msg.msg_control = NULL;        /* ancillary data, see below */
4596         msg.msg_controllen = 0;        /* ancillary data buffer len */
4597         msg.msg_flags = 0;             /* flags on received message */
4598 #endif
4599
4600         tret = swrap_recvmsg_before(s, si, &msg, &tmp);
4601         if (tret < 0) {
4602                 if (tret == -ENOTSOCK) {
4603                         return libc_read(s, buf, len);
4604                 }
4605                 return -1;
4606         }
4607
4608         buf = msg.msg_iov[0].iov_base;
4609         len = msg.msg_iov[0].iov_len;
4610
4611         ret = libc_read(s, buf, len);
4612
4613         tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
4614         if (tret != 0) {
4615                 return tret;
4616         }
4617
4618         return ret;
4619 }
4620
4621 ssize_t read(int s, void *buf, size_t len)
4622 {
4623         return swrap_read(s, buf, len);
4624 }
4625
4626 /****************************************************************************
4627  *   WRITE
4628  ***************************************************************************/
4629
4630 static ssize_t swrap_write(int s, const void *buf, size_t len)
4631 {
4632         struct msghdr msg;
4633         struct iovec tmp;
4634         struct sockaddr_un un_addr;
4635         ssize_t ret;
4636         int rc;
4637         struct socket_info *si;
4638
4639         si = find_socket_info(s);
4640         if (si == NULL) {
4641                 return libc_write(s, buf, len);
4642         }
4643
4644         tmp.iov_base = discard_const_p(char, buf);
4645         tmp.iov_len = len;
4646
4647         ZERO_STRUCT(msg);
4648         msg.msg_name = NULL;           /* optional address */
4649         msg.msg_namelen = 0;           /* size of address */
4650         msg.msg_iov = &tmp;            /* scatter/gather array */
4651         msg.msg_iovlen = 1;            /* # elements in msg_iov */
4652 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
4653         msg.msg_control = NULL;        /* ancillary data, see below */
4654         msg.msg_controllen = 0;        /* ancillary data buffer len */
4655         msg.msg_flags = 0;             /* flags on received message */
4656 #endif
4657
4658         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
4659         if (rc < 0) {
4660                 return -1;
4661         }
4662
4663         buf = msg.msg_iov[0].iov_base;
4664         len = msg.msg_iov[0].iov_len;
4665
4666         ret = libc_write(s, buf, len);
4667
4668         swrap_sendmsg_after(s, si, &msg, NULL, ret);
4669
4670         return ret;
4671 }
4672
4673 ssize_t write(int s, const void *buf, size_t len)
4674 {
4675         return swrap_write(s, buf, len);
4676 }
4677
4678 /****************************************************************************
4679  *   SEND
4680  ***************************************************************************/
4681
4682 static ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
4683 {
4684         struct msghdr msg;
4685         struct iovec tmp;
4686         struct sockaddr_un un_addr;
4687         ssize_t ret;
4688         int rc;
4689         struct socket_info *si = find_socket_info(s);
4690
4691         if (!si) {
4692                 return libc_send(s, buf, len, flags);
4693         }
4694
4695         tmp.iov_base = discard_const_p(char, buf);
4696         tmp.iov_len = len;
4697
4698         ZERO_STRUCT(msg);
4699         msg.msg_name = NULL;           /* optional address */
4700         msg.msg_namelen = 0;           /* size of address */
4701         msg.msg_iov = &tmp;            /* scatter/gather array */
4702         msg.msg_iovlen = 1;            /* # elements in msg_iov */
4703 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
4704         msg.msg_control = NULL;        /* ancillary data, see below */
4705         msg.msg_controllen = 0;        /* ancillary data buffer len */
4706         msg.msg_flags = 0;             /* flags on received message */
4707 #endif
4708
4709         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
4710         if (rc < 0) {
4711                 return -1;
4712         }
4713
4714         buf = msg.msg_iov[0].iov_base;
4715         len = msg.msg_iov[0].iov_len;
4716
4717         ret = libc_send(s, buf, len, flags);
4718
4719         swrap_sendmsg_after(s, si, &msg, NULL, ret);
4720
4721         return ret;
4722 }
4723
4724 ssize_t send(int s, const void *buf, size_t len, int flags)
4725 {
4726         return swrap_send(s, buf, len, flags);
4727 }
4728
4729 /****************************************************************************
4730  *   RECVMSG
4731  ***************************************************************************/
4732
4733 static ssize_t swrap_recvmsg(int s, struct msghdr *omsg, int flags)
4734 {
4735         struct swrap_address from_addr = {
4736                 .sa_socklen = sizeof(struct sockaddr_un),
4737         };
4738         struct swrap_address convert_addr = {
4739                 .sa_socklen = sizeof(struct sockaddr_storage),
4740         };
4741         struct socket_info *si;
4742         struct msghdr msg;
4743         struct iovec tmp;
4744 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4745         size_t msg_ctrllen_filled;
4746         size_t msg_ctrllen_left;
4747 #endif
4748
4749         ssize_t ret;
4750         int rc;
4751
4752         si = find_socket_info(s);
4753         if (si == NULL) {
4754                 return libc_recvmsg(s, omsg, flags);
4755         }
4756
4757         tmp.iov_base = NULL;
4758         tmp.iov_len = 0;
4759
4760         ZERO_STRUCT(msg);
4761         msg.msg_name = &from_addr.sa;              /* optional address */
4762         msg.msg_namelen = from_addr.sa_socklen;    /* size of address */
4763         msg.msg_iov = omsg->msg_iov;               /* scatter/gather array */
4764         msg.msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
4765 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4766         msg_ctrllen_filled = 0;
4767         msg_ctrllen_left = omsg->msg_controllen;
4768
4769         msg.msg_control = omsg->msg_control;       /* ancillary data, see below */
4770         msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
4771         msg.msg_flags = omsg->msg_flags;           /* flags on received message */
4772 #endif
4773
4774         rc = swrap_recvmsg_before(s, si, &msg, &tmp);
4775         if (rc < 0) {
4776                 return -1;
4777         }
4778
4779         ret = libc_recvmsg(s, &msg, flags);
4780
4781 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4782         msg_ctrllen_filled += msg.msg_controllen;
4783         msg_ctrllen_left -= msg.msg_controllen;
4784
4785         if (omsg->msg_control != NULL) {
4786                 uint8_t *p;
4787
4788                 p = omsg->msg_control;
4789                 p += msg_ctrllen_filled;
4790
4791                 msg.msg_control = p;
4792                 msg.msg_controllen = msg_ctrllen_left;
4793         } else {
4794                 msg.msg_control = NULL;
4795                 msg.msg_controllen = 0;
4796         }
4797 #endif
4798
4799         /*
4800          * We convert the unix address to a IP address so we need a buffer
4801          * which can store the address in case of SOCK_DGRAM, see below.
4802          */
4803         msg.msg_name = &convert_addr.sa;
4804         msg.msg_namelen = convert_addr.sa_socklen;
4805
4806         rc = swrap_recvmsg_after(s,
4807                                  si,
4808                                  &msg,
4809                                  &from_addr.sa.un,
4810                                  from_addr.sa_socklen,
4811                                  ret);
4812         if (rc != 0) {
4813                 return rc;
4814         }
4815
4816 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4817         if (omsg->msg_control != NULL) {
4818                 /* msg.msg_controllen = space left */
4819                 msg_ctrllen_left = msg.msg_controllen;
4820                 msg_ctrllen_filled = omsg->msg_controllen - msg_ctrllen_left;
4821         }
4822
4823         /* Update the original message length */
4824         omsg->msg_controllen = msg_ctrllen_filled;
4825         omsg->msg_flags = msg.msg_flags;
4826 #endif
4827         omsg->msg_iovlen = msg.msg_iovlen;
4828
4829         /*
4830          * From the manpage:
4831          *
4832          * The  msg_name  field  points  to a caller-allocated buffer that is
4833          * used to return the source address if the socket is unconnected.  The
4834          * caller should set msg_namelen to the size of this buffer before this
4835          * call; upon return from a successful call, msg_name will contain the
4836          * length of the returned address.  If the application  does  not  need
4837          * to know the source address, msg_name can be specified as NULL.
4838          */
4839         if (si->type == SOCK_STREAM) {
4840                 omsg->msg_namelen = 0;
4841         } else if (omsg->msg_name != NULL &&
4842                    omsg->msg_namelen != 0 &&
4843                    omsg->msg_namelen >= msg.msg_namelen) {
4844                 memcpy(omsg->msg_name, msg.msg_name, msg.msg_namelen);
4845                 omsg->msg_namelen = msg.msg_namelen;
4846         }
4847
4848         return ret;
4849 }
4850
4851 ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)
4852 {
4853         return swrap_recvmsg(sockfd, msg, flags);
4854 }
4855
4856 /****************************************************************************
4857  *   SENDMSG
4858  ***************************************************************************/
4859
4860 static ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags)
4861 {
4862         struct msghdr msg;
4863         struct iovec tmp;
4864         struct sockaddr_un un_addr;
4865         const struct sockaddr_un *to_un = NULL;
4866         const struct sockaddr *to = NULL;
4867         ssize_t ret;
4868         int rc;
4869         struct socket_info *si = find_socket_info(s);
4870         int bcast = 0;
4871
4872         if (!si) {
4873                 return libc_sendmsg(s, omsg, flags);
4874         }
4875
4876         ZERO_STRUCT(un_addr);
4877
4878         tmp.iov_base = NULL;
4879         tmp.iov_len = 0;
4880
4881         ZERO_STRUCT(msg);
4882
4883         if (si->connected == 0) {
4884                 msg.msg_name = omsg->msg_name;             /* optional address */
4885                 msg.msg_namelen = omsg->msg_namelen;       /* size of address */
4886         }
4887         msg.msg_iov = omsg->msg_iov;               /* scatter/gather array */
4888         msg.msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
4889 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4890         if (msg.msg_controllen > 0 && msg.msg_control != NULL) {
4891                 /* omsg is a const so use a local buffer for modifications */
4892                 uint8_t cmbuf[omsg->msg_controllen];
4893
4894                 memcpy(cmbuf, omsg->msg_control, omsg->msg_controllen);
4895
4896                 msg.msg_control = cmbuf;       /* ancillary data, see below */
4897                 msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
4898         }
4899         msg.msg_flags = omsg->msg_flags;           /* flags on received message */
4900 #endif
4901
4902         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
4903         if (rc < 0) {
4904                 return -1;
4905         }
4906
4907         if (bcast) {
4908                 struct stat st;
4909                 unsigned int iface;
4910                 unsigned int prt = ntohs(((const struct sockaddr_in *)(const void *)to)->sin_port);
4911                 char type;
4912                 size_t i, len = 0;
4913                 uint8_t *buf;
4914                 off_t ofs = 0;
4915                 size_t avail = 0;
4916                 size_t remain;
4917
4918                 for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
4919                         avail += msg.msg_iov[i].iov_len;
4920                 }
4921
4922                 len = avail;
4923                 remain = avail;
4924
4925                 /* we capture it as one single packet */
4926                 buf = (uint8_t *)malloc(remain);
4927                 if (!buf) {
4928                         return -1;
4929                 }
4930
4931                 for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
4932                         size_t this_time = MIN(remain, (size_t)msg.msg_iov[i].iov_len);
4933                         memcpy(buf + ofs,
4934                                msg.msg_iov[i].iov_base,
4935                                this_time);
4936                         ofs += this_time;
4937                         remain -= this_time;
4938                 }
4939
4940                 type = SOCKET_TYPE_CHAR_UDP;
4941
4942                 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
4943                         snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT,
4944                                  socket_wrapper_dir(), type, iface, prt);
4945                         if (stat(un_addr.sun_path, &st) != 0) continue;
4946
4947                         msg.msg_name = &un_addr;           /* optional address */
4948                         msg.msg_namelen = sizeof(un_addr); /* size of address */
4949
4950                         /* ignore the any errors in broadcast sends */
4951                         libc_sendmsg(s, &msg, flags);
4952                 }
4953
4954                 swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
4955                 free(buf);
4956
4957                 return len;
4958         }
4959
4960         ret = libc_sendmsg(s, &msg, flags);
4961
4962         swrap_sendmsg_after(s, si, &msg, to, ret);
4963
4964         return ret;
4965 }
4966
4967 ssize_t sendmsg(int s, const struct msghdr *omsg, int flags)
4968 {
4969         return swrap_sendmsg(s, omsg, flags);
4970 }
4971
4972 /****************************************************************************
4973  *   READV
4974  ***************************************************************************/
4975
4976 static ssize_t swrap_readv(int s, const struct iovec *vector, int count)
4977 {
4978         struct socket_info *si;
4979         struct msghdr msg;
4980         struct iovec tmp;
4981         struct swrap_address saddr = {
4982                 .sa_socklen = sizeof(struct sockaddr_storage)
4983         };
4984         ssize_t ret;
4985         int rc;
4986
4987         si = find_socket_info(s);
4988         if (si == NULL) {
4989                 return libc_readv(s, vector, count);
4990         }
4991
4992         tmp.iov_base = NULL;
4993         tmp.iov_len = 0;
4994
4995         ZERO_STRUCT(msg);
4996         msg.msg_name = &saddr.sa.s; /* optional address */
4997         msg.msg_namelen = saddr.sa_socklen;      /* size of address */
4998         msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
4999         msg.msg_iovlen = count;        /* # elements in msg_iov */
5000 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5001         msg.msg_control = NULL;        /* ancillary data, see below */
5002         msg.msg_controllen = 0;        /* ancillary data buffer len */
5003         msg.msg_flags = 0;             /* flags on received message */
5004 #endif
5005
5006         rc = swrap_recvmsg_before(s, si, &msg, &tmp);
5007         if (rc < 0) {
5008                 if (rc == -ENOTSOCK) {
5009                         return libc_readv(s, vector, count);
5010                 }
5011                 return -1;
5012         }
5013
5014         ret = libc_readv(s, msg.msg_iov, msg.msg_iovlen);
5015
5016         rc = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
5017         if (rc != 0) {
5018                 return rc;
5019         }
5020
5021         return ret;
5022 }
5023
5024 ssize_t readv(int s, const struct iovec *vector, int count)
5025 {
5026         return swrap_readv(s, vector, count);
5027 }
5028
5029 /****************************************************************************
5030  *   WRITEV
5031  ***************************************************************************/
5032
5033 static ssize_t swrap_writev(int s, const struct iovec *vector, int count)
5034 {
5035         struct msghdr msg;
5036         struct iovec tmp;
5037         struct sockaddr_un un_addr;
5038         ssize_t ret;
5039         int rc;
5040         struct socket_info *si = find_socket_info(s);
5041
5042         if (!si) {
5043                 return libc_writev(s, vector, count);
5044         }
5045
5046         tmp.iov_base = NULL;
5047         tmp.iov_len = 0;
5048
5049         ZERO_STRUCT(msg);
5050         msg.msg_name = NULL;           /* optional address */
5051         msg.msg_namelen = 0;           /* size of address */
5052         msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
5053         msg.msg_iovlen = count;        /* # elements in msg_iov */
5054 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
5055         msg.msg_control = NULL;        /* ancillary data, see below */
5056         msg.msg_controllen = 0;        /* ancillary data buffer len */
5057         msg.msg_flags = 0;             /* flags on received message */
5058 #endif
5059
5060         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
5061         if (rc < 0) {
5062                 if (rc == -ENOTSOCK) {
5063                         return libc_readv(s, vector, count);
5064                 }
5065                 return -1;
5066         }
5067
5068         ret = libc_writev(s, msg.msg_iov, msg.msg_iovlen);
5069
5070         swrap_sendmsg_after(s, si, &msg, NULL, ret);
5071
5072         return ret;
5073 }
5074
5075 ssize_t writev(int s, const struct iovec *vector, int count)
5076 {
5077         return swrap_writev(s, vector, count);
5078 }
5079
5080 /****************************
5081  * CLOSE
5082  ***************************/
5083
5084 static int swrap_close(int fd)
5085 {
5086         struct socket_info *si = find_socket_info(fd);
5087         struct socket_info_fd *fi;
5088         int ret;
5089
5090         if (!si) {
5091                 return libc_close(fd);
5092         }
5093
5094         for (fi = si->fds; fi; fi = fi->next) {
5095                 if (fi->fd == fd) {
5096                         SWRAP_DLIST_REMOVE(si->fds, fi);
5097                         free(fi);
5098                         break;
5099                 }
5100         }
5101
5102         if (si->fds) {
5103                 /* there are still references left */
5104                 return libc_close(fd);
5105         }
5106
5107         SWRAP_DLIST_REMOVE(sockets, si);
5108
5109         if (si->myname.sa_socklen > 0 && si->peername.sa_socklen > 0) {
5110                 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0);
5111         }
5112
5113         ret = libc_close(fd);
5114
5115         if (si->myname.sa_socklen > 0 && si->peername.sa_socklen > 0) {
5116                 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0);
5117                 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0);
5118         }
5119
5120         if (si->un_addr.sun_path[0] != '\0') {
5121                 unlink(si->un_addr.sun_path);
5122         }
5123         free(si);
5124
5125         return ret;
5126 }
5127
5128 int close(int fd)
5129 {
5130         return swrap_close(fd);
5131 }
5132
5133 /****************************
5134  * DUP
5135  ***************************/
5136
5137 static int swrap_dup(int fd)
5138 {
5139         struct socket_info *si;
5140         struct socket_info_fd *fi;
5141
5142         si = find_socket_info(fd);
5143
5144         if (!si) {
5145                 return libc_dup(fd);
5146         }
5147
5148         fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
5149         if (fi == NULL) {
5150                 errno = ENOMEM;
5151                 return -1;
5152         }
5153
5154         fi->fd = libc_dup(fd);
5155         if (fi->fd == -1) {
5156                 int saved_errno = errno;
5157                 free(fi);
5158                 errno = saved_errno;
5159                 return -1;
5160         }
5161
5162         /* Make sure we don't have an entry for the fd */
5163         swrap_remove_stale(fi->fd);
5164
5165         SWRAP_DLIST_ADD(si->fds, fi);
5166         return fi->fd;
5167 }
5168
5169 int dup(int fd)
5170 {
5171         return swrap_dup(fd);
5172 }
5173
5174 /****************************
5175  * DUP2
5176  ***************************/
5177
5178 static int swrap_dup2(int fd, int newfd)
5179 {
5180         struct socket_info *si;
5181         struct socket_info_fd *fi;
5182
5183         si = find_socket_info(fd);
5184
5185         if (!si) {
5186                 return libc_dup2(fd, newfd);
5187         }
5188
5189         if (fd == newfd) {
5190                 /*
5191                  * According to the manpage:
5192                  *
5193                  * "If oldfd is a valid file descriptor, and newfd has the same
5194                  * value as oldfd, then dup2() does nothing, and returns newfd."
5195                  */
5196                 return newfd;
5197         }
5198
5199         if (find_socket_info(newfd)) {
5200                 /* dup2() does an implicit close of newfd, which we
5201                  * need to emulate */
5202                 swrap_close(newfd);
5203         }
5204
5205         fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
5206         if (fi == NULL) {
5207                 errno = ENOMEM;
5208                 return -1;
5209         }
5210
5211         fi->fd = libc_dup2(fd, newfd);
5212         if (fi->fd == -1) {
5213                 int saved_errno = errno;
5214                 free(fi);
5215                 errno = saved_errno;
5216                 return -1;
5217         }
5218
5219         /* Make sure we don't have an entry for the fd */
5220         swrap_remove_stale(fi->fd);
5221
5222         SWRAP_DLIST_ADD(si->fds, fi);
5223         return fi->fd;
5224 }
5225
5226 int dup2(int fd, int newfd)
5227 {
5228         return swrap_dup2(fd, newfd);
5229 }
5230
5231 /****************************
5232  * FCNTL
5233  ***************************/
5234
5235 static int swrap_vfcntl(int fd, int cmd, va_list va)
5236 {
5237         struct socket_info_fd *fi;
5238         struct socket_info *si;
5239         int rc;
5240
5241         si = find_socket_info(fd);
5242         if (si == NULL) {
5243                 rc = libc_vfcntl(fd, cmd, va);
5244
5245                 return rc;
5246         }
5247
5248         switch (cmd) {
5249         case F_DUPFD:
5250                 fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
5251                 if (fi == NULL) {
5252                         errno = ENOMEM;
5253                         return -1;
5254                 }
5255
5256                 fi->fd = libc_vfcntl(fd, cmd, va);
5257                 if (fi->fd == -1) {
5258                         int saved_errno = errno;
5259                         free(fi);
5260                         errno = saved_errno;
5261                         return -1;
5262                 }
5263
5264                 /* Make sure we don't have an entry for the fd */
5265                 swrap_remove_stale(fi->fd);
5266
5267                 SWRAP_DLIST_ADD(si->fds, fi);
5268
5269                 rc = fi->fd;
5270                 break;
5271         default:
5272                 rc = libc_vfcntl(fd, cmd, va);
5273                 break;
5274         }
5275
5276         return rc;
5277 }
5278
5279 int fcntl(int fd, int cmd, ...)
5280 {
5281         va_list va;
5282         int rc;
5283
5284         va_start(va, cmd);
5285
5286         rc = swrap_vfcntl(fd, cmd, va);
5287
5288         va_end(va);
5289
5290         return rc;
5291 }
5292
5293 /****************************
5294  * EVENTFD
5295  ***************************/
5296
5297 #ifdef HAVE_EVENTFD
5298 static int swrap_eventfd(int count, int flags)
5299 {
5300         int fd;
5301
5302         fd = libc_eventfd(count, flags);
5303         if (fd != -1) {
5304                 swrap_remove_stale(fd);
5305         }
5306
5307         return fd;
5308 }
5309
5310 #ifdef HAVE_EVENTFD_UNSIGNED_INT
5311 int eventfd(unsigned int count, int flags)
5312 #else
5313 int eventfd(int count, int flags)
5314 #endif
5315 {
5316         return swrap_eventfd(count, flags);
5317 }
5318 #endif
5319
5320 #ifdef HAVE_PLEDGE
5321 int pledge(const char *promises, const char *paths[])
5322 {
5323         (void)promises; /* unused */
5324         (void)paths; /* unused */
5325
5326         return 0;
5327 }
5328 #endif /* HAVE_PLEDGE */
5329
5330 /****************************
5331  * DESTRUCTOR
5332  ***************************/
5333
5334 /*
5335  * This function is called when the library is unloaded and makes sure that
5336  * sockets get closed and the unix file for the socket are unlinked.
5337  */
5338 void swrap_destructor(void)
5339 {
5340         struct socket_info *s = sockets;
5341
5342         while (s != NULL) {
5343                 struct socket_info_fd *f = s->fds;
5344                 if (f != NULL) {
5345                         swrap_close(f->fd);
5346                 }
5347                 s = sockets;
5348         }
5349
5350         if (swrap.libc_handle != NULL) {
5351                 dlclose(swrap.libc_handle);
5352         }
5353         if (swrap.libsocket_handle) {
5354                 dlclose(swrap.libsocket_handle);
5355         }
5356 }