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