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