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