repl_meta_data: Allow delete of an object with dangling backlinks
[samba.git] / third_party / socket_wrapper / 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                 for (fi = si->fds; fi; fi = fi->next) {
1474                         if (fi->fd == fd) {
1475                                 SWRAP_LOG(SWRAP_LOG_TRACE, "remove stale wrapper for %d", fd);
1476                                 SWRAP_DLIST_REMOVE(si->fds, fi);
1477                                 free(fi);
1478                                 break;
1479                         }
1480                 }
1481
1482                 if (si->fds == NULL) {
1483                         SWRAP_DLIST_REMOVE(sockets, si);
1484                         if (si->un_addr.sun_path[0] != '\0') {
1485                                 unlink(si->un_addr.sun_path);
1486                         }
1487                         free(si);
1488                 }
1489         }
1490 }
1491
1492 static int sockaddr_convert_to_un(struct socket_info *si,
1493                                   const struct sockaddr *in_addr,
1494                                   socklen_t in_len,
1495                                   struct sockaddr_un *out_addr,
1496                                   int alloc_sock,
1497                                   int *bcast)
1498 {
1499         struct sockaddr *out = (struct sockaddr *)(void *)out_addr;
1500
1501         (void) in_len; /* unused */
1502
1503         if (out_addr == NULL) {
1504                 return 0;
1505         }
1506
1507         out->sa_family = AF_UNIX;
1508 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
1509         out->sa_len = sizeof(*out_addr);
1510 #endif
1511
1512         switch (in_addr->sa_family) {
1513         case AF_UNSPEC: {
1514                 const struct sockaddr_in *sin;
1515                 if (si->family != AF_INET) {
1516                         break;
1517                 }
1518                 if (in_len < sizeof(struct sockaddr_in)) {
1519                         break;
1520                 }
1521                 sin = (const struct sockaddr_in *)(const void *)in_addr;
1522                 if(sin->sin_addr.s_addr != htonl(INADDR_ANY)) {
1523                         break;
1524                 }
1525
1526                 /*
1527                  * Note: in the special case of AF_UNSPEC and INADDR_ANY,
1528                  * AF_UNSPEC is mapped to AF_INET and must be treated here.
1529                  */
1530
1531                 /* FALL THROUGH */
1532         }
1533         case AF_INET:
1534 #ifdef HAVE_IPV6
1535         case AF_INET6:
1536 #endif
1537                 switch (si->type) {
1538                 case SOCK_STREAM:
1539                 case SOCK_DGRAM:
1540                         break;
1541                 default:
1542                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1543                         errno = ESOCKTNOSUPPORT;
1544                         return -1;
1545                 }
1546                 if (alloc_sock) {
1547                         return convert_in_un_alloc(si, in_addr, out_addr, bcast);
1548                 } else {
1549                         return convert_in_un_remote(si, in_addr, out_addr, bcast);
1550                 }
1551         default:
1552                 break;
1553         }
1554
1555         errno = EAFNOSUPPORT;
1556         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n");
1557         return -1;
1558 }
1559
1560 static int sockaddr_convert_from_un(const struct socket_info *si,
1561                                     const struct sockaddr_un *in_addr,
1562                                     socklen_t un_addrlen,
1563                                     int family,
1564                                     struct sockaddr *out_addr,
1565                                     socklen_t *out_addrlen)
1566 {
1567         int ret;
1568
1569         if (out_addr == NULL || out_addrlen == NULL)
1570                 return 0;
1571
1572         if (un_addrlen == 0) {
1573                 *out_addrlen = 0;
1574                 return 0;
1575         }
1576
1577         switch (family) {
1578         case AF_INET:
1579 #ifdef HAVE_IPV6
1580         case AF_INET6:
1581 #endif
1582                 switch (si->type) {
1583                 case SOCK_STREAM:
1584                 case SOCK_DGRAM:
1585                         break;
1586                 default:
1587                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1588                         errno = ESOCKTNOSUPPORT;
1589                         return -1;
1590                 }
1591                 ret = convert_un_in(in_addr, out_addr, out_addrlen);
1592 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
1593                 out_addr->sa_len = *out_addrlen;
1594 #endif
1595                 return ret;
1596         default:
1597                 break;
1598         }
1599
1600         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n");
1601         errno = EAFNOSUPPORT;
1602         return -1;
1603 }
1604
1605 enum swrap_packet_type {
1606         SWRAP_CONNECT_SEND,
1607         SWRAP_CONNECT_UNREACH,
1608         SWRAP_CONNECT_RECV,
1609         SWRAP_CONNECT_ACK,
1610         SWRAP_ACCEPT_SEND,
1611         SWRAP_ACCEPT_RECV,
1612         SWRAP_ACCEPT_ACK,
1613         SWRAP_RECVFROM,
1614         SWRAP_SENDTO,
1615         SWRAP_SENDTO_UNREACH,
1616         SWRAP_PENDING_RST,
1617         SWRAP_RECV,
1618         SWRAP_RECV_RST,
1619         SWRAP_SEND,
1620         SWRAP_SEND_RST,
1621         SWRAP_CLOSE_SEND,
1622         SWRAP_CLOSE_RECV,
1623         SWRAP_CLOSE_ACK,
1624 };
1625
1626 struct swrap_file_hdr {
1627         uint32_t        magic;
1628         uint16_t        version_major;
1629         uint16_t        version_minor;
1630         int32_t         timezone;
1631         uint32_t        sigfigs;
1632         uint32_t        frame_max_len;
1633 #define SWRAP_FRAME_LENGTH_MAX 0xFFFF
1634         uint32_t        link_type;
1635 };
1636 #define SWRAP_FILE_HDR_SIZE 24
1637
1638 struct swrap_packet_frame {
1639         uint32_t seconds;
1640         uint32_t micro_seconds;
1641         uint32_t recorded_length;
1642         uint32_t full_length;
1643 };
1644 #define SWRAP_PACKET_FRAME_SIZE 16
1645
1646 union swrap_packet_ip {
1647         struct {
1648                 uint8_t         ver_hdrlen;
1649                 uint8_t         tos;
1650                 uint16_t        packet_length;
1651                 uint16_t        identification;
1652                 uint8_t         flags;
1653                 uint8_t         fragment;
1654                 uint8_t         ttl;
1655                 uint8_t         protocol;
1656                 uint16_t        hdr_checksum;
1657                 uint32_t        src_addr;
1658                 uint32_t        dest_addr;
1659         } v4;
1660 #define SWRAP_PACKET_IP_V4_SIZE 20
1661         struct {
1662                 uint8_t         ver_prio;
1663                 uint8_t         flow_label_high;
1664                 uint16_t        flow_label_low;
1665                 uint16_t        payload_length;
1666                 uint8_t         next_header;
1667                 uint8_t         hop_limit;
1668                 uint8_t         src_addr[16];
1669                 uint8_t         dest_addr[16];
1670         } v6;
1671 #define SWRAP_PACKET_IP_V6_SIZE 40
1672 };
1673 #define SWRAP_PACKET_IP_SIZE 40
1674
1675 union swrap_packet_payload {
1676         struct {
1677                 uint16_t        source_port;
1678                 uint16_t        dest_port;
1679                 uint32_t        seq_num;
1680                 uint32_t        ack_num;
1681                 uint8_t         hdr_length;
1682                 uint8_t         control;
1683                 uint16_t        window;
1684                 uint16_t        checksum;
1685                 uint16_t        urg;
1686         } tcp;
1687 #define SWRAP_PACKET_PAYLOAD_TCP_SIZE 20
1688         struct {
1689                 uint16_t        source_port;
1690                 uint16_t        dest_port;
1691                 uint16_t        length;
1692                 uint16_t        checksum;
1693         } udp;
1694 #define SWRAP_PACKET_PAYLOAD_UDP_SIZE 8
1695         struct {
1696                 uint8_t         type;
1697                 uint8_t         code;
1698                 uint16_t        checksum;
1699                 uint32_t        unused;
1700         } icmp4;
1701 #define SWRAP_PACKET_PAYLOAD_ICMP4_SIZE 8
1702         struct {
1703                 uint8_t         type;
1704                 uint8_t         code;
1705                 uint16_t        checksum;
1706                 uint32_t        unused;
1707         } icmp6;
1708 #define SWRAP_PACKET_PAYLOAD_ICMP6_SIZE 8
1709 };
1710 #define SWRAP_PACKET_PAYLOAD_SIZE 20
1711
1712 #define SWRAP_PACKET_MIN_ALLOC \
1713         (SWRAP_PACKET_FRAME_SIZE + \
1714          SWRAP_PACKET_IP_SIZE + \
1715          SWRAP_PACKET_PAYLOAD_SIZE)
1716
1717 static const char *swrap_pcap_init_file(void)
1718 {
1719         static int initialized = 0;
1720         static const char *s = NULL;
1721         static const struct swrap_file_hdr h;
1722         static const struct swrap_packet_frame f;
1723         static const union swrap_packet_ip i;
1724         static const union swrap_packet_payload p;
1725
1726         if (initialized == 1) {
1727                 return s;
1728         }
1729         initialized = 1;
1730
1731         /*
1732          * TODO: don't use the structs use plain buffer offsets
1733          *       and PUSH_U8(), PUSH_U16() and PUSH_U32()
1734          *
1735          * for now make sure we disable PCAP support
1736          * if the struct has alignment!
1737          */
1738         if (sizeof(h) != SWRAP_FILE_HDR_SIZE) {
1739                 return NULL;
1740         }
1741         if (sizeof(f) != SWRAP_PACKET_FRAME_SIZE) {
1742                 return NULL;
1743         }
1744         if (sizeof(i) != SWRAP_PACKET_IP_SIZE) {
1745                 return NULL;
1746         }
1747         if (sizeof(i.v4) != SWRAP_PACKET_IP_V4_SIZE) {
1748                 return NULL;
1749         }
1750         if (sizeof(i.v6) != SWRAP_PACKET_IP_V6_SIZE) {
1751                 return NULL;
1752         }
1753         if (sizeof(p) != SWRAP_PACKET_PAYLOAD_SIZE) {
1754                 return NULL;
1755         }
1756         if (sizeof(p.tcp) != SWRAP_PACKET_PAYLOAD_TCP_SIZE) {
1757                 return NULL;
1758         }
1759         if (sizeof(p.udp) != SWRAP_PACKET_PAYLOAD_UDP_SIZE) {
1760                 return NULL;
1761         }
1762         if (sizeof(p.icmp4) != SWRAP_PACKET_PAYLOAD_ICMP4_SIZE) {
1763                 return NULL;
1764         }
1765         if (sizeof(p.icmp6) != SWRAP_PACKET_PAYLOAD_ICMP6_SIZE) {
1766                 return NULL;
1767         }
1768
1769         s = getenv("SOCKET_WRAPPER_PCAP_FILE");
1770         if (s == NULL) {
1771                 return NULL;
1772         }
1773         if (strncmp(s, "./", 2) == 0) {
1774                 s += 2;
1775         }
1776         return s;
1777 }
1778
1779 static uint8_t *swrap_pcap_packet_init(struct timeval *tval,
1780                                        const struct sockaddr *src,
1781                                        const struct sockaddr *dest,
1782                                        int socket_type,
1783                                        const uint8_t *payload,
1784                                        size_t payload_len,
1785                                        unsigned long tcp_seqno,
1786                                        unsigned long tcp_ack,
1787                                        unsigned char tcp_ctl,
1788                                        int unreachable,
1789                                        size_t *_packet_len)
1790 {
1791         uint8_t *base;
1792         uint8_t *buf;
1793         struct swrap_packet_frame *frame;
1794         union swrap_packet_ip *ip;
1795         union swrap_packet_payload *pay;
1796         size_t packet_len;
1797         size_t alloc_len;
1798         size_t nonwire_len = sizeof(*frame);
1799         size_t wire_hdr_len = 0;
1800         size_t wire_len = 0;
1801         size_t ip_hdr_len = 0;
1802         size_t icmp_hdr_len = 0;
1803         size_t icmp_truncate_len = 0;
1804         uint8_t protocol = 0, icmp_protocol = 0;
1805         const struct sockaddr_in *src_in = NULL;
1806         const struct sockaddr_in *dest_in = NULL;
1807 #ifdef HAVE_IPV6
1808         const struct sockaddr_in6 *src_in6 = NULL;
1809         const struct sockaddr_in6 *dest_in6 = NULL;
1810 #endif
1811         uint16_t src_port;
1812         uint16_t dest_port;
1813
1814         switch (src->sa_family) {
1815         case AF_INET:
1816                 src_in = (const struct sockaddr_in *)(const void *)src;
1817                 dest_in = (const struct sockaddr_in *)(const void *)dest;
1818                 src_port = src_in->sin_port;
1819                 dest_port = dest_in->sin_port;
1820                 ip_hdr_len = sizeof(ip->v4);
1821                 break;
1822 #ifdef HAVE_IPV6
1823         case AF_INET6:
1824                 src_in6 = (const struct sockaddr_in6 *)(const void *)src;
1825                 dest_in6 = (const struct sockaddr_in6 *)(const void *)dest;
1826                 src_port = src_in6->sin6_port;
1827                 dest_port = dest_in6->sin6_port;
1828                 ip_hdr_len = sizeof(ip->v6);
1829                 break;
1830 #endif
1831         default:
1832                 return NULL;
1833         }
1834
1835         switch (socket_type) {
1836         case SOCK_STREAM:
1837                 protocol = 0x06; /* TCP */
1838                 wire_hdr_len = ip_hdr_len + sizeof(pay->tcp);
1839                 wire_len = wire_hdr_len + payload_len;
1840                 break;
1841
1842         case SOCK_DGRAM:
1843                 protocol = 0x11; /* UDP */
1844                 wire_hdr_len = ip_hdr_len + sizeof(pay->udp);
1845                 wire_len = wire_hdr_len + payload_len;
1846                 break;
1847
1848         default:
1849                 return NULL;
1850         }
1851
1852         if (unreachable) {
1853                 icmp_protocol = protocol;
1854                 switch (src->sa_family) {
1855                 case AF_INET:
1856                         protocol = 0x01; /* ICMPv4 */
1857                         icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp4);
1858                         break;
1859 #ifdef HAVE_IPV6
1860                 case AF_INET6:
1861                         protocol = 0x3A; /* ICMPv6 */
1862                         icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp6);
1863                         break;
1864 #endif
1865                 }
1866                 if (wire_len > 64 ) {
1867                         icmp_truncate_len = wire_len - 64;
1868                 }
1869                 wire_hdr_len += icmp_hdr_len;
1870                 wire_len += icmp_hdr_len;
1871         }
1872
1873         packet_len = nonwire_len + wire_len;
1874         alloc_len = packet_len;
1875         if (alloc_len < SWRAP_PACKET_MIN_ALLOC) {
1876                 alloc_len = SWRAP_PACKET_MIN_ALLOC;
1877         }
1878
1879         base = (uint8_t *)calloc(1, alloc_len);
1880         if (base == NULL) {
1881                 return NULL;
1882         }
1883
1884         buf = base;
1885
1886         frame = (struct swrap_packet_frame *)(void *)buf;
1887         frame->seconds          = tval->tv_sec;
1888         frame->micro_seconds    = tval->tv_usec;
1889         frame->recorded_length  = wire_len - icmp_truncate_len;
1890         frame->full_length      = wire_len - icmp_truncate_len;
1891         buf += SWRAP_PACKET_FRAME_SIZE;
1892
1893         ip = (union swrap_packet_ip *)(void *)buf;
1894         switch (src->sa_family) {
1895         case AF_INET:
1896                 ip->v4.ver_hdrlen       = 0x45; /* version 4 and 5 * 32 bit words */
1897                 ip->v4.tos              = 0x00;
1898                 ip->v4.packet_length    = htons(wire_len - icmp_truncate_len);
1899                 ip->v4.identification   = htons(0xFFFF);
1900                 ip->v4.flags            = 0x40; /* BIT 1 set - means don't fragment */
1901                 ip->v4.fragment         = htons(0x0000);
1902                 ip->v4.ttl              = 0xFF;
1903                 ip->v4.protocol         = protocol;
1904                 ip->v4.hdr_checksum     = htons(0x0000);
1905                 ip->v4.src_addr         = src_in->sin_addr.s_addr;
1906                 ip->v4.dest_addr        = dest_in->sin_addr.s_addr;
1907                 buf += SWRAP_PACKET_IP_V4_SIZE;
1908                 break;
1909 #ifdef HAVE_IPV6
1910         case AF_INET6:
1911                 ip->v6.ver_prio         = 0x60; /* version 4 and 5 * 32 bit words */
1912                 ip->v6.flow_label_high  = 0x00;
1913                 ip->v6.flow_label_low   = 0x0000;
1914                 ip->v6.payload_length   = htons(wire_len - icmp_truncate_len); /* TODO */
1915                 ip->v6.next_header      = protocol;
1916                 memcpy(ip->v6.src_addr, src_in6->sin6_addr.s6_addr, 16);
1917                 memcpy(ip->v6.dest_addr, dest_in6->sin6_addr.s6_addr, 16);
1918                 buf += SWRAP_PACKET_IP_V6_SIZE;
1919                 break;
1920 #endif
1921         }
1922
1923         if (unreachable) {
1924                 pay = (union swrap_packet_payload *)(void *)buf;
1925                 switch (src->sa_family) {
1926                 case AF_INET:
1927                         pay->icmp4.type         = 0x03; /* destination unreachable */
1928                         pay->icmp4.code         = 0x01; /* host unreachable */
1929                         pay->icmp4.checksum     = htons(0x0000);
1930                         pay->icmp4.unused       = htonl(0x00000000);
1931                         buf += SWRAP_PACKET_PAYLOAD_ICMP4_SIZE;
1932
1933                         /* set the ip header in the ICMP payload */
1934                         ip = (union swrap_packet_ip *)(void *)buf;
1935                         ip->v4.ver_hdrlen       = 0x45; /* version 4 and 5 * 32 bit words */
1936                         ip->v4.tos              = 0x00;
1937                         ip->v4.packet_length    = htons(wire_len - icmp_hdr_len);
1938                         ip->v4.identification   = htons(0xFFFF);
1939                         ip->v4.flags            = 0x40; /* BIT 1 set - means don't fragment */
1940                         ip->v4.fragment         = htons(0x0000);
1941                         ip->v4.ttl              = 0xFF;
1942                         ip->v4.protocol         = icmp_protocol;
1943                         ip->v4.hdr_checksum     = htons(0x0000);
1944                         ip->v4.src_addr         = dest_in->sin_addr.s_addr;
1945                         ip->v4.dest_addr        = src_in->sin_addr.s_addr;
1946                         buf += SWRAP_PACKET_IP_V4_SIZE;
1947
1948                         src_port = dest_in->sin_port;
1949                         dest_port = src_in->sin_port;
1950                         break;
1951 #ifdef HAVE_IPV6
1952                 case AF_INET6:
1953                         pay->icmp6.type         = 0x01; /* destination unreachable */
1954                         pay->icmp6.code         = 0x03; /* address unreachable */
1955                         pay->icmp6.checksum     = htons(0x0000);
1956                         pay->icmp6.unused       = htonl(0x00000000);
1957                         buf += SWRAP_PACKET_PAYLOAD_ICMP6_SIZE;
1958
1959                         /* set the ip header in the ICMP payload */
1960                         ip = (union swrap_packet_ip *)(void *)buf;
1961                         ip->v6.ver_prio         = 0x60; /* version 4 and 5 * 32 bit words */
1962                         ip->v6.flow_label_high  = 0x00;
1963                         ip->v6.flow_label_low   = 0x0000;
1964                         ip->v6.payload_length   = htons(wire_len - icmp_truncate_len); /* TODO */
1965                         ip->v6.next_header      = protocol;
1966                         memcpy(ip->v6.src_addr, dest_in6->sin6_addr.s6_addr, 16);
1967                         memcpy(ip->v6.dest_addr, src_in6->sin6_addr.s6_addr, 16);
1968                         buf += SWRAP_PACKET_IP_V6_SIZE;
1969
1970                         src_port = dest_in6->sin6_port;
1971                         dest_port = src_in6->sin6_port;
1972                         break;
1973 #endif
1974                 }
1975         }
1976
1977         pay = (union swrap_packet_payload *)(void *)buf;
1978
1979         switch (socket_type) {
1980         case SOCK_STREAM:
1981                 pay->tcp.source_port    = src_port;
1982                 pay->tcp.dest_port      = dest_port;
1983                 pay->tcp.seq_num        = htonl(tcp_seqno);
1984                 pay->tcp.ack_num        = htonl(tcp_ack);
1985                 pay->tcp.hdr_length     = 0x50; /* 5 * 32 bit words */
1986                 pay->tcp.control        = tcp_ctl;
1987                 pay->tcp.window         = htons(0x7FFF);
1988                 pay->tcp.checksum       = htons(0x0000);
1989                 pay->tcp.urg            = htons(0x0000);
1990                 buf += SWRAP_PACKET_PAYLOAD_TCP_SIZE;
1991
1992                 break;
1993
1994         case SOCK_DGRAM:
1995                 pay->udp.source_port    = src_port;
1996                 pay->udp.dest_port      = dest_port;
1997                 pay->udp.length         = htons(8 + payload_len);
1998                 pay->udp.checksum       = htons(0x0000);
1999                 buf += SWRAP_PACKET_PAYLOAD_UDP_SIZE;
2000
2001                 break;
2002         }
2003
2004         if (payload && payload_len > 0) {
2005                 memcpy(buf, payload, payload_len);
2006         }
2007
2008         *_packet_len = packet_len - icmp_truncate_len;
2009         return base;
2010 }
2011
2012 static int swrap_pcap_get_fd(const char *fname)
2013 {
2014         static int fd = -1;
2015
2016         if (fd != -1) return fd;
2017
2018         fd = libc_open(fname, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0644);
2019         if (fd != -1) {
2020                 struct swrap_file_hdr file_hdr;
2021                 file_hdr.magic          = 0xA1B2C3D4;
2022                 file_hdr.version_major  = 0x0002;
2023                 file_hdr.version_minor  = 0x0004;
2024                 file_hdr.timezone       = 0x00000000;
2025                 file_hdr.sigfigs        = 0x00000000;
2026                 file_hdr.frame_max_len  = SWRAP_FRAME_LENGTH_MAX;
2027                 file_hdr.link_type      = 0x0065; /* 101 RAW IP */
2028
2029                 if (write(fd, &file_hdr, sizeof(file_hdr)) != sizeof(file_hdr)) {
2030                         close(fd);
2031                         fd = -1;
2032                 }
2033                 return fd;
2034         }
2035
2036         fd = libc_open(fname, O_WRONLY|O_APPEND, 0644);
2037
2038         return fd;
2039 }
2040
2041 static uint8_t *swrap_pcap_marshall_packet(struct socket_info *si,
2042                                            const struct sockaddr *addr,
2043                                            enum swrap_packet_type type,
2044                                            const void *buf, size_t len,
2045                                            size_t *packet_len)
2046 {
2047         const struct sockaddr *src_addr;
2048         const struct sockaddr *dest_addr;
2049         unsigned long tcp_seqno = 0;
2050         unsigned long tcp_ack = 0;
2051         unsigned char tcp_ctl = 0;
2052         int unreachable = 0;
2053
2054         struct timeval tv;
2055
2056         switch (si->family) {
2057         case AF_INET:
2058                 break;
2059 #ifdef HAVE_IPV6
2060         case AF_INET6:
2061                 break;
2062 #endif
2063         default:
2064                 return NULL;
2065         }
2066
2067         switch (type) {
2068         case SWRAP_CONNECT_SEND:
2069                 if (si->type != SOCK_STREAM) return NULL;
2070
2071                 src_addr  = &si->myname.sa.s;
2072                 dest_addr = addr;
2073
2074                 tcp_seqno = si->io.pck_snd;
2075                 tcp_ack = si->io.pck_rcv;
2076                 tcp_ctl = 0x02; /* SYN */
2077
2078                 si->io.pck_snd += 1;
2079
2080                 break;
2081
2082         case SWRAP_CONNECT_RECV:
2083                 if (si->type != SOCK_STREAM) return NULL;
2084
2085                 dest_addr = &si->myname.sa.s;
2086                 src_addr = addr;
2087
2088                 tcp_seqno = si->io.pck_rcv;
2089                 tcp_ack = si->io.pck_snd;
2090                 tcp_ctl = 0x12; /** SYN,ACK */
2091
2092                 si->io.pck_rcv += 1;
2093
2094                 break;
2095
2096         case SWRAP_CONNECT_UNREACH:
2097                 if (si->type != SOCK_STREAM) return NULL;
2098
2099                 dest_addr = &si->myname.sa.s;
2100                 src_addr  = addr;
2101
2102                 /* Unreachable: resend the data of SWRAP_CONNECT_SEND */
2103                 tcp_seqno = si->io.pck_snd - 1;
2104                 tcp_ack = si->io.pck_rcv;
2105                 tcp_ctl = 0x02; /* SYN */
2106                 unreachable = 1;
2107
2108                 break;
2109
2110         case SWRAP_CONNECT_ACK:
2111                 if (si->type != SOCK_STREAM) return NULL;
2112
2113                 src_addr  = &si->myname.sa.s;
2114                 dest_addr = addr;
2115
2116                 tcp_seqno = si->io.pck_snd;
2117                 tcp_ack = si->io.pck_rcv;
2118                 tcp_ctl = 0x10; /* ACK */
2119
2120                 break;
2121
2122         case SWRAP_ACCEPT_SEND:
2123                 if (si->type != SOCK_STREAM) return NULL;
2124
2125                 dest_addr = &si->myname.sa.s;
2126                 src_addr = addr;
2127
2128                 tcp_seqno = si->io.pck_rcv;
2129                 tcp_ack = si->io.pck_snd;
2130                 tcp_ctl = 0x02; /* SYN */
2131
2132                 si->io.pck_rcv += 1;
2133
2134                 break;
2135
2136         case SWRAP_ACCEPT_RECV:
2137                 if (si->type != SOCK_STREAM) return NULL;
2138
2139                 src_addr = &si->myname.sa.s;
2140                 dest_addr = addr;
2141
2142                 tcp_seqno = si->io.pck_snd;
2143                 tcp_ack = si->io.pck_rcv;
2144                 tcp_ctl = 0x12; /* SYN,ACK */
2145
2146                 si->io.pck_snd += 1;
2147
2148                 break;
2149
2150         case SWRAP_ACCEPT_ACK:
2151                 if (si->type != SOCK_STREAM) return NULL;
2152
2153                 dest_addr = &si->myname.sa.s;
2154                 src_addr = addr;
2155
2156                 tcp_seqno = si->io.pck_rcv;
2157                 tcp_ack = si->io.pck_snd;
2158                 tcp_ctl = 0x10; /* ACK */
2159
2160                 break;
2161
2162         case SWRAP_SEND:
2163                 src_addr  = &si->myname.sa.s;
2164                 dest_addr = &si->peername.sa.s;
2165
2166                 tcp_seqno = si->io.pck_snd;
2167                 tcp_ack = si->io.pck_rcv;
2168                 tcp_ctl = 0x18; /* PSH,ACK */
2169
2170                 si->io.pck_snd += len;
2171
2172                 break;
2173
2174         case SWRAP_SEND_RST:
2175                 dest_addr = &si->myname.sa.s;
2176                 src_addr  = &si->peername.sa.s;
2177
2178                 if (si->type == SOCK_DGRAM) {
2179                         return swrap_pcap_marshall_packet(si,
2180                                                           &si->peername.sa.s,
2181                                                           SWRAP_SENDTO_UNREACH,
2182                                                           buf,
2183                                                           len,
2184                                                           packet_len);
2185                 }
2186
2187                 tcp_seqno = si->io.pck_rcv;
2188                 tcp_ack = si->io.pck_snd;
2189                 tcp_ctl = 0x14; /** RST,ACK */
2190
2191                 break;
2192
2193         case SWRAP_PENDING_RST:
2194                 dest_addr = &si->myname.sa.s;
2195                 src_addr  = &si->peername.sa.s;
2196
2197                 if (si->type == SOCK_DGRAM) {
2198                         return NULL;
2199                 }
2200
2201                 tcp_seqno = si->io.pck_rcv;
2202                 tcp_ack = si->io.pck_snd;
2203                 tcp_ctl = 0x14; /* RST,ACK */
2204
2205                 break;
2206
2207         case SWRAP_RECV:
2208                 dest_addr = &si->myname.sa.s;
2209                 src_addr  = &si->peername.sa.s;
2210
2211                 tcp_seqno = si->io.pck_rcv;
2212                 tcp_ack = si->io.pck_snd;
2213                 tcp_ctl = 0x18; /* PSH,ACK */
2214
2215                 si->io.pck_rcv += len;
2216
2217                 break;
2218
2219         case SWRAP_RECV_RST:
2220                 dest_addr = &si->myname.sa.s;
2221                 src_addr  = &si->peername.sa.s;
2222
2223                 if (si->type == SOCK_DGRAM) {
2224                         return NULL;
2225                 }
2226
2227                 tcp_seqno = si->io.pck_rcv;
2228                 tcp_ack = si->io.pck_snd;
2229                 tcp_ctl = 0x14; /* RST,ACK */
2230
2231                 break;
2232
2233         case SWRAP_SENDTO:
2234                 src_addr = &si->myname.sa.s;
2235                 dest_addr = addr;
2236
2237                 si->io.pck_snd += len;
2238
2239                 break;
2240
2241         case SWRAP_SENDTO_UNREACH:
2242                 dest_addr = &si->myname.sa.s;
2243                 src_addr = addr;
2244
2245                 unreachable = 1;
2246
2247                 break;
2248
2249         case SWRAP_RECVFROM:
2250                 dest_addr = &si->myname.sa.s;
2251                 src_addr = addr;
2252
2253                 si->io.pck_rcv += len;
2254
2255                 break;
2256
2257         case SWRAP_CLOSE_SEND:
2258                 if (si->type != SOCK_STREAM) return NULL;
2259
2260                 src_addr  = &si->myname.sa.s;
2261                 dest_addr = &si->peername.sa.s;
2262
2263                 tcp_seqno = si->io.pck_snd;
2264                 tcp_ack = si->io.pck_rcv;
2265                 tcp_ctl = 0x11; /* FIN, ACK */
2266
2267                 si->io.pck_snd += 1;
2268
2269                 break;
2270
2271         case SWRAP_CLOSE_RECV:
2272                 if (si->type != SOCK_STREAM) return NULL;
2273
2274                 dest_addr = &si->myname.sa.s;
2275                 src_addr  = &si->peername.sa.s;
2276
2277                 tcp_seqno = si->io.pck_rcv;
2278                 tcp_ack = si->io.pck_snd;
2279                 tcp_ctl = 0x11; /* FIN,ACK */
2280
2281                 si->io.pck_rcv += 1;
2282
2283                 break;
2284
2285         case SWRAP_CLOSE_ACK:
2286                 if (si->type != SOCK_STREAM) return NULL;
2287
2288                 src_addr  = &si->myname.sa.s;
2289                 dest_addr = &si->peername.sa.s;
2290
2291                 tcp_seqno = si->io.pck_snd;
2292                 tcp_ack = si->io.pck_rcv;
2293                 tcp_ctl = 0x10; /* ACK */
2294
2295                 break;
2296         default:
2297                 return NULL;
2298         }
2299
2300         swrapGetTimeOfDay(&tv);
2301
2302         return swrap_pcap_packet_init(&tv,
2303                                       src_addr,
2304                                       dest_addr,
2305                                       si->type,
2306                                       (const uint8_t *)buf,
2307                                       len,
2308                                       tcp_seqno,
2309                                       tcp_ack,
2310                                       tcp_ctl,
2311                                       unreachable,
2312                                       packet_len);
2313 }
2314
2315 static void swrap_pcap_dump_packet(struct socket_info *si,
2316                                    const struct sockaddr *addr,
2317                                    enum swrap_packet_type type,
2318                                    const void *buf, size_t len)
2319 {
2320         const char *file_name;
2321         uint8_t *packet;
2322         size_t packet_len = 0;
2323         int fd;
2324
2325         file_name = swrap_pcap_init_file();
2326         if (!file_name) {
2327                 return;
2328         }
2329
2330         packet = swrap_pcap_marshall_packet(si,
2331                                             addr,
2332                                             type,
2333                                             buf,
2334                                             len,
2335                                             &packet_len);
2336         if (packet == NULL) {
2337                 return;
2338         }
2339
2340         fd = swrap_pcap_get_fd(file_name);
2341         if (fd != -1) {
2342                 if (write(fd, packet, packet_len) != (ssize_t)packet_len) {
2343                         free(packet);
2344                         return;
2345                 }
2346         }
2347
2348         free(packet);
2349 }
2350
2351 /****************************************************************************
2352  *   SIGNALFD
2353  ***************************************************************************/
2354
2355 #ifdef HAVE_SIGNALFD
2356 static int swrap_signalfd(int fd, const sigset_t *mask, int flags)
2357 {
2358         int rc;
2359
2360         rc = libc_signalfd(fd, mask, flags);
2361         if (rc != -1) {
2362                 swrap_remove_stale(fd);
2363         }
2364
2365         return rc;
2366 }
2367
2368 int signalfd(int fd, const sigset_t *mask, int flags)
2369 {
2370         return swrap_signalfd(fd, mask, flags);
2371 }
2372 #endif
2373
2374 /****************************************************************************
2375  *   SOCKET
2376  ***************************************************************************/
2377
2378 static int swrap_socket(int family, int type, int protocol)
2379 {
2380         struct socket_info *si;
2381         struct socket_info_fd *fi;
2382         int fd;
2383         int real_type = type;
2384
2385         /*
2386          * Remove possible addition flags passed to socket() so
2387          * do not fail checking the type.
2388          * See https://lwn.net/Articles/281965/
2389          */
2390 #ifdef SOCK_CLOEXEC
2391         real_type &= ~SOCK_CLOEXEC;
2392 #endif
2393 #ifdef SOCK_NONBLOCK
2394         real_type &= ~SOCK_NONBLOCK;
2395 #endif
2396
2397         if (!socket_wrapper_enabled()) {
2398                 return libc_socket(family, type, protocol);
2399         }
2400
2401         switch (family) {
2402         case AF_INET:
2403 #ifdef HAVE_IPV6
2404         case AF_INET6:
2405 #endif
2406                 break;
2407 #ifdef AF_NETLINK
2408         case AF_NETLINK:
2409 #endif /* AF_NETLINK */
2410 #ifdef AF_PACKET
2411         case AF_PACKET:
2412 #endif /* AF_PACKET */
2413         case AF_UNIX:
2414                 return libc_socket(family, type, protocol);
2415         default:
2416                 errno = EAFNOSUPPORT;
2417                 return -1;
2418         }
2419
2420         switch (real_type) {
2421         case SOCK_STREAM:
2422                 break;
2423         case SOCK_DGRAM:
2424                 break;
2425         default:
2426                 errno = EPROTONOSUPPORT;
2427                 return -1;
2428         }
2429
2430         switch (protocol) {
2431         case 0:
2432                 break;
2433         case 6:
2434                 if (real_type == SOCK_STREAM) {
2435                         break;
2436                 }
2437                 /*fall through*/
2438         case 17:
2439                 if (real_type == SOCK_DGRAM) {
2440                         break;
2441                 }
2442                 /*fall through*/
2443         default:
2444                 errno = EPROTONOSUPPORT;
2445                 return -1;
2446         }
2447
2448         /*
2449          * We must call libc_socket with type, from the caller, not the version
2450          * we removed SOCK_CLOEXEC and SOCK_NONBLOCK from
2451          */
2452         fd = libc_socket(AF_UNIX, type, 0);
2453
2454         if (fd == -1) {
2455                 return -1;
2456         }
2457
2458         /* Check if we have a stale fd and remove it */
2459         si = find_socket_info(fd);
2460         if (si != NULL) {
2461                 swrap_remove_stale(fd);
2462         }
2463
2464         si = (struct socket_info *)calloc(1, sizeof(struct socket_info));
2465         if (si == NULL) {
2466                 errno = ENOMEM;
2467                 return -1;
2468         }
2469
2470         si->family = family;
2471
2472         /* however, the rest of the socket_wrapper code expects just
2473          * the type, not the flags */
2474         si->type = real_type;
2475         si->protocol = protocol;
2476
2477         /*
2478          * Setup myname so getsockname() can succeed to find out the socket
2479          * type.
2480          */
2481         switch(si->family) {
2482         case AF_INET: {
2483                 struct sockaddr_in sin = {
2484                         .sin_family = AF_INET,
2485                 };
2486
2487                 si->myname.sa_socklen = sizeof(struct sockaddr_in);
2488                 memcpy(&si->myname.sa.in, &sin, si->myname.sa_socklen);
2489                 break;
2490         }
2491         case AF_INET6: {
2492                 struct sockaddr_in6 sin6 = {
2493                         .sin6_family = AF_INET6,
2494                 };
2495
2496                 si->myname.sa_socklen = sizeof(struct sockaddr_in6);
2497                 memcpy(&si->myname.sa.in6, &sin6, si->myname.sa_socklen);
2498                 break;
2499         }
2500         default:
2501                 free(si);
2502                 errno = EINVAL;
2503                 return -1;
2504         }
2505
2506         fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
2507         if (fi == NULL) {
2508                 free(si);
2509                 errno = ENOMEM;
2510                 return -1;
2511         }
2512
2513         fi->fd = fd;
2514
2515         SWRAP_DLIST_ADD(si->fds, fi);
2516         SWRAP_DLIST_ADD(sockets, si);
2517
2518         SWRAP_LOG(SWRAP_LOG_TRACE,
2519                   "Created %s socket for protocol %s",
2520                   si->family == AF_INET ? "IPv4" : "IPv6",
2521                   si->type == SOCK_DGRAM ? "UDP" : "TCP");
2522
2523         return fd;
2524 }
2525
2526 int socket(int family, int type, int protocol)
2527 {
2528         return swrap_socket(family, type, protocol);
2529 }
2530
2531 /****************************************************************************
2532  *   SOCKETPAIR
2533  ***************************************************************************/
2534
2535 static int swrap_socketpair(int family, int type, int protocol, int sv[2])
2536 {
2537         int rc;
2538
2539         rc = libc_socketpair(family, type, protocol, sv);
2540         if (rc != -1) {
2541                 swrap_remove_stale(sv[0]);
2542                 swrap_remove_stale(sv[1]);
2543         }
2544
2545         return rc;
2546 }
2547
2548 int socketpair(int family, int type, int protocol, int sv[2])
2549 {
2550         return swrap_socketpair(family, type, protocol, sv);
2551 }
2552
2553 /****************************************************************************
2554  *   SOCKETPAIR
2555  ***************************************************************************/
2556
2557 #ifdef HAVE_TIMERFD_CREATE
2558 static int swrap_timerfd_create(int clockid, int flags)
2559 {
2560         int fd;
2561
2562         fd = libc_timerfd_create(clockid, flags);
2563         if (fd != -1) {
2564                 swrap_remove_stale(fd);
2565         }
2566
2567         return fd;
2568 }
2569
2570 int timerfd_create(int clockid, int flags)
2571 {
2572         return swrap_timerfd_create(clockid, flags);
2573 }
2574 #endif
2575
2576 /****************************************************************************
2577  *   PIPE
2578  ***************************************************************************/
2579
2580 static int swrap_pipe(int pipefd[2])
2581 {
2582         int rc;
2583
2584         rc = libc_pipe(pipefd);
2585         if (rc != -1) {
2586                 swrap_remove_stale(pipefd[0]);
2587                 swrap_remove_stale(pipefd[1]);
2588         }
2589
2590         return rc;
2591 }
2592
2593 int pipe(int pipefd[2])
2594 {
2595         return swrap_pipe(pipefd);
2596 }
2597
2598 /****************************************************************************
2599  *   ACCEPT
2600  ***************************************************************************/
2601
2602 static int swrap_accept(int s,
2603                         struct sockaddr *addr,
2604                         socklen_t *addrlen,
2605                         int flags)
2606 {
2607         struct socket_info *parent_si, *child_si;
2608         struct socket_info_fd *child_fi;
2609         int fd;
2610         struct swrap_address un_addr = {
2611                 .sa_socklen = sizeof(struct sockaddr_un),
2612         };
2613         struct swrap_address un_my_addr = {
2614                 .sa_socklen = sizeof(struct sockaddr_un),
2615         };
2616         struct swrap_address in_addr = {
2617                 .sa_socklen = sizeof(struct sockaddr_storage),
2618         };
2619         struct swrap_address in_my_addr = {
2620                 .sa_socklen = sizeof(struct sockaddr_storage),
2621         };
2622         int ret;
2623
2624         parent_si = find_socket_info(s);
2625         if (!parent_si) {
2626 #ifdef HAVE_ACCEPT4
2627                 return libc_accept4(s, addr, addrlen, flags);
2628 #else
2629                 return libc_accept(s, addr, addrlen);
2630 #endif
2631         }
2632
2633         /*
2634          * assume out sockaddr have the same size as the in parent
2635          * socket family
2636          */
2637         in_addr.sa_socklen = socket_length(parent_si->family);
2638         if (in_addr.sa_socklen <= 0) {
2639                 errno = EINVAL;
2640                 return -1;
2641         }
2642
2643 #ifdef HAVE_ACCEPT4
2644         ret = libc_accept4(s, &un_addr.sa.s, &un_addr.sa_socklen, flags);
2645 #else
2646         ret = libc_accept(s, &un_addr.sa.s, &un_addr.sa_socklen);
2647 #endif
2648         if (ret == -1) {
2649                 if (errno == ENOTSOCK) {
2650                         /* Remove stale fds */
2651                         swrap_remove_stale(s);
2652                 }
2653                 return ret;
2654         }
2655
2656         fd = ret;
2657
2658         ret = sockaddr_convert_from_un(parent_si,
2659                                        &un_addr.sa.un,
2660                                        un_addr.sa_socklen,
2661                                        parent_si->family,
2662                                        &in_addr.sa.s,
2663                                        &in_addr.sa_socklen);
2664         if (ret == -1) {
2665                 close(fd);
2666                 return ret;
2667         }
2668
2669         child_si = (struct socket_info *)calloc(1, sizeof(struct socket_info));
2670         if (child_si == NULL) {
2671                 close(fd);
2672                 errno = ENOMEM;
2673                 return -1;
2674         }
2675
2676         child_fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
2677         if (child_fi == NULL) {
2678                 free(child_si);
2679                 close(fd);
2680                 errno = ENOMEM;
2681                 return -1;
2682         }
2683
2684         child_fi->fd = fd;
2685
2686         SWRAP_DLIST_ADD(child_si->fds, child_fi);
2687
2688         child_si->family = parent_si->family;
2689         child_si->type = parent_si->type;
2690         child_si->protocol = parent_si->protocol;
2691         child_si->bound = 1;
2692         child_si->is_server = 1;
2693         child_si->connected = 1;
2694
2695         child_si->peername = (struct swrap_address) {
2696                 .sa_socklen = in_addr.sa_socklen,
2697         };
2698         memcpy(&child_si->peername.sa.ss, &in_addr.sa.ss, in_addr.sa_socklen);
2699
2700         if (addr != NULL && addrlen != NULL) {
2701                 size_t copy_len = MIN(*addrlen, in_addr.sa_socklen);
2702                 if (copy_len > 0) {
2703                         memcpy(addr, &in_addr.sa.ss, copy_len);
2704                 }
2705                 *addrlen = in_addr.sa_socklen;
2706         }
2707
2708         ret = libc_getsockname(fd,
2709                                &un_my_addr.sa.s,
2710                                &un_my_addr.sa_socklen);
2711         if (ret == -1) {
2712                 free(child_fi);
2713                 free(child_si);
2714                 close(fd);
2715                 return ret;
2716         }
2717
2718         ret = sockaddr_convert_from_un(child_si,
2719                                        &un_my_addr.sa.un,
2720                                        un_my_addr.sa_socklen,
2721                                        child_si->family,
2722                                        &in_my_addr.sa.s,
2723                                        &in_my_addr.sa_socklen);
2724         if (ret == -1) {
2725                 free(child_fi);
2726                 free(child_si);
2727                 close(fd);
2728                 return ret;
2729         }
2730
2731         SWRAP_LOG(SWRAP_LOG_TRACE,
2732                   "accept() path=%s, fd=%d",
2733                   un_my_addr.sa.un.sun_path, s);
2734
2735         child_si->myname = (struct swrap_address) {
2736                 .sa_socklen = in_my_addr.sa_socklen,
2737         };
2738         memcpy(&child_si->myname.sa.ss, &in_my_addr.sa.ss, in_my_addr.sa_socklen);
2739
2740         SWRAP_DLIST_ADD(sockets, child_si);
2741
2742         if (addr != NULL) {
2743                 swrap_pcap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0);
2744                 swrap_pcap_dump_packet(child_si, addr, SWRAP_ACCEPT_RECV, NULL, 0);
2745                 swrap_pcap_dump_packet(child_si, addr, SWRAP_ACCEPT_ACK, NULL, 0);
2746         }
2747
2748         return fd;
2749 }
2750
2751 #ifdef HAVE_ACCEPT4
2752 int accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags)
2753 {
2754         return swrap_accept(s, addr, (socklen_t *)addrlen, flags);
2755 }
2756 #endif
2757
2758 #ifdef HAVE_ACCEPT_PSOCKLEN_T
2759 int accept(int s, struct sockaddr *addr, Psocklen_t addrlen)
2760 #else
2761 int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
2762 #endif
2763 {
2764         return swrap_accept(s, addr, (socklen_t *)addrlen, 0);
2765 }
2766
2767 static int autobind_start_init;
2768 static int autobind_start;
2769
2770 /* using sendto() or connect() on an unbound socket would give the
2771    recipient no way to reply, as unlike UDP and TCP, a unix domain
2772    socket can't auto-assign ephemeral port numbers, so we need to
2773    assign it here.
2774    Note: this might change the family from ipv6 to ipv4
2775 */
2776 static int swrap_auto_bind(int fd, struct socket_info *si, int family)
2777 {
2778         struct swrap_address un_addr = {
2779                 .sa_socklen = sizeof(struct sockaddr_un),
2780         };
2781         int i;
2782         char type;
2783         int ret;
2784         int port;
2785         struct stat st;
2786
2787         if (autobind_start_init != 1) {
2788                 autobind_start_init = 1;
2789                 autobind_start = getpid();
2790                 autobind_start %= 50000;
2791                 autobind_start += 10000;
2792         }
2793
2794         un_addr.sa.un.sun_family = AF_UNIX;
2795
2796         switch (family) {
2797         case AF_INET: {
2798                 struct sockaddr_in in;
2799
2800                 switch (si->type) {
2801                 case SOCK_STREAM:
2802                         type = SOCKET_TYPE_CHAR_TCP;
2803                         break;
2804                 case SOCK_DGRAM:
2805                         type = SOCKET_TYPE_CHAR_UDP;
2806                         break;
2807                 default:
2808                     errno = ESOCKTNOSUPPORT;
2809                     return -1;
2810                 }
2811
2812                 memset(&in, 0, sizeof(in));
2813                 in.sin_family = AF_INET;
2814                 in.sin_addr.s_addr = htonl(127<<24 |
2815                                            socket_wrapper_default_iface());
2816
2817                 si->myname = (struct swrap_address) {
2818                         .sa_socklen = sizeof(in),
2819                 };
2820                 memcpy(&si->myname.sa.in, &in, si->myname.sa_socklen);
2821                 break;
2822         }
2823 #ifdef HAVE_IPV6
2824         case AF_INET6: {
2825                 struct sockaddr_in6 in6;
2826
2827                 if (si->family != family) {
2828                         errno = ENETUNREACH;
2829                         return -1;
2830                 }
2831
2832                 switch (si->type) {
2833                 case SOCK_STREAM:
2834                         type = SOCKET_TYPE_CHAR_TCP_V6;
2835                         break;
2836                 case SOCK_DGRAM:
2837                         type = SOCKET_TYPE_CHAR_UDP_V6;
2838                         break;
2839                 default:
2840                         errno = ESOCKTNOSUPPORT;
2841                         return -1;
2842                 }
2843
2844                 memset(&in6, 0, sizeof(in6));
2845                 in6.sin6_family = AF_INET6;
2846                 in6.sin6_addr = *swrap_ipv6();
2847                 in6.sin6_addr.s6_addr[15] = socket_wrapper_default_iface();
2848
2849                 si->myname = (struct swrap_address) {
2850                         .sa_socklen = sizeof(in6),
2851                 };
2852                 memcpy(&si->myname.sa.in6, &in6, si->myname.sa_socklen);
2853                 break;
2854         }
2855 #endif
2856         default:
2857                 errno = ESOCKTNOSUPPORT;
2858                 return -1;
2859         }
2860
2861         if (autobind_start > 60000) {
2862                 autobind_start = 10000;
2863         }
2864
2865         for (i = 0; i < SOCKET_MAX_SOCKETS; i++) {
2866                 port = autobind_start + i;
2867                 snprintf(un_addr.sa.un.sun_path, sizeof(un_addr.sa.un.sun_path),
2868                          "%s/"SOCKET_FORMAT, socket_wrapper_dir(),
2869                          type, socket_wrapper_default_iface(), port);
2870                 if (stat(un_addr.sa.un.sun_path, &st) == 0) continue;
2871
2872                 ret = libc_bind(fd, &un_addr.sa.s, un_addr.sa_socklen);
2873                 if (ret == -1) return ret;
2874
2875                 si->un_addr = un_addr.sa.un;
2876
2877                 si->bound = 1;
2878                 autobind_start = port + 1;
2879                 break;
2880         }
2881         if (i == SOCKET_MAX_SOCKETS) {
2882                 SWRAP_LOG(SWRAP_LOG_ERROR, "Too many open unix sockets (%u) for "
2883                                            "interface "SOCKET_FORMAT,
2884                                            SOCKET_MAX_SOCKETS,
2885                                            type,
2886                                            socket_wrapper_default_iface(),
2887                                            0);
2888                 errno = ENFILE;
2889                 return -1;
2890         }
2891
2892         si->family = family;
2893         set_port(si->family, port, &si->myname);
2894
2895         return 0;
2896 }
2897
2898 /****************************************************************************
2899  *   CONNECT
2900  ***************************************************************************/
2901
2902 static int swrap_connect(int s, const struct sockaddr *serv_addr,
2903                          socklen_t addrlen)
2904 {
2905         int ret;
2906         struct swrap_address un_addr = {
2907                 .sa_socklen = sizeof(struct sockaddr_un),
2908         };
2909         struct socket_info *si = find_socket_info(s);
2910         int bcast = 0;
2911
2912         if (!si) {
2913                 return libc_connect(s, serv_addr, addrlen);
2914         }
2915
2916         if (si->bound == 0) {
2917                 ret = swrap_auto_bind(s, si, serv_addr->sa_family);
2918                 if (ret == -1) return -1;
2919         }
2920
2921         if (si->family != serv_addr->sa_family) {
2922                 errno = EINVAL;
2923                 return -1;
2924         }
2925
2926         ret = sockaddr_convert_to_un(si, serv_addr,
2927                                      addrlen, &un_addr.sa.un, 0, &bcast);
2928         if (ret == -1) return -1;
2929
2930         if (bcast) {
2931                 errno = ENETUNREACH;
2932                 return -1;
2933         }
2934
2935         if (si->type == SOCK_DGRAM) {
2936                 si->defer_connect = 1;
2937                 ret = 0;
2938         } else {
2939                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0);
2940
2941                 ret = libc_connect(s,
2942                                    &un_addr.sa.s,
2943                                    un_addr.sa_socklen);
2944         }
2945
2946         SWRAP_LOG(SWRAP_LOG_TRACE,
2947                   "connect() path=%s, fd=%d",
2948                   un_addr.sa.un.sun_path, s);
2949
2950
2951         /* to give better errors */
2952         if (ret == -1 && errno == ENOENT) {
2953                 errno = EHOSTUNREACH;
2954         }
2955
2956         if (ret == 0) {
2957                 si->peername = (struct swrap_address) {
2958                         .sa_socklen = addrlen,
2959                 };
2960
2961                 memcpy(&si->peername.sa.ss, serv_addr, addrlen);
2962                 si->connected = 1;
2963
2964                 /*
2965                  * When we connect() on a socket than we have to bind the
2966                  * outgoing connection on the interface we use for the
2967                  * transport. We already bound it on the right interface
2968                  * but here we have to update the name so getsockname()
2969                  * returns correct information.
2970                  */
2971                 if (si->bindname.sa_socklen > 0) {
2972                         si->myname = (struct swrap_address) {
2973                                 .sa_socklen = si->bindname.sa_socklen,
2974                         };
2975
2976                         memcpy(&si->myname.sa.ss,
2977                                &si->bindname.sa.ss,
2978                                si->bindname.sa_socklen);
2979
2980                         /* Cleanup bindname */
2981                         si->bindname = (struct swrap_address) {
2982                                 .sa_socklen = 0,
2983                         };
2984                 }
2985
2986                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0);
2987                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0);
2988         } else {
2989                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0);
2990         }
2991
2992         return ret;
2993 }
2994
2995 int connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen)
2996 {
2997         return swrap_connect(s, serv_addr, addrlen);
2998 }
2999
3000 /****************************************************************************
3001  *   BIND
3002  ***************************************************************************/
3003
3004 static int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
3005 {
3006         int ret;
3007         struct swrap_address un_addr = {
3008                 .sa_socklen = sizeof(struct sockaddr_un),
3009         };
3010         struct socket_info *si = find_socket_info(s);
3011         int bind_error = 0;
3012 #if 0 /* FIXME */
3013         bool in_use;
3014 #endif
3015
3016         if (!si) {
3017                 return libc_bind(s, myaddr, addrlen);
3018         }
3019
3020         switch (si->family) {
3021         case AF_INET: {
3022                 const struct sockaddr_in *sin;
3023                 if (addrlen < sizeof(struct sockaddr_in)) {
3024                         bind_error = EINVAL;
3025                         break;
3026                 }
3027
3028                 sin = (const struct sockaddr_in *)(const void *)myaddr;
3029
3030                 if (sin->sin_family != AF_INET) {
3031                         bind_error = EAFNOSUPPORT;
3032                 }
3033
3034                 /* special case for AF_UNSPEC */
3035                 if (sin->sin_family == AF_UNSPEC &&
3036                     (sin->sin_addr.s_addr == htonl(INADDR_ANY)))
3037                 {
3038                         bind_error = 0;
3039                 }
3040
3041                 break;
3042         }
3043 #ifdef HAVE_IPV6
3044         case AF_INET6: {
3045                 const struct sockaddr_in6 *sin6;
3046                 if (addrlen < sizeof(struct sockaddr_in6)) {
3047                         bind_error = EINVAL;
3048                         break;
3049                 }
3050
3051                 sin6 = (const struct sockaddr_in6 *)(const void *)myaddr;
3052
3053                 if (sin6->sin6_family != AF_INET6) {
3054                         bind_error = EAFNOSUPPORT;
3055                 }
3056
3057                 break;
3058         }
3059 #endif
3060         default:
3061                 bind_error = EINVAL;
3062                 break;
3063         }
3064
3065         if (bind_error != 0) {
3066                 errno = bind_error;
3067                 return -1;
3068         }
3069
3070 #if 0 /* FIXME */
3071         in_use = check_addr_port_in_use(myaddr, addrlen);
3072         if (in_use) {
3073                 errno = EADDRINUSE;
3074                 return -1;
3075         }
3076 #endif
3077
3078         si->myname.sa_socklen = addrlen;
3079         memcpy(&si->myname.sa.ss, myaddr, addrlen);
3080
3081         ret = sockaddr_convert_to_un(si,
3082                                      myaddr,
3083                                      addrlen,
3084                                      &un_addr.sa.un,
3085                                      1,
3086                                      &si->bcast);
3087         if (ret == -1) return -1;
3088
3089         unlink(un_addr.sa.un.sun_path);
3090
3091         ret = libc_bind(s, &un_addr.sa.s, un_addr.sa_socklen);
3092
3093         SWRAP_LOG(SWRAP_LOG_TRACE,
3094                   "bind() path=%s, fd=%d",
3095                   un_addr.sa.un.sun_path, s);
3096
3097         if (ret == 0) {
3098                 si->bound = 1;
3099         }
3100
3101         return ret;
3102 }
3103
3104 int bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
3105 {
3106         return swrap_bind(s, myaddr, addrlen);
3107 }
3108
3109 /****************************************************************************
3110  *   BINDRESVPORT
3111  ***************************************************************************/
3112
3113 #ifdef HAVE_BINDRESVPORT
3114 static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen);
3115
3116 static int swrap_bindresvport_sa(int sd, struct sockaddr *sa)
3117 {
3118         struct swrap_address myaddr = {
3119                 .sa_socklen = sizeof(struct sockaddr_storage),
3120         };
3121         socklen_t salen;
3122         static uint16_t port;
3123         uint16_t i;
3124         int rc = -1;
3125         int af;
3126
3127 #define SWRAP_STARTPORT 600
3128 #define SWRAP_ENDPORT (IPPORT_RESERVED - 1)
3129 #define SWRAP_NPORTS (SWRAP_ENDPORT - SWRAP_STARTPORT + 1)
3130
3131         if (port == 0) {
3132                 port = (getpid() % SWRAP_NPORTS) + SWRAP_STARTPORT;
3133         }
3134
3135         if (sa == NULL) {
3136                 salen = myaddr.sa_socklen;
3137                 sa = &myaddr.sa.s;
3138
3139                 rc = swrap_getsockname(sd, &myaddr.sa.s, &salen);
3140                 if (rc < 0) {
3141                         return -1;
3142                 }
3143
3144                 af = sa->sa_family;
3145                 memset(&myaddr.sa.ss, 0, salen);
3146         } else {
3147                 af = sa->sa_family;
3148         }
3149
3150         for (i = 0; i < SWRAP_NPORTS; i++, port++) {
3151                 switch(af) {
3152                 case AF_INET: {
3153                         struct sockaddr_in *sinp = (struct sockaddr_in *)(void *)sa;
3154
3155                         salen = sizeof(struct sockaddr_in);
3156                         sinp->sin_port = htons(port);
3157                         break;
3158                 }
3159                 case AF_INET6: {
3160                         struct sockaddr_in6 *sin6p = (struct sockaddr_in6 *)(void *)sa;
3161
3162                         salen = sizeof(struct sockaddr_in6);
3163                         sin6p->sin6_port = htons(port);
3164                         break;
3165                 }
3166                 default:
3167                         errno = EAFNOSUPPORT;
3168                         return -1;
3169                 }
3170                 sa->sa_family = af;
3171
3172                 if (port > SWRAP_ENDPORT) {
3173                         port = SWRAP_STARTPORT;
3174                 }
3175
3176                 rc = swrap_bind(sd, (struct sockaddr *)sa, salen);
3177                 if (rc == 0 || errno != EADDRINUSE) {
3178                         break;
3179                 }
3180         }
3181
3182         return rc;
3183 }
3184
3185 int bindresvport(int sockfd, struct sockaddr_in *sinp)
3186 {
3187         return swrap_bindresvport_sa(sockfd, (struct sockaddr *)sinp);
3188 }
3189 #endif
3190
3191 /****************************************************************************
3192  *   LISTEN
3193  ***************************************************************************/
3194
3195 static int swrap_listen(int s, int backlog)
3196 {
3197         int ret;
3198         struct socket_info *si = find_socket_info(s);
3199
3200         if (!si) {
3201                 return libc_listen(s, backlog);
3202         }
3203
3204         if (si->bound == 0) {
3205                 ret = swrap_auto_bind(s, si, si->family);
3206                 if (ret == -1) {
3207                         errno = EADDRINUSE;
3208                         return ret;
3209                 }
3210         }
3211
3212         ret = libc_listen(s, backlog);
3213
3214         return ret;
3215 }
3216
3217 int listen(int s, int backlog)
3218 {
3219         return swrap_listen(s, backlog);
3220 }
3221
3222 /****************************************************************************
3223  *   FOPEN
3224  ***************************************************************************/
3225
3226 static FILE *swrap_fopen(const char *name, const char *mode)
3227 {
3228         FILE *fp;
3229
3230         fp = libc_fopen(name, mode);
3231         if (fp != NULL) {
3232                 int fd = fileno(fp);
3233
3234                 swrap_remove_stale(fd);
3235         }
3236
3237         return fp;
3238 }
3239
3240 FILE *fopen(const char *name, const char *mode)
3241 {
3242         return swrap_fopen(name, mode);
3243 }
3244
3245 /****************************************************************************
3246  *   OPEN
3247  ***************************************************************************/
3248
3249 static int swrap_vopen(const char *pathname, int flags, va_list ap)
3250 {
3251         int ret;
3252
3253         ret = libc_vopen(pathname, flags, ap);
3254         if (ret != -1) {
3255                 /*
3256                  * There are methods for closing descriptors (libc-internal code
3257                  * paths, direct syscalls) which close descriptors in ways that
3258                  * we can't intercept, so try to recover when we notice that
3259                  * that's happened
3260                  */
3261                 swrap_remove_stale(ret);
3262         }
3263         return ret;
3264 }
3265
3266 int open(const char *pathname, int flags, ...)
3267 {
3268         va_list ap;
3269         int fd;
3270
3271         va_start(ap, flags);
3272         fd = swrap_vopen(pathname, flags, ap);
3273         va_end(ap);
3274
3275         return fd;
3276 }
3277
3278 /****************************************************************************
3279  *   GETPEERNAME
3280  ***************************************************************************/
3281
3282 static int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
3283 {
3284         struct socket_info *si = find_socket_info(s);
3285         socklen_t len;
3286
3287         if (!si) {
3288                 return libc_getpeername(s, name, addrlen);
3289         }
3290
3291         if (si->peername.sa_socklen == 0)
3292         {
3293                 errno = ENOTCONN;
3294                 return -1;
3295         }
3296
3297         len = MIN(*addrlen, si->peername.sa_socklen);
3298         if (len == 0) {
3299                 return 0;
3300         }
3301
3302         memcpy(name, &si->peername.sa.ss, len);
3303         *addrlen = si->peername.sa_socklen;
3304
3305         return 0;
3306 }
3307
3308 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3309 int getpeername(int s, struct sockaddr *name, Psocklen_t addrlen)
3310 #else
3311 int getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
3312 #endif
3313 {
3314         return swrap_getpeername(s, name, (socklen_t *)addrlen);
3315 }
3316
3317 /****************************************************************************
3318  *   GETSOCKNAME
3319  ***************************************************************************/
3320
3321 static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
3322 {
3323         struct socket_info *si = find_socket_info(s);
3324         socklen_t len;
3325
3326         if (!si) {
3327                 return libc_getsockname(s, name, addrlen);
3328         }
3329
3330         len = MIN(*addrlen, si->myname.sa_socklen);
3331         if (len == 0) {
3332                 return 0;
3333         }
3334
3335         memcpy(name, &si->myname.sa.ss, len);
3336         *addrlen = si->myname.sa_socklen;
3337
3338         return 0;
3339 }
3340
3341 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3342 int getsockname(int s, struct sockaddr *name, Psocklen_t addrlen)
3343 #else
3344 int getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
3345 #endif
3346 {
3347         return swrap_getsockname(s, name, (socklen_t *)addrlen);
3348 }
3349
3350 /****************************************************************************
3351  *   GETSOCKOPT
3352  ***************************************************************************/
3353
3354 #ifndef SO_PROTOCOL
3355 # ifdef SO_PROTOTYPE /* The Solaris name */
3356 #  define SO_PROTOCOL SO_PROTOTYPE
3357 # endif /* SO_PROTOTYPE */
3358 #endif /* SO_PROTOCOL */
3359
3360 static int swrap_getsockopt(int s, int level, int optname,
3361                             void *optval, socklen_t *optlen)
3362 {
3363         struct socket_info *si = find_socket_info(s);
3364
3365         if (!si) {
3366                 return libc_getsockopt(s,
3367                                        level,
3368                                        optname,
3369                                        optval,
3370                                        optlen);
3371         }
3372
3373         if (level == SOL_SOCKET) {
3374                 switch (optname) {
3375 #ifdef SO_DOMAIN
3376                 case SO_DOMAIN:
3377                         if (optval == NULL || optlen == NULL ||
3378                             *optlen < (socklen_t)sizeof(int)) {
3379                                 errno = EINVAL;
3380                                 return -1;
3381                         }
3382
3383                         *optlen = sizeof(int);
3384                         *(int *)optval = si->family;
3385                         return 0;
3386 #endif /* SO_DOMAIN */
3387
3388 #ifdef SO_PROTOCOL
3389                 case SO_PROTOCOL:
3390                         if (optval == NULL || optlen == NULL ||
3391                             *optlen < (socklen_t)sizeof(int)) {
3392                                 errno = EINVAL;
3393                                 return -1;
3394                         }
3395
3396                         *optlen = sizeof(int);
3397                         *(int *)optval = si->protocol;
3398                         return 0;
3399 #endif /* SO_PROTOCOL */
3400                 case SO_TYPE:
3401                         if (optval == NULL || optlen == NULL ||
3402                             *optlen < (socklen_t)sizeof(int)) {
3403                                 errno = EINVAL;
3404                                 return -1;
3405                         }
3406
3407                         *optlen = sizeof(int);
3408                         *(int *)optval = si->type;
3409                         return 0;
3410                 default:
3411                         return libc_getsockopt(s,
3412                                                level,
3413                                                optname,
3414                                                optval,
3415                                                optlen);
3416                 }
3417         } else if (level == IPPROTO_TCP) {
3418                 switch (optname) {
3419 #ifdef TCP_NODELAY
3420                 case TCP_NODELAY:
3421                         /*
3422                          * This enables sending packets directly out over TCP.
3423                          * As a unix socket is doing that any way, report it as
3424                          * enabled.
3425                          */
3426                         if (optval == NULL || optlen == NULL ||
3427                             *optlen < (socklen_t)sizeof(int)) {
3428                                 errno = EINVAL;
3429                                 return -1;
3430                         }
3431
3432                         *optlen = sizeof(int);
3433                         *(int *)optval = si->tcp_nodelay;
3434
3435                         return 0;
3436 #endif /* TCP_NODELAY */
3437                 default:
3438                         break;
3439                 }
3440         }
3441
3442         errno = ENOPROTOOPT;
3443         return -1;
3444 }
3445
3446 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3447 int getsockopt(int s, int level, int optname, void *optval, Psocklen_t optlen)
3448 #else
3449 int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
3450 #endif
3451 {
3452         return swrap_getsockopt(s, level, optname, optval, (socklen_t *)optlen);
3453 }
3454
3455 /****************************************************************************
3456  *   SETSOCKOPT
3457  ***************************************************************************/
3458
3459 static int swrap_setsockopt(int s, int level, int optname,
3460                             const void *optval, socklen_t optlen)
3461 {
3462         struct socket_info *si = find_socket_info(s);
3463
3464         if (!si) {
3465                 return libc_setsockopt(s,
3466                                        level,
3467                                        optname,
3468                                        optval,
3469                                        optlen);
3470         }
3471
3472         if (level == SOL_SOCKET) {
3473                 return libc_setsockopt(s,
3474                                        level,
3475                                        optname,
3476                                        optval,
3477                                        optlen);
3478         } else if (level == IPPROTO_TCP) {
3479                 switch (optname) {
3480 #ifdef TCP_NODELAY
3481                 case TCP_NODELAY: {
3482                         int i;
3483
3484                         /*
3485                          * This enables sending packets directly out over TCP.
3486                          * A unix socket is doing that any way.
3487                          */
3488                         if (optval == NULL || optlen == 0 ||
3489                             optlen < (socklen_t)sizeof(int)) {
3490                                 errno = EINVAL;
3491                                 return -1;
3492                         }
3493
3494                         i = *discard_const_p(int, optval);
3495                         if (i != 0 && i != 1) {
3496                                 errno = EINVAL;
3497                                 return -1;
3498                         }
3499                         si->tcp_nodelay = i;
3500
3501                         return 0;
3502                 }
3503 #endif /* TCP_NODELAY */
3504                 default:
3505                         break;
3506                 }
3507         }
3508
3509         switch (si->family) {
3510         case AF_INET:
3511                 if (level == IPPROTO_IP) {
3512 #ifdef IP_PKTINFO
3513                         if (optname == IP_PKTINFO) {
3514                                 si->pktinfo = AF_INET;
3515                         }
3516 #endif /* IP_PKTINFO */
3517                 }
3518                 return 0;
3519 #ifdef HAVE_IPV6
3520         case AF_INET6:
3521                 if (level == IPPROTO_IPV6) {
3522 #ifdef IPV6_RECVPKTINFO
3523                         if (optname == IPV6_RECVPKTINFO) {
3524                                 si->pktinfo = AF_INET6;
3525                         }
3526 #endif /* IPV6_PKTINFO */
3527                 }
3528                 return 0;
3529 #endif
3530         default:
3531                 errno = ENOPROTOOPT;
3532                 return -1;
3533         }
3534 }
3535
3536 int setsockopt(int s, int level, int optname,
3537                const void *optval, socklen_t optlen)
3538 {
3539         return swrap_setsockopt(s, level, optname, optval, optlen);
3540 }
3541
3542 /****************************************************************************
3543  *   IOCTL
3544  ***************************************************************************/
3545
3546 static int swrap_vioctl(int s, unsigned long int r, va_list va)
3547 {
3548         struct socket_info *si = find_socket_info(s);
3549         va_list ap;
3550         int value;
3551         int rc;
3552
3553         if (!si) {
3554                 return libc_vioctl(s, r, va);
3555         }
3556
3557         va_copy(ap, va);
3558
3559         rc = libc_vioctl(s, r, va);
3560
3561         switch (r) {
3562         case FIONREAD:
3563                 value = *((int *)va_arg(ap, int *));
3564
3565                 if (rc == -1 && errno != EAGAIN && errno != ENOBUFS) {
3566                         swrap_pcap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
3567                 } else if (value == 0) { /* END OF FILE */
3568                         swrap_pcap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
3569                 }
3570                 break;
3571         }
3572
3573         va_end(ap);
3574
3575         return rc;
3576 }
3577
3578 #ifdef HAVE_IOCTL_INT
3579 int ioctl(int s, int r, ...)
3580 #else
3581 int ioctl(int s, unsigned long int r, ...)
3582 #endif
3583 {
3584         va_list va;
3585         int rc;
3586
3587         va_start(va, r);
3588
3589         rc = swrap_vioctl(s, (unsigned long int) r, va);
3590
3591         va_end(va);
3592
3593         return rc;
3594 }
3595
3596 /*****************
3597  * CMSG
3598  *****************/
3599
3600 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
3601
3602 #ifndef CMSG_ALIGN
3603 # ifdef _ALIGN /* BSD */
3604 #define CMSG_ALIGN _ALIGN
3605 # else
3606 #define CMSG_ALIGN(len) (((len) + sizeof(size_t) - 1) & ~(sizeof(size_t) - 1))
3607 # endif /* _ALIGN */
3608 #endif /* CMSG_ALIGN */
3609
3610 /**
3611  * @brief Add a cmsghdr to a msghdr.
3612  *
3613  * This is an function to add any type of cmsghdr. It will operate on the
3614  * msg->msg_control and msg->msg_controllen you pass in by adapting them to
3615  * the buffer position after the added cmsg element. Hence, this function is
3616  * intended to be used with an intermediate msghdr and not on the original
3617  * one handed in by the client.
3618  *
3619  * @param[in]  msg      The msghdr to which to add the cmsg.
3620  *
3621  * @param[in]  level    The cmsg level to set.
3622  *
3623  * @param[in]  type     The cmsg type to set.
3624  *
3625  * @param[in]  data     The cmsg data to set.
3626  *
3627  * @param[in]  len      the length of the data to set.
3628  */
3629 static void swrap_msghdr_add_cmsghdr(struct msghdr *msg,
3630                                      int level,
3631                                      int type,
3632                                      const void *data,
3633                                      size_t len)
3634 {
3635         size_t cmlen = CMSG_LEN(len);
3636         size_t cmspace = CMSG_SPACE(len);
3637         uint8_t cmbuf[cmspace];
3638         void *cast_ptr = (void *)cmbuf;
3639         struct cmsghdr *cm = (struct cmsghdr *)cast_ptr;
3640         uint8_t *p;
3641
3642         memset(cmbuf, 0, cmspace);
3643
3644         if (msg->msg_controllen < cmlen) {
3645                 cmlen = msg->msg_controllen;
3646                 msg->msg_flags |= MSG_CTRUNC;
3647         }
3648
3649         if (msg->msg_controllen < cmspace) {
3650                 cmspace = msg->msg_controllen;
3651         }
3652
3653         /*
3654          * We copy the full input data into an intermediate cmsghdr first
3655          * in order to more easily cope with truncation.
3656          */
3657         cm->cmsg_len = cmlen;
3658         cm->cmsg_level = level;
3659         cm->cmsg_type = type;
3660         memcpy(CMSG_DATA(cm), data, len);
3661
3662         /*
3663          * We now copy the possibly truncated buffer.
3664          * We copy cmlen bytes, but consume cmspace bytes,
3665          * leaving the possible padding uninitialiazed.
3666          */
3667         p = (uint8_t *)msg->msg_control;
3668         memcpy(p, cm, cmlen);
3669         p += cmspace;
3670         msg->msg_control = p;
3671         msg->msg_controllen -= cmspace;
3672
3673         return;
3674 }
3675
3676 static int swrap_msghdr_add_pktinfo(struct socket_info *si,
3677                                     struct msghdr *msg)
3678 {
3679         /* Add packet info */
3680         switch (si->pktinfo) {
3681 #if defined(IP_PKTINFO) && (defined(HAVE_STRUCT_IN_PKTINFO) || defined(IP_RECVDSTADDR))
3682         case AF_INET: {
3683                 struct sockaddr_in *sin;
3684 #if defined(HAVE_STRUCT_IN_PKTINFO)
3685                 struct in_pktinfo pkt;
3686 #elif defined(IP_RECVDSTADDR)
3687                 struct in_addr pkt;
3688 #endif
3689
3690                 if (si->bindname.sa_socklen == sizeof(struct sockaddr_in)) {
3691                         sin = &si->bindname.sa.in;
3692                 } else {
3693                         if (si->myname.sa_socklen != sizeof(struct sockaddr_in)) {
3694                                 return 0;
3695                         }
3696                         sin = &si->myname.sa.in;
3697                 }
3698
3699                 ZERO_STRUCT(pkt);
3700
3701 #if defined(HAVE_STRUCT_IN_PKTINFO)
3702                 pkt.ipi_ifindex = socket_wrapper_default_iface();
3703                 pkt.ipi_addr.s_addr = sin->sin_addr.s_addr;
3704 #elif defined(IP_RECVDSTADDR)
3705                 pkt = sin->sin_addr;
3706 #endif
3707
3708                 swrap_msghdr_add_cmsghdr(msg, IPPROTO_IP, IP_PKTINFO,
3709                                          &pkt, sizeof(pkt));
3710
3711                 break;
3712         }
3713 #endif /* IP_PKTINFO */
3714 #if defined(HAVE_IPV6)
3715         case AF_INET6: {
3716 #if defined(IPV6_PKTINFO) && defined(HAVE_STRUCT_IN6_PKTINFO)
3717                 struct sockaddr_in6 *sin6;
3718                 struct in6_pktinfo pkt6;
3719
3720                 if (si->bindname.sa_socklen == sizeof(struct sockaddr_in6)) {
3721                         sin6 = &si->bindname.sa.in6;
3722                 } else {
3723                         if (si->myname.sa_socklen != sizeof(struct sockaddr_in6)) {
3724                                 return 0;
3725                         }
3726                         sin6 = &si->myname.sa.in6;
3727                 }
3728
3729                 ZERO_STRUCT(pkt6);
3730
3731                 pkt6.ipi6_ifindex = socket_wrapper_default_iface();
3732                 pkt6.ipi6_addr = sin6->sin6_addr;
3733
3734                 swrap_msghdr_add_cmsghdr(msg, IPPROTO_IPV6, IPV6_PKTINFO,
3735                                         &pkt6, sizeof(pkt6));
3736 #endif /* HAVE_STRUCT_IN6_PKTINFO */
3737
3738                 break;
3739         }
3740 #endif /* IPV6_PKTINFO */
3741         default:
3742                 return -1;
3743         }
3744
3745         return 0;
3746 }
3747
3748 static int swrap_msghdr_add_socket_info(struct socket_info *si,
3749                                         struct msghdr *omsg)
3750 {
3751         int rc = 0;
3752
3753         if (si->pktinfo > 0) {
3754                 rc = swrap_msghdr_add_pktinfo(si, omsg);
3755         }
3756
3757         return rc;
3758 }
3759
3760 static int swrap_sendmsg_copy_cmsg(struct cmsghdr *cmsg,
3761                                    uint8_t **cm_data,
3762                                    size_t *cm_data_space);
3763 static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr *cmsg,
3764                                             uint8_t **cm_data,
3765                                             size_t *cm_data_space);
3766
3767 static int swrap_sendmsg_filter_cmsghdr(struct msghdr *msg,
3768                                         uint8_t **cm_data,
3769                                         size_t *cm_data_space) {
3770         struct cmsghdr *cmsg;
3771         int rc = -1;
3772
3773         /* Nothing to do */
3774         if (msg->msg_controllen == 0 || msg->msg_control == NULL) {
3775                 return 0;
3776         }
3777
3778         for (cmsg = CMSG_FIRSTHDR(msg);
3779              cmsg != NULL;
3780              cmsg = CMSG_NXTHDR(msg, cmsg)) {
3781                 switch (cmsg->cmsg_level) {
3782                 case IPPROTO_IP:
3783                         rc = swrap_sendmsg_filter_cmsg_socket(cmsg,
3784                                                               cm_data,
3785                                                               cm_data_space);
3786                         break;
3787                 default:
3788                         rc = swrap_sendmsg_copy_cmsg(cmsg,
3789                                                      cm_data,
3790                                                      cm_data_space);
3791                         break;
3792                 }
3793         }
3794
3795         return rc;
3796 }
3797
3798 static int swrap_sendmsg_copy_cmsg(struct cmsghdr *cmsg,
3799                                    uint8_t **cm_data,
3800                                    size_t *cm_data_space)
3801 {
3802         size_t cmspace;
3803         uint8_t *p;
3804
3805         cmspace = *cm_data_space + CMSG_ALIGN(cmsg->cmsg_len);
3806
3807         p = realloc((*cm_data), cmspace);
3808         if (p == NULL) {
3809                 return -1;
3810         }
3811         (*cm_data) = p;
3812
3813         p = (*cm_data) + (*cm_data_space);
3814         *cm_data_space = cmspace;
3815
3816         memcpy(p, cmsg, cmsg->cmsg_len);
3817
3818         return 0;
3819 }
3820
3821 static int swrap_sendmsg_filter_cmsg_pktinfo(struct cmsghdr *cmsg,
3822                                             uint8_t **cm_data,
3823                                             size_t *cm_data_space);
3824
3825
3826 static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr *cmsg,
3827                                             uint8_t **cm_data,
3828                                             size_t *cm_data_space)
3829 {
3830         int rc = -1;
3831
3832         switch(cmsg->cmsg_type) {
3833 #ifdef IP_PKTINFO
3834         case IP_PKTINFO:
3835                 rc = swrap_sendmsg_filter_cmsg_pktinfo(cmsg,
3836                                                        cm_data,
3837                                                        cm_data_space);
3838                 break;
3839 #endif
3840 #ifdef IPV6_PKTINFO
3841         case IPV6_PKTINFO:
3842                 rc = swrap_sendmsg_filter_cmsg_pktinfo(cmsg,
3843                                                        cm_data,
3844                                                        cm_data_space);
3845                 break;
3846 #endif
3847         default:
3848                 break;
3849         }
3850
3851         return rc;
3852 }
3853
3854 static int swrap_sendmsg_filter_cmsg_pktinfo(struct cmsghdr *cmsg,
3855                                              uint8_t **cm_data,
3856                                              size_t *cm_data_space)
3857 {
3858         (void)cmsg; /* unused */
3859         (void)cm_data; /* unused */
3860         (void)cm_data_space; /* unused */
3861
3862         /*
3863          * Passing a IP pktinfo to a unix socket might be rejected by the
3864          * Kernel, at least on FreeBSD. So skip this cmsg.
3865          */
3866         return 0;
3867 }
3868 #endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
3869
3870 static ssize_t swrap_sendmsg_before(int fd,
3871                                     struct socket_info *si,
3872                                     struct msghdr *msg,
3873                                     struct iovec *tmp_iov,
3874                                     struct sockaddr_un *tmp_un,
3875                                     const struct sockaddr_un **to_un,
3876                                     const struct sockaddr **to,
3877                                     int *bcast)
3878 {
3879         size_t i, len = 0;
3880         ssize_t ret;
3881
3882         if (to_un) {
3883                 *to_un = NULL;
3884         }
3885         if (to) {
3886                 *to = NULL;
3887         }
3888         if (bcast) {
3889                 *bcast = 0;
3890         }
3891
3892         switch (si->type) {
3893         case SOCK_STREAM: {
3894                 unsigned long mtu;
3895
3896                 if (!si->connected) {
3897                         errno = ENOTCONN;
3898                         return -1;
3899                 }
3900
3901                 if (msg->msg_iovlen == 0) {
3902                         break;
3903                 }
3904
3905                 mtu = socket_wrapper_mtu();
3906                 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
3907                         size_t nlen;
3908                         nlen = len + msg->msg_iov[i].iov_len;
3909                         if (nlen > mtu) {
3910                                 break;
3911                         }
3912                 }
3913                 msg->msg_iovlen = i;
3914                 if (msg->msg_iovlen == 0) {
3915                         *tmp_iov = msg->msg_iov[0];
3916                         tmp_iov->iov_len = MIN((size_t)tmp_iov->iov_len,
3917                                                (size_t)mtu);
3918                         msg->msg_iov = tmp_iov;
3919                         msg->msg_iovlen = 1;
3920                 }
3921                 break;
3922         }
3923         case SOCK_DGRAM:
3924                 if (si->connected) {
3925                         if (msg->msg_name != NULL) {
3926                                 /*
3927                                  * We are dealing with unix sockets and if we
3928                                  * are connected, we should only talk to the
3929                                  * connected unix path. Using the fd to send
3930                                  * to another server would be hard to achieve.
3931                                  */
3932                                 msg->msg_name = NULL;
3933                                 msg->msg_namelen = 0;
3934                         }
3935                 } else {
3936                         const struct sockaddr *msg_name;
3937                         msg_name = (const struct sockaddr *)msg->msg_name;
3938
3939                         if (msg_name == NULL) {
3940                                 errno = ENOTCONN;
3941                                 return -1;
3942                         }
3943
3944
3945                         ret = sockaddr_convert_to_un(si, msg_name, msg->msg_namelen,
3946                                                      tmp_un, 0, bcast);
3947                         if (ret == -1) return -1;
3948
3949                         if (to_un) {
3950                                 *to_un = tmp_un;
3951                         }
3952                         if (to) {
3953                                 *to = msg_name;
3954                         }
3955                         msg->msg_name = tmp_un;
3956                         msg->msg_namelen = sizeof(*tmp_un);
3957                 }
3958
3959                 if (si->bound == 0) {
3960                         ret = swrap_auto_bind(fd, si, si->family);
3961                         if (ret == -1) {
3962                                 if (errno == ENOTSOCK) {
3963                                         swrap_remove_stale(fd);
3964                                         return -ENOTSOCK;
3965                                 } else {
3966                                         SWRAP_LOG(SWRAP_LOG_ERROR, "swrap_sendmsg_before failed");
3967                                         return -1;
3968                                 }
3969                         }
3970                 }
3971
3972                 if (!si->defer_connect) {
3973                         break;
3974                 }
3975
3976                 ret = sockaddr_convert_to_un(si,
3977                                              &si->peername.sa.s,
3978                                              si->peername.sa_socklen,
3979                                              tmp_un,
3980                                              0,
3981                                              NULL);
3982                 if (ret == -1) return -1;
3983
3984                 ret = libc_connect(fd,
3985                                    (struct sockaddr *)(void *)tmp_un,
3986                                    sizeof(*tmp_un));
3987
3988                 /* to give better errors */
3989                 if (ret == -1 && errno == ENOENT) {
3990                         errno = EHOSTUNREACH;
3991                 }
3992
3993                 if (ret == -1) {
3994                         return ret;
3995                 }
3996
3997                 si->defer_connect = 0;
3998                 break;
3999         default:
4000                 errno = EHOSTUNREACH;
4001                 return -1;
4002         }
4003
4004 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4005         if (msg->msg_controllen > 0 && msg->msg_control != NULL) {
4006                 uint8_t *cmbuf = NULL;
4007                 size_t cmlen = 0;
4008
4009                 ret = swrap_sendmsg_filter_cmsghdr(msg, &cmbuf, &cmlen);
4010                 if (ret < 0) {
4011                         free(cmbuf);
4012                         return -1;
4013                 }
4014
4015                 if (cmlen == 0) {
4016                         msg->msg_controllen = 0;
4017                         msg->msg_control = NULL;
4018                 } else if (cmlen < msg->msg_controllen && cmbuf != NULL) {
4019                         memcpy(msg->msg_control, cmbuf, cmlen);
4020                         msg->msg_controllen = cmlen;
4021                 }
4022                 free(cmbuf);
4023         }
4024 #endif
4025
4026         return 0;
4027 }
4028
4029 static void swrap_sendmsg_after(int fd,
4030                                 struct socket_info *si,
4031                                 struct msghdr *msg,
4032                                 const struct sockaddr *to,
4033                                 ssize_t ret)
4034 {
4035         int saved_errno = errno;
4036         size_t i, len = 0;
4037         uint8_t *buf;
4038         off_t ofs = 0;
4039         size_t avail = 0;
4040         size_t remain;
4041
4042         /* to give better errors */
4043         if (ret == -1) {
4044                 if (saved_errno == ENOENT) {
4045                         saved_errno = EHOSTUNREACH;
4046                 } else if (saved_errno == ENOTSOCK) {
4047                         /* If the fd is not a socket, remove it */
4048                         swrap_remove_stale(fd);
4049                 }
4050         }
4051
4052         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
4053                 avail += msg->msg_iov[i].iov_len;
4054         }
4055
4056         if (ret == -1) {
4057                 remain = MIN(80, avail);
4058         } else {
4059                 remain = ret;
4060         }
4061
4062         /* we capture it as one single packet */
4063         buf = (uint8_t *)malloc(remain);
4064         if (!buf) {
4065                 /* we just not capture the packet */
4066                 errno = saved_errno;
4067                 return;
4068         }
4069
4070         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
4071                 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
4072                 memcpy(buf + ofs,
4073                        msg->msg_iov[i].iov_base,
4074                        this_time);
4075                 ofs += this_time;
4076                 remain -= this_time;
4077         }
4078         len = ofs;
4079
4080         switch (si->type) {
4081         case SOCK_STREAM:
4082                 if (ret == -1) {
4083                         swrap_pcap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
4084                         swrap_pcap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
4085                 } else {
4086                         swrap_pcap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
4087                 }
4088                 break;
4089
4090         case SOCK_DGRAM:
4091                 if (si->connected) {
4092                         to = &si->peername.sa.s;
4093                 }
4094                 if (ret == -1) {
4095                         swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
4096                         swrap_pcap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);
4097                 } else {
4098                         swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
4099                 }
4100                 break;
4101         }
4102
4103         free(buf);
4104         errno = saved_errno;
4105 }
4106
4107 static int swrap_recvmsg_before(int fd,
4108                                 struct socket_info *si,
4109                                 struct msghdr *msg,
4110                                 struct iovec *tmp_iov)
4111 {
4112         size_t i, len = 0;
4113         ssize_t ret;
4114
4115         (void)fd; /* unused */
4116
4117         switch (si->type) {
4118         case SOCK_STREAM: {
4119                 unsigned int mtu;
4120                 if (!si->connected) {
4121                         errno = ENOTCONN;
4122                         return -1;
4123                 }
4124
4125                 if (msg->msg_iovlen == 0) {
4126                         break;
4127                 }
4128
4129                 mtu = socket_wrapper_mtu();
4130                 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
4131                         size_t nlen;
4132                         nlen = len + msg->msg_iov[i].iov_len;
4133                         if (nlen > mtu) {
4134                                 break;
4135                         }
4136                 }
4137                 msg->msg_iovlen = i;
4138                 if (msg->msg_iovlen == 0) {
4139                         *tmp_iov = msg->msg_iov[0];
4140                         tmp_iov->iov_len = MIN((size_t)tmp_iov->iov_len,
4141                                                (size_t)mtu);
4142                         msg->msg_iov = tmp_iov;
4143                         msg->msg_iovlen = 1;
4144                 }
4145                 break;
4146         }
4147         case SOCK_DGRAM:
4148                 if (msg->msg_name == NULL) {
4149                         errno = EINVAL;
4150                         return -1;
4151                 }
4152
4153                 if (msg->msg_iovlen == 0) {
4154                         break;
4155                 }
4156
4157                 if (si->bound == 0) {
4158                         ret = swrap_auto_bind(fd, si, si->family);
4159                         if (ret == -1) {
4160                                 /*
4161                                  * When attempting to read or write to a
4162                                  * descriptor, if an underlying autobind fails
4163                                  * because it's not a socket, stop intercepting
4164                                  * uses of that descriptor.
4165                                  */
4166                                 if (errno == ENOTSOCK) {
4167                                         swrap_remove_stale(fd);
4168                                         return -ENOTSOCK;
4169                                 } else {
4170                                         SWRAP_LOG(SWRAP_LOG_ERROR,
4171                                                   "swrap_recvmsg_before failed");
4172                                         return -1;
4173                                 }
4174                         }
4175                 }
4176                 break;
4177         default:
4178                 errno = EHOSTUNREACH;
4179                 return -1;
4180         }
4181
4182         return 0;
4183 }
4184
4185 static int swrap_recvmsg_after(int fd,
4186                                struct socket_info *si,
4187                                struct msghdr *msg,
4188                                const struct sockaddr_un *un_addr,
4189                                socklen_t un_addrlen,
4190                                ssize_t ret)
4191 {
4192         int saved_errno = errno;
4193         size_t i;
4194         uint8_t *buf = NULL;
4195         off_t ofs = 0;
4196         size_t avail = 0;
4197         size_t remain;
4198         int rc;
4199
4200         /* to give better errors */
4201         if (ret == -1) {
4202                 if (saved_errno == ENOENT) {
4203                         saved_errno = EHOSTUNREACH;
4204                 } else if (saved_errno == ENOTSOCK) {
4205                         /* If the fd is not a socket, remove it */
4206                         swrap_remove_stale(fd);
4207                 }
4208         }
4209
4210         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
4211                 avail += msg->msg_iov[i].iov_len;
4212         }
4213
4214         /* Convert the socket address before we leave */
4215         if (si->type == SOCK_DGRAM && un_addr != NULL) {
4216                 rc = sockaddr_convert_from_un(si,
4217                                               un_addr,
4218                                               un_addrlen,
4219                                               si->family,
4220                                               msg->msg_name,
4221                                               &msg->msg_namelen);
4222                 if (rc == -1) {
4223                         goto done;
4224                 }
4225         }
4226
4227         if (avail == 0) {
4228                 rc = 0;
4229                 goto done;
4230         }
4231
4232         if (ret == -1) {
4233                 remain = MIN(80, avail);
4234         } else {
4235                 remain = ret;
4236         }
4237
4238         /* we capture it as one single packet */
4239         buf = (uint8_t *)malloc(remain);
4240         if (buf == NULL) {
4241                 /* we just not capture the packet */
4242                 errno = saved_errno;
4243                 return -1;
4244         }
4245
4246         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
4247                 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
4248                 memcpy(buf + ofs,
4249                        msg->msg_iov[i].iov_base,
4250                        this_time);
4251                 ofs += this_time;
4252                 remain -= this_time;
4253         }
4254
4255         switch (si->type) {
4256         case SOCK_STREAM:
4257                 if (ret == -1 && saved_errno != EAGAIN && saved_errno != ENOBUFS) {
4258                         swrap_pcap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
4259                 } else if (ret == 0) { /* END OF FILE */
4260                         swrap_pcap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
4261                 } else if (ret > 0) {
4262                         swrap_pcap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
4263                 }
4264                 break;
4265
4266         case SOCK_DGRAM:
4267                 if (ret == -1) {
4268                         break;
4269                 }
4270
4271                 if (un_addr != NULL) {
4272                         swrap_pcap_dump_packet(si,
4273                                           msg->msg_name,
4274                                           SWRAP_RECVFROM,
4275                                           buf,
4276                                           ret);
4277                 } else {
4278                         swrap_pcap_dump_packet(si,
4279                                           msg->msg_name,
4280                                           SWRAP_RECV,
4281                                           buf,
4282                                           ret);
4283                 }
4284
4285                 break;
4286         }
4287
4288         rc = 0;
4289 done:
4290         free(buf);
4291         errno = saved_errno;
4292
4293 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4294         if (rc == 0 &&
4295             msg->msg_controllen > 0 &&
4296             msg->msg_control != NULL) {
4297                 rc = swrap_msghdr_add_socket_info(si, msg);
4298                 if (rc < 0) {
4299                         return -1;
4300                 }
4301         }
4302 #endif
4303
4304         return rc;
4305 }
4306
4307 /****************************************************************************
4308  *   RECVFROM
4309  ***************************************************************************/
4310
4311 static ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags,
4312                               struct sockaddr *from, socklen_t *fromlen)
4313 {
4314         struct swrap_address from_addr = {
4315                 .sa_socklen = sizeof(struct sockaddr_un),
4316         };
4317         ssize_t ret;
4318         struct socket_info *si = find_socket_info(s);
4319         struct swrap_address saddr = {
4320                 .sa_socklen = sizeof(struct sockaddr_storage),
4321         };
4322         struct msghdr msg;
4323         struct iovec tmp;
4324         int tret;
4325
4326         if (!si) {
4327                 return libc_recvfrom(s,
4328                                      buf,
4329                                      len,
4330                                      flags,
4331                                      from,
4332                                      fromlen);
4333         }
4334
4335         tmp.iov_base = buf;
4336         tmp.iov_len = len;
4337
4338         ZERO_STRUCT(msg);
4339         if (from != NULL && fromlen != NULL) {
4340                 msg.msg_name = from;   /* optional address */
4341                 msg.msg_namelen = *fromlen; /* size of address */
4342         } else {
4343                 msg.msg_name = &saddr.sa.s; /* optional address */
4344                 msg.msg_namelen = saddr.sa_socklen; /* size of address */
4345         }
4346         msg.msg_iov = &tmp;            /* scatter/gather array */
4347         msg.msg_iovlen = 1;            /* # elements in msg_iov */
4348 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4349         msg.msg_control = NULL;        /* ancillary data, see below */
4350         msg.msg_controllen = 0;        /* ancillary data buffer len */
4351         msg.msg_flags = 0;             /* flags on received message */
4352 #endif
4353
4354         tret = swrap_recvmsg_before(s, si, &msg, &tmp);
4355         if (tret < 0) {
4356                 return -1;
4357         }
4358
4359         buf = msg.msg_iov[0].iov_base;
4360         len = msg.msg_iov[0].iov_len;
4361
4362         ret = libc_recvfrom(s,
4363                             buf,
4364                             len,
4365                             flags,
4366                             &from_addr.sa.s,
4367                             &from_addr.sa_socklen);
4368         if (ret == -1) {
4369                 return ret;
4370         }
4371
4372         tret = swrap_recvmsg_after(s,
4373                                    si,
4374                                    &msg,
4375                                    &from_addr.sa.un,
4376                                    from_addr.sa_socklen,
4377                                    ret);
4378         if (tret != 0) {
4379                 return tret;
4380         }
4381
4382         if (from != NULL && fromlen != NULL) {
4383                 *fromlen = msg.msg_namelen;
4384         }
4385
4386         return ret;
4387 }
4388
4389 #ifdef HAVE_ACCEPT_PSOCKLEN_T
4390 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
4391                  struct sockaddr *from, Psocklen_t fromlen)
4392 #else
4393 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
4394                  struct sockaddr *from, socklen_t *fromlen)
4395 #endif
4396 {
4397         return swrap_recvfrom(s, buf, len, flags, from, (socklen_t *)fromlen);
4398 }
4399
4400 /****************************************************************************
4401  *   SENDTO
4402  ***************************************************************************/
4403
4404 static ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags,
4405                             const struct sockaddr *to, socklen_t tolen)
4406 {
4407         struct msghdr msg;
4408         struct iovec tmp;
4409         struct swrap_address un_addr = {
4410                 .sa_socklen = sizeof(struct sockaddr_un),
4411         };
4412         const struct sockaddr_un *to_un = NULL;
4413         ssize_t ret;
4414         int rc;
4415         struct socket_info *si = find_socket_info(s);
4416         int bcast = 0;
4417
4418         if (!si) {
4419                 return libc_sendto(s, buf, len, flags, to, tolen);
4420         }
4421
4422         tmp.iov_base = discard_const_p(char, buf);
4423         tmp.iov_len = len;
4424
4425         ZERO_STRUCT(msg);
4426         msg.msg_name = discard_const_p(struct sockaddr, to); /* optional address */
4427         msg.msg_namelen = tolen;       /* size of address */
4428         msg.msg_iov = &tmp;            /* scatter/gather array */
4429         msg.msg_iovlen = 1;            /* # elements in msg_iov */
4430 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
4431         msg.msg_control = NULL;        /* ancillary data, see below */
4432         msg.msg_controllen = 0;        /* ancillary data buffer len */
4433         msg.msg_flags = 0;             /* flags on received message */
4434 #endif
4435
4436         rc = swrap_sendmsg_before(s,
4437                                   si,
4438                                   &msg,
4439                                   &tmp,
4440                                   &un_addr.sa.un,
4441                                   &to_un,
4442                                   &to,
4443                                   &bcast);
4444         if (rc < 0) {
4445                 return -1;
4446         }
4447
4448         buf = msg.msg_iov[0].iov_base;
4449         len = msg.msg_iov[0].iov_len;
4450
4451         if (bcast) {
4452                 struct stat st;
4453                 unsigned int iface;
4454                 unsigned int prt = ntohs(((const struct sockaddr_in *)(const void *)to)->sin_port);
4455                 char type;
4456
4457                 type = SOCKET_TYPE_CHAR_UDP;
4458
4459                 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
4460                         snprintf(un_addr.sa.un.sun_path,
4461                                  sizeof(un_addr.sa.un.sun_path),
4462                                  "%s/"SOCKET_FORMAT,
4463                                  socket_wrapper_dir(), type, iface, prt);
4464                         if (stat(un_addr.sa.un.sun_path, &st) != 0) continue;
4465
4466                         /* ignore the any errors in broadcast sends */
4467                         libc_sendto(s,
4468                                     buf,
4469                                     len,
4470                                     flags,
4471                                     &un_addr.sa.s,
4472                                     un_addr.sa_socklen);
4473                 }
4474
4475                 swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
4476
4477                 return len;
4478         }
4479
4480         /*
4481          * If it is a dgram socket and we are connected, don't include the
4482          * 'to' address.
4483          */
4484         if (si->type == SOCK_DGRAM && si->connected) {
4485                 ret = libc_sendto(s,
4486                                   buf,
4487                                   len,
4488                                   flags,
4489                                   NULL,
4490                                   0);
4491         } else {
4492                 ret = libc_sendto(s,
4493                                   buf,
4494                                   len,
4495                                   flags,
4496                                   (struct sockaddr *)msg.msg_name,
4497                                   msg.msg_namelen);
4498         }
4499
4500         swrap_sendmsg_after(s, si, &msg, to, ret);
4501
4502         return ret;
4503 }
4504
4505 ssize_t sendto(int s, const void *buf, size_t len, int flags,
4506                const struct sockaddr *to, socklen_t tolen)
4507 {
4508         return swrap_sendto(s, buf, len, flags, to, tolen);
4509 }
4510
4511 /****************************************************************************
4512  *   READV
4513  ***************************************************************************/
4514
4515 static ssize_t swrap_recv(int s, void *buf, size_t len, int flags)
4516 {
4517         struct socket_info *si;
4518         struct msghdr msg;
4519         struct swrap_address saddr = {
4520                 .sa_socklen = sizeof(struct sockaddr_storage),
4521         };
4522         struct iovec tmp;
4523         ssize_t ret;
4524         int tret;
4525
4526         si = find_socket_info(s);
4527         if (si == NULL) {
4528                 return libc_recv(s, buf, len, flags);
4529         }
4530
4531         tmp.iov_base = buf;
4532         tmp.iov_len = len;
4533
4534         ZERO_STRUCT(msg);
4535         msg.msg_name = &saddr.sa.s;    /* optional address */
4536         msg.msg_namelen = saddr.sa_socklen; /* size of address */
4537         msg.msg_iov = &tmp;            /* scatter/gather array */
4538         msg.msg_iovlen = 1;            /* # elements in msg_iov */
4539 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4540         msg.msg_control = NULL;        /* ancillary data, see below */
4541         msg.msg_controllen = 0;        /* ancillary data buffer len */
4542         msg.msg_flags = 0;             /* flags on received message */
4543 #endif
4544
4545         tret = swrap_recvmsg_before(s, si, &msg, &tmp);
4546         if (tret < 0) {
4547                 return -1;
4548         }
4549
4550         buf = msg.msg_iov[0].iov_base;
4551         len = msg.msg_iov[0].iov_len;
4552
4553         ret = libc_recv(s, buf, len, flags);
4554
4555         tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
4556         if (tret != 0) {
4557                 return tret;
4558         }
4559
4560         return ret;
4561 }
4562
4563 ssize_t recv(int s, void *buf, size_t len, int flags)
4564 {
4565         return swrap_recv(s, buf, len, flags);
4566 }
4567
4568 /****************************************************************************
4569  *   READ
4570  ***************************************************************************/
4571
4572 static ssize_t swrap_read(int s, void *buf, size_t len)
4573 {
4574         struct socket_info *si;
4575         struct msghdr msg;
4576         struct iovec tmp;
4577         struct swrap_address saddr = {
4578                 .sa_socklen = sizeof(struct sockaddr_storage),
4579         };
4580         ssize_t ret;
4581         int tret;
4582
4583         si = find_socket_info(s);
4584         if (si == NULL) {
4585                 return libc_read(s, buf, len);
4586         }
4587
4588         tmp.iov_base = buf;
4589         tmp.iov_len = len;
4590
4591         ZERO_STRUCT(msg);
4592         msg.msg_name = &saddr.sa.ss;   /* optional address */
4593         msg.msg_namelen = saddr.sa_socklen; /* size of address */
4594         msg.msg_iov = &tmp;            /* scatter/gather array */
4595         msg.msg_iovlen = 1;            /* # elements in msg_iov */
4596 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4597         msg.msg_control = NULL;        /* ancillary data, see below */
4598         msg.msg_controllen = 0;        /* ancillary data buffer len */
4599         msg.msg_flags = 0;             /* flags on received message */
4600 #endif
4601
4602         tret = swrap_recvmsg_before(s, si, &msg, &tmp);
4603         if (tret < 0) {
4604                 if (tret == -ENOTSOCK) {
4605                         return libc_read(s, buf, len);
4606                 }
4607                 return -1;
4608         }
4609
4610         buf = msg.msg_iov[0].iov_base;
4611         len = msg.msg_iov[0].iov_len;
4612
4613         ret = libc_read(s, buf, len);
4614
4615         tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
4616         if (tret != 0) {
4617                 return tret;
4618         }
4619
4620         return ret;
4621 }
4622
4623 ssize_t read(int s, void *buf, size_t len)
4624 {
4625         return swrap_read(s, buf, len);
4626 }
4627
4628 /****************************************************************************
4629  *   WRITE
4630  ***************************************************************************/
4631
4632 static ssize_t swrap_write(int s, const void *buf, size_t len)
4633 {
4634         struct msghdr msg;
4635         struct iovec tmp;
4636         struct sockaddr_un un_addr;
4637         ssize_t ret;
4638         int rc;
4639         struct socket_info *si;
4640
4641         si = find_socket_info(s);
4642         if (si == NULL) {
4643                 return libc_write(s, buf, len);
4644         }
4645
4646         tmp.iov_base = discard_const_p(char, buf);
4647         tmp.iov_len = len;
4648
4649         ZERO_STRUCT(msg);
4650         msg.msg_name = NULL;           /* optional address */
4651         msg.msg_namelen = 0;           /* size of address */
4652         msg.msg_iov = &tmp;            /* scatter/gather array */
4653         msg.msg_iovlen = 1;            /* # elements in msg_iov */
4654 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
4655         msg.msg_control = NULL;        /* ancillary data, see below */
4656         msg.msg_controllen = 0;        /* ancillary data buffer len */
4657         msg.msg_flags = 0;             /* flags on received message */
4658 #endif
4659
4660         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
4661         if (rc < 0) {
4662                 return -1;
4663         }
4664
4665         buf = msg.msg_iov[0].iov_base;
4666         len = msg.msg_iov[0].iov_len;
4667
4668         ret = libc_write(s, buf, len);
4669
4670         swrap_sendmsg_after(s, si, &msg, NULL, ret);
4671
4672         return ret;
4673 }
4674
4675 ssize_t write(int s, const void *buf, size_t len)
4676 {
4677         return swrap_write(s, buf, len);
4678 }
4679
4680 /****************************************************************************
4681  *   SEND
4682  ***************************************************************************/
4683
4684 static ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
4685 {
4686         struct msghdr msg;
4687         struct iovec tmp;
4688         struct sockaddr_un un_addr;
4689         ssize_t ret;
4690         int rc;
4691         struct socket_info *si = find_socket_info(s);
4692
4693         if (!si) {
4694                 return libc_send(s, buf, len, flags);
4695         }
4696
4697         tmp.iov_base = discard_const_p(char, buf);
4698         tmp.iov_len = len;
4699
4700         ZERO_STRUCT(msg);
4701         msg.msg_name = NULL;           /* optional address */
4702         msg.msg_namelen = 0;           /* size of address */
4703         msg.msg_iov = &tmp;            /* scatter/gather array */
4704         msg.msg_iovlen = 1;            /* # elements in msg_iov */
4705 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
4706         msg.msg_control = NULL;        /* ancillary data, see below */
4707         msg.msg_controllen = 0;        /* ancillary data buffer len */
4708         msg.msg_flags = 0;             /* flags on received message */
4709 #endif
4710
4711         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
4712         if (rc < 0) {
4713                 return -1;
4714         }
4715
4716         buf = msg.msg_iov[0].iov_base;
4717         len = msg.msg_iov[0].iov_len;
4718
4719         ret = libc_send(s, buf, len, flags);
4720
4721         swrap_sendmsg_after(s, si, &msg, NULL, ret);
4722
4723         return ret;
4724 }
4725
4726 ssize_t send(int s, const void *buf, size_t len, int flags)
4727 {
4728         return swrap_send(s, buf, len, flags);
4729 }
4730
4731 /****************************************************************************
4732  *   RECVMSG
4733  ***************************************************************************/
4734
4735 static ssize_t swrap_recvmsg(int s, struct msghdr *omsg, int flags)
4736 {
4737         struct swrap_address from_addr = {
4738                 .sa_socklen = sizeof(struct sockaddr_un),
4739         };
4740         struct swrap_address convert_addr = {
4741                 .sa_socklen = sizeof(struct sockaddr_storage),
4742         };
4743         struct socket_info *si;
4744         struct msghdr msg;
4745         struct iovec tmp;
4746 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4747         size_t msg_ctrllen_filled;
4748         size_t msg_ctrllen_left;
4749 #endif
4750
4751         ssize_t ret;
4752         int rc;
4753
4754         si = find_socket_info(s);
4755         if (si == NULL) {
4756                 return libc_recvmsg(s, omsg, flags);
4757         }
4758
4759         tmp.iov_base = NULL;
4760         tmp.iov_len = 0;
4761
4762         ZERO_STRUCT(msg);
4763         msg.msg_name = &from_addr.sa;              /* optional address */
4764         msg.msg_namelen = from_addr.sa_socklen;    /* size of address */
4765         msg.msg_iov = omsg->msg_iov;               /* scatter/gather array */
4766         msg.msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
4767 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4768         msg_ctrllen_filled = 0;
4769         msg_ctrllen_left = omsg->msg_controllen;
4770
4771         msg.msg_control = omsg->msg_control;       /* ancillary data, see below */
4772         msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
4773         msg.msg_flags = omsg->msg_flags;           /* flags on received message */
4774 #endif
4775
4776         rc = swrap_recvmsg_before(s, si, &msg, &tmp);
4777         if (rc < 0) {
4778                 return -1;
4779         }
4780
4781         ret = libc_recvmsg(s, &msg, flags);
4782
4783 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4784         msg_ctrllen_filled += msg.msg_controllen;
4785         msg_ctrllen_left -= msg.msg_controllen;
4786
4787         if (omsg->msg_control != NULL) {
4788                 uint8_t *p;
4789
4790                 p = omsg->msg_control;
4791                 p += msg_ctrllen_filled;
4792
4793                 msg.msg_control = p;
4794                 msg.msg_controllen = msg_ctrllen_left;
4795         } else {
4796                 msg.msg_control = NULL;
4797                 msg.msg_controllen = 0;
4798         }
4799 #endif
4800
4801         /*
4802          * We convert the unix address to a IP address so we need a buffer
4803          * which can store the address in case of SOCK_DGRAM, see below.
4804          */
4805         msg.msg_name = &convert_addr.sa;
4806         msg.msg_namelen = convert_addr.sa_socklen;
4807
4808         rc = swrap_recvmsg_after(s,
4809                                  si,
4810                                  &msg,
4811                                  &from_addr.sa.un,
4812                                  from_addr.sa_socklen,
4813                                  ret);
4814         if (rc != 0) {
4815                 return rc;
4816         }
4817
4818 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4819         if (omsg->msg_control != NULL) {
4820                 /* msg.msg_controllen = space left */
4821                 msg_ctrllen_left = msg.msg_controllen;
4822                 msg_ctrllen_filled = omsg->msg_controllen - msg_ctrllen_left;
4823         }
4824
4825         /* Update the original message length */
4826         omsg->msg_controllen = msg_ctrllen_filled;
4827         omsg->msg_flags = msg.msg_flags;
4828 #endif
4829         omsg->msg_iovlen = msg.msg_iovlen;
4830
4831         /*
4832          * From the manpage:
4833          *
4834          * The  msg_name  field  points  to a caller-allocated buffer that is
4835          * used to return the source address if the socket is unconnected.  The
4836          * caller should set msg_namelen to the size of this buffer before this
4837          * call; upon return from a successful call, msg_name will contain the
4838          * length of the returned address.  If the application  does  not  need
4839          * to know the source address, msg_name can be specified as NULL.
4840          */
4841         if (si->type == SOCK_STREAM) {
4842                 omsg->msg_namelen = 0;
4843         } else if (omsg->msg_name != NULL &&
4844                    omsg->msg_namelen != 0 &&
4845                    omsg->msg_namelen >= msg.msg_namelen) {
4846                 memcpy(omsg->msg_name, msg.msg_name, msg.msg_namelen);
4847                 omsg->msg_namelen = msg.msg_namelen;
4848         }
4849
4850         return ret;
4851 }
4852
4853 ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)
4854 {
4855         return swrap_recvmsg(sockfd, msg, flags);
4856 }
4857
4858 /****************************************************************************
4859  *   SENDMSG
4860  ***************************************************************************/
4861
4862 static ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags)
4863 {
4864         struct msghdr msg;
4865         struct iovec tmp;
4866         struct sockaddr_un un_addr;
4867         const struct sockaddr_un *to_un = NULL;
4868         const struct sockaddr *to = NULL;
4869         ssize_t ret;
4870         int rc;
4871         struct socket_info *si = find_socket_info(s);
4872         int bcast = 0;
4873
4874         if (!si) {
4875                 return libc_sendmsg(s, omsg, flags);
4876         }
4877
4878         ZERO_STRUCT(un_addr);
4879
4880         tmp.iov_base = NULL;
4881         tmp.iov_len = 0;
4882
4883         ZERO_STRUCT(msg);
4884
4885         if (si->connected == 0) {
4886                 msg.msg_name = omsg->msg_name;             /* optional address */
4887                 msg.msg_namelen = omsg->msg_namelen;       /* size of address */
4888         }
4889         msg.msg_iov = omsg->msg_iov;               /* scatter/gather array */
4890         msg.msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
4891 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4892         if (msg.msg_controllen > 0 && msg.msg_control != NULL) {
4893                 /* omsg is a const so use a local buffer for modifications */
4894                 uint8_t cmbuf[omsg->msg_controllen];
4895
4896                 memcpy(cmbuf, omsg->msg_control, omsg->msg_controllen);
4897
4898                 msg.msg_control = cmbuf;       /* ancillary data, see below */
4899                 msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
4900         }
4901         msg.msg_flags = omsg->msg_flags;           /* flags on received message */
4902 #endif
4903
4904         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
4905         if (rc < 0) {
4906                 return -1;
4907         }
4908
4909         if (bcast) {
4910                 struct stat st;
4911                 unsigned int iface;
4912                 unsigned int prt = ntohs(((const struct sockaddr_in *)(const void *)to)->sin_port);
4913                 char type;
4914                 size_t i, len = 0;
4915                 uint8_t *buf;
4916                 off_t ofs = 0;
4917                 size_t avail = 0;
4918                 size_t remain;
4919
4920                 for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
4921                         avail += msg.msg_iov[i].iov_len;
4922                 }
4923
4924                 len = avail;
4925                 remain = avail;
4926
4927                 /* we capture it as one single packet */
4928                 buf = (uint8_t *)malloc(remain);
4929                 if (!buf) {
4930                         return -1;
4931                 }
4932
4933                 for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
4934                         size_t this_time = MIN(remain, (size_t)msg.msg_iov[i].iov_len);
4935                         memcpy(buf + ofs,
4936                                msg.msg_iov[i].iov_base,
4937                                this_time);
4938                         ofs += this_time;
4939                         remain -= this_time;
4940                 }
4941
4942                 type = SOCKET_TYPE_CHAR_UDP;
4943
4944                 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
4945                         snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT,
4946                                  socket_wrapper_dir(), type, iface, prt);
4947                         if (stat(un_addr.sun_path, &st) != 0) continue;
4948
4949                         msg.msg_name = &un_addr;           /* optional address */
4950                         msg.msg_namelen = sizeof(un_addr); /* size of address */
4951
4952                         /* ignore the any errors in broadcast sends */
4953                         libc_sendmsg(s, &msg, flags);
4954                 }
4955
4956                 swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
4957                 free(buf);
4958
4959                 return len;
4960         }
4961
4962         ret = libc_sendmsg(s, &msg, flags);
4963
4964         swrap_sendmsg_after(s, si, &msg, to, ret);
4965
4966         return ret;
4967 }
4968
4969 ssize_t sendmsg(int s, const struct msghdr *omsg, int flags)
4970 {
4971         return swrap_sendmsg(s, omsg, flags);
4972 }
4973
4974 /****************************************************************************
4975  *   READV
4976  ***************************************************************************/
4977
4978 static ssize_t swrap_readv(int s, const struct iovec *vector, int count)
4979 {
4980         struct socket_info *si;
4981         struct msghdr msg;
4982         struct iovec tmp;
4983         struct swrap_address saddr = {
4984                 .sa_socklen = sizeof(struct sockaddr_storage)
4985         };
4986         ssize_t ret;
4987         int rc;
4988
4989         si = find_socket_info(s);
4990         if (si == NULL) {
4991                 return libc_readv(s, vector, count);
4992         }
4993
4994         tmp.iov_base = NULL;
4995         tmp.iov_len = 0;
4996
4997         ZERO_STRUCT(msg);
4998         msg.msg_name = &saddr.sa.s; /* optional address */
4999         msg.msg_namelen = saddr.sa_socklen;      /* size of address */
5000         msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
5001         msg.msg_iovlen = count;        /* # elements in msg_iov */
5002 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5003         msg.msg_control = NULL;        /* ancillary data, see below */
5004         msg.msg_controllen = 0;        /* ancillary data buffer len */
5005         msg.msg_flags = 0;             /* flags on received message */
5006 #endif
5007
5008         rc = swrap_recvmsg_before(s, si, &msg, &tmp);
5009         if (rc < 0) {
5010                 if (rc == -ENOTSOCK) {
5011                         return libc_readv(s, vector, count);
5012                 }
5013                 return -1;
5014         }
5015
5016         ret = libc_readv(s, msg.msg_iov, msg.msg_iovlen);
5017
5018         rc = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
5019         if (rc != 0) {
5020                 return rc;
5021         }
5022
5023         return ret;
5024 }
5025
5026 ssize_t readv(int s, const struct iovec *vector, int count)
5027 {
5028         return swrap_readv(s, vector, count);
5029 }
5030
5031 /****************************************************************************
5032  *   WRITEV
5033  ***************************************************************************/
5034
5035 static ssize_t swrap_writev(int s, const struct iovec *vector, int count)
5036 {
5037         struct msghdr msg;
5038         struct iovec tmp;
5039         struct sockaddr_un un_addr;
5040         ssize_t ret;
5041         int rc;
5042         struct socket_info *si = find_socket_info(s);
5043
5044         if (!si) {
5045                 return libc_writev(s, vector, count);
5046         }
5047
5048         tmp.iov_base = NULL;
5049         tmp.iov_len = 0;
5050
5051         ZERO_STRUCT(msg);
5052         msg.msg_name = NULL;           /* optional address */
5053         msg.msg_namelen = 0;           /* size of address */
5054         msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
5055         msg.msg_iovlen = count;        /* # elements in msg_iov */
5056 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
5057         msg.msg_control = NULL;        /* ancillary data, see below */
5058         msg.msg_controllen = 0;        /* ancillary data buffer len */
5059         msg.msg_flags = 0;             /* flags on received message */
5060 #endif
5061
5062         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
5063         if (rc < 0) {
5064                 if (rc == -ENOTSOCK) {
5065                         return libc_readv(s, vector, count);
5066                 }
5067                 return -1;
5068         }
5069
5070         ret = libc_writev(s, msg.msg_iov, msg.msg_iovlen);
5071
5072         swrap_sendmsg_after(s, si, &msg, NULL, ret);
5073
5074         return ret;
5075 }
5076
5077 ssize_t writev(int s, const struct iovec *vector, int count)
5078 {
5079         return swrap_writev(s, vector, count);
5080 }
5081
5082 /****************************
5083  * CLOSE
5084  ***************************/
5085
5086 static int swrap_close(int fd)
5087 {
5088         struct socket_info *si = find_socket_info(fd);
5089         struct socket_info_fd *fi;
5090         int ret;
5091
5092         if (!si) {
5093                 return libc_close(fd);
5094         }
5095
5096         for (fi = si->fds; fi; fi = fi->next) {
5097                 if (fi->fd == fd) {
5098                         SWRAP_DLIST_REMOVE(si->fds, fi);
5099                         free(fi);
5100                         break;
5101                 }
5102         }
5103
5104         if (si->fds) {
5105                 /* there are still references left */
5106                 return libc_close(fd);
5107         }
5108
5109         SWRAP_DLIST_REMOVE(sockets, si);
5110
5111         if (si->myname.sa_socklen > 0 && si->peername.sa_socklen > 0) {
5112                 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0);
5113         }
5114
5115         ret = libc_close(fd);
5116
5117         if (si->myname.sa_socklen > 0 && si->peername.sa_socklen > 0) {
5118                 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0);
5119                 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0);
5120         }
5121
5122         if (si->un_addr.sun_path[0] != '\0') {
5123                 unlink(si->un_addr.sun_path);
5124         }
5125         free(si);
5126
5127         return ret;
5128 }
5129
5130 int close(int fd)
5131 {
5132         return swrap_close(fd);
5133 }
5134
5135 /****************************
5136  * DUP
5137  ***************************/
5138
5139 static int swrap_dup(int fd)
5140 {
5141         struct socket_info *si;
5142         struct socket_info_fd *fi;
5143
5144         si = find_socket_info(fd);
5145
5146         if (!si) {
5147                 return libc_dup(fd);
5148         }
5149
5150         fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
5151         if (fi == NULL) {
5152                 errno = ENOMEM;
5153                 return -1;
5154         }
5155
5156         fi->fd = libc_dup(fd);
5157         if (fi->fd == -1) {
5158                 int saved_errno = errno;
5159                 free(fi);
5160                 errno = saved_errno;
5161                 return -1;
5162         }
5163
5164         /* Make sure we don't have an entry for the fd */
5165         swrap_remove_stale(fi->fd);
5166
5167         SWRAP_DLIST_ADD(si->fds, fi);
5168         return fi->fd;
5169 }
5170
5171 int dup(int fd)
5172 {
5173         return swrap_dup(fd);
5174 }
5175
5176 /****************************
5177  * DUP2
5178  ***************************/
5179
5180 static int swrap_dup2(int fd, int newfd)
5181 {
5182         struct socket_info *si;
5183         struct socket_info_fd *fi;
5184
5185         si = find_socket_info(fd);
5186
5187         if (!si) {
5188                 return libc_dup2(fd, newfd);
5189         }
5190
5191         if (find_socket_info(newfd)) {
5192                 /* dup2() does an implicit close of newfd, which we
5193                  * need to emulate */
5194                 swrap_close(newfd);
5195         }
5196
5197         fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
5198         if (fi == NULL) {
5199                 errno = ENOMEM;
5200                 return -1;
5201         }
5202
5203         fi->fd = libc_dup2(fd, newfd);
5204         if (fi->fd == -1) {
5205                 int saved_errno = errno;
5206                 free(fi);
5207                 errno = saved_errno;
5208                 return -1;
5209         }
5210
5211         /* Make sure we don't have an entry for the fd */
5212         swrap_remove_stale(fi->fd);
5213
5214         SWRAP_DLIST_ADD(si->fds, fi);
5215         return fi->fd;
5216 }
5217
5218 int dup2(int fd, int newfd)
5219 {
5220         return swrap_dup2(fd, newfd);
5221 }
5222
5223 /****************************
5224  * FCNTL
5225  ***************************/
5226
5227 static int swrap_vfcntl(int fd, int cmd, va_list va)
5228 {
5229         struct socket_info_fd *fi;
5230         struct socket_info *si;
5231         int rc;
5232
5233         si = find_socket_info(fd);
5234         if (si == NULL) {
5235                 rc = libc_vfcntl(fd, cmd, va);
5236
5237                 return rc;
5238         }
5239
5240         switch (cmd) {
5241         case F_DUPFD:
5242                 fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
5243                 if (fi == NULL) {
5244                         errno = ENOMEM;
5245                         return -1;
5246                 }
5247
5248                 fi->fd = libc_vfcntl(fd, cmd, va);
5249                 if (fi->fd == -1) {
5250                         int saved_errno = errno;
5251                         free(fi);
5252                         errno = saved_errno;
5253                         return -1;
5254                 }
5255
5256                 /* Make sure we don't have an entry for the fd */
5257                 swrap_remove_stale(fi->fd);
5258
5259                 SWRAP_DLIST_ADD(si->fds, fi);
5260
5261                 rc = fi->fd;
5262                 break;
5263         default:
5264                 rc = libc_vfcntl(fd, cmd, va);
5265                 break;
5266         }
5267
5268         return rc;
5269 }
5270
5271 int fcntl(int fd, int cmd, ...)
5272 {
5273         va_list va;
5274         int rc;
5275
5276         va_start(va, cmd);
5277
5278         rc = swrap_vfcntl(fd, cmd, va);
5279
5280         va_end(va);
5281
5282         return rc;
5283 }
5284
5285 /****************************
5286  * EVENTFD
5287  ***************************/
5288
5289 #ifdef HAVE_EVENTFD
5290 static int swrap_eventfd(int count, int flags)
5291 {
5292         int fd;
5293
5294         fd = libc_eventfd(count, flags);
5295         if (fd != -1) {
5296                 swrap_remove_stale(fd);
5297         }
5298
5299         return fd;
5300 }
5301
5302 #ifdef HAVE_EVENTFD_UNSIGNED_INT
5303 int eventfd(unsigned int count, int flags)
5304 #else
5305 int eventfd(int count, int flags)
5306 #endif
5307 {
5308         return swrap_eventfd(count, flags);
5309 }
5310 #endif
5311
5312 #ifdef HAVE_PLEDGE
5313 int pledge(const char *promises, const char *paths[])
5314 {
5315         (void)promises; /* unused */
5316         (void)paths; /* unused */
5317
5318         return 0;
5319 }
5320 #endif /* HAVE_PLEDGE */
5321
5322 /****************************
5323  * DESTRUCTOR
5324  ***************************/
5325
5326 /*
5327  * This function is called when the library is unloaded and makes sure that
5328  * sockets get closed and the unix file for the socket are unlinked.
5329  */
5330 void swrap_destructor(void)
5331 {
5332         struct socket_info *s = sockets;
5333
5334         while (s != NULL) {
5335                 struct socket_info_fd *f = s->fds;
5336                 if (f != NULL) {
5337                         swrap_close(f->fd);
5338                 }
5339                 s = sockets;
5340         }
5341
5342         if (swrap.libc_handle != NULL) {
5343                 dlclose(swrap.libc_handle);
5344         }
5345         if (swrap.libsocket_handle) {
5346                 dlclose(swrap.libsocket_handle);
5347         }
5348 }