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