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