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