swrap: Use swrap_create_socket within swrap_socket
[socket_wrapper.git] / src / socket_wrapper.c
1 /*
2  * Copyright (c) 2005-2008 Jelmer Vernooij <jelmer@samba.org>
3  * Copyright (C) 2006-2014 Stefan Metzmacher <metze@samba.org>
4  * Copyright (C) 2013-2014 Andreas Schneider <asn@samba.org>
5  *
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * 3. Neither the name of the author nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  */
36
37 /*
38    Socket wrapper library. Passes all socket communication over
39    unix domain sockets if the environment variable SOCKET_WRAPPER_DIR
40    is set.
41 */
42
43 #include "config.h"
44
45 #include <sys/types.h>
46 #include <sys/time.h>
47 #include <sys/stat.h>
48 #include <sys/socket.h>
49 #include <sys/ioctl.h>
50 #ifdef HAVE_SYS_FILIO_H
51 #include <sys/filio.h>
52 #endif
53 #ifdef HAVE_SYS_SIGNALFD_H
54 #include <sys/signalfd.h>
55 #endif
56 #ifdef HAVE_SYS_EVENTFD_H
57 #include <sys/eventfd.h>
58 #endif
59 #ifdef HAVE_SYS_TIMERFD_H
60 #include <sys/timerfd.h>
61 #endif
62 #include <sys/uio.h>
63 #include <errno.h>
64 #include <sys/un.h>
65 #include <netinet/in.h>
66 #include <netinet/tcp.h>
67 #include <arpa/inet.h>
68 #include <fcntl.h>
69 #include <stdlib.h>
70 #include <string.h>
71 #include <stdio.h>
72 #include <stdint.h>
73 #include <stdarg.h>
74 #include <stdbool.h>
75 #include <unistd.h>
76 #ifdef HAVE_GNU_LIB_NAMES_H
77 #include <gnu/lib-names.h>
78 #endif
79 #ifdef HAVE_RPC_RPC_H
80 #include <rpc/rpc.h>
81 #endif
82 #include <pthread.h>
83
84 enum swrap_dbglvl_e {
85         SWRAP_LOG_ERROR = 0,
86         SWRAP_LOG_WARN,
87         SWRAP_LOG_DEBUG,
88         SWRAP_LOG_TRACE
89 };
90
91 /* GCC have printf type attribute check. */
92 #ifdef HAVE_FUNCTION_ATTRIBUTE_FORMAT
93 #define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
94 #else
95 #define PRINTF_ATTRIBUTE(a,b)
96 #endif /* HAVE_FUNCTION_ATTRIBUTE_FORMAT */
97
98 #ifdef HAVE_CONSTRUCTOR_ATTRIBUTE
99 #define CONSTRUCTOR_ATTRIBUTE __attribute__ ((constructor))
100 #else
101 #define CONSTRUCTOR_ATTRIBUTE
102 #endif /* HAVE_CONSTRUCTOR_ATTRIBUTE */
103
104 #ifdef HAVE_DESTRUCTOR_ATTRIBUTE
105 #define DESTRUCTOR_ATTRIBUTE __attribute__ ((destructor))
106 #else
107 #define DESTRUCTOR_ATTRIBUTE
108 #endif
109
110 #ifndef FALL_THROUGH
111 # ifdef HAVE_FALLTHROUGH_ATTRIBUTE
112 #  define FALL_THROUGH __attribute__ ((fallthrough))
113 # else /* HAVE_FALLTHROUGH_ATTRIBUTE */
114 #  define FALL_THROUGH ((void)0)
115 # endif /* HAVE_FALLTHROUGH_ATTRIBUTE */
116 #endif /* FALL_THROUGH */
117
118 #ifdef HAVE_ADDRESS_SANITIZER_ATTRIBUTE
119 #define DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE __attribute__((no_sanitize_address))
120 #else
121 #define DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
122 #endif
123
124 #ifdef HAVE_GCC_THREAD_LOCAL_STORAGE
125 # define SWRAP_THREAD __thread
126 #else
127 # define SWRAP_THREAD
128 #endif
129
130 #ifndef MIN
131 #define MIN(a,b) ((a)<(b)?(a):(b))
132 #endif
133
134 #ifndef ZERO_STRUCT
135 #define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
136 #endif
137
138 #ifndef ZERO_STRUCTP
139 #define ZERO_STRUCTP(x) do { \
140                 if ((x) != NULL) \
141                         memset((char *)(x), 0, sizeof(*(x))); \
142         } while(0)
143 #endif
144
145 #ifndef discard_const
146 #define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
147 #endif
148
149 #ifndef discard_const_p
150 #define discard_const_p(type, ptr) ((type *)discard_const(ptr))
151 #endif
152
153 #define UNUSED(x) (void)(x)
154
155 #ifdef IPV6_PKTINFO
156 # ifndef IPV6_RECVPKTINFO
157 #  define IPV6_RECVPKTINFO IPV6_PKTINFO
158 # endif /* IPV6_RECVPKTINFO */
159 #endif /* IPV6_PKTINFO */
160
161 /*
162  * On BSD IP_PKTINFO has a different name because during
163  * the time when they implemented it, there was no RFC.
164  * The name for IPv6 is the same as on Linux.
165  */
166 #ifndef IP_PKTINFO
167 # ifdef IP_RECVDSTADDR
168 #  define IP_PKTINFO IP_RECVDSTADDR
169 # endif
170 #endif
171
172 /* Macros for accessing mutexes */
173 # define SWRAP_LOCK(m) do { \
174         pthread_mutex_lock(&(m ## _mutex)); \
175 } while(0)
176
177 # define SWRAP_UNLOCK(m) do { \
178         pthread_mutex_unlock(&(m ## _mutex)); \
179 } while(0)
180
181 /* Add new global locks here please */
182 # define SWRAP_LOCK_ALL \
183         SWRAP_LOCK(libc_symbol_binding); \
184
185 # define SWRAP_UNLOCK_ALL \
186         SWRAP_UNLOCK(libc_symbol_binding); \
187
188 #define SOCKET_INFO_CONTAINER(si) \
189         (struct socket_info_container *)(si)
190
191 #define SWRAP_DLIST_ADD(list,item) do { \
192         if (!(list)) { \
193                 (item)->prev    = NULL; \
194                 (item)->next    = NULL; \
195                 (list)          = (item); \
196         } else { \
197                 (item)->prev    = NULL; \
198                 (item)->next    = (list); \
199                 (list)->prev    = (item); \
200                 (list)          = (item); \
201         } \
202 } while (0)
203
204 #define SWRAP_DLIST_REMOVE(list,item) do { \
205         if ((list) == (item)) { \
206                 (list)          = (item)->next; \
207                 if (list) { \
208                         (list)->prev    = NULL; \
209                 } \
210         } else { \
211                 if ((item)->prev) { \
212                         (item)->prev->next      = (item)->next; \
213                 } \
214                 if ((item)->next) { \
215                         (item)->next->prev      = (item)->prev; \
216                 } \
217         } \
218         (item)->prev    = NULL; \
219         (item)->next    = NULL; \
220 } while (0)
221
222 #define SWRAP_DLIST_ADD_AFTER(list, item, el) \
223 do { \
224         if ((list) == NULL || (el) == NULL) { \
225                 SWRAP_DLIST_ADD(list, item); \
226         } else { \
227                 (item)->prev = (el); \
228                 (item)->next = (el)->next; \
229                 (el)->next = (item); \
230                 if ((item)->next != NULL) { \
231                         (item)->next->prev = (item); \
232                 } \
233         } \
234 } while (0)
235
236 #if defined(HAVE_GETTIMEOFDAY_TZ) || defined(HAVE_GETTIMEOFDAY_TZ_VOID)
237 #define swrapGetTimeOfDay(tval) gettimeofday(tval,NULL)
238 #else
239 #define swrapGetTimeOfDay(tval) gettimeofday(tval)
240 #endif
241
242 /* we need to use a very terse format here as IRIX 6.4 silently
243    truncates names to 16 chars, so if we use a longer name then we
244    can't tell which port a packet came from with recvfrom()
245
246    with this format we have 8 chars left for the directory name
247 */
248 #define SOCKET_FORMAT "%c%02X%04X"
249 #define SOCKET_TYPE_CHAR_TCP            'T'
250 #define SOCKET_TYPE_CHAR_UDP            'U'
251 #define SOCKET_TYPE_CHAR_TCP_V6         'X'
252 #define SOCKET_TYPE_CHAR_UDP_V6         'Y'
253
254 /*
255  * Set the packet MTU to 1500 bytes for stream sockets to make it it easier to
256  * format PCAP capture files (as the caller will simply continue from here).
257  */
258 #define SOCKET_WRAPPER_MTU_DEFAULT 1500
259 #define SOCKET_WRAPPER_MTU_MIN     512
260 #define SOCKET_WRAPPER_MTU_MAX     32768
261
262 #define SOCKET_MAX_SOCKETS 1024
263
264
265 /*
266  * Maximum number of socket_info structures that can
267  * be used. Can be overriden by the environment variable
268  * SOCKET_WRAPPER_MAX_SOCKETS.
269  */
270 #define SOCKET_WRAPPER_MAX_SOCKETS_DEFAULT 65535
271
272 #define SOCKET_WRAPPER_MAX_SOCKETS_LIMIT 256000
273
274 /* This limit is to avoid broadcast sendto() needing to stat too many
275  * files.  It may be raised (with a performance cost) to up to 254
276  * without changing the format above */
277 #define MAX_WRAPPED_INTERFACES 64
278
279 struct swrap_address {
280         socklen_t sa_socklen;
281         union {
282                 struct sockaddr s;
283                 struct sockaddr_in in;
284 #ifdef HAVE_IPV6
285                 struct sockaddr_in6 in6;
286 #endif
287                 struct sockaddr_un un;
288                 struct sockaddr_storage ss;
289         } sa;
290 };
291
292 struct socket_info_fd {
293         struct socket_info_fd *prev, *next;
294         int fd;
295
296         /*
297          * Points to corresponding index in array of
298          * socket_info structures
299          */
300         int si_index;
301 };
302
303 int first_free;
304
305 struct socket_info
306 {
307         int family;
308         int type;
309         int protocol;
310         int bound;
311         int bcast;
312         int is_server;
313         int connected;
314         int defer_connect;
315         int pktinfo;
316         int tcp_nodelay;
317
318         /* The unix path so we can unlink it on close() */
319         struct sockaddr_un un_addr;
320
321         struct swrap_address bindname;
322         struct swrap_address myname;
323         struct swrap_address peername;
324
325         struct {
326                 unsigned long pck_snd;
327                 unsigned long pck_rcv;
328         } io;
329 };
330
331 struct socket_info_container
332 {
333         struct socket_info info;
334         unsigned int refcount;
335         int next_free;
336 };
337
338 static struct socket_info_container *sockets;
339 static size_t max_sockets = 0;
340
341 /*
342  * While socket file descriptors are passed among different processes, the
343  * numerical value gets changed. So its better to store it locally to each
344  * process rather than including it within socket_info which will be shared.
345  */
346 static struct socket_info_fd *socket_fds;
347
348 /* The mutex for accessing the global libc.symbols */
349 static pthread_mutex_t libc_symbol_binding_mutex = PTHREAD_MUTEX_INITIALIZER;
350
351 /* Function prototypes */
352
353 bool socket_wrapper_enabled(void);
354
355 void swrap_constructor(void) CONSTRUCTOR_ATTRIBUTE;
356 void swrap_destructor(void) DESTRUCTOR_ATTRIBUTE;
357
358 static void swrap_log(enum swrap_dbglvl_e dbglvl, const char *func, const char *format, ...) PRINTF_ATTRIBUTE(3, 4);
359 # define SWRAP_LOG(dbglvl, ...) swrap_log((dbglvl), __func__, __VA_ARGS__)
360
361 static void swrap_log(enum swrap_dbglvl_e dbglvl,
362                       const char *func,
363                       const char *format, ...)
364 {
365         char buffer[1024];
366         va_list va;
367         const char *d;
368         unsigned int lvl = 0;
369         const char *prefix = "SWRAP";
370
371         d = getenv("SOCKET_WRAPPER_DEBUGLEVEL");
372         if (d != NULL) {
373                 lvl = atoi(d);
374         }
375
376         if (lvl < dbglvl) {
377                 return;
378         }
379
380         va_start(va, format);
381         vsnprintf(buffer, sizeof(buffer), format, va);
382         va_end(va);
383
384         switch (dbglvl) {
385                 case SWRAP_LOG_ERROR:
386                         prefix = "SWRAP_ERROR";
387                         break;
388                 case SWRAP_LOG_WARN:
389                         prefix = "SWRAP_WARN";
390                         break;
391                 case SWRAP_LOG_DEBUG:
392                         prefix = "SWRAP_DEBUG";
393                         break;
394                 case SWRAP_LOG_TRACE:
395                         prefix = "SWRAP_TRACE";
396                         break;
397         }
398
399         fprintf(stderr,
400                 "%s(%d) - %s: %s\n",
401                 prefix, (int)getpid(), func, buffer);
402 }
403
404 /*********************************************************
405  * SWRAP LOADING LIBC FUNCTIONS
406  *********************************************************/
407
408 #include <dlfcn.h>
409
410 #ifdef HAVE_ACCEPT4
411 typedef int (*__libc_accept4)(int sockfd,
412                               struct sockaddr *addr,
413                               socklen_t *addrlen,
414                               int flags);
415 #else
416 typedef int (*__libc_accept)(int sockfd,
417                              struct sockaddr *addr,
418                              socklen_t *addrlen);
419 #endif
420 typedef int (*__libc_bind)(int sockfd,
421                            const struct sockaddr *addr,
422                            socklen_t addrlen);
423 typedef int (*__libc_close)(int fd);
424 typedef int (*__libc_connect)(int sockfd,
425                               const struct sockaddr *addr,
426                               socklen_t addrlen);
427 typedef int (*__libc_dup)(int fd);
428 typedef int (*__libc_dup2)(int oldfd, int newfd);
429 typedef int (*__libc_fcntl)(int fd, int cmd, ...);
430 typedef FILE *(*__libc_fopen)(const char *name, const char *mode);
431 #ifdef HAVE_FOPEN64
432 typedef FILE *(*__libc_fopen64)(const char *name, const char *mode);
433 #endif
434 #ifdef HAVE_EVENTFD
435 typedef int (*__libc_eventfd)(int count, int flags);
436 #endif
437 typedef int (*__libc_getpeername)(int sockfd,
438                                   struct sockaddr *addr,
439                                   socklen_t *addrlen);
440 typedef int (*__libc_getsockname)(int sockfd,
441                                   struct sockaddr *addr,
442                                   socklen_t *addrlen);
443 typedef int (*__libc_getsockopt)(int sockfd,
444                                int level,
445                                int optname,
446                                void *optval,
447                                socklen_t *optlen);
448 typedef int (*__libc_ioctl)(int d, unsigned long int request, ...);
449 typedef int (*__libc_listen)(int sockfd, int backlog);
450 typedef int (*__libc_open)(const char *pathname, int flags, ...);
451 #ifdef HAVE_OPEN64
452 typedef int (*__libc_open64)(const char *pathname, int flags, ...);
453 #endif /* HAVE_OPEN64 */
454 typedef int (*__libc_openat)(int dirfd, const char *path, int flags, ...);
455 typedef int (*__libc_pipe)(int pipefd[2]);
456 typedef int (*__libc_read)(int fd, void *buf, size_t count);
457 typedef ssize_t (*__libc_readv)(int fd, const struct iovec *iov, int iovcnt);
458 typedef int (*__libc_recv)(int sockfd, void *buf, size_t len, int flags);
459 typedef int (*__libc_recvfrom)(int sockfd,
460                              void *buf,
461                              size_t len,
462                              int flags,
463                              struct sockaddr *src_addr,
464                              socklen_t *addrlen);
465 typedef int (*__libc_recvmsg)(int sockfd, const struct msghdr *msg, int flags);
466 typedef int (*__libc_send)(int sockfd, const void *buf, size_t len, int flags);
467 typedef int (*__libc_sendmsg)(int sockfd, const struct msghdr *msg, int flags);
468 typedef int (*__libc_sendto)(int sockfd,
469                            const void *buf,
470                            size_t len,
471                            int flags,
472                            const  struct sockaddr *dst_addr,
473                            socklen_t addrlen);
474 typedef int (*__libc_setsockopt)(int sockfd,
475                                int level,
476                                int optname,
477                                const void *optval,
478                                socklen_t optlen);
479 #ifdef HAVE_SIGNALFD
480 typedef int (*__libc_signalfd)(int fd, const sigset_t *mask, int flags);
481 #endif
482 typedef int (*__libc_socket)(int domain, int type, int protocol);
483 typedef int (*__libc_socketpair)(int domain, int type, int protocol, int sv[2]);
484 #ifdef HAVE_TIMERFD_CREATE
485 typedef int (*__libc_timerfd_create)(int clockid, int flags);
486 #endif
487 typedef ssize_t (*__libc_write)(int fd, const void *buf, size_t count);
488 typedef ssize_t (*__libc_writev)(int fd, const struct iovec *iov, int iovcnt);
489
490 #define SWRAP_SYMBOL_ENTRY(i) \
491         union { \
492                 __libc_##i f; \
493                 void *obj; \
494         } _libc_##i
495
496 struct swrap_libc_symbols {
497 #ifdef HAVE_ACCEPT4
498         SWRAP_SYMBOL_ENTRY(accept4);
499 #else
500         SWRAP_SYMBOL_ENTRY(accept);
501 #endif
502         SWRAP_SYMBOL_ENTRY(bind);
503         SWRAP_SYMBOL_ENTRY(close);
504         SWRAP_SYMBOL_ENTRY(connect);
505         SWRAP_SYMBOL_ENTRY(dup);
506         SWRAP_SYMBOL_ENTRY(dup2);
507         SWRAP_SYMBOL_ENTRY(fcntl);
508         SWRAP_SYMBOL_ENTRY(fopen);
509 #ifdef HAVE_FOPEN64
510         SWRAP_SYMBOL_ENTRY(fopen64);
511 #endif
512 #ifdef HAVE_EVENTFD
513         SWRAP_SYMBOL_ENTRY(eventfd);
514 #endif
515         SWRAP_SYMBOL_ENTRY(getpeername);
516         SWRAP_SYMBOL_ENTRY(getsockname);
517         SWRAP_SYMBOL_ENTRY(getsockopt);
518         SWRAP_SYMBOL_ENTRY(ioctl);
519         SWRAP_SYMBOL_ENTRY(listen);
520         SWRAP_SYMBOL_ENTRY(open);
521 #ifdef HAVE_OPEN64
522         SWRAP_SYMBOL_ENTRY(open64);
523 #endif
524         SWRAP_SYMBOL_ENTRY(openat);
525         SWRAP_SYMBOL_ENTRY(pipe);
526         SWRAP_SYMBOL_ENTRY(read);
527         SWRAP_SYMBOL_ENTRY(readv);
528         SWRAP_SYMBOL_ENTRY(recv);
529         SWRAP_SYMBOL_ENTRY(recvfrom);
530         SWRAP_SYMBOL_ENTRY(recvmsg);
531         SWRAP_SYMBOL_ENTRY(send);
532         SWRAP_SYMBOL_ENTRY(sendmsg);
533         SWRAP_SYMBOL_ENTRY(sendto);
534         SWRAP_SYMBOL_ENTRY(setsockopt);
535 #ifdef HAVE_SIGNALFD
536         SWRAP_SYMBOL_ENTRY(signalfd);
537 #endif
538         SWRAP_SYMBOL_ENTRY(socket);
539         SWRAP_SYMBOL_ENTRY(socketpair);
540 #ifdef HAVE_TIMERFD_CREATE
541         SWRAP_SYMBOL_ENTRY(timerfd_create);
542 #endif
543         SWRAP_SYMBOL_ENTRY(write);
544         SWRAP_SYMBOL_ENTRY(writev);
545 };
546
547 struct swrap {
548         struct {
549                 void *handle;
550                 void *socket_handle;
551                 struct swrap_libc_symbols symbols;
552         } libc;
553 };
554
555 static struct swrap swrap;
556
557 /* prototypes */
558 static const char *socket_wrapper_dir(void);
559
560 #define LIBC_NAME "libc.so"
561
562 enum swrap_lib {
563     SWRAP_LIBC,
564     SWRAP_LIBNSL,
565     SWRAP_LIBSOCKET,
566 };
567
568 static const char *swrap_str_lib(enum swrap_lib lib)
569 {
570         switch (lib) {
571         case SWRAP_LIBC:
572                 return "libc";
573         case SWRAP_LIBNSL:
574                 return "libnsl";
575         case SWRAP_LIBSOCKET:
576                 return "libsocket";
577         }
578
579         /* Compiler would warn us about unhandled enum value if we get here */
580         return "unknown";
581 }
582
583 static void *swrap_load_lib_handle(enum swrap_lib lib)
584 {
585         int flags = RTLD_LAZY;
586         void *handle = NULL;
587         int i;
588
589 #ifdef RTLD_DEEPBIND
590         flags |= RTLD_DEEPBIND;
591 #endif
592
593         switch (lib) {
594         case SWRAP_LIBNSL:
595                 FALL_THROUGH;
596         case SWRAP_LIBSOCKET:
597 #ifdef HAVE_LIBSOCKET
598                 handle = swrap.libc.socket_handle;
599                 if (handle == NULL) {
600                         for (i = 10; i >= 0; i--) {
601                                 char soname[256] = {0};
602
603                                 snprintf(soname, sizeof(soname), "libsocket.so.%d", i);
604                                 handle = dlopen(soname, flags);
605                                 if (handle != NULL) {
606                                         break;
607                                 }
608                         }
609
610                         swrap.libc.socket_handle = handle;
611                 }
612                 break;
613 #endif
614                 FALL_THROUGH;
615         case SWRAP_LIBC:
616                 handle = swrap.libc.handle;
617 #ifdef LIBC_SO
618                 if (handle == NULL) {
619                         handle = dlopen(LIBC_SO, flags);
620
621                         swrap.libc.handle = handle;
622                 }
623 #endif
624                 if (handle == NULL) {
625                         for (i = 10; i >= 0; i--) {
626                                 char soname[256] = {0};
627
628                                 snprintf(soname, sizeof(soname), "libc.so.%d", i);
629                                 handle = dlopen(soname, flags);
630                                 if (handle != NULL) {
631                                         break;
632                                 }
633                         }
634
635                         swrap.libc.handle = handle;
636                 }
637                 break;
638         }
639
640         if (handle == NULL) {
641 #ifdef RTLD_NEXT
642                 handle = swrap.libc.handle = swrap.libc.socket_handle = RTLD_NEXT;
643 #else
644                 SWRAP_LOG(SWRAP_LOG_ERROR,
645                           "Failed to dlopen library: %s\n",
646                           dlerror());
647                 exit(-1);
648 #endif
649         }
650
651         return handle;
652 }
653
654 static void *_swrap_bind_symbol(enum swrap_lib lib, const char *fn_name)
655 {
656         void *handle;
657         void *func;
658
659         handle = swrap_load_lib_handle(lib);
660
661         func = dlsym(handle, fn_name);
662         if (func == NULL) {
663                 SWRAP_LOG(SWRAP_LOG_ERROR,
664                           "Failed to find %s: %s\n",
665                           fn_name,
666                           dlerror());
667                 exit(-1);
668         }
669
670         SWRAP_LOG(SWRAP_LOG_TRACE,
671                   "Loaded %s from %s",
672                   fn_name,
673                   swrap_str_lib(lib));
674
675         return func;
676 }
677
678 #define swrap_bind_symbol_libc(sym_name) \
679         if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \
680                 SWRAP_LOCK(libc_symbol_binding); \
681                 if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \
682                         swrap.libc.symbols._libc_##sym_name.obj = \
683                                 _swrap_bind_symbol(SWRAP_LIBC, #sym_name); \
684                 } \
685                 SWRAP_UNLOCK(libc_symbol_binding); \
686         }
687
688 #define swrap_bind_symbol_libsocket(sym_name) \
689         if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \
690                 SWRAP_LOCK(libc_symbol_binding); \
691                 if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \
692                         swrap.libc.symbols._libc_##sym_name.obj = \
693                                 _swrap_bind_symbol(SWRAP_LIBSOCKET, #sym_name); \
694                 } \
695                 SWRAP_UNLOCK(libc_symbol_binding); \
696         }
697
698 #define swrap_bind_symbol_libnsl(sym_name) \
699         if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \
700                 SWRAP_LOCK(libc_symbol_binding); \
701                 if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \
702                         swrap.libc.symbols._libc_##sym_name.obj = \
703                                 _swrap_bind_symbol(SWRAP_LIBNSL, #sym_name); \
704                 } \
705                 SWRAP_UNLOCK(libc_symbol_binding); \
706         }
707
708 /****************************************************************************
709  *                               IMPORTANT
710  ****************************************************************************
711  *
712  * Functions especially from libc need to be loaded individually, you can't
713  * load all at once or gdb will segfault at startup. The same applies to
714  * valgrind and has probably something todo with with the linker.  So we need
715  * load each function at the point it is called the first time.
716  *
717  ****************************************************************************/
718
719 #ifdef HAVE_ACCEPT4
720 static int libc_accept4(int sockfd,
721                         struct sockaddr *addr,
722                         socklen_t *addrlen,
723                         int flags)
724 {
725         swrap_bind_symbol_libsocket(accept4);
726
727         return swrap.libc.symbols._libc_accept4.f(sockfd, addr, addrlen, flags);
728 }
729
730 #else /* HAVE_ACCEPT4 */
731
732 static int libc_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
733 {
734         swrap_bind_symbol_libsocket(accept);
735
736         return swrap.libc.symbols._libc_accept.f(sockfd, addr, addrlen);
737 }
738 #endif /* HAVE_ACCEPT4 */
739
740 static int libc_bind(int sockfd,
741                      const struct sockaddr *addr,
742                      socklen_t addrlen)
743 {
744         swrap_bind_symbol_libsocket(bind);
745
746         return swrap.libc.symbols._libc_bind.f(sockfd, addr, addrlen);
747 }
748
749 static int libc_close(int fd)
750 {
751         swrap_bind_symbol_libc(close);
752
753         return swrap.libc.symbols._libc_close.f(fd);
754 }
755
756 static int libc_connect(int sockfd,
757                         const struct sockaddr *addr,
758                         socklen_t addrlen)
759 {
760         swrap_bind_symbol_libsocket(connect);
761
762         return swrap.libc.symbols._libc_connect.f(sockfd, addr, addrlen);
763 }
764
765 static int libc_dup(int fd)
766 {
767         swrap_bind_symbol_libc(dup);
768
769         return swrap.libc.symbols._libc_dup.f(fd);
770 }
771
772 static int libc_dup2(int oldfd, int newfd)
773 {
774         swrap_bind_symbol_libc(dup2);
775
776         return swrap.libc.symbols._libc_dup2.f(oldfd, newfd);
777 }
778
779 #ifdef HAVE_EVENTFD
780 static int libc_eventfd(int count, int flags)
781 {
782         swrap_bind_symbol_libc(eventfd);
783
784         return swrap.libc.symbols._libc_eventfd.f(count, flags);
785 }
786 #endif
787
788 DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
789 static int libc_vfcntl(int fd, int cmd, va_list ap)
790 {
791         void *arg;
792         int rc;
793
794         swrap_bind_symbol_libc(fcntl);
795
796         arg = va_arg(ap, void *);
797
798         rc = swrap.libc.symbols._libc_fcntl.f(fd, cmd, arg);
799
800         return rc;
801 }
802
803 static int libc_getpeername(int sockfd,
804                             struct sockaddr *addr,
805                             socklen_t *addrlen)
806 {
807         swrap_bind_symbol_libsocket(getpeername);
808
809         return swrap.libc.symbols._libc_getpeername.f(sockfd, addr, addrlen);
810 }
811
812 static int libc_getsockname(int sockfd,
813                             struct sockaddr *addr,
814                             socklen_t *addrlen)
815 {
816         swrap_bind_symbol_libsocket(getsockname);
817
818         return swrap.libc.symbols._libc_getsockname.f(sockfd, addr, addrlen);
819 }
820
821 static int libc_getsockopt(int sockfd,
822                            int level,
823                            int optname,
824                            void *optval,
825                            socklen_t *optlen)
826 {
827         swrap_bind_symbol_libsocket(getsockopt);
828
829         return swrap.libc.symbols._libc_getsockopt.f(sockfd,
830                                                      level,
831                                                      optname,
832                                                      optval,
833                                                      optlen);
834 }
835
836 DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
837 static int libc_vioctl(int d, unsigned long int request, va_list ap)
838 {
839         void *arg;
840         int rc;
841
842         swrap_bind_symbol_libc(ioctl);
843
844         arg = va_arg(ap, void *);
845
846         rc = swrap.libc.symbols._libc_ioctl.f(d, request, arg);
847
848         return rc;
849 }
850
851 static int libc_listen(int sockfd, int backlog)
852 {
853         swrap_bind_symbol_libsocket(listen);
854
855         return swrap.libc.symbols._libc_listen.f(sockfd, backlog);
856 }
857
858 static FILE *libc_fopen(const char *name, const char *mode)
859 {
860         swrap_bind_symbol_libc(fopen);
861
862         return swrap.libc.symbols._libc_fopen.f(name, mode);
863 }
864
865 #ifdef HAVE_FOPEN64
866 static FILE *libc_fopen64(const char *name, const char *mode)
867 {
868         swrap_bind_symbol_libc(fopen64);
869
870         return swrap.libc.symbols._libc_fopen64.f(name, mode);
871 }
872 #endif /* HAVE_FOPEN64 */
873
874 static int libc_vopen(const char *pathname, int flags, va_list ap)
875 {
876         int mode = 0;
877         int fd;
878
879         swrap_bind_symbol_libc(open);
880
881         if (flags & O_CREAT) {
882                 mode = va_arg(ap, int);
883         }
884         fd = swrap.libc.symbols._libc_open.f(pathname, flags, (mode_t)mode);
885
886         return fd;
887 }
888
889 static int libc_open(const char *pathname, int flags, ...)
890 {
891         va_list ap;
892         int fd;
893
894         va_start(ap, flags);
895         fd = libc_vopen(pathname, flags, ap);
896         va_end(ap);
897
898         return fd;
899 }
900
901 #ifdef HAVE_OPEN64
902 static int libc_vopen64(const char *pathname, int flags, va_list ap)
903 {
904         int mode = 0;
905         int fd;
906
907         swrap_bind_symbol_libc(open64);
908
909         if (flags & O_CREAT) {
910                 mode = va_arg(ap, int);
911         }
912         fd = swrap.libc.symbols._libc_open64.f(pathname, flags, (mode_t)mode);
913
914         return fd;
915 }
916 #endif /* HAVE_OPEN64 */
917
918 static int libc_vopenat(int dirfd, const char *path, int flags, va_list ap)
919 {
920         int mode = 0;
921         int fd;
922
923         swrap_bind_symbol_libc(openat);
924
925         if (flags & O_CREAT) {
926                 mode = va_arg(ap, int);
927         }
928         fd = swrap.libc.symbols._libc_openat.f(dirfd,
929                                                path,
930                                                flags,
931                                                (mode_t)mode);
932
933         return fd;
934 }
935
936 #if 0
937 static int libc_openat(int dirfd, const char *path, int flags, ...)
938 {
939         va_list ap;
940         int fd;
941
942         va_start(ap, flags);
943         fd = libc_vopenat(dirfd, path, flags, ap);
944         va_end(ap);
945
946         return fd;
947 }
948 #endif
949
950 static int libc_pipe(int pipefd[2])
951 {
952         swrap_bind_symbol_libsocket(pipe);
953
954         return swrap.libc.symbols._libc_pipe.f(pipefd);
955 }
956
957 static int libc_read(int fd, void *buf, size_t count)
958 {
959         swrap_bind_symbol_libc(read);
960
961         return swrap.libc.symbols._libc_read.f(fd, buf, count);
962 }
963
964 static ssize_t libc_readv(int fd, const struct iovec *iov, int iovcnt)
965 {
966         swrap_bind_symbol_libsocket(readv);
967
968         return swrap.libc.symbols._libc_readv.f(fd, iov, iovcnt);
969 }
970
971 static int libc_recv(int sockfd, void *buf, size_t len, int flags)
972 {
973         swrap_bind_symbol_libsocket(recv);
974
975         return swrap.libc.symbols._libc_recv.f(sockfd, buf, len, flags);
976 }
977
978 static int libc_recvfrom(int sockfd,
979                          void *buf,
980                          size_t len,
981                          int flags,
982                          struct sockaddr *src_addr,
983                          socklen_t *addrlen)
984 {
985         swrap_bind_symbol_libsocket(recvfrom);
986
987         return swrap.libc.symbols._libc_recvfrom.f(sockfd,
988                                                    buf,
989                                                    len,
990                                                    flags,
991                                                    src_addr,
992                                                    addrlen);
993 }
994
995 static int libc_recvmsg(int sockfd, struct msghdr *msg, int flags)
996 {
997         swrap_bind_symbol_libsocket(recvmsg);
998
999         return swrap.libc.symbols._libc_recvmsg.f(sockfd, msg, flags);
1000 }
1001
1002 static int libc_send(int sockfd, const void *buf, size_t len, int flags)
1003 {
1004         swrap_bind_symbol_libsocket(send);
1005
1006         return swrap.libc.symbols._libc_send.f(sockfd, buf, len, flags);
1007 }
1008
1009 static int libc_sendmsg(int sockfd, const struct msghdr *msg, int flags)
1010 {
1011         swrap_bind_symbol_libsocket(sendmsg);
1012
1013         return swrap.libc.symbols._libc_sendmsg.f(sockfd, msg, flags);
1014 }
1015
1016 static int libc_sendto(int sockfd,
1017                        const void *buf,
1018                        size_t len,
1019                        int flags,
1020                        const  struct sockaddr *dst_addr,
1021                        socklen_t addrlen)
1022 {
1023         swrap_bind_symbol_libsocket(sendto);
1024
1025         return swrap.libc.symbols._libc_sendto.f(sockfd,
1026                                                  buf,
1027                                                  len,
1028                                                  flags,
1029                                                  dst_addr,
1030                                                  addrlen);
1031 }
1032
1033 static int libc_setsockopt(int sockfd,
1034                            int level,
1035                            int optname,
1036                            const void *optval,
1037                            socklen_t optlen)
1038 {
1039         swrap_bind_symbol_libsocket(setsockopt);
1040
1041         return swrap.libc.symbols._libc_setsockopt.f(sockfd,
1042                                                      level,
1043                                                      optname,
1044                                                      optval,
1045                                                      optlen);
1046 }
1047
1048 #ifdef HAVE_SIGNALFD
1049 static int libc_signalfd(int fd, const sigset_t *mask, int flags)
1050 {
1051         swrap_bind_symbol_libsocket(signalfd);
1052
1053         return swrap.libc.symbols._libc_signalfd.f(fd, mask, flags);
1054 }
1055 #endif
1056
1057 static int libc_socket(int domain, int type, int protocol)
1058 {
1059         swrap_bind_symbol_libsocket(socket);
1060
1061         return swrap.libc.symbols._libc_socket.f(domain, type, protocol);
1062 }
1063
1064 static int libc_socketpair(int domain, int type, int protocol, int sv[2])
1065 {
1066         swrap_bind_symbol_libsocket(socketpair);
1067
1068         return swrap.libc.symbols._libc_socketpair.f(domain, type, protocol, sv);
1069 }
1070
1071 #ifdef HAVE_TIMERFD_CREATE
1072 static int libc_timerfd_create(int clockid, int flags)
1073 {
1074         swrap_bind_symbol_libc(timerfd_create);
1075
1076         return swrap.libc.symbols._libc_timerfd_create.f(clockid, flags);
1077 }
1078 #endif
1079
1080 static ssize_t libc_write(int fd, const void *buf, size_t count)
1081 {
1082         swrap_bind_symbol_libc(write);
1083
1084         return swrap.libc.symbols._libc_write.f(fd, buf, count);
1085 }
1086
1087 static ssize_t libc_writev(int fd, const struct iovec *iov, int iovcnt)
1088 {
1089         swrap_bind_symbol_libsocket(writev);
1090
1091         return swrap.libc.symbols._libc_writev.f(fd, iov, iovcnt);
1092 }
1093
1094 /* DO NOT call this function during library initialization! */
1095 static void swrap_bind_symbol_all(void)
1096 {
1097 #ifdef HAVE_ACCEPT4
1098         swrap_bind_symbol_libsocket(accept4);
1099 #else
1100         swrap_bind_symbol_libsocket(accept);
1101 #endif
1102         swrap_bind_symbol_libsocket(bind);
1103         swrap_bind_symbol_libc(close);
1104         swrap_bind_symbol_libsocket(connect);
1105         swrap_bind_symbol_libc(dup);
1106         swrap_bind_symbol_libc(dup2);
1107         swrap_bind_symbol_libc(fcntl);
1108         swrap_bind_symbol_libc(fopen);
1109 #ifdef HAVE_FOPEN64
1110         swrap_bind_symbol_libc(fopen64);
1111 #endif
1112 #ifdef HAVE_EVENTFD
1113         swrap_bind_symbol_libc(eventfd);
1114 #endif
1115         swrap_bind_symbol_libsocket(getpeername);
1116         swrap_bind_symbol_libsocket(getsockname);
1117         swrap_bind_symbol_libsocket(getsockopt);
1118         swrap_bind_symbol_libc(ioctl);
1119         swrap_bind_symbol_libsocket(listen);
1120         swrap_bind_symbol_libc(open);
1121 #ifdef HAVE_OPEN64
1122         swrap_bind_symbol_libc(open64);
1123 #endif
1124         swrap_bind_symbol_libc(openat);
1125         swrap_bind_symbol_libsocket(pipe);
1126         swrap_bind_symbol_libc(read);
1127         swrap_bind_symbol_libsocket(readv);
1128         swrap_bind_symbol_libsocket(recv);
1129         swrap_bind_symbol_libsocket(recvfrom);
1130         swrap_bind_symbol_libsocket(recvmsg);
1131         swrap_bind_symbol_libsocket(send);
1132         swrap_bind_symbol_libsocket(sendmsg);
1133         swrap_bind_symbol_libsocket(sendto);
1134         swrap_bind_symbol_libsocket(setsockopt);
1135 #ifdef HAVE_SIGNALFD
1136         swrap_bind_symbol_libsocket(signalfd);
1137 #endif
1138         swrap_bind_symbol_libsocket(socket);
1139         swrap_bind_symbol_libsocket(socketpair);
1140 #ifdef HAVE_TIMERFD_CREATE
1141         swrap_bind_symbol_libc(timerfd_create);
1142 #endif
1143         swrap_bind_symbol_libc(write);
1144         swrap_bind_symbol_libsocket(writev);
1145 }
1146
1147 /*********************************************************
1148  * SWRAP HELPER FUNCTIONS
1149  *********************************************************/
1150
1151 #ifdef HAVE_IPV6
1152 /*
1153  * FD00::5357:5FXX
1154  */
1155 static const struct in6_addr *swrap_ipv6(void)
1156 {
1157         static struct in6_addr v;
1158         static int initialized;
1159         int ret;
1160
1161         if (initialized) {
1162                 return &v;
1163         }
1164         initialized = 1;
1165
1166         ret = inet_pton(AF_INET6, "FD00::5357:5F00", &v);
1167         if (ret <= 0) {
1168                 abort();
1169         }
1170
1171         return &v;
1172 }
1173 #endif
1174
1175 static void set_port(int family, int prt, struct swrap_address *addr)
1176 {
1177         switch (family) {
1178         case AF_INET:
1179                 addr->sa.in.sin_port = htons(prt);
1180                 break;
1181 #ifdef HAVE_IPV6
1182         case AF_INET6:
1183                 addr->sa.in6.sin6_port = htons(prt);
1184                 break;
1185 #endif
1186         }
1187 }
1188
1189 static size_t socket_length(int family)
1190 {
1191         switch (family) {
1192         case AF_INET:
1193                 return sizeof(struct sockaddr_in);
1194 #ifdef HAVE_IPV6
1195         case AF_INET6:
1196                 return sizeof(struct sockaddr_in6);
1197 #endif
1198         }
1199         return 0;
1200 }
1201
1202 static struct socket_info *swrap_get_socket_info(int si_index)
1203 {
1204         return (struct socket_info *)(&(sockets[si_index].info));
1205 }
1206
1207 static int swrap_get_refcount(struct socket_info *si)
1208 {
1209         struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si);
1210         return sic->refcount;
1211 }
1212
1213 static void swrap_inc_refcount(struct socket_info *si)
1214 {
1215         struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si);
1216
1217         sic->refcount += 1;
1218 }
1219
1220 static void swrap_dec_refcount(struct socket_info *si)
1221 {
1222         struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si);
1223
1224         sic->refcount -= 1;
1225 }
1226
1227 static int swrap_get_next_free(struct socket_info *si)
1228 {
1229         struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si);
1230
1231         return sic->next_free;
1232 }
1233
1234 static void swrap_set_next_free(struct socket_info *si, int next_free)
1235 {
1236         struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si);
1237         sic->next_free = next_free;
1238 }
1239
1240 static const char *socket_wrapper_dir(void)
1241 {
1242         const char *s = getenv("SOCKET_WRAPPER_DIR");
1243         if (s == NULL) {
1244                 return NULL;
1245         }
1246         /* TODO use realpath(3) here, when we add support for threads */
1247         if (strncmp(s, "./", 2) == 0) {
1248                 s += 2;
1249         }
1250
1251         SWRAP_LOG(SWRAP_LOG_TRACE, "socket_wrapper_dir: %s", s);
1252         return s;
1253 }
1254
1255 static unsigned int socket_wrapper_mtu(void)
1256 {
1257         static unsigned int max_mtu = 0;
1258         unsigned int tmp;
1259         const char *s;
1260         char *endp;
1261
1262         if (max_mtu != 0) {
1263                 return max_mtu;
1264         }
1265
1266         max_mtu = SOCKET_WRAPPER_MTU_DEFAULT;
1267
1268         s = getenv("SOCKET_WRAPPER_MTU");
1269         if (s == NULL) {
1270                 goto done;
1271         }
1272
1273         tmp = strtol(s, &endp, 10);
1274         if (s == endp) {
1275                 goto done;
1276         }
1277
1278         if (tmp < SOCKET_WRAPPER_MTU_MIN || tmp > SOCKET_WRAPPER_MTU_MAX) {
1279                 goto done;
1280         }
1281         max_mtu = tmp;
1282
1283 done:
1284         return max_mtu;
1285 }
1286
1287 static size_t socket_wrapper_max_sockets(void)
1288 {
1289         const char *s;
1290         unsigned long tmp;
1291         char *endp;
1292
1293         if (max_sockets != 0) {
1294                 return max_sockets;
1295         }
1296
1297         max_sockets = SOCKET_WRAPPER_MAX_SOCKETS_DEFAULT;
1298
1299         s = getenv("SOCKET_WRAPPER_MAX_SOCKETS");
1300         if (s == NULL || s[0] == '\0') {
1301                 goto done;
1302         }
1303
1304         tmp = strtoul(s, &endp, 10);
1305         if (s == endp) {
1306                 goto done;
1307         }
1308         if (tmp == 0 || tmp > SOCKET_WRAPPER_MAX_SOCKETS_LIMIT) {
1309                 SWRAP_LOG(SWRAP_LOG_ERROR,
1310                           "Invalid number of sockets specified, using default.");
1311                 goto done;
1312         }
1313
1314         max_sockets = tmp;
1315
1316 done:
1317         return max_sockets;
1318 }
1319
1320 static void socket_wrapper_init_sockets(void)
1321 {
1322         size_t i;
1323
1324         if (sockets != NULL) {
1325                 return;
1326         }
1327
1328         max_sockets = socket_wrapper_max_sockets();
1329
1330         sockets = (struct socket_info_container *)calloc(max_sockets,
1331                                         sizeof(struct socket_info_container));
1332
1333         if (sockets == NULL) {
1334                 SWRAP_LOG(SWRAP_LOG_ERROR,
1335                           "Failed to allocate sockets array.\n");
1336                 exit(-1);
1337         }
1338
1339         first_free = 0;
1340
1341         for (i = 0; i < max_sockets; i++) {
1342                 swrap_set_next_free(&sockets[i].info, i+1);
1343         }
1344
1345         /* mark the end of the free list */
1346         swrap_set_next_free(&sockets[max_sockets-1].info, -1);
1347 }
1348
1349 bool socket_wrapper_enabled(void)
1350 {
1351         const char *s = socket_wrapper_dir();
1352
1353         if (s == NULL) {
1354                 return false;
1355         }
1356
1357         socket_wrapper_init_sockets();
1358
1359         return true;
1360 }
1361
1362 static unsigned int socket_wrapper_default_iface(void)
1363 {
1364         const char *s = getenv("SOCKET_WRAPPER_DEFAULT_IFACE");
1365         if (s) {
1366                 unsigned int iface;
1367                 if (sscanf(s, "%u", &iface) == 1) {
1368                         if (iface >= 1 && iface <= MAX_WRAPPED_INTERFACES) {
1369                                 return iface;
1370                         }
1371                 }
1372         }
1373
1374         return 1;/* 127.0.0.1 */
1375 }
1376
1377 /*
1378  * Return the first free entry (if any) and make
1379  * it re-usable again (by nulling it out)
1380  */
1381 static int socket_wrapper_first_free_index(void)
1382 {
1383         struct socket_info *si = NULL;
1384         int next_free;
1385
1386         if (first_free == -1) {
1387                 errno = ENFILE;
1388                 return -1;
1389         }
1390
1391         si = swrap_get_socket_info(first_free);
1392         next_free = swrap_get_next_free(si);
1393         ZERO_STRUCTP(si);
1394         swrap_set_next_free(si, next_free);
1395
1396         return first_free;
1397 }
1398
1399 static int swrap_add_socket_info(struct socket_info *si_input)
1400 {
1401         struct socket_info *si = NULL;
1402         int si_index;
1403
1404         if (si_input == NULL) {
1405                 errno = EINVAL;
1406                 return -1;
1407         }
1408
1409         if (first_free == -1) {
1410                 errno = ENFILE;
1411                 return -1;
1412         }
1413
1414         si_index = first_free;
1415         si = swrap_get_socket_info(si_index);
1416
1417         first_free = swrap_get_next_free(si);
1418         *si = *si_input;
1419         swrap_inc_refcount(si);
1420
1421         return si_index;
1422 }
1423
1424 static int swrap_create_socket(struct socket_info *si, int fd)
1425 {
1426         struct socket_info_fd *fi = NULL;
1427         int idx;
1428
1429         fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
1430         if (fi == NULL) {
1431                 errno = ENOMEM;
1432                 return -1;
1433         }
1434
1435         idx = swrap_add_socket_info(si);
1436         if (idx == -1) {
1437                 free(fi);
1438                 return -1;
1439         }
1440
1441         fi->fd = fd;
1442         fi->si_index = idx;
1443
1444         SWRAP_DLIST_ADD(socket_fds, fi);
1445
1446         return idx;
1447 }
1448
1449 static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, socklen_t *len)
1450 {
1451         unsigned int iface;
1452         unsigned int prt;
1453         const char *p;
1454         char type;
1455
1456         p = strrchr(un->sun_path, '/');
1457         if (p) p++; else p = un->sun_path;
1458
1459         if (sscanf(p, SOCKET_FORMAT, &type, &iface, &prt) != 3) {
1460                 errno = EINVAL;
1461                 return -1;
1462         }
1463
1464         SWRAP_LOG(SWRAP_LOG_TRACE, "type %c iface %u port %u",
1465                         type, iface, prt);
1466
1467         if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
1468                 errno = EINVAL;
1469                 return -1;
1470         }
1471
1472         if (prt > 0xFFFF) {
1473                 errno = EINVAL;
1474                 return -1;
1475         }
1476
1477         switch(type) {
1478         case SOCKET_TYPE_CHAR_TCP:
1479         case SOCKET_TYPE_CHAR_UDP: {
1480                 struct sockaddr_in *in2 = (struct sockaddr_in *)(void *)in;
1481
1482                 if ((*len) < sizeof(*in2)) {
1483                     errno = EINVAL;
1484                     return -1;
1485                 }
1486
1487                 memset(in2, 0, sizeof(*in2));
1488                 in2->sin_family = AF_INET;
1489                 in2->sin_addr.s_addr = htonl((127<<24) | iface);
1490                 in2->sin_port = htons(prt);
1491
1492                 *len = sizeof(*in2);
1493                 break;
1494         }
1495 #ifdef HAVE_IPV6
1496         case SOCKET_TYPE_CHAR_TCP_V6:
1497         case SOCKET_TYPE_CHAR_UDP_V6: {
1498                 struct sockaddr_in6 *in2 = (struct sockaddr_in6 *)(void *)in;
1499
1500                 if ((*len) < sizeof(*in2)) {
1501                         errno = EINVAL;
1502                         return -1;
1503                 }
1504
1505                 memset(in2, 0, sizeof(*in2));
1506                 in2->sin6_family = AF_INET6;
1507                 in2->sin6_addr = *swrap_ipv6();
1508                 in2->sin6_addr.s6_addr[15] = iface;
1509                 in2->sin6_port = htons(prt);
1510
1511                 *len = sizeof(*in2);
1512                 break;
1513         }
1514 #endif
1515         default:
1516                 errno = EINVAL;
1517                 return -1;
1518         }
1519
1520         return 0;
1521 }
1522
1523 static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un,
1524                                 int *bcast)
1525 {
1526         char type = '\0';
1527         unsigned int prt;
1528         unsigned int iface;
1529         int is_bcast = 0;
1530
1531         if (bcast) *bcast = 0;
1532
1533         switch (inaddr->sa_family) {
1534         case AF_INET: {
1535                 const struct sockaddr_in *in =
1536                     (const struct sockaddr_in *)(const void *)inaddr;
1537                 unsigned int addr = ntohl(in->sin_addr.s_addr);
1538                 char u_type = '\0';
1539                 char b_type = '\0';
1540                 char a_type = '\0';
1541
1542                 switch (si->type) {
1543                 case SOCK_STREAM:
1544                         u_type = SOCKET_TYPE_CHAR_TCP;
1545                         break;
1546                 case SOCK_DGRAM:
1547                         u_type = SOCKET_TYPE_CHAR_UDP;
1548                         a_type = SOCKET_TYPE_CHAR_UDP;
1549                         b_type = SOCKET_TYPE_CHAR_UDP;
1550                         break;
1551                 default:
1552                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1553                         errno = ESOCKTNOSUPPORT;
1554                         return -1;
1555                 }
1556
1557                 prt = ntohs(in->sin_port);
1558                 if (a_type && addr == 0xFFFFFFFF) {
1559                         /* 255.255.255.255 only udp */
1560                         is_bcast = 2;
1561                         type = a_type;
1562                         iface = socket_wrapper_default_iface();
1563                 } else if (b_type && addr == 0x7FFFFFFF) {
1564                         /* 127.255.255.255 only udp */
1565                         is_bcast = 1;
1566                         type = b_type;
1567                         iface = socket_wrapper_default_iface();
1568                 } else if ((addr & 0xFFFFFF00) == 0x7F000000) {
1569                         /* 127.0.0.X */
1570                         is_bcast = 0;
1571                         type = u_type;
1572                         iface = (addr & 0x000000FF);
1573                 } else {
1574                         errno = ENETUNREACH;
1575                         return -1;
1576                 }
1577                 if (bcast) *bcast = is_bcast;
1578                 break;
1579         }
1580 #ifdef HAVE_IPV6
1581         case AF_INET6: {
1582                 const struct sockaddr_in6 *in =
1583                     (const struct sockaddr_in6 *)(const void *)inaddr;
1584                 struct in6_addr cmp1, cmp2;
1585
1586                 switch (si->type) {
1587                 case SOCK_STREAM:
1588                         type = SOCKET_TYPE_CHAR_TCP_V6;
1589                         break;
1590                 case SOCK_DGRAM:
1591                         type = SOCKET_TYPE_CHAR_UDP_V6;
1592                         break;
1593                 default:
1594                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1595                         errno = ESOCKTNOSUPPORT;
1596                         return -1;
1597                 }
1598
1599                 /* XXX no multicast/broadcast */
1600
1601                 prt = ntohs(in->sin6_port);
1602
1603                 cmp1 = *swrap_ipv6();
1604                 cmp2 = in->sin6_addr;
1605                 cmp2.s6_addr[15] = 0;
1606                 if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
1607                         iface = in->sin6_addr.s6_addr[15];
1608                 } else {
1609                         errno = ENETUNREACH;
1610                         return -1;
1611                 }
1612
1613                 break;
1614         }
1615 #endif
1616         default:
1617                 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family!\n");
1618                 errno = ENETUNREACH;
1619                 return -1;
1620         }
1621
1622         if (prt == 0) {
1623                 SWRAP_LOG(SWRAP_LOG_WARN, "Port not set\n");
1624                 errno = EINVAL;
1625                 return -1;
1626         }
1627
1628         if (is_bcast) {
1629                 snprintf(un->sun_path, sizeof(un->sun_path), "%s/EINVAL",
1630                          socket_wrapper_dir());
1631                 SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
1632                 /* the caller need to do more processing */
1633                 return 0;
1634         }
1635
1636         snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT,
1637                  socket_wrapper_dir(), type, iface, prt);
1638         SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
1639
1640         return 0;
1641 }
1642
1643 static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un,
1644                                int *bcast)
1645 {
1646         char type = '\0';
1647         unsigned int prt;
1648         unsigned int iface;
1649         struct stat st;
1650         int is_bcast = 0;
1651
1652         if (bcast) *bcast = 0;
1653
1654         switch (si->family) {
1655         case AF_INET: {
1656                 const struct sockaddr_in *in =
1657                     (const struct sockaddr_in *)(const void *)inaddr;
1658                 unsigned int addr = ntohl(in->sin_addr.s_addr);
1659                 char u_type = '\0';
1660                 char d_type = '\0';
1661                 char b_type = '\0';
1662                 char a_type = '\0';
1663
1664                 prt = ntohs(in->sin_port);
1665
1666                 switch (si->type) {
1667                 case SOCK_STREAM:
1668                         u_type = SOCKET_TYPE_CHAR_TCP;
1669                         d_type = SOCKET_TYPE_CHAR_TCP;
1670                         break;
1671                 case SOCK_DGRAM:
1672                         u_type = SOCKET_TYPE_CHAR_UDP;
1673                         d_type = SOCKET_TYPE_CHAR_UDP;
1674                         a_type = SOCKET_TYPE_CHAR_UDP;
1675                         b_type = SOCKET_TYPE_CHAR_UDP;
1676                         break;
1677                 default:
1678                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1679                         errno = ESOCKTNOSUPPORT;
1680                         return -1;
1681                 }
1682
1683                 if (addr == 0) {
1684                         /* 0.0.0.0 */
1685                         is_bcast = 0;
1686                         type = d_type;
1687                         iface = socket_wrapper_default_iface();
1688                 } else if (a_type && addr == 0xFFFFFFFF) {
1689                         /* 255.255.255.255 only udp */
1690                         is_bcast = 2;
1691                         type = a_type;
1692                         iface = socket_wrapper_default_iface();
1693                 } else if (b_type && addr == 0x7FFFFFFF) {
1694                         /* 127.255.255.255 only udp */
1695                         is_bcast = 1;
1696                         type = b_type;
1697                         iface = socket_wrapper_default_iface();
1698                 } else if ((addr & 0xFFFFFF00) == 0x7F000000) {
1699                         /* 127.0.0.X */
1700                         is_bcast = 0;
1701                         type = u_type;
1702                         iface = (addr & 0x000000FF);
1703                 } else {
1704                         errno = EADDRNOTAVAIL;
1705                         return -1;
1706                 }
1707
1708                 /* Store the bind address for connect() */
1709                 if (si->bindname.sa_socklen == 0) {
1710                         struct sockaddr_in bind_in;
1711                         socklen_t blen = sizeof(struct sockaddr_in);
1712
1713                         ZERO_STRUCT(bind_in);
1714                         bind_in.sin_family = in->sin_family;
1715                         bind_in.sin_port = in->sin_port;
1716                         bind_in.sin_addr.s_addr = htonl(0x7F000000 | iface);
1717
1718                         si->bindname.sa_socklen = blen;
1719                         memcpy(&si->bindname.sa.in, &bind_in, blen);
1720                 }
1721
1722                 break;
1723         }
1724 #ifdef HAVE_IPV6
1725         case AF_INET6: {
1726                 const struct sockaddr_in6 *in =
1727                     (const struct sockaddr_in6 *)(const void *)inaddr;
1728                 struct in6_addr cmp1, cmp2;
1729
1730                 switch (si->type) {
1731                 case SOCK_STREAM:
1732                         type = SOCKET_TYPE_CHAR_TCP_V6;
1733                         break;
1734                 case SOCK_DGRAM:
1735                         type = SOCKET_TYPE_CHAR_UDP_V6;
1736                         break;
1737                 default:
1738                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
1739                         errno = ESOCKTNOSUPPORT;
1740                         return -1;
1741                 }
1742
1743                 /* XXX no multicast/broadcast */
1744
1745                 prt = ntohs(in->sin6_port);
1746
1747                 cmp1 = *swrap_ipv6();
1748                 cmp2 = in->sin6_addr;
1749                 cmp2.s6_addr[15] = 0;
1750                 if (IN6_IS_ADDR_UNSPECIFIED(&in->sin6_addr)) {
1751                         iface = socket_wrapper_default_iface();
1752                 } else if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
1753                         iface = in->sin6_addr.s6_addr[15];
1754                 } else {
1755                         errno = EADDRNOTAVAIL;
1756                         return -1;
1757                 }
1758
1759                 /* Store the bind address for connect() */
1760                 if (si->bindname.sa_socklen == 0) {
1761                         struct sockaddr_in6 bind_in;
1762                         socklen_t blen = sizeof(struct sockaddr_in6);
1763
1764                         ZERO_STRUCT(bind_in);
1765                         bind_in.sin6_family = in->sin6_family;
1766                         bind_in.sin6_port = in->sin6_port;
1767
1768                         bind_in.sin6_addr = *swrap_ipv6();
1769                         bind_in.sin6_addr.s6_addr[15] = iface;
1770
1771                         memcpy(&si->bindname.sa.in6, &bind_in, blen);
1772                         si->bindname.sa_socklen = blen;
1773                 }
1774
1775                 break;
1776         }
1777 #endif
1778         default:
1779                 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n");
1780                 errno = EADDRNOTAVAIL;
1781                 return -1;
1782         }
1783
1784
1785         if (bcast) *bcast = is_bcast;
1786
1787         if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
1788                 errno = EINVAL;
1789                 return -1;
1790         }
1791
1792         if (prt == 0) {
1793                 /* handle auto-allocation of ephemeral ports */
1794                 for (prt = 5001; prt < 10000; prt++) {
1795                         snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT,
1796                                  socket_wrapper_dir(), type, iface, prt);
1797                         if (stat(un->sun_path, &st) == 0) continue;
1798
1799                         set_port(si->family, prt, &si->myname);
1800                         set_port(si->family, prt, &si->bindname);
1801
1802                         break;
1803                 }
1804                 if (prt == 10000) {
1805                         errno = ENFILE;
1806                         return -1;
1807                 }
1808         }
1809
1810         snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT,
1811                  socket_wrapper_dir(), type, iface, prt);
1812         SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
1813         return 0;
1814 }
1815
1816 static struct socket_info_fd *find_socket_info_fd(int fd)
1817 {
1818         struct socket_info_fd *f;
1819
1820         for (f = socket_fds; f; f = f->next) {
1821                 if (f->fd == fd) {
1822                         return f;
1823                 }
1824         }
1825
1826         return NULL;
1827 }
1828
1829 static int find_socket_info_index(int fd)
1830 {
1831         struct socket_info_fd *fi = find_socket_info_fd(fd);
1832
1833         if (fi == NULL) {
1834                 return -1;
1835         }
1836
1837         return fi->si_index;
1838 }
1839
1840 static struct socket_info *find_socket_info(int fd)
1841 {
1842         int idx = find_socket_info_index(fd);
1843
1844         if (idx == -1) {
1845                 return NULL;
1846         }
1847
1848         return swrap_get_socket_info(idx);
1849 }
1850
1851 #if 0 /* FIXME */
1852 static bool check_addr_port_in_use(const struct sockaddr *sa, socklen_t len)
1853 {
1854         struct socket_info_fd *f;
1855         const struct socket_info *last_s = NULL;
1856
1857         /* first catch invalid input */
1858         switch (sa->sa_family) {
1859         case AF_INET:
1860                 if (len < sizeof(struct sockaddr_in)) {
1861                         return false;
1862                 }
1863                 break;
1864 #if HAVE_IPV6
1865         case AF_INET6:
1866                 if (len < sizeof(struct sockaddr_in6)) {
1867                         return false;
1868                 }
1869                 break;
1870 #endif
1871         default:
1872                 return false;
1873                 break;
1874         }
1875
1876         for (f = socket_fds; f; f = f->next) {
1877                 struct socket_info *s = swrap_get_socket_info(f->si_index);
1878
1879                 if (s == last_s) {
1880                         continue;
1881                 }
1882                 last_s = s;
1883
1884                 if (s->myname == NULL) {
1885                         continue;
1886                 }
1887                 if (s->myname->sa_family != sa->sa_family) {
1888                         continue;
1889                 }
1890                 switch (s->myname->sa_family) {
1891                 case AF_INET: {
1892                         struct sockaddr_in *sin1, *sin2;
1893
1894                         sin1 = (struct sockaddr_in *)s->myname;
1895                         sin2 = (struct sockaddr_in *)sa;
1896
1897                         if (sin1->sin_addr.s_addr == htonl(INADDR_ANY)) {
1898                                 continue;
1899                         }
1900                         if (sin1->sin_port != sin2->sin_port) {
1901                                 continue;
1902                         }
1903                         if (sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) {
1904                                 continue;
1905                         }
1906
1907                         /* found */
1908                         return true;
1909                         break;
1910                 }
1911 #if HAVE_IPV6
1912                 case AF_INET6: {
1913                         struct sockaddr_in6 *sin1, *sin2;
1914
1915                         sin1 = (struct sockaddr_in6 *)s->myname;
1916                         sin2 = (struct sockaddr_in6 *)sa;
1917
1918                         if (sin1->sin6_port != sin2->sin6_port) {
1919                                 continue;
1920                         }
1921                         if (!IN6_ARE_ADDR_EQUAL(&sin1->sin6_addr,
1922                                                 &sin2->sin6_addr))
1923                         {
1924                                 continue;
1925                         }
1926
1927                         /* found */
1928                         return true;
1929                         break;
1930                 }
1931 #endif
1932                 default:
1933                         continue;
1934                         break;
1935
1936                 }
1937         }
1938
1939         return false;
1940 }
1941 #endif
1942
1943 static void swrap_remove_stale(int fd)
1944 {
1945         struct socket_info_fd *fi = find_socket_info_fd(fd);
1946         struct socket_info *si;
1947         int si_index;
1948
1949         if (fi == NULL) {
1950                 return;
1951         }
1952
1953         si_index = fi->si_index;
1954
1955         SWRAP_LOG(SWRAP_LOG_TRACE, "remove stale wrapper for %d", fd);
1956         SWRAP_DLIST_REMOVE(socket_fds, fi);
1957         free(fi);
1958
1959         si = swrap_get_socket_info(si_index);
1960         swrap_dec_refcount(si);
1961
1962         if (swrap_get_refcount(si) > 0) {
1963                 return;
1964         }
1965
1966         if (si->un_addr.sun_path[0] != '\0') {
1967                 unlink(si->un_addr.sun_path);
1968         }
1969
1970         swrap_set_next_free(si, first_free);
1971         first_free = si_index;
1972 }
1973
1974 static int sockaddr_convert_to_un(struct socket_info *si,
1975                                   const struct sockaddr *in_addr,
1976                                   socklen_t in_len,
1977                                   struct sockaddr_un *out_addr,
1978                                   int alloc_sock,
1979                                   int *bcast)
1980 {
1981         struct sockaddr *out = (struct sockaddr *)(void *)out_addr;
1982
1983         (void) in_len; /* unused */
1984
1985         if (out_addr == NULL) {
1986                 return 0;
1987         }
1988
1989         out->sa_family = AF_UNIX;
1990 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
1991         out->sa_len = sizeof(*out_addr);
1992 #endif
1993
1994         switch (in_addr->sa_family) {
1995         case AF_UNSPEC: {
1996                 const struct sockaddr_in *sin;
1997                 if (si->family != AF_INET) {
1998                         break;
1999                 }
2000                 if (in_len < sizeof(struct sockaddr_in)) {
2001                         break;
2002                 }
2003                 sin = (const struct sockaddr_in *)(const void *)in_addr;
2004                 if(sin->sin_addr.s_addr != htonl(INADDR_ANY)) {
2005                         break;
2006                 }
2007
2008                 /*
2009                  * Note: in the special case of AF_UNSPEC and INADDR_ANY,
2010                  * AF_UNSPEC is mapped to AF_INET and must be treated here.
2011                  */
2012
2013                 FALL_THROUGH;
2014         }
2015         case AF_INET:
2016 #ifdef HAVE_IPV6
2017         case AF_INET6:
2018 #endif
2019                 switch (si->type) {
2020                 case SOCK_STREAM:
2021                 case SOCK_DGRAM:
2022                         break;
2023                 default:
2024                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
2025                         errno = ESOCKTNOSUPPORT;
2026                         return -1;
2027                 }
2028                 if (alloc_sock) {
2029                         return convert_in_un_alloc(si, in_addr, out_addr, bcast);
2030                 } else {
2031                         return convert_in_un_remote(si, in_addr, out_addr, bcast);
2032                 }
2033         default:
2034                 break;
2035         }
2036
2037         errno = EAFNOSUPPORT;
2038         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n");
2039         return -1;
2040 }
2041
2042 static int sockaddr_convert_from_un(const struct socket_info *si,
2043                                     const struct sockaddr_un *in_addr,
2044                                     socklen_t un_addrlen,
2045                                     int family,
2046                                     struct sockaddr *out_addr,
2047                                     socklen_t *out_addrlen)
2048 {
2049         int ret;
2050
2051         if (out_addr == NULL || out_addrlen == NULL)
2052                 return 0;
2053
2054         if (un_addrlen == 0) {
2055                 *out_addrlen = 0;
2056                 return 0;
2057         }
2058
2059         switch (family) {
2060         case AF_INET:
2061 #ifdef HAVE_IPV6
2062         case AF_INET6:
2063 #endif
2064                 switch (si->type) {
2065                 case SOCK_STREAM:
2066                 case SOCK_DGRAM:
2067                         break;
2068                 default:
2069                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
2070                         errno = ESOCKTNOSUPPORT;
2071                         return -1;
2072                 }
2073                 ret = convert_un_in(in_addr, out_addr, out_addrlen);
2074 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
2075                 out_addr->sa_len = *out_addrlen;
2076 #endif
2077                 return ret;
2078         default:
2079                 break;
2080         }
2081
2082         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n");
2083         errno = EAFNOSUPPORT;
2084         return -1;
2085 }
2086
2087 enum swrap_packet_type {
2088         SWRAP_CONNECT_SEND,
2089         SWRAP_CONNECT_UNREACH,
2090         SWRAP_CONNECT_RECV,
2091         SWRAP_CONNECT_ACK,
2092         SWRAP_ACCEPT_SEND,
2093         SWRAP_ACCEPT_RECV,
2094         SWRAP_ACCEPT_ACK,
2095         SWRAP_RECVFROM,
2096         SWRAP_SENDTO,
2097         SWRAP_SENDTO_UNREACH,
2098         SWRAP_PENDING_RST,
2099         SWRAP_RECV,
2100         SWRAP_RECV_RST,
2101         SWRAP_SEND,
2102         SWRAP_SEND_RST,
2103         SWRAP_CLOSE_SEND,
2104         SWRAP_CLOSE_RECV,
2105         SWRAP_CLOSE_ACK,
2106 };
2107
2108 struct swrap_file_hdr {
2109         uint32_t        magic;
2110         uint16_t        version_major;
2111         uint16_t        version_minor;
2112         int32_t         timezone;
2113         uint32_t        sigfigs;
2114         uint32_t        frame_max_len;
2115 #define SWRAP_FRAME_LENGTH_MAX 0xFFFF
2116         uint32_t        link_type;
2117 };
2118 #define SWRAP_FILE_HDR_SIZE 24
2119
2120 struct swrap_packet_frame {
2121         uint32_t seconds;
2122         uint32_t micro_seconds;
2123         uint32_t recorded_length;
2124         uint32_t full_length;
2125 };
2126 #define SWRAP_PACKET_FRAME_SIZE 16
2127
2128 union swrap_packet_ip {
2129         struct {
2130                 uint8_t         ver_hdrlen;
2131                 uint8_t         tos;
2132                 uint16_t        packet_length;
2133                 uint16_t        identification;
2134                 uint8_t         flags;
2135                 uint8_t         fragment;
2136                 uint8_t         ttl;
2137                 uint8_t         protocol;
2138                 uint16_t        hdr_checksum;
2139                 uint32_t        src_addr;
2140                 uint32_t        dest_addr;
2141         } v4;
2142 #define SWRAP_PACKET_IP_V4_SIZE 20
2143         struct {
2144                 uint8_t         ver_prio;
2145                 uint8_t         flow_label_high;
2146                 uint16_t        flow_label_low;
2147                 uint16_t        payload_length;
2148                 uint8_t         next_header;
2149                 uint8_t         hop_limit;
2150                 uint8_t         src_addr[16];
2151                 uint8_t         dest_addr[16];
2152         } v6;
2153 #define SWRAP_PACKET_IP_V6_SIZE 40
2154 };
2155 #define SWRAP_PACKET_IP_SIZE 40
2156
2157 union swrap_packet_payload {
2158         struct {
2159                 uint16_t        source_port;
2160                 uint16_t        dest_port;
2161                 uint32_t        seq_num;
2162                 uint32_t        ack_num;
2163                 uint8_t         hdr_length;
2164                 uint8_t         control;
2165                 uint16_t        window;
2166                 uint16_t        checksum;
2167                 uint16_t        urg;
2168         } tcp;
2169 #define SWRAP_PACKET_PAYLOAD_TCP_SIZE 20
2170         struct {
2171                 uint16_t        source_port;
2172                 uint16_t        dest_port;
2173                 uint16_t        length;
2174                 uint16_t        checksum;
2175         } udp;
2176 #define SWRAP_PACKET_PAYLOAD_UDP_SIZE 8
2177         struct {
2178                 uint8_t         type;
2179                 uint8_t         code;
2180                 uint16_t        checksum;
2181                 uint32_t        unused;
2182         } icmp4;
2183 #define SWRAP_PACKET_PAYLOAD_ICMP4_SIZE 8
2184         struct {
2185                 uint8_t         type;
2186                 uint8_t         code;
2187                 uint16_t        checksum;
2188                 uint32_t        unused;
2189         } icmp6;
2190 #define SWRAP_PACKET_PAYLOAD_ICMP6_SIZE 8
2191 };
2192 #define SWRAP_PACKET_PAYLOAD_SIZE 20
2193
2194 #define SWRAP_PACKET_MIN_ALLOC \
2195         (SWRAP_PACKET_FRAME_SIZE + \
2196          SWRAP_PACKET_IP_SIZE + \
2197          SWRAP_PACKET_PAYLOAD_SIZE)
2198
2199 static const char *swrap_pcap_init_file(void)
2200 {
2201         static int initialized = 0;
2202         static const char *s = NULL;
2203         static const struct swrap_file_hdr h;
2204         static const struct swrap_packet_frame f;
2205         static const union swrap_packet_ip i;
2206         static const union swrap_packet_payload p;
2207
2208         if (initialized == 1) {
2209                 return s;
2210         }
2211         initialized = 1;
2212
2213         /*
2214          * TODO: don't use the structs use plain buffer offsets
2215          *       and PUSH_U8(), PUSH_U16() and PUSH_U32()
2216          *
2217          * for now make sure we disable PCAP support
2218          * if the struct has alignment!
2219          */
2220         if (sizeof(h) != SWRAP_FILE_HDR_SIZE) {
2221                 return NULL;
2222         }
2223         if (sizeof(f) != SWRAP_PACKET_FRAME_SIZE) {
2224                 return NULL;
2225         }
2226         if (sizeof(i) != SWRAP_PACKET_IP_SIZE) {
2227                 return NULL;
2228         }
2229         if (sizeof(i.v4) != SWRAP_PACKET_IP_V4_SIZE) {
2230                 return NULL;
2231         }
2232         if (sizeof(i.v6) != SWRAP_PACKET_IP_V6_SIZE) {
2233                 return NULL;
2234         }
2235         if (sizeof(p) != SWRAP_PACKET_PAYLOAD_SIZE) {
2236                 return NULL;
2237         }
2238         if (sizeof(p.tcp) != SWRAP_PACKET_PAYLOAD_TCP_SIZE) {
2239                 return NULL;
2240         }
2241         if (sizeof(p.udp) != SWRAP_PACKET_PAYLOAD_UDP_SIZE) {
2242                 return NULL;
2243         }
2244         if (sizeof(p.icmp4) != SWRAP_PACKET_PAYLOAD_ICMP4_SIZE) {
2245                 return NULL;
2246         }
2247         if (sizeof(p.icmp6) != SWRAP_PACKET_PAYLOAD_ICMP6_SIZE) {
2248                 return NULL;
2249         }
2250
2251         s = getenv("SOCKET_WRAPPER_PCAP_FILE");
2252         if (s == NULL) {
2253                 return NULL;
2254         }
2255         if (strncmp(s, "./", 2) == 0) {
2256                 s += 2;
2257         }
2258         return s;
2259 }
2260
2261 static uint8_t *swrap_pcap_packet_init(struct timeval *tval,
2262                                        const struct sockaddr *src,
2263                                        const struct sockaddr *dest,
2264                                        int socket_type,
2265                                        const uint8_t *payload,
2266                                        size_t payload_len,
2267                                        unsigned long tcp_seqno,
2268                                        unsigned long tcp_ack,
2269                                        unsigned char tcp_ctl,
2270                                        int unreachable,
2271                                        size_t *_packet_len)
2272 {
2273         uint8_t *base;
2274         uint8_t *buf;
2275         struct swrap_packet_frame *frame;
2276         union swrap_packet_ip *ip;
2277         union swrap_packet_payload *pay;
2278         size_t packet_len;
2279         size_t alloc_len;
2280         size_t nonwire_len = sizeof(*frame);
2281         size_t wire_hdr_len = 0;
2282         size_t wire_len = 0;
2283         size_t ip_hdr_len = 0;
2284         size_t icmp_hdr_len = 0;
2285         size_t icmp_truncate_len = 0;
2286         uint8_t protocol = 0, icmp_protocol = 0;
2287         const struct sockaddr_in *src_in = NULL;
2288         const struct sockaddr_in *dest_in = NULL;
2289 #ifdef HAVE_IPV6
2290         const struct sockaddr_in6 *src_in6 = NULL;
2291         const struct sockaddr_in6 *dest_in6 = NULL;
2292 #endif
2293         uint16_t src_port;
2294         uint16_t dest_port;
2295
2296         switch (src->sa_family) {
2297         case AF_INET:
2298                 src_in = (const struct sockaddr_in *)(const void *)src;
2299                 dest_in = (const struct sockaddr_in *)(const void *)dest;
2300                 src_port = src_in->sin_port;
2301                 dest_port = dest_in->sin_port;
2302                 ip_hdr_len = sizeof(ip->v4);
2303                 break;
2304 #ifdef HAVE_IPV6
2305         case AF_INET6:
2306                 src_in6 = (const struct sockaddr_in6 *)(const void *)src;
2307                 dest_in6 = (const struct sockaddr_in6 *)(const void *)dest;
2308                 src_port = src_in6->sin6_port;
2309                 dest_port = dest_in6->sin6_port;
2310                 ip_hdr_len = sizeof(ip->v6);
2311                 break;
2312 #endif
2313         default:
2314                 return NULL;
2315         }
2316
2317         switch (socket_type) {
2318         case SOCK_STREAM:
2319                 protocol = 0x06; /* TCP */
2320                 wire_hdr_len = ip_hdr_len + sizeof(pay->tcp);
2321                 wire_len = wire_hdr_len + payload_len;
2322                 break;
2323
2324         case SOCK_DGRAM:
2325                 protocol = 0x11; /* UDP */
2326                 wire_hdr_len = ip_hdr_len + sizeof(pay->udp);
2327                 wire_len = wire_hdr_len + payload_len;
2328                 break;
2329
2330         default:
2331                 return NULL;
2332         }
2333
2334         if (unreachable) {
2335                 icmp_protocol = protocol;
2336                 switch (src->sa_family) {
2337                 case AF_INET:
2338                         protocol = 0x01; /* ICMPv4 */
2339                         icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp4);
2340                         break;
2341 #ifdef HAVE_IPV6
2342                 case AF_INET6:
2343                         protocol = 0x3A; /* ICMPv6 */
2344                         icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp6);
2345                         break;
2346 #endif
2347                 }
2348                 if (wire_len > 64 ) {
2349                         icmp_truncate_len = wire_len - 64;
2350                 }
2351                 wire_hdr_len += icmp_hdr_len;
2352                 wire_len += icmp_hdr_len;
2353         }
2354
2355         packet_len = nonwire_len + wire_len;
2356         alloc_len = packet_len;
2357         if (alloc_len < SWRAP_PACKET_MIN_ALLOC) {
2358                 alloc_len = SWRAP_PACKET_MIN_ALLOC;
2359         }
2360
2361         base = (uint8_t *)calloc(1, alloc_len);
2362         if (base == NULL) {
2363                 return NULL;
2364         }
2365
2366         buf = base;
2367
2368         frame = (struct swrap_packet_frame *)(void *)buf;
2369         frame->seconds          = tval->tv_sec;
2370         frame->micro_seconds    = tval->tv_usec;
2371         frame->recorded_length  = wire_len - icmp_truncate_len;
2372         frame->full_length      = wire_len - icmp_truncate_len;
2373         buf += SWRAP_PACKET_FRAME_SIZE;
2374
2375         ip = (union swrap_packet_ip *)(void *)buf;
2376         switch (src->sa_family) {
2377         case AF_INET:
2378                 ip->v4.ver_hdrlen       = 0x45; /* version 4 and 5 * 32 bit words */
2379                 ip->v4.tos              = 0x00;
2380                 ip->v4.packet_length    = htons(wire_len - icmp_truncate_len);
2381                 ip->v4.identification   = htons(0xFFFF);
2382                 ip->v4.flags            = 0x40; /* BIT 1 set - means don't fragment */
2383                 ip->v4.fragment         = htons(0x0000);
2384                 ip->v4.ttl              = 0xFF;
2385                 ip->v4.protocol         = protocol;
2386                 ip->v4.hdr_checksum     = htons(0x0000);
2387                 ip->v4.src_addr         = src_in->sin_addr.s_addr;
2388                 ip->v4.dest_addr        = dest_in->sin_addr.s_addr;
2389                 buf += SWRAP_PACKET_IP_V4_SIZE;
2390                 break;
2391 #ifdef HAVE_IPV6
2392         case AF_INET6:
2393                 ip->v6.ver_prio         = 0x60; /* version 4 and 5 * 32 bit words */
2394                 ip->v6.flow_label_high  = 0x00;
2395                 ip->v6.flow_label_low   = 0x0000;
2396                 ip->v6.payload_length   = htons(wire_len - icmp_truncate_len); /* TODO */
2397                 ip->v6.next_header      = protocol;
2398                 memcpy(ip->v6.src_addr, src_in6->sin6_addr.s6_addr, 16);
2399                 memcpy(ip->v6.dest_addr, dest_in6->sin6_addr.s6_addr, 16);
2400                 buf += SWRAP_PACKET_IP_V6_SIZE;
2401                 break;
2402 #endif
2403         }
2404
2405         if (unreachable) {
2406                 pay = (union swrap_packet_payload *)(void *)buf;
2407                 switch (src->sa_family) {
2408                 case AF_INET:
2409                         pay->icmp4.type         = 0x03; /* destination unreachable */
2410                         pay->icmp4.code         = 0x01; /* host unreachable */
2411                         pay->icmp4.checksum     = htons(0x0000);
2412                         pay->icmp4.unused       = htonl(0x00000000);
2413                         buf += SWRAP_PACKET_PAYLOAD_ICMP4_SIZE;
2414
2415                         /* set the ip header in the ICMP payload */
2416                         ip = (union swrap_packet_ip *)(void *)buf;
2417                         ip->v4.ver_hdrlen       = 0x45; /* version 4 and 5 * 32 bit words */
2418                         ip->v4.tos              = 0x00;
2419                         ip->v4.packet_length    = htons(wire_len - icmp_hdr_len);
2420                         ip->v4.identification   = htons(0xFFFF);
2421                         ip->v4.flags            = 0x40; /* BIT 1 set - means don't fragment */
2422                         ip->v4.fragment         = htons(0x0000);
2423                         ip->v4.ttl              = 0xFF;
2424                         ip->v4.protocol         = icmp_protocol;
2425                         ip->v4.hdr_checksum     = htons(0x0000);
2426                         ip->v4.src_addr         = dest_in->sin_addr.s_addr;
2427                         ip->v4.dest_addr        = src_in->sin_addr.s_addr;
2428                         buf += SWRAP_PACKET_IP_V4_SIZE;
2429
2430                         src_port = dest_in->sin_port;
2431                         dest_port = src_in->sin_port;
2432                         break;
2433 #ifdef HAVE_IPV6
2434                 case AF_INET6:
2435                         pay->icmp6.type         = 0x01; /* destination unreachable */
2436                         pay->icmp6.code         = 0x03; /* address unreachable */
2437                         pay->icmp6.checksum     = htons(0x0000);
2438                         pay->icmp6.unused       = htonl(0x00000000);
2439                         buf += SWRAP_PACKET_PAYLOAD_ICMP6_SIZE;
2440
2441                         /* set the ip header in the ICMP payload */
2442                         ip = (union swrap_packet_ip *)(void *)buf;
2443                         ip->v6.ver_prio         = 0x60; /* version 4 and 5 * 32 bit words */
2444                         ip->v6.flow_label_high  = 0x00;
2445                         ip->v6.flow_label_low   = 0x0000;
2446                         ip->v6.payload_length   = htons(wire_len - icmp_truncate_len); /* TODO */
2447                         ip->v6.next_header      = protocol;
2448                         memcpy(ip->v6.src_addr, dest_in6->sin6_addr.s6_addr, 16);
2449                         memcpy(ip->v6.dest_addr, src_in6->sin6_addr.s6_addr, 16);
2450                         buf += SWRAP_PACKET_IP_V6_SIZE;
2451
2452                         src_port = dest_in6->sin6_port;
2453                         dest_port = src_in6->sin6_port;
2454                         break;
2455 #endif
2456                 }
2457         }
2458
2459         pay = (union swrap_packet_payload *)(void *)buf;
2460
2461         switch (socket_type) {
2462         case SOCK_STREAM:
2463                 pay->tcp.source_port    = src_port;
2464                 pay->tcp.dest_port      = dest_port;
2465                 pay->tcp.seq_num        = htonl(tcp_seqno);
2466                 pay->tcp.ack_num        = htonl(tcp_ack);
2467                 pay->tcp.hdr_length     = 0x50; /* 5 * 32 bit words */
2468                 pay->tcp.control        = tcp_ctl;
2469                 pay->tcp.window         = htons(0x7FFF);
2470                 pay->tcp.checksum       = htons(0x0000);
2471                 pay->tcp.urg            = htons(0x0000);
2472                 buf += SWRAP_PACKET_PAYLOAD_TCP_SIZE;
2473
2474                 break;
2475
2476         case SOCK_DGRAM:
2477                 pay->udp.source_port    = src_port;
2478                 pay->udp.dest_port      = dest_port;
2479                 pay->udp.length         = htons(8 + payload_len);
2480                 pay->udp.checksum       = htons(0x0000);
2481                 buf += SWRAP_PACKET_PAYLOAD_UDP_SIZE;
2482
2483                 break;
2484         }
2485
2486         if (payload && payload_len > 0) {
2487                 memcpy(buf, payload, payload_len);
2488         }
2489
2490         *_packet_len = packet_len - icmp_truncate_len;
2491         return base;
2492 }
2493
2494 static int swrap_pcap_get_fd(const char *fname)
2495 {
2496         static int fd = -1;
2497
2498         if (fd != -1) {
2499                 return fd;
2500         }
2501
2502         fd = libc_open(fname, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0644);
2503         if (fd != -1) {
2504                 struct swrap_file_hdr file_hdr;
2505                 file_hdr.magic          = 0xA1B2C3D4;
2506                 file_hdr.version_major  = 0x0002;
2507                 file_hdr.version_minor  = 0x0004;
2508                 file_hdr.timezone       = 0x00000000;
2509                 file_hdr.sigfigs        = 0x00000000;
2510                 file_hdr.frame_max_len  = SWRAP_FRAME_LENGTH_MAX;
2511                 file_hdr.link_type      = 0x0065; /* 101 RAW IP */
2512
2513                 if (write(fd, &file_hdr, sizeof(file_hdr)) != sizeof(file_hdr)) {
2514                         close(fd);
2515                         fd = -1;
2516                 }
2517                 return fd;
2518         }
2519
2520         fd = libc_open(fname, O_WRONLY|O_APPEND, 0644);
2521
2522         return fd;
2523 }
2524
2525 static uint8_t *swrap_pcap_marshall_packet(struct socket_info *si,
2526                                            const struct sockaddr *addr,
2527                                            enum swrap_packet_type type,
2528                                            const void *buf, size_t len,
2529                                            size_t *packet_len)
2530 {
2531         const struct sockaddr *src_addr;
2532         const struct sockaddr *dest_addr;
2533         unsigned long tcp_seqno = 0;
2534         unsigned long tcp_ack = 0;
2535         unsigned char tcp_ctl = 0;
2536         int unreachable = 0;
2537
2538         struct timeval tv;
2539
2540         switch (si->family) {
2541         case AF_INET:
2542                 break;
2543 #ifdef HAVE_IPV6
2544         case AF_INET6:
2545                 break;
2546 #endif
2547         default:
2548                 return NULL;
2549         }
2550
2551         switch (type) {
2552         case SWRAP_CONNECT_SEND:
2553                 if (si->type != SOCK_STREAM) {
2554                         return NULL;
2555                 }
2556
2557                 src_addr  = &si->myname.sa.s;
2558                 dest_addr = addr;
2559
2560                 tcp_seqno = si->io.pck_snd;
2561                 tcp_ack = si->io.pck_rcv;
2562                 tcp_ctl = 0x02; /* SYN */
2563
2564                 si->io.pck_snd += 1;
2565
2566                 break;
2567
2568         case SWRAP_CONNECT_RECV:
2569                 if (si->type != SOCK_STREAM) {
2570                         return NULL;
2571                 }
2572
2573                 dest_addr = &si->myname.sa.s;
2574                 src_addr = addr;
2575
2576                 tcp_seqno = si->io.pck_rcv;
2577                 tcp_ack = si->io.pck_snd;
2578                 tcp_ctl = 0x12; /** SYN,ACK */
2579
2580                 si->io.pck_rcv += 1;
2581
2582                 break;
2583
2584         case SWRAP_CONNECT_UNREACH:
2585                 if (si->type != SOCK_STREAM) {
2586                         return NULL;
2587                 }
2588
2589                 dest_addr = &si->myname.sa.s;
2590                 src_addr  = addr;
2591
2592                 /* Unreachable: resend the data of SWRAP_CONNECT_SEND */
2593                 tcp_seqno = si->io.pck_snd - 1;
2594                 tcp_ack = si->io.pck_rcv;
2595                 tcp_ctl = 0x02; /* SYN */
2596                 unreachable = 1;
2597
2598                 break;
2599
2600         case SWRAP_CONNECT_ACK:
2601                 if (si->type != SOCK_STREAM) {
2602                         return NULL;
2603                 }
2604
2605                 src_addr  = &si->myname.sa.s;
2606                 dest_addr = addr;
2607
2608                 tcp_seqno = si->io.pck_snd;
2609                 tcp_ack = si->io.pck_rcv;
2610                 tcp_ctl = 0x10; /* ACK */
2611
2612                 break;
2613
2614         case SWRAP_ACCEPT_SEND:
2615                 if (si->type != SOCK_STREAM) {
2616                         return NULL;
2617                 }
2618
2619                 dest_addr = &si->myname.sa.s;
2620                 src_addr = addr;
2621
2622                 tcp_seqno = si->io.pck_rcv;
2623                 tcp_ack = si->io.pck_snd;
2624                 tcp_ctl = 0x02; /* SYN */
2625
2626                 si->io.pck_rcv += 1;
2627
2628                 break;
2629
2630         case SWRAP_ACCEPT_RECV:
2631                 if (si->type != SOCK_STREAM) {
2632                         return NULL;
2633                 }
2634
2635                 src_addr = &si->myname.sa.s;
2636                 dest_addr = addr;
2637
2638                 tcp_seqno = si->io.pck_snd;
2639                 tcp_ack = si->io.pck_rcv;
2640                 tcp_ctl = 0x12; /* SYN,ACK */
2641
2642                 si->io.pck_snd += 1;
2643
2644                 break;
2645
2646         case SWRAP_ACCEPT_ACK:
2647                 if (si->type != SOCK_STREAM) {
2648                         return NULL;
2649                 }
2650
2651                 dest_addr = &si->myname.sa.s;
2652                 src_addr = addr;
2653
2654                 tcp_seqno = si->io.pck_rcv;
2655                 tcp_ack = si->io.pck_snd;
2656                 tcp_ctl = 0x10; /* ACK */
2657
2658                 break;
2659
2660         case SWRAP_SEND:
2661                 src_addr  = &si->myname.sa.s;
2662                 dest_addr = &si->peername.sa.s;
2663
2664                 tcp_seqno = si->io.pck_snd;
2665                 tcp_ack = si->io.pck_rcv;
2666                 tcp_ctl = 0x18; /* PSH,ACK */
2667
2668                 si->io.pck_snd += len;
2669
2670                 break;
2671
2672         case SWRAP_SEND_RST:
2673                 dest_addr = &si->myname.sa.s;
2674                 src_addr  = &si->peername.sa.s;
2675
2676                 if (si->type == SOCK_DGRAM) {
2677                         return swrap_pcap_marshall_packet(si,
2678                                                           &si->peername.sa.s,
2679                                                           SWRAP_SENDTO_UNREACH,
2680                                                           buf,
2681                                                           len,
2682                                                           packet_len);
2683                 }
2684
2685                 tcp_seqno = si->io.pck_rcv;
2686                 tcp_ack = si->io.pck_snd;
2687                 tcp_ctl = 0x14; /** RST,ACK */
2688
2689                 break;
2690
2691         case SWRAP_PENDING_RST:
2692                 dest_addr = &si->myname.sa.s;
2693                 src_addr  = &si->peername.sa.s;
2694
2695                 if (si->type == SOCK_DGRAM) {
2696                         return NULL;
2697                 }
2698
2699                 tcp_seqno = si->io.pck_rcv;
2700                 tcp_ack = si->io.pck_snd;
2701                 tcp_ctl = 0x14; /* RST,ACK */
2702
2703                 break;
2704
2705         case SWRAP_RECV:
2706                 dest_addr = &si->myname.sa.s;
2707                 src_addr  = &si->peername.sa.s;
2708
2709                 tcp_seqno = si->io.pck_rcv;
2710                 tcp_ack = si->io.pck_snd;
2711                 tcp_ctl = 0x18; /* PSH,ACK */
2712
2713                 si->io.pck_rcv += len;
2714
2715                 break;
2716
2717         case SWRAP_RECV_RST:
2718                 dest_addr = &si->myname.sa.s;
2719                 src_addr  = &si->peername.sa.s;
2720
2721                 if (si->type == SOCK_DGRAM) {
2722                         return NULL;
2723                 }
2724
2725                 tcp_seqno = si->io.pck_rcv;
2726                 tcp_ack = si->io.pck_snd;
2727                 tcp_ctl = 0x14; /* RST,ACK */
2728
2729                 break;
2730
2731         case SWRAP_SENDTO:
2732                 src_addr = &si->myname.sa.s;
2733                 dest_addr = addr;
2734
2735                 si->io.pck_snd += len;
2736
2737                 break;
2738
2739         case SWRAP_SENDTO_UNREACH:
2740                 dest_addr = &si->myname.sa.s;
2741                 src_addr = addr;
2742
2743                 unreachable = 1;
2744
2745                 break;
2746
2747         case SWRAP_RECVFROM:
2748                 dest_addr = &si->myname.sa.s;
2749                 src_addr = addr;
2750
2751                 si->io.pck_rcv += len;
2752
2753                 break;
2754
2755         case SWRAP_CLOSE_SEND:
2756                 if (si->type != SOCK_STREAM) {
2757                         return NULL;
2758                 }
2759
2760                 src_addr  = &si->myname.sa.s;
2761                 dest_addr = &si->peername.sa.s;
2762
2763                 tcp_seqno = si->io.pck_snd;
2764                 tcp_ack = si->io.pck_rcv;
2765                 tcp_ctl = 0x11; /* FIN, ACK */
2766
2767                 si->io.pck_snd += 1;
2768
2769                 break;
2770
2771         case SWRAP_CLOSE_RECV:
2772                 if (si->type != SOCK_STREAM) {
2773                         return NULL;
2774                 }
2775
2776                 dest_addr = &si->myname.sa.s;
2777                 src_addr  = &si->peername.sa.s;
2778
2779                 tcp_seqno = si->io.pck_rcv;
2780                 tcp_ack = si->io.pck_snd;
2781                 tcp_ctl = 0x11; /* FIN,ACK */
2782
2783                 si->io.pck_rcv += 1;
2784
2785                 break;
2786
2787         case SWRAP_CLOSE_ACK:
2788                 if (si->type != SOCK_STREAM) {
2789                         return NULL;
2790                 }
2791
2792                 src_addr  = &si->myname.sa.s;
2793                 dest_addr = &si->peername.sa.s;
2794
2795                 tcp_seqno = si->io.pck_snd;
2796                 tcp_ack = si->io.pck_rcv;
2797                 tcp_ctl = 0x10; /* ACK */
2798
2799                 break;
2800         default:
2801                 return NULL;
2802         }
2803
2804         swrapGetTimeOfDay(&tv);
2805
2806         return swrap_pcap_packet_init(&tv,
2807                                       src_addr,
2808                                       dest_addr,
2809                                       si->type,
2810                                       (const uint8_t *)buf,
2811                                       len,
2812                                       tcp_seqno,
2813                                       tcp_ack,
2814                                       tcp_ctl,
2815                                       unreachable,
2816                                       packet_len);
2817 }
2818
2819 static void swrap_pcap_dump_packet(struct socket_info *si,
2820                                    const struct sockaddr *addr,
2821                                    enum swrap_packet_type type,
2822                                    const void *buf, size_t len)
2823 {
2824         const char *file_name;
2825         uint8_t *packet;
2826         size_t packet_len = 0;
2827         int fd;
2828
2829         file_name = swrap_pcap_init_file();
2830         if (!file_name) {
2831                 return;
2832         }
2833
2834         packet = swrap_pcap_marshall_packet(si,
2835                                             addr,
2836                                             type,
2837                                             buf,
2838                                             len,
2839                                             &packet_len);
2840         if (packet == NULL) {
2841                 return;
2842         }
2843
2844         fd = swrap_pcap_get_fd(file_name);
2845         if (fd != -1) {
2846                 if (write(fd, packet, packet_len) != (ssize_t)packet_len) {
2847                         free(packet);
2848                         return;
2849                 }
2850         }
2851
2852         free(packet);
2853 }
2854
2855 /****************************************************************************
2856  *   SIGNALFD
2857  ***************************************************************************/
2858
2859 #ifdef HAVE_SIGNALFD
2860 static int swrap_signalfd(int fd, const sigset_t *mask, int flags)
2861 {
2862         int rc;
2863
2864         rc = libc_signalfd(fd, mask, flags);
2865         if (rc != -1) {
2866                 swrap_remove_stale(fd);
2867         }
2868
2869         return rc;
2870 }
2871
2872 int signalfd(int fd, const sigset_t *mask, int flags)
2873 {
2874         return swrap_signalfd(fd, mask, flags);
2875 }
2876 #endif
2877
2878 /****************************************************************************
2879  *   SOCKET
2880  ***************************************************************************/
2881
2882 static int swrap_socket(int family, int type, int protocol)
2883 {
2884         struct socket_info *si = NULL;
2885         struct socket_info _si = { 0 };
2886         int fd;
2887         int ret;
2888         int real_type = type;
2889
2890         /*
2891          * Remove possible addition flags passed to socket() so
2892          * do not fail checking the type.
2893          * See https://lwn.net/Articles/281965/
2894          */
2895 #ifdef SOCK_CLOEXEC
2896         real_type &= ~SOCK_CLOEXEC;
2897 #endif
2898 #ifdef SOCK_NONBLOCK
2899         real_type &= ~SOCK_NONBLOCK;
2900 #endif
2901
2902         if (!socket_wrapper_enabled()) {
2903                 return libc_socket(family, type, protocol);
2904         }
2905
2906         switch (family) {
2907         case AF_INET:
2908 #ifdef HAVE_IPV6
2909         case AF_INET6:
2910 #endif
2911                 break;
2912 #ifdef AF_NETLINK
2913         case AF_NETLINK:
2914 #endif /* AF_NETLINK */
2915 #ifdef AF_PACKET
2916         case AF_PACKET:
2917 #endif /* AF_PACKET */
2918         case AF_UNIX:
2919                 return libc_socket(family, type, protocol);
2920         default:
2921                 errno = EAFNOSUPPORT;
2922                 return -1;
2923         }
2924
2925         switch (real_type) {
2926         case SOCK_STREAM:
2927                 break;
2928         case SOCK_DGRAM:
2929                 break;
2930         default:
2931                 errno = EPROTONOSUPPORT;
2932                 return -1;
2933         }
2934
2935         switch (protocol) {
2936         case 0:
2937                 break;
2938         case 6:
2939                 if (real_type == SOCK_STREAM) {
2940                         break;
2941                 }
2942                 FALL_THROUGH;
2943         case 17:
2944                 if (real_type == SOCK_DGRAM) {
2945                         break;
2946                 }
2947                 FALL_THROUGH;
2948         default:
2949                 errno = EPROTONOSUPPORT;
2950                 return -1;
2951         }
2952
2953         /*
2954          * We must call libc_socket with type, from the caller, not the version
2955          * we removed SOCK_CLOEXEC and SOCK_NONBLOCK from
2956          */
2957         fd = libc_socket(AF_UNIX, type, 0);
2958
2959         if (fd == -1) {
2960                 return -1;
2961         }
2962
2963         /* Check if we have a stale fd and remove it */
2964         swrap_remove_stale(fd);
2965
2966         si = &_si;
2967         si->family = family;
2968
2969         /* however, the rest of the socket_wrapper code expects just
2970          * the type, not the flags */
2971         si->type = real_type;
2972         si->protocol = protocol;
2973
2974         /*
2975          * Setup myname so getsockname() can succeed to find out the socket
2976          * type.
2977          */
2978         switch(si->family) {
2979         case AF_INET: {
2980                 struct sockaddr_in sin = {
2981                         .sin_family = AF_INET,
2982                 };
2983
2984                 si->myname.sa_socklen = sizeof(struct sockaddr_in);
2985                 memcpy(&si->myname.sa.in, &sin, si->myname.sa_socklen);
2986                 break;
2987         }
2988         case AF_INET6: {
2989                 struct sockaddr_in6 sin6 = {
2990                         .sin6_family = AF_INET6,
2991                 };
2992
2993                 si->myname.sa_socklen = sizeof(struct sockaddr_in6);
2994                 memcpy(&si->myname.sa.in6, &sin6, si->myname.sa_socklen);
2995                 break;
2996         }
2997         default:
2998                 errno = EINVAL;
2999                 return -1;
3000         }
3001
3002         ret = swrap_create_socket(si, fd);
3003         if (ret == -1) {
3004                 return -1;
3005         }
3006
3007         SWRAP_LOG(SWRAP_LOG_TRACE,
3008                   "Created %s socket for protocol %s",
3009                   family == AF_INET ? "IPv4" : "IPv6",
3010                   real_type == SOCK_DGRAM ? "UDP" : "TCP");
3011
3012         return fd;
3013 }
3014
3015 int socket(int family, int type, int protocol)
3016 {
3017         return swrap_socket(family, type, protocol);
3018 }
3019
3020 /****************************************************************************
3021  *   SOCKETPAIR
3022  ***************************************************************************/
3023
3024 static int swrap_socketpair(int family, int type, int protocol, int sv[2])
3025 {
3026         int rc;
3027
3028         rc = libc_socketpair(family, type, protocol, sv);
3029         if (rc != -1) {
3030                 swrap_remove_stale(sv[0]);
3031                 swrap_remove_stale(sv[1]);
3032         }
3033
3034         return rc;
3035 }
3036
3037 int socketpair(int family, int type, int protocol, int sv[2])
3038 {
3039         return swrap_socketpair(family, type, protocol, sv);
3040 }
3041
3042 /****************************************************************************
3043  *   SOCKETPAIR
3044  ***************************************************************************/
3045
3046 #ifdef HAVE_TIMERFD_CREATE
3047 static int swrap_timerfd_create(int clockid, int flags)
3048 {
3049         int fd;
3050
3051         fd = libc_timerfd_create(clockid, flags);
3052         if (fd != -1) {
3053                 swrap_remove_stale(fd);
3054         }
3055
3056         return fd;
3057 }
3058
3059 int timerfd_create(int clockid, int flags)
3060 {
3061         return swrap_timerfd_create(clockid, flags);
3062 }
3063 #endif
3064
3065 /****************************************************************************
3066  *   PIPE
3067  ***************************************************************************/
3068
3069 static int swrap_pipe(int pipefd[2])
3070 {
3071         int rc;
3072
3073         rc = libc_pipe(pipefd);
3074         if (rc != -1) {
3075                 swrap_remove_stale(pipefd[0]);
3076                 swrap_remove_stale(pipefd[1]);
3077         }
3078
3079         return rc;
3080 }
3081
3082 int pipe(int pipefd[2])
3083 {
3084         return swrap_pipe(pipefd);
3085 }
3086
3087 /****************************************************************************
3088  *   ACCEPT
3089  ***************************************************************************/
3090
3091 static int swrap_accept(int s,
3092                         struct sockaddr *addr,
3093                         socklen_t *addrlen,
3094                         int flags)
3095 {
3096         struct socket_info *parent_si, *child_si;
3097         struct socket_info_fd *child_fi;
3098         int fd;
3099         int idx;
3100         struct swrap_address un_addr = {
3101                 .sa_socklen = sizeof(struct sockaddr_un),
3102         };
3103         struct swrap_address un_my_addr = {
3104                 .sa_socklen = sizeof(struct sockaddr_un),
3105         };
3106         struct swrap_address in_addr = {
3107                 .sa_socklen = sizeof(struct sockaddr_storage),
3108         };
3109         struct swrap_address in_my_addr = {
3110                 .sa_socklen = sizeof(struct sockaddr_storage),
3111         };
3112         int ret;
3113
3114         parent_si = find_socket_info(s);
3115         if (!parent_si) {
3116 #ifdef HAVE_ACCEPT4
3117                 return libc_accept4(s, addr, addrlen, flags);
3118 #else
3119                 UNUSED(flags);
3120                 return libc_accept(s, addr, addrlen);
3121 #endif
3122         }
3123
3124         /*
3125          * assume out sockaddr have the same size as the in parent
3126          * socket family
3127          */
3128         in_addr.sa_socklen = socket_length(parent_si->family);
3129         if (in_addr.sa_socklen <= 0) {
3130                 errno = EINVAL;
3131                 return -1;
3132         }
3133
3134 #ifdef HAVE_ACCEPT4
3135         ret = libc_accept4(s, &un_addr.sa.s, &un_addr.sa_socklen, flags);
3136 #else
3137         UNUSED(flags);
3138         ret = libc_accept(s, &un_addr.sa.s, &un_addr.sa_socklen);
3139 #endif
3140         if (ret == -1) {
3141                 if (errno == ENOTSOCK) {
3142                         /* Remove stale fds */
3143                         swrap_remove_stale(s);
3144                 }
3145                 return ret;
3146         }
3147
3148         fd = ret;
3149
3150         ret = sockaddr_convert_from_un(parent_si,
3151                                        &un_addr.sa.un,
3152                                        un_addr.sa_socklen,
3153                                        parent_si->family,
3154                                        &in_addr.sa.s,
3155                                        &in_addr.sa_socklen);
3156         if (ret == -1) {
3157                 close(fd);
3158                 return ret;
3159         }
3160
3161         idx = socket_wrapper_first_free_index();
3162         if (idx == -1) {
3163                 return -1;
3164         }
3165
3166         child_si = swrap_get_socket_info(idx);
3167
3168         child_fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
3169         if (child_fi == NULL) {
3170                 close(fd);
3171                 errno = ENOMEM;
3172                 return -1;
3173         }
3174
3175         child_fi->fd = fd;
3176
3177         child_si->family = parent_si->family;
3178         child_si->type = parent_si->type;
3179         child_si->protocol = parent_si->protocol;
3180         child_si->bound = 1;
3181         child_si->is_server = 1;
3182         child_si->connected = 1;
3183
3184         child_si->peername = (struct swrap_address) {
3185                 .sa_socklen = in_addr.sa_socklen,
3186         };
3187         memcpy(&child_si->peername.sa.ss, &in_addr.sa.ss, in_addr.sa_socklen);
3188
3189         if (addr != NULL && addrlen != NULL) {
3190                 size_t copy_len = MIN(*addrlen, in_addr.sa_socklen);
3191                 if (copy_len > 0) {
3192                         memcpy(addr, &in_addr.sa.ss, copy_len);
3193                 }
3194                 *addrlen = in_addr.sa_socklen;
3195         }
3196
3197         ret = libc_getsockname(fd,
3198                                &un_my_addr.sa.s,
3199                                &un_my_addr.sa_socklen);
3200         if (ret == -1) {
3201                 free(child_fi);
3202                 close(fd);
3203                 return ret;
3204         }
3205
3206         ret = sockaddr_convert_from_un(child_si,
3207                                        &un_my_addr.sa.un,
3208                                        un_my_addr.sa_socklen,
3209                                        child_si->family,
3210                                        &in_my_addr.sa.s,
3211                                        &in_my_addr.sa_socklen);
3212         if (ret == -1) {
3213                 free(child_fi);
3214                 close(fd);
3215                 return ret;
3216         }
3217
3218         SWRAP_LOG(SWRAP_LOG_TRACE,
3219                   "accept() path=%s, fd=%d",
3220                   un_my_addr.sa.un.sun_path, s);
3221
3222         child_si->myname = (struct swrap_address) {
3223                 .sa_socklen = in_my_addr.sa_socklen,
3224         };
3225         memcpy(&child_si->myname.sa.ss, &in_my_addr.sa.ss, in_my_addr.sa_socklen);
3226
3227         swrap_inc_refcount(child_si);
3228         first_free = swrap_get_next_free(child_si);
3229         swrap_set_next_free(child_si, 0);
3230
3231         child_fi->si_index = idx;
3232
3233         SWRAP_DLIST_ADD(socket_fds, child_fi);
3234
3235         if (addr != NULL) {
3236                 swrap_pcap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0);
3237                 swrap_pcap_dump_packet(child_si, addr, SWRAP_ACCEPT_RECV, NULL, 0);
3238                 swrap_pcap_dump_packet(child_si, addr, SWRAP_ACCEPT_ACK, NULL, 0);
3239         }
3240
3241         return fd;
3242 }
3243
3244 #ifdef HAVE_ACCEPT4
3245 int accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags)
3246 {
3247         return swrap_accept(s, addr, (socklen_t *)addrlen, flags);
3248 }
3249 #endif
3250
3251 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3252 int accept(int s, struct sockaddr *addr, Psocklen_t addrlen)
3253 #else
3254 int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
3255 #endif
3256 {
3257         return swrap_accept(s, addr, (socklen_t *)addrlen, 0);
3258 }
3259
3260 static int autobind_start_init;
3261 static int autobind_start;
3262
3263 /* using sendto() or connect() on an unbound socket would give the
3264    recipient no way to reply, as unlike UDP and TCP, a unix domain
3265    socket can't auto-assign ephemeral port numbers, so we need to
3266    assign it here.
3267    Note: this might change the family from ipv6 to ipv4
3268 */
3269 static int swrap_auto_bind(int fd, struct socket_info *si, int family)
3270 {
3271         struct swrap_address un_addr = {
3272                 .sa_socklen = sizeof(struct sockaddr_un),
3273         };
3274         int i;
3275         char type;
3276         int ret;
3277         int port;
3278         struct stat st;
3279
3280         if (autobind_start_init != 1) {
3281                 autobind_start_init = 1;
3282                 autobind_start = getpid();
3283                 autobind_start %= 50000;
3284                 autobind_start += 10000;
3285         }
3286
3287         un_addr.sa.un.sun_family = AF_UNIX;
3288
3289         switch (family) {
3290         case AF_INET: {
3291                 struct sockaddr_in in;
3292
3293                 switch (si->type) {
3294                 case SOCK_STREAM:
3295                         type = SOCKET_TYPE_CHAR_TCP;
3296                         break;
3297                 case SOCK_DGRAM:
3298                         type = SOCKET_TYPE_CHAR_UDP;
3299                         break;
3300                 default:
3301                         errno = ESOCKTNOSUPPORT;
3302                         ret = -1;
3303                         goto done;
3304                 }
3305
3306                 memset(&in, 0, sizeof(in));
3307                 in.sin_family = AF_INET;
3308                 in.sin_addr.s_addr = htonl(127<<24 |
3309                                            socket_wrapper_default_iface());
3310
3311                 si->myname = (struct swrap_address) {
3312                         .sa_socklen = sizeof(in),
3313                 };
3314                 memcpy(&si->myname.sa.in, &in, si->myname.sa_socklen);
3315                 break;
3316         }
3317 #ifdef HAVE_IPV6
3318         case AF_INET6: {
3319                 struct sockaddr_in6 in6;
3320
3321                 if (si->family != family) {
3322                         errno = ENETUNREACH;
3323                         ret = -1;
3324                         goto done;
3325                 }
3326
3327                 switch (si->type) {
3328                 case SOCK_STREAM:
3329                         type = SOCKET_TYPE_CHAR_TCP_V6;
3330                         break;
3331                 case SOCK_DGRAM:
3332                         type = SOCKET_TYPE_CHAR_UDP_V6;
3333                         break;
3334                 default:
3335                         errno = ESOCKTNOSUPPORT;
3336                         ret = -1;
3337                         goto done;
3338                 }
3339
3340                 memset(&in6, 0, sizeof(in6));
3341                 in6.sin6_family = AF_INET6;
3342                 in6.sin6_addr = *swrap_ipv6();
3343                 in6.sin6_addr.s6_addr[15] = socket_wrapper_default_iface();
3344
3345                 si->myname = (struct swrap_address) {
3346                         .sa_socklen = sizeof(in6),
3347                 };
3348                 memcpy(&si->myname.sa.in6, &in6, si->myname.sa_socklen);
3349                 break;
3350         }
3351 #endif
3352         default:
3353                 errno = ESOCKTNOSUPPORT;
3354                 ret = -1;
3355                 goto done;
3356         }
3357
3358         if (autobind_start > 60000) {
3359                 autobind_start = 10000;
3360         }
3361
3362         for (i = 0; i < SOCKET_MAX_SOCKETS; i++) {
3363                 port = autobind_start + i;
3364                 snprintf(un_addr.sa.un.sun_path, sizeof(un_addr.sa.un.sun_path),
3365                          "%s/"SOCKET_FORMAT, socket_wrapper_dir(),
3366                          type, socket_wrapper_default_iface(), port);
3367                 if (stat(un_addr.sa.un.sun_path, &st) == 0) continue;
3368
3369                 ret = libc_bind(fd, &un_addr.sa.s, un_addr.sa_socklen);
3370                 if (ret == -1) {
3371                         goto done;
3372                 }
3373
3374                 si->un_addr = un_addr.sa.un;
3375
3376                 si->bound = 1;
3377                 autobind_start = port + 1;
3378                 break;
3379         }
3380         if (i == SOCKET_MAX_SOCKETS) {
3381                 SWRAP_LOG(SWRAP_LOG_ERROR, "Too many open unix sockets (%u) for "
3382                                            "interface "SOCKET_FORMAT,
3383                                            SOCKET_MAX_SOCKETS,
3384                                            type,
3385                                            socket_wrapper_default_iface(),
3386                                            0);
3387                 errno = ENFILE;
3388                 ret = -1;
3389                 goto done;
3390         }
3391
3392         si->family = family;
3393         set_port(si->family, port, &si->myname);
3394
3395         ret = 0;
3396
3397 done:
3398         return ret;
3399 }
3400
3401 /****************************************************************************
3402  *   CONNECT
3403  ***************************************************************************/
3404
3405 static int swrap_connect(int s, const struct sockaddr *serv_addr,
3406                          socklen_t addrlen)
3407 {
3408         int ret;
3409         struct swrap_address un_addr = {
3410                 .sa_socklen = sizeof(struct sockaddr_un),
3411         };
3412         struct socket_info *si = find_socket_info(s);
3413         int bcast = 0;
3414
3415         if (!si) {
3416                 return libc_connect(s, serv_addr, addrlen);
3417         }
3418
3419         if (si->bound == 0) {
3420                 ret = swrap_auto_bind(s, si, serv_addr->sa_family);
3421                 if (ret == -1) {
3422                         goto done;
3423                 }
3424         }
3425
3426         if (si->family != serv_addr->sa_family) {
3427                 errno = EINVAL;
3428                 ret = -1;
3429                 goto done;
3430         }
3431
3432         ret = sockaddr_convert_to_un(si, serv_addr,
3433                                      addrlen, &un_addr.sa.un, 0, &bcast);
3434         if (ret == -1) {
3435                 goto done;
3436         }
3437
3438         if (bcast) {
3439                 errno = ENETUNREACH;
3440                 ret = -1;
3441                 goto done;
3442         }
3443
3444         if (si->type == SOCK_DGRAM) {
3445                 si->defer_connect = 1;
3446                 ret = 0;
3447         } else {
3448                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0);
3449
3450                 ret = libc_connect(s,
3451                                    &un_addr.sa.s,
3452                                    un_addr.sa_socklen);
3453         }
3454
3455         SWRAP_LOG(SWRAP_LOG_TRACE,
3456                   "connect() path=%s, fd=%d",
3457                   un_addr.sa.un.sun_path, s);
3458
3459
3460         /* to give better errors */
3461         if (ret == -1 && errno == ENOENT) {
3462                 errno = EHOSTUNREACH;
3463         }
3464
3465         if (ret == 0) {
3466                 si->peername = (struct swrap_address) {
3467                         .sa_socklen = addrlen,
3468                 };
3469
3470                 memcpy(&si->peername.sa.ss, serv_addr, addrlen);
3471                 si->connected = 1;
3472
3473                 /*
3474                  * When we connect() on a socket than we have to bind the
3475                  * outgoing connection on the interface we use for the
3476                  * transport. We already bound it on the right interface
3477                  * but here we have to update the name so getsockname()
3478                  * returns correct information.
3479                  */
3480                 if (si->bindname.sa_socklen > 0) {
3481                         si->myname = (struct swrap_address) {
3482                                 .sa_socklen = si->bindname.sa_socklen,
3483                         };
3484
3485                         memcpy(&si->myname.sa.ss,
3486                                &si->bindname.sa.ss,
3487                                si->bindname.sa_socklen);
3488
3489                         /* Cleanup bindname */
3490                         si->bindname = (struct swrap_address) {
3491                                 .sa_socklen = 0,
3492                         };
3493                 }
3494
3495                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0);
3496                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0);
3497         } else {
3498                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0);
3499         }
3500
3501 done:
3502         return ret;
3503 }
3504
3505 int connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen)
3506 {
3507         return swrap_connect(s, serv_addr, addrlen);
3508 }
3509
3510 /****************************************************************************
3511  *   BIND
3512  ***************************************************************************/
3513
3514 static int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
3515 {
3516         int ret;
3517         struct swrap_address un_addr = {
3518                 .sa_socklen = sizeof(struct sockaddr_un),
3519         };
3520         struct socket_info *si = find_socket_info(s);
3521         int bind_error = 0;
3522 #if 0 /* FIXME */
3523         bool in_use;
3524 #endif
3525
3526         if (!si) {
3527                 return libc_bind(s, myaddr, addrlen);
3528         }
3529
3530         switch (si->family) {
3531         case AF_INET: {
3532                 const struct sockaddr_in *sin;
3533                 if (addrlen < sizeof(struct sockaddr_in)) {
3534                         bind_error = EINVAL;
3535                         break;
3536                 }
3537
3538                 sin = (const struct sockaddr_in *)(const void *)myaddr;
3539
3540                 if (sin->sin_family != AF_INET) {
3541                         bind_error = EAFNOSUPPORT;
3542                 }
3543
3544                 /* special case for AF_UNSPEC */
3545                 if (sin->sin_family == AF_UNSPEC &&
3546                     (sin->sin_addr.s_addr == htonl(INADDR_ANY)))
3547                 {
3548                         bind_error = 0;
3549                 }
3550
3551                 break;
3552         }
3553 #ifdef HAVE_IPV6
3554         case AF_INET6: {
3555                 const struct sockaddr_in6 *sin6;
3556                 if (addrlen < sizeof(struct sockaddr_in6)) {
3557                         bind_error = EINVAL;
3558                         break;
3559                 }
3560
3561                 sin6 = (const struct sockaddr_in6 *)(const void *)myaddr;
3562
3563                 if (sin6->sin6_family != AF_INET6) {
3564                         bind_error = EAFNOSUPPORT;
3565                 }
3566
3567                 break;
3568         }
3569 #endif
3570         default:
3571                 bind_error = EINVAL;
3572                 break;
3573         }
3574
3575         if (bind_error != 0) {
3576                 errno = bind_error;
3577                 return -1;
3578         }
3579
3580 #if 0 /* FIXME */
3581         in_use = check_addr_port_in_use(myaddr, addrlen);
3582         if (in_use) {
3583                 errno = EADDRINUSE;
3584                 return -1;
3585         }
3586 #endif
3587
3588         si->myname.sa_socklen = addrlen;
3589         memcpy(&si->myname.sa.ss, myaddr, addrlen);
3590
3591         ret = sockaddr_convert_to_un(si,
3592                                      myaddr,
3593                                      addrlen,
3594                                      &un_addr.sa.un,
3595                                      1,
3596                                      &si->bcast);
3597         if (ret == -1) {
3598                 return -1;
3599         }
3600
3601         unlink(un_addr.sa.un.sun_path);
3602
3603         ret = libc_bind(s, &un_addr.sa.s, un_addr.sa_socklen);
3604
3605         SWRAP_LOG(SWRAP_LOG_TRACE,
3606                   "bind() path=%s, fd=%d",
3607                   un_addr.sa.un.sun_path, s);
3608
3609         if (ret == 0) {
3610                 si->bound = 1;
3611         }
3612
3613         return ret;
3614 }
3615
3616 int bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
3617 {
3618         return swrap_bind(s, myaddr, addrlen);
3619 }
3620
3621 /****************************************************************************
3622  *   BINDRESVPORT
3623  ***************************************************************************/
3624
3625 #ifdef HAVE_BINDRESVPORT
3626 static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen);
3627
3628 static int swrap_bindresvport_sa(int sd, struct sockaddr *sa)
3629 {
3630         struct swrap_address myaddr = {
3631                 .sa_socklen = sizeof(struct sockaddr_storage),
3632         };
3633         socklen_t salen;
3634         static uint16_t port;
3635         uint16_t i;
3636         int rc = -1;
3637         int af;
3638
3639 #define SWRAP_STARTPORT 600
3640 #define SWRAP_ENDPORT (IPPORT_RESERVED - 1)
3641 #define SWRAP_NPORTS (SWRAP_ENDPORT - SWRAP_STARTPORT + 1)
3642
3643         if (port == 0) {
3644                 port = (getpid() % SWRAP_NPORTS) + SWRAP_STARTPORT;
3645         }
3646
3647         if (sa == NULL) {
3648                 salen = myaddr.sa_socklen;
3649                 sa = &myaddr.sa.s;
3650
3651                 rc = swrap_getsockname(sd, &myaddr.sa.s, &salen);
3652                 if (rc < 0) {
3653                         return -1;
3654                 }
3655
3656                 af = sa->sa_family;
3657                 memset(&myaddr.sa.ss, 0, salen);
3658         } else {
3659                 af = sa->sa_family;
3660         }
3661
3662         for (i = 0; i < SWRAP_NPORTS; i++, port++) {
3663                 switch(af) {
3664                 case AF_INET: {
3665                         struct sockaddr_in *sinp = (struct sockaddr_in *)(void *)sa;
3666
3667                         salen = sizeof(struct sockaddr_in);
3668                         sinp->sin_port = htons(port);
3669                         break;
3670                 }
3671                 case AF_INET6: {
3672                         struct sockaddr_in6 *sin6p = (struct sockaddr_in6 *)(void *)sa;
3673
3674                         salen = sizeof(struct sockaddr_in6);
3675                         sin6p->sin6_port = htons(port);
3676                         break;
3677                 }
3678                 default:
3679                         errno = EAFNOSUPPORT;
3680                         return -1;
3681                 }
3682                 sa->sa_family = af;
3683
3684                 if (port > SWRAP_ENDPORT) {
3685                         port = SWRAP_STARTPORT;
3686                 }
3687
3688                 rc = swrap_bind(sd, (struct sockaddr *)sa, salen);
3689                 if (rc == 0 || errno != EADDRINUSE) {
3690                         break;
3691                 }
3692         }
3693
3694         return rc;
3695 }
3696
3697 int bindresvport(int sockfd, struct sockaddr_in *sinp)
3698 {
3699         return swrap_bindresvport_sa(sockfd, (struct sockaddr *)sinp);
3700 }
3701 #endif
3702
3703 /****************************************************************************
3704  *   LISTEN
3705  ***************************************************************************/
3706
3707 static int swrap_listen(int s, int backlog)
3708 {
3709         int ret;
3710         struct socket_info *si = find_socket_info(s);
3711
3712         if (!si) {
3713                 return libc_listen(s, backlog);
3714         }
3715
3716         if (si->bound == 0) {
3717                 ret = swrap_auto_bind(s, si, si->family);
3718                 if (ret == -1) {
3719                         errno = EADDRINUSE;
3720                         return ret;
3721                 }
3722         }
3723
3724         ret = libc_listen(s, backlog);
3725
3726         return ret;
3727 }
3728
3729 int listen(int s, int backlog)
3730 {
3731         return swrap_listen(s, backlog);
3732 }
3733
3734 /****************************************************************************
3735  *   FOPEN
3736  ***************************************************************************/
3737
3738 static FILE *swrap_fopen(const char *name, const char *mode)
3739 {
3740         FILE *fp;
3741
3742         fp = libc_fopen(name, mode);
3743         if (fp != NULL) {
3744                 int fd = fileno(fp);
3745
3746                 swrap_remove_stale(fd);
3747         }
3748
3749         return fp;
3750 }
3751
3752 FILE *fopen(const char *name, const char *mode)
3753 {
3754         return swrap_fopen(name, mode);
3755 }
3756
3757 /****************************************************************************
3758  *   FOPEN64
3759  ***************************************************************************/
3760
3761 #ifdef HAVE_FOPEN64
3762 static FILE *swrap_fopen64(const char *name, const char *mode)
3763 {
3764         FILE *fp;
3765
3766         fp = libc_fopen64(name, mode);
3767         if (fp != NULL) {
3768                 int fd = fileno(fp);
3769
3770                 swrap_remove_stale(fd);
3771         }
3772
3773         return fp;
3774 }
3775
3776 FILE *fopen64(const char *name, const char *mode)
3777 {
3778         return swrap_fopen64(name, mode);
3779 }
3780 #endif /* HAVE_FOPEN64 */
3781
3782 /****************************************************************************
3783  *   OPEN
3784  ***************************************************************************/
3785
3786 static int swrap_vopen(const char *pathname, int flags, va_list ap)
3787 {
3788         int ret;
3789
3790         ret = libc_vopen(pathname, flags, ap);
3791         if (ret != -1) {
3792                 /*
3793                  * There are methods for closing descriptors (libc-internal code
3794                  * paths, direct syscalls) which close descriptors in ways that
3795                  * we can't intercept, so try to recover when we notice that
3796                  * that's happened
3797                  */
3798                 swrap_remove_stale(ret);
3799         }
3800         return ret;
3801 }
3802
3803 int open(const char *pathname, int flags, ...)
3804 {
3805         va_list ap;
3806         int fd;
3807
3808         va_start(ap, flags);
3809         fd = swrap_vopen(pathname, flags, ap);
3810         va_end(ap);
3811
3812         return fd;
3813 }
3814
3815 /****************************************************************************
3816  *   OPEN64
3817  ***************************************************************************/
3818
3819 #ifdef HAVE_OPEN64
3820 static int swrap_vopen64(const char *pathname, int flags, va_list ap)
3821 {
3822         int ret;
3823
3824         ret = libc_vopen64(pathname, flags, ap);
3825         if (ret != -1) {
3826                 /*
3827                  * There are methods for closing descriptors (libc-internal code
3828                  * paths, direct syscalls) which close descriptors in ways that
3829                  * we can't intercept, so try to recover when we notice that
3830                  * that's happened
3831                  */
3832                 swrap_remove_stale(ret);
3833         }
3834         return ret;
3835 }
3836
3837 int open64(const char *pathname, int flags, ...)
3838 {
3839         va_list ap;
3840         int fd;
3841
3842         va_start(ap, flags);
3843         fd = swrap_vopen64(pathname, flags, ap);
3844         va_end(ap);
3845
3846         return fd;
3847 }
3848 #endif /* HAVE_OPEN64 */
3849
3850 /****************************************************************************
3851  *   OPENAT
3852  ***************************************************************************/
3853
3854 static int swrap_vopenat(int dirfd, const char *path, int flags, va_list ap)
3855 {
3856         int ret;
3857
3858         ret = libc_vopenat(dirfd, path, flags, ap);
3859         if (ret != -1) {
3860                 /*
3861                  * There are methods for closing descriptors (libc-internal code
3862                  * paths, direct syscalls) which close descriptors in ways that
3863                  * we can't intercept, so try to recover when we notice that
3864                  * that's happened
3865                  */
3866                 swrap_remove_stale(ret);
3867         }
3868
3869         return ret;
3870 }
3871
3872 int openat(int dirfd, const char *path, int flags, ...)
3873 {
3874         va_list ap;
3875         int fd;
3876
3877         va_start(ap, flags);
3878         fd = swrap_vopenat(dirfd, path, flags, ap);
3879         va_end(ap);
3880
3881         return fd;
3882 }
3883
3884 /****************************************************************************
3885  *   GETPEERNAME
3886  ***************************************************************************/
3887
3888 static int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
3889 {
3890         struct socket_info *si = find_socket_info(s);
3891         socklen_t len;
3892
3893         if (!si) {
3894                 return libc_getpeername(s, name, addrlen);
3895         }
3896
3897         if (si->peername.sa_socklen == 0)
3898         {
3899                 errno = ENOTCONN;
3900                 return -1;
3901         }
3902
3903         len = MIN(*addrlen, si->peername.sa_socklen);
3904         if (len == 0) {
3905                 return 0;
3906         }
3907
3908         memcpy(name, &si->peername.sa.ss, len);
3909         *addrlen = si->peername.sa_socklen;
3910
3911         return 0;
3912 }
3913
3914 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3915 int getpeername(int s, struct sockaddr *name, Psocklen_t addrlen)
3916 #else
3917 int getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
3918 #endif
3919 {
3920         return swrap_getpeername(s, name, (socklen_t *)addrlen);
3921 }
3922
3923 /****************************************************************************
3924  *   GETSOCKNAME
3925  ***************************************************************************/
3926
3927 static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
3928 {
3929         struct socket_info *si = find_socket_info(s);
3930         socklen_t len;
3931
3932         if (!si) {
3933                 return libc_getsockname(s, name, addrlen);
3934         }
3935
3936         len = MIN(*addrlen, si->myname.sa_socklen);
3937         if (len == 0) {
3938                 return 0;
3939         }
3940
3941         memcpy(name, &si->myname.sa.ss, len);
3942         *addrlen = si->myname.sa_socklen;
3943
3944         return 0;
3945 }
3946
3947 #ifdef HAVE_ACCEPT_PSOCKLEN_T
3948 int getsockname(int s, struct sockaddr *name, Psocklen_t addrlen)
3949 #else
3950 int getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
3951 #endif
3952 {
3953         return swrap_getsockname(s, name, (socklen_t *)addrlen);
3954 }
3955
3956 /****************************************************************************
3957  *   GETSOCKOPT
3958  ***************************************************************************/
3959
3960 #ifndef SO_PROTOCOL
3961 # ifdef SO_PROTOTYPE /* The Solaris name */
3962 #  define SO_PROTOCOL SO_PROTOTYPE
3963 # endif /* SO_PROTOTYPE */
3964 #endif /* SO_PROTOCOL */
3965
3966 static int swrap_getsockopt(int s, int level, int optname,
3967                             void *optval, socklen_t *optlen)
3968 {
3969         struct socket_info *si = find_socket_info(s);
3970         int ret;
3971
3972         if (!si) {
3973                 return libc_getsockopt(s,
3974                                        level,
3975                                        optname,
3976                                        optval,
3977                                        optlen);
3978         }
3979
3980         if (level == SOL_SOCKET) {
3981                 switch (optname) {
3982 #ifdef SO_DOMAIN
3983                 case SO_DOMAIN:
3984                         if (optval == NULL || optlen == NULL ||
3985                             *optlen < (socklen_t)sizeof(int)) {
3986                                 errno = EINVAL;
3987                                 ret = -1;
3988                                 goto done;
3989                         }
3990
3991                         *optlen = sizeof(int);
3992                         *(int *)optval = si->family;
3993                         ret = 0;
3994                         goto done;
3995 #endif /* SO_DOMAIN */
3996
3997 #ifdef SO_PROTOCOL
3998                 case SO_PROTOCOL:
3999                         if (optval == NULL || optlen == NULL ||
4000                             *optlen < (socklen_t)sizeof(int)) {
4001                                 errno = EINVAL;
4002                                 ret = -1;
4003                                 goto done;
4004                         }
4005
4006                         *optlen = sizeof(int);
4007                         *(int *)optval = si->protocol;
4008                         ret = 0;
4009                         goto done;
4010 #endif /* SO_PROTOCOL */
4011                 case SO_TYPE:
4012                         if (optval == NULL || optlen == NULL ||
4013                             *optlen < (socklen_t)sizeof(int)) {
4014                                 errno = EINVAL;
4015                                 ret = -1;
4016                                 goto done;
4017                         }
4018
4019                         *optlen = sizeof(int);
4020                         *(int *)optval = si->type;
4021                         ret = 0;
4022                         goto done;
4023                 default:
4024                         ret = libc_getsockopt(s,
4025                                               level,
4026                                               optname,
4027                                               optval,
4028                                               optlen);
4029                         goto done;
4030                 }
4031         } else if (level == IPPROTO_TCP) {
4032                 switch (optname) {
4033 #ifdef TCP_NODELAY
4034                 case TCP_NODELAY:
4035                         /*
4036                          * This enables sending packets directly out over TCP.
4037                          * As a unix socket is doing that any way, report it as
4038                          * enabled.
4039                          */
4040                         if (optval == NULL || optlen == NULL ||
4041                             *optlen < (socklen_t)sizeof(int)) {
4042                                 errno = EINVAL;
4043                                 ret = -1;
4044                                 goto done;
4045                         }
4046
4047                         *optlen = sizeof(int);
4048                         *(int *)optval = si->tcp_nodelay;
4049
4050                         ret = 0;
4051                         goto done;
4052 #endif /* TCP_NODELAY */
4053                 default:
4054                         break;
4055                 }
4056         }
4057
4058         errno = ENOPROTOOPT;
4059         ret = -1;
4060
4061 done:
4062         return ret;
4063 }
4064
4065 #ifdef HAVE_ACCEPT_PSOCKLEN_T
4066 int getsockopt(int s, int level, int optname, void *optval, Psocklen_t optlen)
4067 #else
4068 int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
4069 #endif
4070 {
4071         return swrap_getsockopt(s, level, optname, optval, (socklen_t *)optlen);
4072 }
4073
4074 /****************************************************************************
4075  *   SETSOCKOPT
4076  ***************************************************************************/
4077
4078 static int swrap_setsockopt(int s, int level, int optname,
4079                             const void *optval, socklen_t optlen)
4080 {
4081         struct socket_info *si = find_socket_info(s);
4082         int ret;
4083
4084         if (!si) {
4085                 return libc_setsockopt(s,
4086                                        level,
4087                                        optname,
4088                                        optval,
4089                                        optlen);
4090         }
4091
4092         if (level == SOL_SOCKET) {
4093                 return libc_setsockopt(s,
4094                                        level,
4095                                        optname,
4096                                        optval,
4097                                        optlen);
4098         }
4099
4100         if (level == IPPROTO_TCP) {
4101                 switch (optname) {
4102 #ifdef TCP_NODELAY
4103                 case TCP_NODELAY: {
4104                         int i;
4105
4106                         /*
4107                          * This enables sending packets directly out over TCP.
4108                          * A unix socket is doing that any way.
4109                          */
4110                         if (optval == NULL || optlen == 0 ||
4111                             optlen < (socklen_t)sizeof(int)) {
4112                                 errno = EINVAL;
4113                                 ret = -1;
4114                                 goto done;
4115                         }
4116
4117                         i = *discard_const_p(int, optval);
4118                         if (i != 0 && i != 1) {
4119                                 errno = EINVAL;
4120                                 ret = -1;
4121                                 goto done;
4122                         }
4123                         si->tcp_nodelay = i;
4124
4125                         ret = 0;
4126                         goto done;
4127                 }
4128 #endif /* TCP_NODELAY */
4129                 default:
4130                         break;
4131                 }
4132         }
4133
4134         switch (si->family) {
4135         case AF_INET:
4136                 if (level == IPPROTO_IP) {
4137 #ifdef IP_PKTINFO
4138                         if (optname == IP_PKTINFO) {
4139                                 si->pktinfo = AF_INET;
4140                         }
4141 #endif /* IP_PKTINFO */
4142                 }
4143                 ret = 0;
4144                 goto done;
4145 #ifdef HAVE_IPV6
4146         case AF_INET6:
4147                 if (level == IPPROTO_IPV6) {
4148 #ifdef IPV6_RECVPKTINFO
4149                         if (optname == IPV6_RECVPKTINFO) {
4150                                 si->pktinfo = AF_INET6;
4151                         }
4152 #endif /* IPV6_PKTINFO */
4153                 }
4154                 ret = 0;
4155                 goto done;
4156 #endif
4157         default:
4158                 errno = ENOPROTOOPT;
4159                 ret = -1;
4160                 goto done;
4161         }
4162
4163 done:
4164         return ret;
4165 }
4166
4167 int setsockopt(int s, int level, int optname,
4168                const void *optval, socklen_t optlen)
4169 {
4170         return swrap_setsockopt(s, level, optname, optval, optlen);
4171 }
4172
4173 /****************************************************************************
4174  *   IOCTL
4175  ***************************************************************************/
4176
4177 static int swrap_vioctl(int s, unsigned long int r, va_list va)
4178 {
4179         struct socket_info *si = find_socket_info(s);
4180         va_list ap;
4181         int value;
4182         int rc;
4183
4184         if (!si) {
4185                 return libc_vioctl(s, r, va);
4186         }
4187
4188         va_copy(ap, va);
4189
4190         rc = libc_vioctl(s, r, va);
4191
4192         switch (r) {
4193         case FIONREAD:
4194                 value = *((int *)va_arg(ap, int *));
4195
4196                 if (rc == -1 && errno != EAGAIN && errno != ENOBUFS) {
4197                         swrap_pcap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
4198                 } else if (value == 0) { /* END OF FILE */
4199                         swrap_pcap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
4200                 }
4201                 break;
4202         }
4203
4204         va_end(ap);
4205
4206         return rc;
4207 }
4208
4209 #ifdef HAVE_IOCTL_INT
4210 int ioctl(int s, int r, ...)
4211 #else
4212 int ioctl(int s, unsigned long int r, ...)
4213 #endif
4214 {
4215         va_list va;
4216         int rc;
4217
4218         va_start(va, r);
4219
4220         rc = swrap_vioctl(s, (unsigned long int) r, va);
4221
4222         va_end(va);
4223
4224         return rc;
4225 }
4226
4227 /*****************
4228  * CMSG
4229  *****************/
4230
4231 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4232
4233 #ifndef CMSG_ALIGN
4234 # ifdef _ALIGN /* BSD */
4235 #define CMSG_ALIGN _ALIGN
4236 # else
4237 #define CMSG_ALIGN(len) (((len) + sizeof(size_t) - 1) & ~(sizeof(size_t) - 1))
4238 # endif /* _ALIGN */
4239 #endif /* CMSG_ALIGN */
4240
4241 /**
4242  * @brief Add a cmsghdr to a msghdr.
4243  *
4244  * This is an function to add any type of cmsghdr. It will operate on the
4245  * msg->msg_control and msg->msg_controllen you pass in by adapting them to
4246  * the buffer position after the added cmsg element. Hence, this function is
4247  * intended to be used with an intermediate msghdr and not on the original
4248  * one handed in by the client.
4249  *
4250  * @param[in]  msg      The msghdr to which to add the cmsg.
4251  *
4252  * @param[in]  level    The cmsg level to set.
4253  *
4254  * @param[in]  type     The cmsg type to set.
4255  *
4256  * @param[in]  data     The cmsg data to set.
4257  *
4258  * @param[in]  len      the length of the data to set.
4259  */
4260 static void swrap_msghdr_add_cmsghdr(struct msghdr *msg,
4261                                      int level,
4262                                      int type,
4263                                      const void *data,
4264                                      size_t len)
4265 {
4266         size_t cmlen = CMSG_LEN(len);
4267         size_t cmspace = CMSG_SPACE(len);
4268         uint8_t cmbuf[cmspace];
4269         void *cast_ptr = (void *)cmbuf;
4270         struct cmsghdr *cm = (struct cmsghdr *)cast_ptr;
4271         uint8_t *p;
4272
4273         memset(cmbuf, 0, cmspace);
4274
4275         if (msg->msg_controllen < cmlen) {
4276                 cmlen = msg->msg_controllen;
4277                 msg->msg_flags |= MSG_CTRUNC;
4278         }
4279
4280         if (msg->msg_controllen < cmspace) {
4281                 cmspace = msg->msg_controllen;
4282         }
4283
4284         /*
4285          * We copy the full input data into an intermediate cmsghdr first
4286          * in order to more easily cope with truncation.
4287          */
4288         cm->cmsg_len = cmlen;
4289         cm->cmsg_level = level;
4290         cm->cmsg_type = type;
4291         memcpy(CMSG_DATA(cm), data, len);
4292
4293         /*
4294          * We now copy the possibly truncated buffer.
4295          * We copy cmlen bytes, but consume cmspace bytes,
4296          * leaving the possible padding uninitialiazed.
4297          */
4298         p = (uint8_t *)msg->msg_control;
4299         memcpy(p, cm, cmlen);
4300         p += cmspace;
4301         msg->msg_control = p;
4302         msg->msg_controllen -= cmspace;
4303
4304         return;
4305 }
4306
4307 static int swrap_msghdr_add_pktinfo(struct socket_info *si,
4308                                     struct msghdr *msg)
4309 {
4310         /* Add packet info */
4311         switch (si->pktinfo) {
4312 #if defined(IP_PKTINFO) && (defined(HAVE_STRUCT_IN_PKTINFO) || defined(IP_RECVDSTADDR))
4313         case AF_INET: {
4314                 struct sockaddr_in *sin;
4315 #if defined(HAVE_STRUCT_IN_PKTINFO)
4316                 struct in_pktinfo pkt;
4317 #elif defined(IP_RECVDSTADDR)
4318                 struct in_addr pkt;
4319 #endif
4320
4321                 if (si->bindname.sa_socklen == sizeof(struct sockaddr_in)) {
4322                         sin = &si->bindname.sa.in;
4323                 } else {
4324                         if (si->myname.sa_socklen != sizeof(struct sockaddr_in)) {
4325                                 return 0;
4326                         }
4327                         sin = &si->myname.sa.in;
4328                 }
4329
4330                 ZERO_STRUCT(pkt);
4331
4332 #if defined(HAVE_STRUCT_IN_PKTINFO)
4333                 pkt.ipi_ifindex = socket_wrapper_default_iface();
4334                 pkt.ipi_addr.s_addr = sin->sin_addr.s_addr;
4335 #elif defined(IP_RECVDSTADDR)
4336                 pkt = sin->sin_addr;
4337 #endif
4338
4339                 swrap_msghdr_add_cmsghdr(msg, IPPROTO_IP, IP_PKTINFO,
4340                                          &pkt, sizeof(pkt));
4341
4342                 break;
4343         }
4344 #endif /* IP_PKTINFO */
4345 #if defined(HAVE_IPV6)
4346         case AF_INET6: {
4347 #if defined(IPV6_PKTINFO) && defined(HAVE_STRUCT_IN6_PKTINFO)
4348                 struct sockaddr_in6 *sin6;
4349                 struct in6_pktinfo pkt6;
4350
4351                 if (si->bindname.sa_socklen == sizeof(struct sockaddr_in6)) {
4352                         sin6 = &si->bindname.sa.in6;
4353                 } else {
4354                         if (si->myname.sa_socklen != sizeof(struct sockaddr_in6)) {
4355                                 return 0;
4356                         }
4357                         sin6 = &si->myname.sa.in6;
4358                 }
4359
4360                 ZERO_STRUCT(pkt6);
4361
4362                 pkt6.ipi6_ifindex = socket_wrapper_default_iface();
4363                 pkt6.ipi6_addr = sin6->sin6_addr;
4364
4365                 swrap_msghdr_add_cmsghdr(msg, IPPROTO_IPV6, IPV6_PKTINFO,
4366                                         &pkt6, sizeof(pkt6));
4367 #endif /* HAVE_STRUCT_IN6_PKTINFO */
4368
4369                 break;
4370         }
4371 #endif /* IPV6_PKTINFO */
4372         default:
4373                 return -1;
4374         }
4375
4376         return 0;
4377 }
4378
4379 static int swrap_msghdr_add_socket_info(struct socket_info *si,
4380                                         struct msghdr *omsg)
4381 {
4382         int rc = 0;
4383
4384         if (si->pktinfo > 0) {
4385                 rc = swrap_msghdr_add_pktinfo(si, omsg);
4386         }
4387
4388         return rc;
4389 }
4390
4391 static int swrap_sendmsg_copy_cmsg(struct cmsghdr *cmsg,
4392                                    uint8_t **cm_data,
4393                                    size_t *cm_data_space);
4394 static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr *cmsg,
4395                                             uint8_t **cm_data,
4396                                             size_t *cm_data_space);
4397
4398 static int swrap_sendmsg_filter_cmsghdr(struct msghdr *msg,
4399                                         uint8_t **cm_data,
4400                                         size_t *cm_data_space) {
4401         struct cmsghdr *cmsg;
4402         int rc = -1;
4403
4404         /* Nothing to do */
4405         if (msg->msg_controllen == 0 || msg->msg_control == NULL) {
4406                 return 0;
4407         }
4408
4409         for (cmsg = CMSG_FIRSTHDR(msg);
4410              cmsg != NULL;
4411              cmsg = CMSG_NXTHDR(msg, cmsg)) {
4412                 switch (cmsg->cmsg_level) {
4413                 case IPPROTO_IP:
4414                         rc = swrap_sendmsg_filter_cmsg_socket(cmsg,
4415                                                               cm_data,
4416                                                               cm_data_space);
4417                         break;
4418                 default:
4419                         rc = swrap_sendmsg_copy_cmsg(cmsg,
4420                                                      cm_data,
4421                                                      cm_data_space);
4422                         break;
4423                 }
4424         }
4425
4426         return rc;
4427 }
4428
4429 static int swrap_sendmsg_copy_cmsg(struct cmsghdr *cmsg,
4430                                    uint8_t **cm_data,
4431                                    size_t *cm_data_space)
4432 {
4433         size_t cmspace;
4434         uint8_t *p;
4435
4436         cmspace = *cm_data_space + CMSG_ALIGN(cmsg->cmsg_len);
4437
4438         p = realloc((*cm_data), cmspace);
4439         if (p == NULL) {
4440                 return -1;
4441         }
4442         (*cm_data) = p;
4443
4444         p = (*cm_data) + (*cm_data_space);
4445         *cm_data_space = cmspace;
4446
4447         memcpy(p, cmsg, cmsg->cmsg_len);
4448
4449         return 0;
4450 }
4451
4452 static int swrap_sendmsg_filter_cmsg_pktinfo(struct cmsghdr *cmsg,
4453                                             uint8_t **cm_data,
4454                                             size_t *cm_data_space);
4455
4456
4457 static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr *cmsg,
4458                                             uint8_t **cm_data,
4459                                             size_t *cm_data_space)
4460 {
4461         int rc = -1;
4462
4463         switch(cmsg->cmsg_type) {
4464 #ifdef IP_PKTINFO
4465         case IP_PKTINFO:
4466                 rc = swrap_sendmsg_filter_cmsg_pktinfo(cmsg,
4467                                                        cm_data,
4468                                                        cm_data_space);
4469                 break;
4470 #endif
4471 #ifdef IPV6_PKTINFO
4472         case IPV6_PKTINFO:
4473                 rc = swrap_sendmsg_filter_cmsg_pktinfo(cmsg,
4474                                                        cm_data,
4475                                                        cm_data_space);
4476                 break;
4477 #endif
4478         default:
4479                 break;
4480         }
4481
4482         return rc;
4483 }
4484
4485 static int swrap_sendmsg_filter_cmsg_pktinfo(struct cmsghdr *cmsg,
4486                                              uint8_t **cm_data,
4487                                              size_t *cm_data_space)
4488 {
4489         (void)cmsg; /* unused */
4490         (void)cm_data; /* unused */
4491         (void)cm_data_space; /* unused */
4492
4493         /*
4494          * Passing a IP pktinfo to a unix socket might be rejected by the
4495          * Kernel, at least on FreeBSD. So skip this cmsg.
4496          */
4497         return 0;
4498 }
4499 #endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
4500
4501 static ssize_t swrap_sendmsg_before(int fd,
4502                                     struct socket_info *si,
4503                                     struct msghdr *msg,
4504                                     struct iovec *tmp_iov,
4505                                     struct sockaddr_un *tmp_un,
4506                                     const struct sockaddr_un **to_un,
4507                                     const struct sockaddr **to,
4508                                     int *bcast)
4509 {
4510         size_t i, len = 0;
4511         ssize_t ret;
4512
4513         if (to_un) {
4514                 *to_un = NULL;
4515         }
4516         if (to) {
4517                 *to = NULL;
4518         }
4519         if (bcast) {
4520                 *bcast = 0;
4521         }
4522
4523         switch (si->type) {
4524         case SOCK_STREAM: {
4525                 unsigned long mtu;
4526
4527                 if (!si->connected) {
4528                         errno = ENOTCONN;
4529                         return -1;
4530                 }
4531
4532                 if (msg->msg_iovlen == 0) {
4533                         break;
4534                 }
4535
4536                 mtu = socket_wrapper_mtu();
4537                 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
4538                         size_t nlen;
4539                         nlen = len + msg->msg_iov[i].iov_len;
4540                         if (nlen > mtu) {
4541                                 break;
4542                         }
4543                 }
4544                 msg->msg_iovlen = i;
4545                 if (msg->msg_iovlen == 0) {
4546                         *tmp_iov = msg->msg_iov[0];
4547                         tmp_iov->iov_len = MIN((size_t)tmp_iov->iov_len,
4548                                                (size_t)mtu);
4549                         msg->msg_iov = tmp_iov;
4550                         msg->msg_iovlen = 1;
4551                 }
4552                 break;
4553         }
4554         case SOCK_DGRAM:
4555                 if (si->connected) {
4556                         if (msg->msg_name != NULL) {
4557                                 /*
4558                                  * We are dealing with unix sockets and if we
4559                                  * are connected, we should only talk to the
4560                                  * connected unix path. Using the fd to send
4561                                  * to another server would be hard to achieve.
4562                                  */
4563                                 msg->msg_name = NULL;
4564                                 msg->msg_namelen = 0;
4565                         }
4566                 } else {
4567                         const struct sockaddr *msg_name;
4568                         msg_name = (const struct sockaddr *)msg->msg_name;
4569
4570                         if (msg_name == NULL) {
4571                                 errno = ENOTCONN;
4572                                 return -1;
4573                         }
4574
4575
4576                         ret = sockaddr_convert_to_un(si, msg_name, msg->msg_namelen,
4577                                                      tmp_un, 0, bcast);
4578                         if (ret == -1) {
4579                                 return -1;
4580                         }
4581
4582                         if (to_un) {
4583                                 *to_un = tmp_un;
4584                         }
4585                         if (to) {
4586                                 *to = msg_name;
4587                         }
4588                         msg->msg_name = tmp_un;
4589                         msg->msg_namelen = sizeof(*tmp_un);
4590                 }
4591
4592                 if (si->bound == 0) {
4593                         ret = swrap_auto_bind(fd, si, si->family);
4594                         if (ret == -1) {
4595                                 if (errno == ENOTSOCK) {
4596                                         swrap_remove_stale(fd);
4597                                         return -ENOTSOCK;
4598                                 } else {
4599                                         SWRAP_LOG(SWRAP_LOG_ERROR, "swrap_sendmsg_before failed");
4600                                         return -1;
4601                                 }
4602                         }
4603                 }
4604
4605                 if (!si->defer_connect) {
4606                         break;
4607                 }
4608
4609                 ret = sockaddr_convert_to_un(si,
4610                                              &si->peername.sa.s,
4611                                              si->peername.sa_socklen,
4612                                              tmp_un,
4613                                              0,
4614                                              NULL);
4615                 if (ret == -1) {
4616                         return -1;
4617                 }
4618
4619                 ret = libc_connect(fd,
4620                                    (struct sockaddr *)(void *)tmp_un,
4621                                    sizeof(*tmp_un));
4622
4623                 /* to give better errors */
4624                 if (ret == -1 && errno == ENOENT) {
4625                         errno = EHOSTUNREACH;
4626                 }
4627
4628                 if (ret == -1) {
4629                         return ret;
4630                 }
4631
4632                 si->defer_connect = 0;
4633                 break;
4634         default:
4635                 errno = EHOSTUNREACH;
4636                 return -1;
4637         }
4638
4639 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4640         if (msg->msg_controllen > 0 && msg->msg_control != NULL) {
4641                 uint8_t *cmbuf = NULL;
4642                 size_t cmlen = 0;
4643
4644                 ret = swrap_sendmsg_filter_cmsghdr(msg, &cmbuf, &cmlen);
4645                 if (ret < 0) {
4646                         free(cmbuf);
4647                         return -1;
4648                 }
4649
4650                 if (cmlen == 0) {
4651                         msg->msg_controllen = 0;
4652                         msg->msg_control = NULL;
4653                 } else if (cmlen < msg->msg_controllen && cmbuf != NULL) {
4654                         memcpy(msg->msg_control, cmbuf, cmlen);
4655                         msg->msg_controllen = cmlen;
4656                 }
4657                 free(cmbuf);
4658         }
4659 #endif
4660
4661         return 0;
4662 }
4663
4664 static void swrap_sendmsg_after(int fd,
4665                                 struct socket_info *si,
4666                                 struct msghdr *msg,
4667                                 const struct sockaddr *to,
4668                                 ssize_t ret)
4669 {
4670         int saved_errno = errno;
4671         size_t i, len = 0;
4672         uint8_t *buf;
4673         off_t ofs = 0;
4674         size_t avail = 0;
4675         size_t remain;
4676
4677         /* to give better errors */
4678         if (ret == -1) {
4679                 if (saved_errno == ENOENT) {
4680                         saved_errno = EHOSTUNREACH;
4681                 } else if (saved_errno == ENOTSOCK) {
4682                         /* If the fd is not a socket, remove it */
4683                         swrap_remove_stale(fd);
4684                 }
4685         }
4686
4687         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
4688                 avail += msg->msg_iov[i].iov_len;
4689         }
4690
4691         if (ret == -1) {
4692                 remain = MIN(80, avail);
4693         } else {
4694                 remain = ret;
4695         }
4696
4697         /* we capture it as one single packet */
4698         buf = (uint8_t *)malloc(remain);
4699         if (!buf) {
4700                 /* we just not capture the packet */
4701                 errno = saved_errno;
4702                 return;
4703         }
4704
4705         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
4706                 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
4707                 memcpy(buf + ofs,
4708                        msg->msg_iov[i].iov_base,
4709                        this_time);
4710                 ofs += this_time;
4711                 remain -= this_time;
4712         }
4713         len = ofs;
4714
4715         switch (si->type) {
4716         case SOCK_STREAM:
4717                 if (ret == -1) {
4718                         swrap_pcap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
4719                         swrap_pcap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
4720                 } else {
4721                         swrap_pcap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
4722                 }
4723                 break;
4724
4725         case SOCK_DGRAM:
4726                 if (si->connected) {
4727                         to = &si->peername.sa.s;
4728                 }
4729                 if (ret == -1) {
4730                         swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
4731                         swrap_pcap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);
4732                 } else {
4733                         swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
4734                 }
4735                 break;
4736         }
4737
4738         free(buf);
4739         errno = saved_errno;
4740 }
4741
4742 static int swrap_recvmsg_before(int fd,
4743                                 struct socket_info *si,
4744                                 struct msghdr *msg,
4745                                 struct iovec *tmp_iov)
4746 {
4747         size_t i, len = 0;
4748         ssize_t ret;
4749
4750         (void)fd; /* unused */
4751
4752         switch (si->type) {
4753         case SOCK_STREAM: {
4754                 unsigned int mtu;
4755                 if (!si->connected) {
4756                         errno = ENOTCONN;
4757                         return -1;
4758                 }
4759
4760                 if (msg->msg_iovlen == 0) {
4761                         break;
4762                 }
4763
4764                 mtu = socket_wrapper_mtu();
4765                 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
4766                         size_t nlen;
4767                         nlen = len + msg->msg_iov[i].iov_len;
4768                         if (nlen > mtu) {
4769                                 break;
4770                         }
4771                 }
4772                 msg->msg_iovlen = i;
4773                 if (msg->msg_iovlen == 0) {
4774                         *tmp_iov = msg->msg_iov[0];
4775                         tmp_iov->iov_len = MIN((size_t)tmp_iov->iov_len,
4776                                                (size_t)mtu);
4777                         msg->msg_iov = tmp_iov;
4778                         msg->msg_iovlen = 1;
4779                 }
4780                 break;
4781         }
4782         case SOCK_DGRAM:
4783                 if (msg->msg_name == NULL) {
4784                         errno = EINVAL;
4785                         return -1;
4786                 }
4787
4788                 if (msg->msg_iovlen == 0) {
4789                         break;
4790                 }
4791
4792                 if (si->bound == 0) {
4793                         ret = swrap_auto_bind(fd, si, si->family);
4794                         if (ret == -1) {
4795                                 /*
4796                                  * When attempting to read or write to a
4797                                  * descriptor, if an underlying autobind fails
4798                                  * because it's not a socket, stop intercepting
4799                                  * uses of that descriptor.
4800                                  */
4801                                 if (errno == ENOTSOCK) {
4802                                         swrap_remove_stale(fd);
4803                                         return -ENOTSOCK;
4804                                 } else {
4805                                         SWRAP_LOG(SWRAP_LOG_ERROR,
4806                                                   "swrap_recvmsg_before failed");
4807                                         return -1;
4808                                 }
4809                         }
4810                 }
4811                 break;
4812         default:
4813                 errno = EHOSTUNREACH;
4814                 return -1;
4815         }
4816
4817         return 0;
4818 }
4819
4820 static int swrap_recvmsg_after(int fd,
4821                                struct socket_info *si,
4822                                struct msghdr *msg,
4823                                const struct sockaddr_un *un_addr,
4824                                socklen_t un_addrlen,
4825                                ssize_t ret)
4826 {
4827         int saved_errno = errno;
4828         size_t i;
4829         uint8_t *buf = NULL;
4830         off_t ofs = 0;
4831         size_t avail = 0;
4832         size_t remain;
4833         int rc;
4834
4835         /* to give better errors */
4836         if (ret == -1) {
4837                 if (saved_errno == ENOENT) {
4838                         saved_errno = EHOSTUNREACH;
4839                 } else if (saved_errno == ENOTSOCK) {
4840                         /* If the fd is not a socket, remove it */
4841                         swrap_remove_stale(fd);
4842                 }
4843         }
4844
4845         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
4846                 avail += msg->msg_iov[i].iov_len;
4847         }
4848
4849         /* Convert the socket address before we leave */
4850         if (si->type == SOCK_DGRAM && un_addr != NULL) {
4851                 rc = sockaddr_convert_from_un(si,
4852                                               un_addr,
4853                                               un_addrlen,
4854                                               si->family,
4855                                               msg->msg_name,
4856                                               &msg->msg_namelen);
4857                 if (rc == -1) {
4858                         goto done;
4859                 }
4860         }
4861
4862         if (avail == 0) {
4863                 rc = 0;
4864                 goto done;
4865         }
4866
4867         if (ret == -1) {
4868                 remain = MIN(80, avail);
4869         } else {
4870                 remain = ret;
4871         }
4872
4873         /* we capture it as one single packet */
4874         buf = (uint8_t *)malloc(remain);
4875         if (buf == NULL) {
4876                 /* we just not capture the packet */
4877                 errno = saved_errno;
4878                 return -1;
4879         }
4880
4881         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
4882                 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
4883                 memcpy(buf + ofs,
4884                        msg->msg_iov[i].iov_base,
4885                        this_time);
4886                 ofs += this_time;
4887                 remain -= this_time;
4888         }
4889
4890         switch (si->type) {
4891         case SOCK_STREAM:
4892                 if (ret == -1 && saved_errno != EAGAIN && saved_errno != ENOBUFS) {
4893                         swrap_pcap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
4894                 } else if (ret == 0) { /* END OF FILE */
4895                         swrap_pcap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
4896                 } else if (ret > 0) {
4897                         swrap_pcap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
4898                 }
4899                 break;
4900
4901         case SOCK_DGRAM:
4902                 if (ret == -1) {
4903                         break;
4904                 }
4905
4906                 if (un_addr != NULL) {
4907                         swrap_pcap_dump_packet(si,
4908                                           msg->msg_name,
4909                                           SWRAP_RECVFROM,
4910                                           buf,
4911                                           ret);
4912                 } else {
4913                         swrap_pcap_dump_packet(si,
4914                                           msg->msg_name,
4915                                           SWRAP_RECV,
4916                                           buf,
4917                                           ret);
4918                 }
4919
4920                 break;
4921         }
4922
4923         rc = 0;
4924 done:
4925         free(buf);
4926         errno = saved_errno;
4927
4928 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4929         if (rc == 0 &&
4930             msg->msg_controllen > 0 &&
4931             msg->msg_control != NULL) {
4932                 rc = swrap_msghdr_add_socket_info(si, msg);
4933                 if (rc < 0) {
4934                         return -1;
4935                 }
4936         }
4937 #endif
4938
4939         return rc;
4940 }
4941
4942 /****************************************************************************
4943  *   RECVFROM
4944  ***************************************************************************/
4945
4946 static ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags,
4947                               struct sockaddr *from, socklen_t *fromlen)
4948 {
4949         struct swrap_address from_addr = {
4950                 .sa_socklen = sizeof(struct sockaddr_un),
4951         };
4952         ssize_t ret;
4953         struct socket_info *si = find_socket_info(s);
4954         struct swrap_address saddr = {
4955                 .sa_socklen = sizeof(struct sockaddr_storage),
4956         };
4957         struct msghdr msg;
4958         struct iovec tmp;
4959         int tret;
4960
4961         if (!si) {
4962                 return libc_recvfrom(s,
4963                                      buf,
4964                                      len,
4965                                      flags,
4966                                      from,
4967                                      fromlen);
4968         }
4969
4970         tmp.iov_base = buf;
4971         tmp.iov_len = len;
4972
4973         ZERO_STRUCT(msg);
4974         if (from != NULL && fromlen != NULL) {
4975                 msg.msg_name = from;   /* optional address */
4976                 msg.msg_namelen = *fromlen; /* size of address */
4977         } else {
4978                 msg.msg_name = &saddr.sa.s; /* optional address */
4979                 msg.msg_namelen = saddr.sa_socklen; /* size of address */
4980         }
4981         msg.msg_iov = &tmp;            /* scatter/gather array */
4982         msg.msg_iovlen = 1;            /* # elements in msg_iov */
4983 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
4984         msg.msg_control = NULL;        /* ancillary data, see below */
4985         msg.msg_controllen = 0;        /* ancillary data buffer len */
4986         msg.msg_flags = 0;             /* flags on received message */
4987 #endif
4988
4989         tret = swrap_recvmsg_before(s, si, &msg, &tmp);
4990         if (tret < 0) {
4991                 return -1;
4992         }
4993
4994         buf = msg.msg_iov[0].iov_base;
4995         len = msg.msg_iov[0].iov_len;
4996
4997         ret = libc_recvfrom(s,
4998                             buf,
4999                             len,
5000                             flags,
5001                             &from_addr.sa.s,
5002                             &from_addr.sa_socklen);
5003         if (ret == -1) {
5004                 return ret;
5005         }
5006
5007         tret = swrap_recvmsg_after(s,
5008                                    si,
5009                                    &msg,
5010                                    &from_addr.sa.un,
5011                                    from_addr.sa_socklen,
5012                                    ret);
5013         if (tret != 0) {
5014                 return tret;
5015         }
5016
5017         if (from != NULL && fromlen != NULL) {
5018                 *fromlen = msg.msg_namelen;
5019         }
5020
5021         return ret;
5022 }
5023
5024 #ifdef HAVE_ACCEPT_PSOCKLEN_T
5025 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
5026                  struct sockaddr *from, Psocklen_t fromlen)
5027 #else
5028 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
5029                  struct sockaddr *from, socklen_t *fromlen)
5030 #endif
5031 {
5032         return swrap_recvfrom(s, buf, len, flags, from, (socklen_t *)fromlen);
5033 }
5034
5035 /****************************************************************************
5036  *   SENDTO
5037  ***************************************************************************/
5038
5039 static ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags,
5040                             const struct sockaddr *to, socklen_t tolen)
5041 {
5042         struct msghdr msg;
5043         struct iovec tmp;
5044         struct swrap_address un_addr = {
5045                 .sa_socklen = sizeof(struct sockaddr_un),
5046         };
5047         const struct sockaddr_un *to_un = NULL;
5048         ssize_t ret;
5049         int rc;
5050         struct socket_info *si = find_socket_info(s);
5051         int bcast = 0;
5052
5053         if (!si) {
5054                 return libc_sendto(s, buf, len, flags, to, tolen);
5055         }
5056
5057         tmp.iov_base = discard_const_p(char, buf);
5058         tmp.iov_len = len;
5059
5060         ZERO_STRUCT(msg);
5061         msg.msg_name = discard_const_p(struct sockaddr, to); /* optional address */
5062         msg.msg_namelen = tolen;       /* size of address */
5063         msg.msg_iov = &tmp;            /* scatter/gather array */
5064         msg.msg_iovlen = 1;            /* # elements in msg_iov */
5065 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
5066         msg.msg_control = NULL;        /* ancillary data, see below */
5067         msg.msg_controllen = 0;        /* ancillary data buffer len */
5068         msg.msg_flags = 0;             /* flags on received message */
5069 #endif
5070
5071         rc = swrap_sendmsg_before(s,
5072                                   si,
5073                                   &msg,
5074                                   &tmp,
5075                                   &un_addr.sa.un,
5076                                   &to_un,
5077                                   &to,
5078                                   &bcast);
5079         if (rc < 0) {
5080                 return -1;
5081         }
5082
5083         buf = msg.msg_iov[0].iov_base;
5084         len = msg.msg_iov[0].iov_len;
5085
5086         if (bcast) {
5087                 struct stat st;
5088                 unsigned int iface;
5089                 unsigned int prt = ntohs(((const struct sockaddr_in *)(const void *)to)->sin_port);
5090                 char type;
5091
5092                 type = SOCKET_TYPE_CHAR_UDP;
5093
5094                 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
5095                         snprintf(un_addr.sa.un.sun_path,
5096                                  sizeof(un_addr.sa.un.sun_path),
5097                                  "%s/"SOCKET_FORMAT,
5098                                  socket_wrapper_dir(), type, iface, prt);
5099                         if (stat(un_addr.sa.un.sun_path, &st) != 0) continue;
5100
5101                         /* ignore the any errors in broadcast sends */
5102                         libc_sendto(s,
5103                                     buf,
5104                                     len,
5105                                     flags,
5106                                     &un_addr.sa.s,
5107                                     un_addr.sa_socklen);
5108                 }
5109
5110                 swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
5111
5112                 return len;
5113         }
5114
5115         /*
5116          * If it is a dgram socket and we are connected, don't include the
5117          * 'to' address.
5118          */
5119         if (si->type == SOCK_DGRAM && si->connected) {
5120                 ret = libc_sendto(s,
5121                                   buf,
5122                                   len,
5123                                   flags,
5124                                   NULL,
5125                                   0);
5126         } else {
5127                 ret = libc_sendto(s,
5128                                   buf,
5129                                   len,
5130                                   flags,
5131                                   (struct sockaddr *)msg.msg_name,
5132                                   msg.msg_namelen);
5133         }
5134
5135         swrap_sendmsg_after(s, si, &msg, to, ret);
5136
5137         return ret;
5138 }
5139
5140 ssize_t sendto(int s, const void *buf, size_t len, int flags,
5141                const struct sockaddr *to, socklen_t tolen)
5142 {
5143         return swrap_sendto(s, buf, len, flags, to, tolen);
5144 }
5145
5146 /****************************************************************************
5147  *   READV
5148  ***************************************************************************/
5149
5150 static ssize_t swrap_recv(int s, void *buf, size_t len, int flags)
5151 {
5152         struct socket_info *si;
5153         struct msghdr msg;
5154         struct swrap_address saddr = {
5155                 .sa_socklen = sizeof(struct sockaddr_storage),
5156         };
5157         struct iovec tmp;
5158         ssize_t ret;
5159         int tret;
5160
5161         si = find_socket_info(s);
5162         if (si == NULL) {
5163                 return libc_recv(s, buf, len, flags);
5164         }
5165
5166         tmp.iov_base = buf;
5167         tmp.iov_len = len;
5168
5169         ZERO_STRUCT(msg);
5170         msg.msg_name = &saddr.sa.s;    /* optional address */
5171         msg.msg_namelen = saddr.sa_socklen; /* size of address */
5172         msg.msg_iov = &tmp;            /* scatter/gather array */
5173         msg.msg_iovlen = 1;            /* # elements in msg_iov */
5174 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5175         msg.msg_control = NULL;        /* ancillary data, see below */
5176         msg.msg_controllen = 0;        /* ancillary data buffer len */
5177         msg.msg_flags = 0;             /* flags on received message */
5178 #endif
5179
5180         tret = swrap_recvmsg_before(s, si, &msg, &tmp);
5181         if (tret < 0) {
5182                 return -1;
5183         }
5184
5185         buf = msg.msg_iov[0].iov_base;
5186         len = msg.msg_iov[0].iov_len;
5187
5188         ret = libc_recv(s, buf, len, flags);
5189
5190         tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
5191         if (tret != 0) {
5192                 return tret;
5193         }
5194
5195         return ret;
5196 }
5197
5198 ssize_t recv(int s, void *buf, size_t len, int flags)
5199 {
5200         return swrap_recv(s, buf, len, flags);
5201 }
5202
5203 /****************************************************************************
5204  *   READ
5205  ***************************************************************************/
5206
5207 static ssize_t swrap_read(int s, void *buf, size_t len)
5208 {
5209         struct socket_info *si;
5210         struct msghdr msg;
5211         struct iovec tmp;
5212         struct swrap_address saddr = {
5213                 .sa_socklen = sizeof(struct sockaddr_storage),
5214         };
5215         ssize_t ret;
5216         int tret;
5217
5218         si = find_socket_info(s);
5219         if (si == NULL) {
5220                 return libc_read(s, buf, len);
5221         }
5222
5223         tmp.iov_base = buf;
5224         tmp.iov_len = len;
5225
5226         ZERO_STRUCT(msg);
5227         msg.msg_name = &saddr.sa.ss;   /* optional address */
5228         msg.msg_namelen = saddr.sa_socklen; /* size of address */
5229         msg.msg_iov = &tmp;            /* scatter/gather array */
5230         msg.msg_iovlen = 1;            /* # elements in msg_iov */
5231 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5232         msg.msg_control = NULL;        /* ancillary data, see below */
5233         msg.msg_controllen = 0;        /* ancillary data buffer len */
5234         msg.msg_flags = 0;             /* flags on received message */
5235 #endif
5236
5237         tret = swrap_recvmsg_before(s, si, &msg, &tmp);
5238         if (tret < 0) {
5239                 if (tret == -ENOTSOCK) {
5240                         return libc_read(s, buf, len);
5241                 }
5242                 return -1;
5243         }
5244
5245         buf = msg.msg_iov[0].iov_base;
5246         len = msg.msg_iov[0].iov_len;
5247
5248         ret = libc_read(s, buf, len);
5249
5250         tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
5251         if (tret != 0) {
5252                 return tret;
5253         }
5254
5255         return ret;
5256 }
5257
5258 ssize_t read(int s, void *buf, size_t len)
5259 {
5260         return swrap_read(s, buf, len);
5261 }
5262
5263 /****************************************************************************
5264  *   WRITE
5265  ***************************************************************************/
5266
5267 static ssize_t swrap_write(int s, const void *buf, size_t len)
5268 {
5269         struct msghdr msg;
5270         struct iovec tmp;
5271         struct sockaddr_un un_addr;
5272         ssize_t ret;
5273         int rc;
5274         struct socket_info *si;
5275
5276         si = find_socket_info(s);
5277         if (si == NULL) {
5278                 return libc_write(s, buf, len);
5279         }
5280
5281         tmp.iov_base = discard_const_p(char, buf);
5282         tmp.iov_len = len;
5283
5284         ZERO_STRUCT(msg);
5285         msg.msg_name = NULL;           /* optional address */
5286         msg.msg_namelen = 0;           /* size of address */
5287         msg.msg_iov = &tmp;            /* scatter/gather array */
5288         msg.msg_iovlen = 1;            /* # elements in msg_iov */
5289 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
5290         msg.msg_control = NULL;        /* ancillary data, see below */
5291         msg.msg_controllen = 0;        /* ancillary data buffer len */
5292         msg.msg_flags = 0;             /* flags on received message */
5293 #endif
5294
5295         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
5296         if (rc < 0) {
5297                 return -1;
5298         }
5299
5300         buf = msg.msg_iov[0].iov_base;
5301         len = msg.msg_iov[0].iov_len;
5302
5303         ret = libc_write(s, buf, len);
5304
5305         swrap_sendmsg_after(s, si, &msg, NULL, ret);
5306
5307         return ret;
5308 }
5309
5310 ssize_t write(int s, const void *buf, size_t len)
5311 {
5312         return swrap_write(s, buf, len);
5313 }
5314
5315 /****************************************************************************
5316  *   SEND
5317  ***************************************************************************/
5318
5319 static ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
5320 {
5321         struct msghdr msg;
5322         struct iovec tmp;
5323         struct sockaddr_un un_addr;
5324         ssize_t ret;
5325         int rc;
5326         struct socket_info *si = find_socket_info(s);
5327
5328         if (!si) {
5329                 return libc_send(s, buf, len, flags);
5330         }
5331
5332         tmp.iov_base = discard_const_p(char, buf);
5333         tmp.iov_len = len;
5334
5335         ZERO_STRUCT(msg);
5336         msg.msg_name = NULL;           /* optional address */
5337         msg.msg_namelen = 0;           /* size of address */
5338         msg.msg_iov = &tmp;            /* scatter/gather array */
5339         msg.msg_iovlen = 1;            /* # elements in msg_iov */
5340 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
5341         msg.msg_control = NULL;        /* ancillary data, see below */
5342         msg.msg_controllen = 0;        /* ancillary data buffer len */
5343         msg.msg_flags = 0;             /* flags on received message */
5344 #endif
5345
5346         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
5347         if (rc < 0) {
5348                 return -1;
5349         }
5350
5351         buf = msg.msg_iov[0].iov_base;
5352         len = msg.msg_iov[0].iov_len;
5353
5354         ret = libc_send(s, buf, len, flags);
5355
5356         swrap_sendmsg_after(s, si, &msg, NULL, ret);
5357
5358         return ret;
5359 }
5360
5361 ssize_t send(int s, const void *buf, size_t len, int flags)
5362 {
5363         return swrap_send(s, buf, len, flags);
5364 }
5365
5366 /****************************************************************************
5367  *   RECVMSG
5368  ***************************************************************************/
5369
5370 static ssize_t swrap_recvmsg(int s, struct msghdr *omsg, int flags)
5371 {
5372         struct swrap_address from_addr = {
5373                 .sa_socklen = sizeof(struct sockaddr_un),
5374         };
5375         struct swrap_address convert_addr = {
5376                 .sa_socklen = sizeof(struct sockaddr_storage),
5377         };
5378         struct socket_info *si;
5379         struct msghdr msg;
5380         struct iovec tmp;
5381 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5382         size_t msg_ctrllen_filled;
5383         size_t msg_ctrllen_left;
5384 #endif
5385
5386         ssize_t ret;
5387         int rc;
5388
5389         si = find_socket_info(s);
5390         if (si == NULL) {
5391                 return libc_recvmsg(s, omsg, flags);
5392         }
5393
5394         tmp.iov_base = NULL;
5395         tmp.iov_len = 0;
5396
5397         ZERO_STRUCT(msg);
5398         msg.msg_name = &from_addr.sa;              /* optional address */
5399         msg.msg_namelen = from_addr.sa_socklen;    /* size of address */
5400         msg.msg_iov = omsg->msg_iov;               /* scatter/gather array */
5401         msg.msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
5402 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5403         msg_ctrllen_filled = 0;
5404         msg_ctrllen_left = omsg->msg_controllen;
5405
5406         msg.msg_control = omsg->msg_control;       /* ancillary data, see below */
5407         msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
5408         msg.msg_flags = omsg->msg_flags;           /* flags on received message */
5409 #endif
5410
5411         rc = swrap_recvmsg_before(s, si, &msg, &tmp);
5412         if (rc < 0) {
5413                 return -1;
5414         }
5415
5416         ret = libc_recvmsg(s, &msg, flags);
5417
5418 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5419         msg_ctrllen_filled += msg.msg_controllen;
5420         msg_ctrllen_left -= msg.msg_controllen;
5421
5422         if (omsg->msg_control != NULL) {
5423                 uint8_t *p;
5424
5425                 p = omsg->msg_control;
5426                 p += msg_ctrllen_filled;
5427
5428                 msg.msg_control = p;
5429                 msg.msg_controllen = msg_ctrllen_left;
5430         } else {
5431                 msg.msg_control = NULL;
5432                 msg.msg_controllen = 0;
5433         }
5434 #endif
5435
5436         /*
5437          * We convert the unix address to a IP address so we need a buffer
5438          * which can store the address in case of SOCK_DGRAM, see below.
5439          */
5440         msg.msg_name = &convert_addr.sa;
5441         msg.msg_namelen = convert_addr.sa_socklen;
5442
5443         rc = swrap_recvmsg_after(s,
5444                                  si,
5445                                  &msg,
5446                                  &from_addr.sa.un,
5447                                  from_addr.sa_socklen,
5448                                  ret);
5449         if (rc != 0) {
5450                 return rc;
5451         }
5452
5453 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5454         if (omsg->msg_control != NULL) {
5455                 /* msg.msg_controllen = space left */
5456                 msg_ctrllen_left = msg.msg_controllen;
5457                 msg_ctrllen_filled = omsg->msg_controllen - msg_ctrllen_left;
5458         }
5459
5460         /* Update the original message length */
5461         omsg->msg_controllen = msg_ctrllen_filled;
5462         omsg->msg_flags = msg.msg_flags;
5463 #endif
5464         omsg->msg_iovlen = msg.msg_iovlen;
5465
5466         /*
5467          * From the manpage:
5468          *
5469          * The  msg_name  field  points  to a caller-allocated buffer that is
5470          * used to return the source address if the socket is unconnected.  The
5471          * caller should set msg_namelen to the size of this buffer before this
5472          * call; upon return from a successful call, msg_name will contain the
5473          * length of the returned address.  If the application  does  not  need
5474          * to know the source address, msg_name can be specified as NULL.
5475          */
5476         if (si->type == SOCK_STREAM) {
5477                 omsg->msg_namelen = 0;
5478         } else if (omsg->msg_name != NULL &&
5479                    omsg->msg_namelen != 0 &&
5480                    omsg->msg_namelen >= msg.msg_namelen) {
5481                 memcpy(omsg->msg_name, msg.msg_name, msg.msg_namelen);
5482                 omsg->msg_namelen = msg.msg_namelen;
5483         }
5484
5485         return ret;
5486 }
5487
5488 ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)
5489 {
5490         return swrap_recvmsg(sockfd, msg, flags);
5491 }
5492
5493 /****************************************************************************
5494  *   SENDMSG
5495  ***************************************************************************/
5496
5497 static ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags)
5498 {
5499         struct msghdr msg;
5500         struct iovec tmp;
5501         struct sockaddr_un un_addr;
5502         const struct sockaddr_un *to_un = NULL;
5503         const struct sockaddr *to = NULL;
5504         ssize_t ret;
5505         int rc;
5506         struct socket_info *si = find_socket_info(s);
5507         int bcast = 0;
5508
5509         if (!si) {
5510                 return libc_sendmsg(s, omsg, flags);
5511         }
5512
5513         ZERO_STRUCT(un_addr);
5514
5515         tmp.iov_base = NULL;
5516         tmp.iov_len = 0;
5517
5518         ZERO_STRUCT(msg);
5519
5520         if (si->connected == 0) {
5521                 msg.msg_name = omsg->msg_name;             /* optional address */
5522                 msg.msg_namelen = omsg->msg_namelen;       /* size of address */
5523         }
5524         msg.msg_iov = omsg->msg_iov;               /* scatter/gather array */
5525         msg.msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
5526 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5527         if (msg.msg_controllen > 0 && msg.msg_control != NULL) {
5528                 /* omsg is a const so use a local buffer for modifications */
5529                 uint8_t cmbuf[omsg->msg_controllen];
5530
5531                 memcpy(cmbuf, omsg->msg_control, omsg->msg_controllen);
5532
5533                 msg.msg_control = cmbuf;       /* ancillary data, see below */
5534                 msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
5535         }
5536         msg.msg_flags = omsg->msg_flags;           /* flags on received message */
5537 #endif
5538
5539         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
5540         if (rc < 0) {
5541                 return -1;
5542         }
5543
5544         if (bcast) {
5545                 struct stat st;
5546                 unsigned int iface;
5547                 unsigned int prt = ntohs(((const struct sockaddr_in *)(const void *)to)->sin_port);
5548                 char type;
5549                 size_t i, len = 0;
5550                 uint8_t *buf;
5551                 off_t ofs = 0;
5552                 size_t avail = 0;
5553                 size_t remain;
5554
5555                 for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
5556                         avail += msg.msg_iov[i].iov_len;
5557                 }
5558
5559                 len = avail;
5560                 remain = avail;
5561
5562                 /* we capture it as one single packet */
5563                 buf = (uint8_t *)malloc(remain);
5564                 if (!buf) {
5565                         return -1;
5566                 }
5567
5568                 for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
5569                         size_t this_time = MIN(remain, (size_t)msg.msg_iov[i].iov_len);
5570                         memcpy(buf + ofs,
5571                                msg.msg_iov[i].iov_base,
5572                                this_time);
5573                         ofs += this_time;
5574                         remain -= this_time;
5575                 }
5576
5577                 type = SOCKET_TYPE_CHAR_UDP;
5578
5579                 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
5580                         snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT,
5581                                  socket_wrapper_dir(), type, iface, prt);
5582                         if (stat(un_addr.sun_path, &st) != 0) continue;
5583
5584                         msg.msg_name = &un_addr;           /* optional address */
5585                         msg.msg_namelen = sizeof(un_addr); /* size of address */
5586
5587                         /* ignore the any errors in broadcast sends */
5588                         libc_sendmsg(s, &msg, flags);
5589                 }
5590
5591                 swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
5592                 free(buf);
5593
5594                 return len;
5595         }
5596
5597         ret = libc_sendmsg(s, &msg, flags);
5598
5599         swrap_sendmsg_after(s, si, &msg, to, ret);
5600
5601         return ret;
5602 }
5603
5604 ssize_t sendmsg(int s, const struct msghdr *omsg, int flags)
5605 {
5606         return swrap_sendmsg(s, omsg, flags);
5607 }
5608
5609 /****************************************************************************
5610  *   READV
5611  ***************************************************************************/
5612
5613 static ssize_t swrap_readv(int s, const struct iovec *vector, int count)
5614 {
5615         struct socket_info *si;
5616         struct msghdr msg;
5617         struct iovec tmp;
5618         struct swrap_address saddr = {
5619                 .sa_socklen = sizeof(struct sockaddr_storage)
5620         };
5621         ssize_t ret;
5622         int rc;
5623
5624         si = find_socket_info(s);
5625         if (si == NULL) {
5626                 return libc_readv(s, vector, count);
5627         }
5628
5629         tmp.iov_base = NULL;
5630         tmp.iov_len = 0;
5631
5632         ZERO_STRUCT(msg);
5633         msg.msg_name = &saddr.sa.s; /* optional address */
5634         msg.msg_namelen = saddr.sa_socklen;      /* size of address */
5635         msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
5636         msg.msg_iovlen = count;        /* # elements in msg_iov */
5637 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5638         msg.msg_control = NULL;        /* ancillary data, see below */
5639         msg.msg_controllen = 0;        /* ancillary data buffer len */
5640         msg.msg_flags = 0;             /* flags on received message */
5641 #endif
5642
5643         rc = swrap_recvmsg_before(s, si, &msg, &tmp);
5644         if (rc < 0) {
5645                 if (rc == -ENOTSOCK) {
5646                         return libc_readv(s, vector, count);
5647                 }
5648                 return -1;
5649         }
5650
5651         ret = libc_readv(s, msg.msg_iov, msg.msg_iovlen);
5652
5653         rc = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
5654         if (rc != 0) {
5655                 return rc;
5656         }
5657
5658         return ret;
5659 }
5660
5661 ssize_t readv(int s, const struct iovec *vector, int count)
5662 {
5663         return swrap_readv(s, vector, count);
5664 }
5665
5666 /****************************************************************************
5667  *   WRITEV
5668  ***************************************************************************/
5669
5670 static ssize_t swrap_writev(int s, const struct iovec *vector, int count)
5671 {
5672         struct msghdr msg;
5673         struct iovec tmp;
5674         struct sockaddr_un un_addr;
5675         ssize_t ret;
5676         int rc;
5677         struct socket_info *si = find_socket_info(s);
5678
5679         if (!si) {
5680                 return libc_writev(s, vector, count);
5681         }
5682
5683         tmp.iov_base = NULL;
5684         tmp.iov_len = 0;
5685
5686         ZERO_STRUCT(msg);
5687         msg.msg_name = NULL;           /* optional address */
5688         msg.msg_namelen = 0;           /* size of address */
5689         msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
5690         msg.msg_iovlen = count;        /* # elements in msg_iov */
5691 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL
5692         msg.msg_control = NULL;        /* ancillary data, see below */
5693         msg.msg_controllen = 0;        /* ancillary data buffer len */
5694         msg.msg_flags = 0;             /* flags on received message */
5695 #endif
5696
5697         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
5698         if (rc < 0) {
5699                 if (rc == -ENOTSOCK) {
5700                         return libc_readv(s, vector, count);
5701                 }
5702                 return -1;
5703         }
5704
5705         ret = libc_writev(s, msg.msg_iov, msg.msg_iovlen);
5706
5707         swrap_sendmsg_after(s, si, &msg, NULL, ret);
5708
5709         return ret;
5710 }
5711
5712 ssize_t writev(int s, const struct iovec *vector, int count)
5713 {
5714         return swrap_writev(s, vector, count);
5715 }
5716
5717 /****************************
5718  * CLOSE
5719  ***************************/
5720
5721 static int swrap_close(int fd)
5722 {
5723         struct socket_info_fd *fi = find_socket_info_fd(fd);
5724         struct socket_info *si = NULL;
5725         int si_index;
5726         int ret;
5727
5728         if (fi == NULL) {
5729                 return libc_close(fd);
5730         }
5731
5732         si_index = fi->si_index;
5733
5734         SWRAP_DLIST_REMOVE(socket_fds, fi);
5735         free(fi);
5736
5737         ret = libc_close(fd);
5738
5739         si = swrap_get_socket_info(si_index);
5740         swrap_dec_refcount(si);
5741
5742         if (swrap_get_refcount(si) > 0) {
5743                 /* there are still references left */
5744                 return ret;
5745         }
5746
5747         if (si->myname.sa_socklen > 0 && si->peername.sa_socklen > 0) {
5748                 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0);
5749         }
5750
5751         if (si->myname.sa_socklen > 0 && si->peername.sa_socklen > 0) {
5752                 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0);
5753                 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0);
5754         }
5755
5756         if (si->un_addr.sun_path[0] != '\0') {
5757                 unlink(si->un_addr.sun_path);
5758         }
5759
5760         swrap_set_next_free(si, first_free);
5761         first_free = si_index;
5762
5763         return ret;
5764 }
5765
5766 int close(int fd)
5767 {
5768         return swrap_close(fd);
5769 }
5770
5771 /****************************
5772  * DUP
5773  ***************************/
5774
5775 static int swrap_dup(int fd)
5776 {
5777         struct socket_info *si;
5778         struct socket_info_fd *src_fi, *fi;
5779
5780         src_fi = find_socket_info_fd(fd);
5781         if (src_fi == NULL) {
5782                 return libc_dup(fd);
5783         }
5784
5785         si = swrap_get_socket_info(src_fi->si_index);
5786
5787         fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
5788         if (fi == NULL) {
5789                 errno = ENOMEM;
5790                 return -1;
5791         }
5792
5793         fi->fd = libc_dup(fd);
5794         if (fi->fd == -1) {
5795                 int saved_errno = errno;
5796                 free(fi);
5797                 errno = saved_errno;
5798                 return -1;
5799         }
5800
5801         swrap_inc_refcount(si);
5802         fi->si_index = src_fi->si_index;
5803
5804         /* Make sure we don't have an entry for the fd */
5805         swrap_remove_stale(fi->fd);
5806
5807         SWRAP_DLIST_ADD_AFTER(socket_fds, fi, src_fi);
5808         return fi->fd;
5809 }
5810
5811 int dup(int fd)
5812 {
5813         return swrap_dup(fd);
5814 }
5815
5816 /****************************
5817  * DUP2
5818  ***************************/
5819
5820 static int swrap_dup2(int fd, int newfd)
5821 {
5822         struct socket_info *si;
5823         struct socket_info_fd *src_fi, *fi;
5824
5825         src_fi = find_socket_info_fd(fd);
5826         if (src_fi == NULL) {
5827                 return libc_dup2(fd, newfd);
5828         }
5829
5830         si = swrap_get_socket_info(src_fi->si_index);
5831
5832         if (fd == newfd) {
5833                 /*
5834                  * According to the manpage:
5835                  *
5836                  * "If oldfd is a valid file descriptor, and newfd has the same
5837                  * value as oldfd, then dup2() does nothing, and returns newfd."
5838                  */
5839                 return newfd;
5840         }
5841
5842         if (find_socket_info(newfd)) {
5843                 /* dup2() does an implicit close of newfd, which we
5844                  * need to emulate */
5845                 swrap_close(newfd);
5846         }
5847
5848         fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
5849         if (fi == NULL) {
5850                 errno = ENOMEM;
5851                 return -1;
5852         }
5853
5854         fi->fd = libc_dup2(fd, newfd);
5855         if (fi->fd == -1) {
5856                 int saved_errno = errno;
5857                 free(fi);
5858                 errno = saved_errno;
5859                 return -1;
5860         }
5861
5862         swrap_inc_refcount(si);
5863         fi->si_index = src_fi->si_index;
5864
5865         /* Make sure we don't have an entry for the fd */
5866         swrap_remove_stale(fi->fd);
5867
5868         SWRAP_DLIST_ADD_AFTER(socket_fds, fi, src_fi);
5869         return fi->fd;
5870 }
5871
5872 int dup2(int fd, int newfd)
5873 {
5874         return swrap_dup2(fd, newfd);
5875 }
5876
5877 /****************************
5878  * FCNTL
5879  ***************************/
5880
5881 static int swrap_vfcntl(int fd, int cmd, va_list va)
5882 {
5883         struct socket_info_fd *src_fi, *fi;
5884         struct socket_info *si;
5885         int rc;
5886
5887         src_fi = find_socket_info_fd(fd);
5888         if (src_fi == NULL) {
5889                 return libc_vfcntl(fd, cmd, va);
5890         }
5891
5892         si = swrap_get_socket_info(src_fi->si_index);
5893
5894         switch (cmd) {
5895         case F_DUPFD:
5896                 fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
5897                 if (fi == NULL) {
5898                         errno = ENOMEM;
5899                         return -1;
5900                 }
5901
5902                 fi->fd = libc_vfcntl(fd, cmd, va);
5903                 if (fi->fd == -1) {
5904                         int saved_errno = errno;
5905                         free(fi);
5906                         errno = saved_errno;
5907                         return -1;
5908                 }
5909
5910                 swrap_inc_refcount(si);
5911                 fi->si_index = src_fi->si_index;
5912
5913                 /* Make sure we don't have an entry for the fd */
5914                 swrap_remove_stale(fi->fd);
5915
5916                 SWRAP_DLIST_ADD_AFTER(socket_fds, fi, src_fi);
5917
5918                 rc = fi->fd;
5919                 break;
5920         default:
5921                 rc = libc_vfcntl(fd, cmd, va);
5922                 break;
5923         }
5924
5925         return rc;
5926 }
5927
5928 int fcntl(int fd, int cmd, ...)
5929 {
5930         va_list va;
5931         int rc;
5932
5933         va_start(va, cmd);
5934
5935         rc = swrap_vfcntl(fd, cmd, va);
5936
5937         va_end(va);
5938
5939         return rc;
5940 }
5941
5942 /****************************
5943  * EVENTFD
5944  ***************************/
5945
5946 #ifdef HAVE_EVENTFD
5947 static int swrap_eventfd(int count, int flags)
5948 {
5949         int fd;
5950
5951         fd = libc_eventfd(count, flags);
5952         if (fd != -1) {
5953                 swrap_remove_stale(fd);
5954         }
5955
5956         return fd;
5957 }
5958
5959 #ifdef HAVE_EVENTFD_UNSIGNED_INT
5960 int eventfd(unsigned int count, int flags)
5961 #else
5962 int eventfd(int count, int flags)
5963 #endif
5964 {
5965         return swrap_eventfd(count, flags);
5966 }
5967 #endif
5968
5969 #ifdef HAVE_PLEDGE
5970 int pledge(const char *promises, const char *paths[])
5971 {
5972         (void)promises; /* unused */
5973         (void)paths; /* unused */
5974
5975         return 0;
5976 }
5977 #endif /* HAVE_PLEDGE */
5978
5979 static void swrap_thread_prepare(void)
5980 {
5981         /*
5982          * This function should only be called here!!
5983          *
5984          * We bind all symobls to avoid deadlocks of the fork is
5985          * interrupted by a signal handler using a symbol of this
5986          * library.
5987          */
5988         swrap_bind_symbol_all();
5989
5990         SWRAP_LOCK_ALL;
5991 }
5992
5993 static void swrap_thread_parent(void)
5994 {
5995         SWRAP_UNLOCK_ALL;
5996 }
5997
5998 static void swrap_thread_child(void)
5999 {
6000         SWRAP_UNLOCK_ALL;
6001 }
6002
6003 /****************************
6004  * CONSTRUCTOR
6005  ***************************/
6006 void swrap_constructor(void)
6007 {
6008         /*
6009         * If we hold a lock and the application forks, then the child
6010         * is not able to unlock the mutex and we are in a deadlock.
6011         * This should prevent such deadlocks.
6012         */
6013         pthread_atfork(&swrap_thread_prepare,
6014                        &swrap_thread_parent,
6015                        &swrap_thread_child);
6016 }
6017
6018 /****************************
6019  * DESTRUCTOR
6020  ***************************/
6021
6022 /*
6023  * This function is called when the library is unloaded and makes sure that
6024  * sockets get closed and the unix file for the socket are unlinked.
6025  */
6026 void swrap_destructor(void)
6027 {
6028         struct socket_info_fd *s = socket_fds;
6029
6030         while (s != NULL) {
6031                 swrap_close(s->fd);
6032                 s = socket_fds;
6033         }
6034
6035         free(sockets);
6036
6037         if (swrap.libc.handle != NULL) {
6038                 dlclose(swrap.libc.handle);
6039         }
6040         if (swrap.libc.socket_handle) {
6041                 dlclose(swrap.libc.socket_handle);
6042         }
6043 }