socket_wrapper: simplify include path for replace.h
[sfrench/samba-autobuild/.git] / lib / socket_wrapper / socket_wrapper.c
1 /*
2  * Copyright (C) Jelmer Vernooij 2005,2008 <jelmer@samba.org>
3  * Copyright (C) Stefan Metzmacher 2006-2009 <metze@samba.org>
4  *
5  * All rights reserved.
6  * 
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 
18  * 3. Neither the name of the author nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  * 
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  */
35
36 /*
37    Socket wrapper library. Passes all socket communication over
38    unix domain sockets if the environment variable SOCKET_WRAPPER_DIR
39    is set.
40 */
41
42 #ifdef _SAMBA_BUILD_
43
44 #define SOCKET_WRAPPER_NOT_REPLACE
45 #include "replace.h"
46 #include "system/network.h"
47 #include "system/filesys.h"
48 #include "system/time.h"
49
50 #else /* _SAMBA_BUILD_ */
51
52 #include <sys/types.h>
53 #include <sys/time.h>
54 #include <sys/stat.h>
55 #include <sys/socket.h>
56 #include <sys/ioctl.h>
57 #include <sys/filio.h>
58 #include <errno.h>
59 #include <sys/un.h>
60 #include <netinet/in.h>
61 #include <netinet/tcp.h>
62 #include <fcntl.h>
63 #include <stdlib.h>
64 #include <unistd.h>
65 #include <string.h>
66 #include <stdio.h>
67 #include <stdint.h>
68
69 #endif
70
71 #ifndef _PUBLIC_
72 #define _PUBLIC_
73 #endif
74
75 #define SWRAP_DLIST_ADD(list,item) do { \
76         if (!(list)) { \
77                 (item)->prev    = NULL; \
78                 (item)->next    = NULL; \
79                 (list)          = (item); \
80         } else { \
81                 (item)->prev    = NULL; \
82                 (item)->next    = (list); \
83                 (list)->prev    = (item); \
84                 (list)          = (item); \
85         } \
86 } while (0)
87
88 #define SWRAP_DLIST_REMOVE(list,item) do { \
89         if ((list) == (item)) { \
90                 (list)          = (item)->next; \
91                 if (list) { \
92                         (list)->prev    = NULL; \
93                 } \
94         } else { \
95                 if ((item)->prev) { \
96                         (item)->prev->next      = (item)->next; \
97                 } \
98                 if ((item)->next) { \
99                         (item)->next->prev      = (item)->prev; \
100                 } \
101         } \
102         (item)->prev    = NULL; \
103         (item)->next    = NULL; \
104 } while (0)
105
106 /* LD_PRELOAD doesn't work yet, so REWRITE_CALLS is all we support
107  * for now */
108 #define REWRITE_CALLS 
109
110 #ifdef REWRITE_CALLS
111 #define real_accept accept
112 #define real_connect connect
113 #define real_bind bind
114 #define real_listen listen
115 #define real_getpeername getpeername
116 #define real_getsockname getsockname
117 #define real_getsockopt getsockopt
118 #define real_setsockopt setsockopt
119 #define real_recvfrom recvfrom
120 #define real_sendto sendto
121 #define real_sendmsg sendmsg
122 #define real_ioctl ioctl
123 #define real_recv recv
124 #define real_read read
125 #define real_send send
126 #define real_readv readv
127 #define real_writev writev
128 #define real_socket socket
129 #define real_close close
130 #define real_dup dup
131 #define real_dup2 dup2
132 #endif
133
134 #ifdef HAVE_GETTIMEOFDAY_TZ
135 #define swrapGetTimeOfDay(tval) gettimeofday(tval,NULL)
136 #else
137 #define swrapGetTimeOfDay(tval) gettimeofday(tval)
138 #endif
139
140 /* we need to use a very terse format here as IRIX 6.4 silently
141    truncates names to 16 chars, so if we use a longer name then we
142    can't tell which port a packet came from with recvfrom() 
143    
144    with this format we have 8 chars left for the directory name
145 */
146 #define SOCKET_FORMAT "%c%02X%04X"
147 #define SOCKET_TYPE_CHAR_TCP            'T'
148 #define SOCKET_TYPE_CHAR_UDP            'U'
149 #define SOCKET_TYPE_CHAR_TCP_V6         'X'
150 #define SOCKET_TYPE_CHAR_UDP_V6         'Y'
151
152 /* This limit is to avoid broadcast sendto() needing to stat too many
153  * files.  It may be raised (with a performance cost) to up to 254
154  * without changing the format above */
155 #define MAX_WRAPPED_INTERFACES 32
156
157 #ifdef HAVE_IPV6
158 /*
159  * FD00::5357:5FXX
160  */
161 static const struct in6_addr *swrap_ipv6(void)
162 {
163         static struct in6_addr v;
164         static int initialized;
165         int ret;
166
167         if (initialized) {
168                 return &v;
169         }
170         initialized = 1;
171
172         ret = inet_pton(AF_INET6, "FD00::5357:5F00", &v);
173         if (ret <= 0) {
174                 abort();
175         }
176
177         return &v;
178 }
179 #endif
180
181 static struct sockaddr *sockaddr_dup(const void *data, socklen_t len)
182 {
183         struct sockaddr *ret = (struct sockaddr *)malloc(len);
184         memcpy(ret, data, len);
185         return ret;
186 }
187
188 static void set_port(int family, int prt, struct sockaddr *addr)
189 {
190         switch (family) {
191         case AF_INET:
192                 ((struct sockaddr_in *)addr)->sin_port = htons(prt);
193                 break;
194 #ifdef HAVE_IPV6
195         case AF_INET6:
196                 ((struct sockaddr_in6 *)addr)->sin6_port = htons(prt);
197                 break;
198 #endif
199         }
200 }
201
202 static size_t socket_length(int family)
203 {
204         switch (family) {
205         case AF_INET:
206                 return sizeof(struct sockaddr_in);
207 #ifdef HAVE_IPV6
208         case AF_INET6:
209                 return sizeof(struct sockaddr_in6);
210 #endif
211         }
212         return 0;
213 }
214
215 struct socket_info_fd {
216         struct socket_info_fd *prev, *next;
217         int fd;
218 };
219
220 struct socket_info
221 {
222         struct socket_info_fd *fds;
223
224         int family;
225         int type;
226         int protocol;
227         int bound;
228         int bcast;
229         int is_server;
230         int connected;
231         int defer_connect;
232
233         char *tmp_path;
234
235         struct sockaddr *myname;
236         socklen_t myname_len;
237
238         struct sockaddr *peername;
239         socklen_t peername_len;
240
241         struct {
242                 unsigned long pck_snd;
243                 unsigned long pck_rcv;
244         } io;
245
246         struct socket_info *prev, *next;
247 };
248
249 static struct socket_info *sockets;
250
251 const char *socket_wrapper_dir(void)
252 {
253         const char *s = getenv("SOCKET_WRAPPER_DIR");
254         if (s == NULL) {
255                 return NULL;
256         }
257         if (strncmp(s, "./", 2) == 0) {
258                 s += 2;
259         }
260         return s;
261 }
262
263 unsigned int socket_wrapper_default_iface(void)
264 {
265         const char *s = getenv("SOCKET_WRAPPER_DEFAULT_IFACE");
266         if (s) {
267                 unsigned int iface;
268                 if (sscanf(s, "%u", &iface) == 1) {
269                         if (iface >= 1 && iface <= MAX_WRAPPED_INTERFACES) {
270                                 return iface;
271                         }
272                 }
273         }
274
275         return 1;/* 127.0.0.1 */
276 }
277
278 static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, socklen_t *len)
279 {
280         unsigned int iface;
281         unsigned int prt;
282         const char *p;
283         char type;
284
285         p = strrchr(un->sun_path, '/');
286         if (p) p++; else p = un->sun_path;
287
288         if (sscanf(p, SOCKET_FORMAT, &type, &iface, &prt) != 3) {
289                 errno = EINVAL;
290                 return -1;
291         }
292
293         if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
294                 errno = EINVAL;
295                 return -1;
296         }
297
298         if (prt > 0xFFFF) {
299                 errno = EINVAL;
300                 return -1;
301         }
302
303         switch(type) {
304         case SOCKET_TYPE_CHAR_TCP:
305         case SOCKET_TYPE_CHAR_UDP: {
306                 struct sockaddr_in *in2 = (struct sockaddr_in *)(void *)in;
307
308                 if ((*len) < sizeof(*in2)) {
309                     errno = EINVAL;
310                     return -1;
311                 }
312
313                 memset(in2, 0, sizeof(*in2));
314                 in2->sin_family = AF_INET;
315                 in2->sin_addr.s_addr = htonl((127<<24) | iface);
316                 in2->sin_port = htons(prt);
317
318                 *len = sizeof(*in2);
319                 break;
320         }
321 #ifdef HAVE_IPV6
322         case SOCKET_TYPE_CHAR_TCP_V6:
323         case SOCKET_TYPE_CHAR_UDP_V6: {
324                 struct sockaddr_in6 *in2 = (struct sockaddr_in6 *)(void *)in;
325
326                 if ((*len) < sizeof(*in2)) {
327                         errno = EINVAL;
328                         return -1;
329                 }
330
331                 memset(in2, 0, sizeof(*in2));
332                 in2->sin6_family = AF_INET6;
333                 in2->sin6_addr = *swrap_ipv6();
334                 in2->sin6_addr.s6_addr[15] = iface;
335                 in2->sin6_port = htons(prt);
336
337                 *len = sizeof(*in2);
338                 break;
339         }
340 #endif
341         default:
342                 errno = EINVAL;
343                 return -1;
344         }
345
346         return 0;
347 }
348
349 static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un,
350                                 int *bcast)
351 {
352         char type = '\0';
353         unsigned int prt;
354         unsigned int iface;
355         int is_bcast = 0;
356
357         if (bcast) *bcast = 0;
358
359         switch (inaddr->sa_family) {
360         case AF_INET: {
361                 const struct sockaddr_in *in = 
362                     (const struct sockaddr_in *)(const void *)inaddr;
363                 unsigned int addr = ntohl(in->sin_addr.s_addr);
364                 char u_type = '\0';
365                 char b_type = '\0';
366                 char a_type = '\0';
367
368                 switch (si->type) {
369                 case SOCK_STREAM:
370                         u_type = SOCKET_TYPE_CHAR_TCP;
371                         break;
372                 case SOCK_DGRAM:
373                         u_type = SOCKET_TYPE_CHAR_UDP;
374                         a_type = SOCKET_TYPE_CHAR_UDP;
375                         b_type = SOCKET_TYPE_CHAR_UDP;
376                         break;
377                 }
378
379                 prt = ntohs(in->sin_port);
380                 if (a_type && addr == 0xFFFFFFFF) {
381                         /* 255.255.255.255 only udp */
382                         is_bcast = 2;
383                         type = a_type;
384                         iface = socket_wrapper_default_iface();
385                 } else if (b_type && addr == 0x7FFFFFFF) {
386                         /* 127.255.255.255 only udp */
387                         is_bcast = 1;
388                         type = b_type;
389                         iface = socket_wrapper_default_iface();
390                 } else if ((addr & 0xFFFFFF00) == 0x7F000000) {
391                         /* 127.0.0.X */
392                         is_bcast = 0;
393                         type = u_type;
394                         iface = (addr & 0x000000FF);
395                 } else {
396                         errno = ENETUNREACH;
397                         return -1;
398                 }
399                 if (bcast) *bcast = is_bcast;
400                 break;
401         }
402 #ifdef HAVE_IPV6
403         case AF_INET6: {
404                 const struct sockaddr_in6 *in = 
405                     (const struct sockaddr_in6 *)(const void *)inaddr;
406                 struct in6_addr cmp1, cmp2;
407
408                 switch (si->type) {
409                 case SOCK_STREAM:
410                         type = SOCKET_TYPE_CHAR_TCP_V6;
411                         break;
412                 case SOCK_DGRAM:
413                         type = SOCKET_TYPE_CHAR_UDP_V6;
414                         break;
415                 }
416
417                 /* XXX no multicast/broadcast */
418
419                 prt = ntohs(in->sin6_port);
420
421                 cmp1 = *swrap_ipv6();
422                 cmp2 = in->sin6_addr;
423                 cmp2.s6_addr[15] = 0;
424                 if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
425                         iface = in->sin6_addr.s6_addr[15];
426                 } else {
427                         errno = ENETUNREACH;
428                         return -1;
429                 }
430
431                 break;
432         }
433 #endif
434         default:
435                 errno = ENETUNREACH;
436                 return -1;
437         }
438
439         if (prt == 0) {
440                 errno = EINVAL;
441                 return -1;
442         }
443
444         if (is_bcast) {
445                 snprintf(un->sun_path, sizeof(un->sun_path), "%s/EINVAL", 
446                          socket_wrapper_dir());
447                 /* the caller need to do more processing */
448                 return 0;
449         }
450
451         snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, 
452                  socket_wrapper_dir(), type, iface, prt);
453
454         return 0;
455 }
456
457 static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un,
458                                int *bcast)
459 {
460         char type = '\0';
461         unsigned int prt;
462         unsigned int iface;
463         struct stat st;
464         int is_bcast = 0;
465
466         if (bcast) *bcast = 0;
467
468         switch (si->family) {
469         case AF_INET: {
470                 const struct sockaddr_in *in = 
471                     (const struct sockaddr_in *)(const void *)inaddr;
472                 unsigned int addr = ntohl(in->sin_addr.s_addr);
473                 char u_type = '\0';
474                 char d_type = '\0';
475                 char b_type = '\0';
476                 char a_type = '\0';
477
478                 prt = ntohs(in->sin_port);
479
480                 switch (si->type) {
481                 case SOCK_STREAM:
482                         u_type = SOCKET_TYPE_CHAR_TCP;
483                         d_type = SOCKET_TYPE_CHAR_TCP;
484                         break;
485                 case SOCK_DGRAM:
486                         u_type = SOCKET_TYPE_CHAR_UDP;
487                         d_type = SOCKET_TYPE_CHAR_UDP;
488                         a_type = SOCKET_TYPE_CHAR_UDP;
489                         b_type = SOCKET_TYPE_CHAR_UDP;
490                         break;
491                 }
492
493                 if (addr == 0) {
494                         /* 0.0.0.0 */
495                         is_bcast = 0;
496                         type = d_type;
497                         iface = socket_wrapper_default_iface();
498                 } else if (a_type && addr == 0xFFFFFFFF) {
499                         /* 255.255.255.255 only udp */
500                         is_bcast = 2;
501                         type = a_type;
502                         iface = socket_wrapper_default_iface();
503                 } else if (b_type && addr == 0x7FFFFFFF) {
504                         /* 127.255.255.255 only udp */
505                         is_bcast = 1;
506                         type = b_type;
507                         iface = socket_wrapper_default_iface();
508                 } else if ((addr & 0xFFFFFF00) == 0x7F000000) {
509                         /* 127.0.0.X */
510                         is_bcast = 0;
511                         type = u_type;
512                         iface = (addr & 0x000000FF);
513                 } else {
514                         errno = EADDRNOTAVAIL;
515                         return -1;
516                 }
517                 break;
518         }
519 #ifdef HAVE_IPV6
520         case AF_INET6: {
521                 const struct sockaddr_in6 *in = 
522                     (const struct sockaddr_in6 *)(const void *)inaddr;
523                 struct in6_addr cmp1, cmp2;
524
525                 switch (si->type) {
526                 case SOCK_STREAM:
527                         type = SOCKET_TYPE_CHAR_TCP_V6;
528                         break;
529                 case SOCK_DGRAM:
530                         type = SOCKET_TYPE_CHAR_UDP_V6;
531                         break;
532                 }
533
534                 /* XXX no multicast/broadcast */
535
536                 prt = ntohs(in->sin6_port);
537
538                 cmp1 = *swrap_ipv6();
539                 cmp2 = in->sin6_addr;
540                 cmp2.s6_addr[15] = 0;
541                 if (IN6_IS_ADDR_UNSPECIFIED(&in->sin6_addr)) {
542                         iface = socket_wrapper_default_iface();
543                 } else if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
544                         iface = in->sin6_addr.s6_addr[15];
545                 } else {
546                         errno = EADDRNOTAVAIL;
547                         return -1;
548                 }
549
550                 break;
551         }
552 #endif
553         default:
554                 errno = EADDRNOTAVAIL;
555                 return -1;
556         }
557
558
559         if (bcast) *bcast = is_bcast;
560
561         if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
562                 errno = EINVAL;
563                 return -1;
564         }
565
566         if (prt == 0) {
567                 /* handle auto-allocation of ephemeral ports */
568                 for (prt = 5001; prt < 10000; prt++) {
569                         snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, 
570                                  socket_wrapper_dir(), type, iface, prt);
571                         if (stat(un->sun_path, &st) == 0) continue;
572
573                         set_port(si->family, prt, si->myname);
574                         break;
575                 }
576                 if (prt == 10000) {
577                         errno = ENFILE;
578                         return -1;
579                 }
580         }
581
582         snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, 
583                  socket_wrapper_dir(), type, iface, prt);
584         return 0;
585 }
586
587 static struct socket_info *find_socket_info(int fd)
588 {
589         struct socket_info *i;
590         for (i = sockets; i; i = i->next) {
591                 struct socket_info_fd *f;
592                 for (f = i->fds; f; f = f->next) {
593                         if (f->fd == fd) {
594                                 return i;
595                         }
596                 }
597         }
598
599         return NULL;
600 }
601
602 static int sockaddr_convert_to_un(struct socket_info *si, const struct sockaddr *in_addr, socklen_t in_len, 
603                                   struct sockaddr_un *out_addr, int alloc_sock, int *bcast)
604 {
605         struct sockaddr *out = (struct sockaddr *)(void *)out_addr;
606         if (!out_addr)
607                 return 0;
608
609         out->sa_family = AF_UNIX;
610 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
611         out->sa_len = sizeof(*out_addr);
612 #endif
613
614         switch (in_addr->sa_family) {
615         case AF_INET:
616 #ifdef HAVE_IPV6
617         case AF_INET6:
618 #endif
619                 switch (si->type) {
620                 case SOCK_STREAM:
621                 case SOCK_DGRAM:
622                         break;
623                 default:
624                         errno = ESOCKTNOSUPPORT;
625                         return -1;
626                 }
627                 if (alloc_sock) {
628                         return convert_in_un_alloc(si, in_addr, out_addr, bcast);
629                 } else {
630                         return convert_in_un_remote(si, in_addr, out_addr, bcast);
631                 }
632         default:
633                 break;
634         }
635
636         errno = EAFNOSUPPORT;
637         return -1;
638 }
639
640 static int sockaddr_convert_from_un(const struct socket_info *si, 
641                                     const struct sockaddr_un *in_addr, 
642                                     socklen_t un_addrlen,
643                                     int family,
644                                     struct sockaddr *out_addr,
645                                     socklen_t *out_addrlen)
646 {
647         int ret;
648
649         if (out_addr == NULL || out_addrlen == NULL) 
650                 return 0;
651
652         if (un_addrlen == 0) {
653                 *out_addrlen = 0;
654                 return 0;
655         }
656
657         switch (family) {
658         case AF_INET:
659 #ifdef HAVE_IPV6
660         case AF_INET6:
661 #endif
662                 switch (si->type) {
663                 case SOCK_STREAM:
664                 case SOCK_DGRAM:
665                         break;
666                 default:
667                         errno = ESOCKTNOSUPPORT;
668                         return -1;
669                 }
670                 ret = convert_un_in(in_addr, out_addr, out_addrlen);
671 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
672                 out_addr->sa_len = *out_addrlen;
673 #endif
674                 return ret;
675         default:
676                 break;
677         }
678
679         errno = EAFNOSUPPORT;
680         return -1;
681 }
682
683 enum swrap_packet_type {
684         SWRAP_CONNECT_SEND,
685         SWRAP_CONNECT_UNREACH,
686         SWRAP_CONNECT_RECV,
687         SWRAP_CONNECT_ACK,
688         SWRAP_ACCEPT_SEND,
689         SWRAP_ACCEPT_RECV,
690         SWRAP_ACCEPT_ACK,
691         SWRAP_RECVFROM,
692         SWRAP_SENDTO,
693         SWRAP_SENDTO_UNREACH,
694         SWRAP_PENDING_RST,
695         SWRAP_RECV,
696         SWRAP_RECV_RST,
697         SWRAP_SEND,
698         SWRAP_SEND_RST,
699         SWRAP_CLOSE_SEND,
700         SWRAP_CLOSE_RECV,
701         SWRAP_CLOSE_ACK,
702 };
703
704 struct swrap_file_hdr {
705         uint32_t        magic;
706         uint16_t        version_major;
707         uint16_t        version_minor;
708         int32_t         timezone;
709         uint32_t        sigfigs;
710         uint32_t        frame_max_len;
711 #define SWRAP_FRAME_LENGTH_MAX 0xFFFF
712         uint32_t        link_type;
713 };
714 #define SWRAP_FILE_HDR_SIZE 24
715
716 struct swrap_packet_frame {
717         uint32_t seconds;
718         uint32_t micro_seconds;
719         uint32_t recorded_length;
720         uint32_t full_length;
721 };
722 #define SWRAP_PACKET_FRAME_SIZE 16
723
724 union swrap_packet_ip {
725         struct {
726                 uint8_t         ver_hdrlen;
727                 uint8_t         tos;
728                 uint16_t        packet_length;
729                 uint16_t        identification;
730                 uint8_t         flags;
731                 uint8_t         fragment;
732                 uint8_t         ttl;
733                 uint8_t         protocol;
734                 uint16_t        hdr_checksum;
735                 uint32_t        src_addr;
736                 uint32_t        dest_addr;
737         } v4;
738 #define SWRAP_PACKET_IP_V4_SIZE 20
739         struct {
740                 uint8_t         ver_prio;
741                 uint8_t         flow_label_high;
742                 uint16_t        flow_label_low;
743                 uint16_t        payload_length;
744                 uint8_t         next_header;
745                 uint8_t         hop_limit;
746                 uint8_t         src_addr[16];
747                 uint8_t         dest_addr[16];
748         } v6;
749 #define SWRAP_PACKET_IP_V6_SIZE 40
750 };
751 #define SWRAP_PACKET_IP_SIZE 40
752
753 union swrap_packet_payload {
754         struct {
755                 uint16_t        source_port;
756                 uint16_t        dest_port;
757                 uint32_t        seq_num;
758                 uint32_t        ack_num;
759                 uint8_t         hdr_length;
760                 uint8_t         control;
761                 uint16_t        window;
762                 uint16_t        checksum;
763                 uint16_t        urg;
764         } tcp;
765 #define SWRAP_PACKET_PAYLOAD_TCP_SIZE 20
766         struct {
767                 uint16_t        source_port;
768                 uint16_t        dest_port;
769                 uint16_t        length;
770                 uint16_t        checksum;
771         } udp;
772 #define SWRAP_PACKET_PAYLOAD_UDP_SIZE 8
773         struct {
774                 uint8_t         type;
775                 uint8_t         code;
776                 uint16_t        checksum;
777                 uint32_t        unused;
778         } icmp4;
779 #define SWRAP_PACKET_PAYLOAD_ICMP4_SIZE 8
780         struct {
781                 uint8_t         type;
782                 uint8_t         code;
783                 uint16_t        checksum;
784                 uint32_t        unused;
785         } icmp6;
786 #define SWRAP_PACKET_PAYLOAD_ICMP6_SIZE 8
787 };
788 #define SWRAP_PACKET_PAYLOAD_SIZE 20
789
790 #define SWRAP_PACKET_MIN_ALLOC \
791         (SWRAP_PACKET_FRAME_SIZE + \
792          SWRAP_PACKET_IP_SIZE + \
793          SWRAP_PACKET_PAYLOAD_SIZE)
794
795 static const char *socket_wrapper_pcap_file(void)
796 {
797         static int initialized = 0;
798         static const char *s = NULL;
799         static const struct swrap_file_hdr h;
800         static const struct swrap_packet_frame f;
801         static const union swrap_packet_ip i;
802         static const union swrap_packet_payload p;
803
804         if (initialized == 1) {
805                 return s;
806         }
807         initialized = 1;
808
809         /*
810          * TODO: don't use the structs use plain buffer offsets
811          *       and PUSH_U8(), PUSH_U16() and PUSH_U32()
812          * 
813          * for now make sure we disable PCAP support
814          * if the struct has alignment!
815          */
816         if (sizeof(h) != SWRAP_FILE_HDR_SIZE) {
817                 return NULL;
818         }
819         if (sizeof(f) != SWRAP_PACKET_FRAME_SIZE) {
820                 return NULL;
821         }
822         if (sizeof(i) != SWRAP_PACKET_IP_SIZE) {
823                 return NULL;
824         }
825         if (sizeof(i.v4) != SWRAP_PACKET_IP_V4_SIZE) {
826                 return NULL;
827         }
828         if (sizeof(i.v6) != SWRAP_PACKET_IP_V6_SIZE) {
829                 return NULL;
830         }
831         if (sizeof(p) != SWRAP_PACKET_PAYLOAD_SIZE) {
832                 return NULL;
833         }
834         if (sizeof(p.tcp) != SWRAP_PACKET_PAYLOAD_TCP_SIZE) {
835                 return NULL;
836         }
837         if (sizeof(p.udp) != SWRAP_PACKET_PAYLOAD_UDP_SIZE) {
838                 return NULL;
839         }
840         if (sizeof(p.icmp4) != SWRAP_PACKET_PAYLOAD_ICMP4_SIZE) {
841                 return NULL;
842         }
843         if (sizeof(p.icmp6) != SWRAP_PACKET_PAYLOAD_ICMP6_SIZE) {
844                 return NULL;
845         }
846
847         s = getenv("SOCKET_WRAPPER_PCAP_FILE");
848         if (s == NULL) {
849                 return NULL;
850         }
851         if (strncmp(s, "./", 2) == 0) {
852                 s += 2;
853         }
854         return s;
855 }
856
857 static uint8_t *swrap_packet_init(struct timeval *tval,
858                                   const struct sockaddr *src,
859                                   const struct sockaddr *dest,
860                                   int socket_type,
861                                   const uint8_t *payload,
862                                   size_t payload_len,
863                                   unsigned long tcp_seqno,
864                                   unsigned long tcp_ack,
865                                   unsigned char tcp_ctl,
866                                   int unreachable,
867                                   size_t *_packet_len)
868 {
869         uint8_t *base;
870         uint8_t *buf;
871         struct swrap_packet_frame *frame;
872         union swrap_packet_ip *ip;
873         union swrap_packet_payload *pay;
874         size_t packet_len;
875         size_t alloc_len;
876         size_t nonwire_len = sizeof(*frame);
877         size_t wire_hdr_len = 0;
878         size_t wire_len = 0;
879         size_t ip_hdr_len = 0;
880         size_t icmp_hdr_len = 0;
881         size_t icmp_truncate_len = 0;
882         uint8_t protocol = 0, icmp_protocol = 0;
883         const struct sockaddr_in *src_in = NULL;
884         const struct sockaddr_in *dest_in = NULL;
885 #ifdef HAVE_IPV6
886         const struct sockaddr_in6 *src_in6 = NULL;
887         const struct sockaddr_in6 *dest_in6 = NULL;
888 #endif
889         uint16_t src_port;
890         uint16_t dest_port;
891
892         switch (src->sa_family) {
893         case AF_INET:
894                 src_in = (const struct sockaddr_in *)src;
895                 dest_in = (const struct sockaddr_in *)dest;
896                 src_port = src_in->sin_port;
897                 dest_port = dest_in->sin_port;
898                 ip_hdr_len = sizeof(ip->v4);
899                 break;
900 #ifdef HAVE_IPV6
901         case AF_INET6:
902                 src_in6 = (const struct sockaddr_in6 *)src;
903                 dest_in6 = (const struct sockaddr_in6 *)dest;
904                 src_port = src_in6->sin6_port;
905                 dest_port = dest_in6->sin6_port;
906                 ip_hdr_len = sizeof(ip->v6);
907                 break;
908 #endif
909         default:
910                 return NULL;
911         }
912
913         switch (socket_type) {
914         case SOCK_STREAM:
915                 protocol = 0x06; /* TCP */
916                 wire_hdr_len = ip_hdr_len + sizeof(pay->tcp);
917                 wire_len = wire_hdr_len + payload_len;
918                 break;
919
920         case SOCK_DGRAM:
921                 protocol = 0x11; /* UDP */
922                 wire_hdr_len = ip_hdr_len + sizeof(pay->udp);
923                 wire_len = wire_hdr_len + payload_len;
924                 break;
925
926         default:
927                 return NULL;
928         }
929
930         if (unreachable) {
931                 icmp_protocol = protocol;
932                 switch (src->sa_family) {
933                 case AF_INET:
934                         protocol = 0x01; /* ICMPv4 */
935                         icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp4);
936                         break;
937 #ifdef HAVE_IPV6
938                 case AF_INET6:
939                         protocol = 0x3A; /* ICMPv6 */
940                         icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp6);
941                         break;
942 #endif
943                 }
944                 if (wire_len > 64 ) {
945                         icmp_truncate_len = wire_len - 64;
946                 }
947                 wire_hdr_len += icmp_hdr_len;
948                 wire_len += icmp_hdr_len;
949         }
950
951         packet_len = nonwire_len + wire_len;
952         alloc_len = packet_len;
953         if (alloc_len < SWRAP_PACKET_MIN_ALLOC) {
954                 alloc_len = SWRAP_PACKET_MIN_ALLOC;
955         }
956
957         base = (uint8_t *)malloc(alloc_len);
958         if (!base) return NULL;
959
960         buf = base;
961
962         frame = (struct swrap_packet_frame *)buf;
963         frame->seconds          = tval->tv_sec;
964         frame->micro_seconds    = tval->tv_usec;
965         frame->recorded_length  = wire_len - icmp_truncate_len;
966         frame->full_length      = wire_len - icmp_truncate_len;
967         buf += SWRAP_PACKET_FRAME_SIZE;
968
969         ip = (union swrap_packet_ip *)buf;
970         switch (src->sa_family) {
971         case AF_INET:
972                 ip->v4.ver_hdrlen       = 0x45; /* version 4 and 5 * 32 bit words */
973                 ip->v4.tos              = 0x00;
974                 ip->v4.packet_length    = htons(wire_len - icmp_truncate_len);
975                 ip->v4.identification   = htons(0xFFFF);
976                 ip->v4.flags            = 0x40; /* BIT 1 set - means don't fraqment */
977                 ip->v4.fragment         = htons(0x0000);
978                 ip->v4.ttl              = 0xFF;
979                 ip->v4.protocol         = protocol;
980                 ip->v4.hdr_checksum     = htons(0x0000);
981                 ip->v4.src_addr         = src_in->sin_addr.s_addr;
982                 ip->v4.dest_addr        = dest_in->sin_addr.s_addr;
983                 buf += SWRAP_PACKET_IP_V4_SIZE;
984                 break;
985 #ifdef HAVE_IPV6
986         case AF_INET6:
987                 ip->v6.ver_prio         = 0x60; /* version 4 and 5 * 32 bit words */
988                 ip->v6.flow_label_high  = 0x00;
989                 ip->v6.flow_label_low   = 0x0000;
990                 ip->v6.payload_length   = htons(wire_len - icmp_truncate_len); /* TODO */
991                 ip->v6.next_header      = protocol;
992                 memcpy(ip->v6.src_addr, src_in6->sin6_addr.s6_addr, 16);
993                 memcpy(ip->v6.dest_addr, dest_in6->sin6_addr.s6_addr, 16);
994                 buf += SWRAP_PACKET_IP_V6_SIZE;
995                 break;
996 #endif
997         }
998
999         if (unreachable) {
1000                 pay = (union swrap_packet_payload *)buf;
1001                 switch (src->sa_family) {
1002                 case AF_INET:
1003                         pay->icmp4.type         = 0x03; /* destination unreachable */
1004                         pay->icmp4.code         = 0x01; /* host unreachable */
1005                         pay->icmp4.checksum     = htons(0x0000);
1006                         pay->icmp4.unused       = htonl(0x00000000);
1007                         buf += SWRAP_PACKET_PAYLOAD_ICMP4_SIZE;
1008
1009                         /* set the ip header in the ICMP payload */
1010                         ip = (union swrap_packet_ip *)buf;
1011                         ip->v4.ver_hdrlen       = 0x45; /* version 4 and 5 * 32 bit words */
1012                         ip->v4.tos              = 0x00;
1013                         ip->v4.packet_length    = htons(wire_len - icmp_hdr_len);
1014                         ip->v4.identification   = htons(0xFFFF);
1015                         ip->v4.flags            = 0x40; /* BIT 1 set - means don't fraqment */
1016                         ip->v4.fragment         = htons(0x0000);
1017                         ip->v4.ttl              = 0xFF;
1018                         ip->v4.protocol         = icmp_protocol;
1019                         ip->v4.hdr_checksum     = htons(0x0000);
1020                         ip->v4.src_addr         = dest_in->sin_addr.s_addr;
1021                         ip->v4.dest_addr        = src_in->sin_addr.s_addr;
1022                         buf += SWRAP_PACKET_IP_V4_SIZE;
1023
1024                         src_port = dest_in->sin_port;
1025                         dest_port = src_in->sin_port;
1026                         break;
1027 #ifdef HAVE_IPV6
1028                 case AF_INET6:
1029                         pay->icmp6.type         = 0x01; /* destination unreachable */
1030                         pay->icmp6.code         = 0x03; /* address unreachable */
1031                         pay->icmp6.checksum     = htons(0x0000);
1032                         pay->icmp6.unused       = htonl(0x00000000);
1033                         buf += SWRAP_PACKET_PAYLOAD_ICMP6_SIZE;
1034
1035                         /* set the ip header in the ICMP payload */
1036                         ip = (union swrap_packet_ip *)buf;
1037                         ip->v6.ver_prio         = 0x60; /* version 4 and 5 * 32 bit words */
1038                         ip->v6.flow_label_high  = 0x00;
1039                         ip->v6.flow_label_low   = 0x0000;
1040                         ip->v6.payload_length   = htons(wire_len - icmp_truncate_len); /* TODO */
1041                         ip->v6.next_header      = protocol;
1042                         memcpy(ip->v6.src_addr, dest_in6->sin6_addr.s6_addr, 16);
1043                         memcpy(ip->v6.dest_addr, src_in6->sin6_addr.s6_addr, 16);
1044                         buf += SWRAP_PACKET_IP_V6_SIZE;
1045
1046                         src_port = dest_in6->sin6_port;
1047                         dest_port = src_in6->sin6_port;
1048                         break;
1049 #endif
1050                 }
1051         }
1052
1053         pay = (union swrap_packet_payload *)buf;
1054
1055         switch (socket_type) {
1056         case SOCK_STREAM:
1057                 pay->tcp.source_port    = src_port;
1058                 pay->tcp.dest_port      = dest_port;
1059                 pay->tcp.seq_num        = htonl(tcp_seqno);
1060                 pay->tcp.ack_num        = htonl(tcp_ack);
1061                 pay->tcp.hdr_length     = 0x50; /* 5 * 32 bit words */
1062                 pay->tcp.control        = tcp_ctl;
1063                 pay->tcp.window         = htons(0x7FFF);
1064                 pay->tcp.checksum       = htons(0x0000);
1065                 pay->tcp.urg            = htons(0x0000);
1066                 buf += SWRAP_PACKET_PAYLOAD_TCP_SIZE;
1067
1068                 break;
1069
1070         case SOCK_DGRAM:
1071                 pay->udp.source_port    = src_port;
1072                 pay->udp.dest_port      = dest_port;
1073                 pay->udp.length         = htons(8 + payload_len);
1074                 pay->udp.checksum       = htons(0x0000);
1075                 buf += SWRAP_PACKET_PAYLOAD_UDP_SIZE;
1076
1077                 break;
1078         }
1079
1080         if (payload && payload_len > 0) {
1081                 memcpy(buf, payload, payload_len);
1082         }
1083
1084         *_packet_len = packet_len - icmp_truncate_len;
1085         return base;
1086 }
1087
1088 static int swrap_get_pcap_fd(const char *fname)
1089 {
1090         static int fd = -1;
1091
1092         if (fd != -1) return fd;
1093
1094         fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0644);
1095         if (fd != -1) {
1096                 struct swrap_file_hdr file_hdr;
1097                 file_hdr.magic          = 0xA1B2C3D4;
1098                 file_hdr.version_major  = 0x0002;       
1099                 file_hdr.version_minor  = 0x0004;
1100                 file_hdr.timezone       = 0x00000000;
1101                 file_hdr.sigfigs        = 0x00000000;
1102                 file_hdr.frame_max_len  = SWRAP_FRAME_LENGTH_MAX;
1103                 file_hdr.link_type      = 0x0065; /* 101 RAW IP */
1104
1105                 if (write(fd, &file_hdr, sizeof(file_hdr)) != sizeof(file_hdr)) {
1106                         close(fd);
1107                         fd = -1;
1108                 }
1109                 return fd;
1110         }
1111
1112         fd = open(fname, O_WRONLY|O_APPEND, 0644);
1113
1114         return fd;
1115 }
1116
1117 static uint8_t *swrap_marshall_packet(struct socket_info *si,
1118                                       const struct sockaddr *addr,
1119                                       enum swrap_packet_type type,
1120                                       const void *buf, size_t len,
1121                                       size_t *packet_len)
1122 {
1123         const struct sockaddr *src_addr;
1124         const struct sockaddr *dest_addr;
1125         unsigned long tcp_seqno = 0;
1126         unsigned long tcp_ack = 0;
1127         unsigned char tcp_ctl = 0;
1128         int unreachable = 0;
1129
1130         struct timeval tv;
1131
1132         switch (si->family) {
1133         case AF_INET:
1134                 break;
1135 #ifdef HAVE_IPV6
1136         case AF_INET6:
1137                 break;
1138 #endif
1139         default:
1140                 return NULL;
1141         }
1142
1143         switch (type) {
1144         case SWRAP_CONNECT_SEND:
1145                 if (si->type != SOCK_STREAM) return NULL;
1146
1147                 src_addr = si->myname;
1148                 dest_addr = addr;
1149
1150                 tcp_seqno = si->io.pck_snd;
1151                 tcp_ack = si->io.pck_rcv;
1152                 tcp_ctl = 0x02; /* SYN */
1153
1154                 si->io.pck_snd += 1;
1155
1156                 break;
1157
1158         case SWRAP_CONNECT_RECV:
1159                 if (si->type != SOCK_STREAM) return NULL;
1160
1161                 dest_addr = si->myname;
1162                 src_addr = addr;
1163
1164                 tcp_seqno = si->io.pck_rcv;
1165                 tcp_ack = si->io.pck_snd;
1166                 tcp_ctl = 0x12; /** SYN,ACK */
1167
1168                 si->io.pck_rcv += 1;
1169
1170                 break;
1171
1172         case SWRAP_CONNECT_UNREACH:
1173                 if (si->type != SOCK_STREAM) return NULL;
1174
1175                 dest_addr = si->myname;
1176                 src_addr = addr;
1177
1178                 /* Unreachable: resend the data of SWRAP_CONNECT_SEND */
1179                 tcp_seqno = si->io.pck_snd - 1;
1180                 tcp_ack = si->io.pck_rcv;
1181                 tcp_ctl = 0x02; /* SYN */
1182                 unreachable = 1;
1183
1184                 break;
1185
1186         case SWRAP_CONNECT_ACK:
1187                 if (si->type != SOCK_STREAM) return NULL;
1188
1189                 src_addr = si->myname;
1190                 dest_addr = addr;
1191
1192                 tcp_seqno = si->io.pck_snd;
1193                 tcp_ack = si->io.pck_rcv;
1194                 tcp_ctl = 0x10; /* ACK */
1195
1196                 break;
1197
1198         case SWRAP_ACCEPT_SEND:
1199                 if (si->type != SOCK_STREAM) return NULL;
1200
1201                 dest_addr = si->myname;
1202                 src_addr = addr;
1203
1204                 tcp_seqno = si->io.pck_rcv;
1205                 tcp_ack = si->io.pck_snd;
1206                 tcp_ctl = 0x02; /* SYN */
1207
1208                 si->io.pck_rcv += 1;
1209
1210                 break;
1211
1212         case SWRAP_ACCEPT_RECV:
1213                 if (si->type != SOCK_STREAM) return NULL;
1214
1215                 src_addr = si->myname;
1216                 dest_addr = addr;
1217
1218                 tcp_seqno = si->io.pck_snd;
1219                 tcp_ack = si->io.pck_rcv;
1220                 tcp_ctl = 0x12; /* SYN,ACK */
1221
1222                 si->io.pck_snd += 1;
1223
1224                 break;
1225
1226         case SWRAP_ACCEPT_ACK:
1227                 if (si->type != SOCK_STREAM) return NULL;
1228
1229                 dest_addr = si->myname;
1230                 src_addr = addr;
1231
1232                 tcp_seqno = si->io.pck_rcv;
1233                 tcp_ack = si->io.pck_snd;
1234                 tcp_ctl = 0x10; /* ACK */
1235
1236                 break;
1237
1238         case SWRAP_SEND:
1239                 src_addr = si->myname;
1240                 dest_addr = si->peername;
1241
1242                 tcp_seqno = si->io.pck_snd;
1243                 tcp_ack = si->io.pck_rcv;
1244                 tcp_ctl = 0x18; /* PSH,ACK */
1245
1246                 si->io.pck_snd += len;
1247
1248                 break;
1249
1250         case SWRAP_SEND_RST:
1251                 dest_addr = si->myname;
1252                 src_addr = si->peername;
1253
1254                 if (si->type == SOCK_DGRAM) {
1255                         return swrap_marshall_packet(si, si->peername,
1256                                           SWRAP_SENDTO_UNREACH,
1257                                           buf, len, packet_len);
1258                 }
1259
1260                 tcp_seqno = si->io.pck_rcv;
1261                 tcp_ack = si->io.pck_snd;
1262                 tcp_ctl = 0x14; /** RST,ACK */
1263
1264                 break;
1265
1266         case SWRAP_PENDING_RST:
1267                 dest_addr = si->myname;
1268                 src_addr = si->peername;
1269
1270                 if (si->type == SOCK_DGRAM) {
1271                         return NULL;
1272                 }
1273
1274                 tcp_seqno = si->io.pck_rcv;
1275                 tcp_ack = si->io.pck_snd;
1276                 tcp_ctl = 0x14; /* RST,ACK */
1277
1278                 break;
1279
1280         case SWRAP_RECV:
1281                 dest_addr = si->myname;
1282                 src_addr = si->peername;
1283
1284                 tcp_seqno = si->io.pck_rcv;
1285                 tcp_ack = si->io.pck_snd;
1286                 tcp_ctl = 0x18; /* PSH,ACK */
1287
1288                 si->io.pck_rcv += len;
1289
1290                 break;
1291
1292         case SWRAP_RECV_RST:
1293                 dest_addr = si->myname;
1294                 src_addr = si->peername;
1295
1296                 if (si->type == SOCK_DGRAM) {
1297                         return NULL;
1298                 }
1299
1300                 tcp_seqno = si->io.pck_rcv;
1301                 tcp_ack = si->io.pck_snd;
1302                 tcp_ctl = 0x14; /* RST,ACK */
1303
1304                 break;
1305
1306         case SWRAP_SENDTO:
1307                 src_addr = si->myname;
1308                 dest_addr = addr;
1309
1310                 si->io.pck_snd += len;
1311
1312                 break;
1313
1314         case SWRAP_SENDTO_UNREACH:
1315                 dest_addr = si->myname;
1316                 src_addr = addr;
1317
1318                 unreachable = 1;
1319
1320                 break;
1321
1322         case SWRAP_RECVFROM:
1323                 dest_addr = si->myname;
1324                 src_addr = addr;
1325
1326                 si->io.pck_rcv += len;
1327
1328                 break;
1329
1330         case SWRAP_CLOSE_SEND:
1331                 if (si->type != SOCK_STREAM) return NULL;
1332
1333                 src_addr = si->myname;
1334                 dest_addr = si->peername;
1335
1336                 tcp_seqno = si->io.pck_snd;
1337                 tcp_ack = si->io.pck_rcv;
1338                 tcp_ctl = 0x11; /* FIN, ACK */
1339
1340                 si->io.pck_snd += 1;
1341
1342                 break;
1343
1344         case SWRAP_CLOSE_RECV:
1345                 if (si->type != SOCK_STREAM) return NULL;
1346
1347                 dest_addr = si->myname;
1348                 src_addr = si->peername;
1349
1350                 tcp_seqno = si->io.pck_rcv;
1351                 tcp_ack = si->io.pck_snd;
1352                 tcp_ctl = 0x11; /* FIN,ACK */
1353
1354                 si->io.pck_rcv += 1;
1355
1356                 break;
1357
1358         case SWRAP_CLOSE_ACK:
1359                 if (si->type != SOCK_STREAM) return NULL;
1360
1361                 src_addr = si->myname;
1362                 dest_addr = si->peername;
1363
1364                 tcp_seqno = si->io.pck_snd;
1365                 tcp_ack = si->io.pck_rcv;
1366                 tcp_ctl = 0x10; /* ACK */
1367
1368                 break;
1369         default:
1370                 return NULL;
1371         }
1372
1373         swrapGetTimeOfDay(&tv);
1374
1375         return swrap_packet_init(&tv, src_addr, dest_addr, si->type,
1376                                  (const uint8_t *)buf, len,
1377                                  tcp_seqno, tcp_ack, tcp_ctl, unreachable,
1378                                  packet_len);
1379 }
1380
1381 static void swrap_dump_packet(struct socket_info *si,
1382                               const struct sockaddr *addr,
1383                               enum swrap_packet_type type,
1384                               const void *buf, size_t len)
1385 {
1386         const char *file_name;
1387         uint8_t *packet;
1388         size_t packet_len = 0;
1389         int fd;
1390
1391         file_name = socket_wrapper_pcap_file();
1392         if (!file_name) {
1393                 return;
1394         }
1395
1396         packet = swrap_marshall_packet(si, addr, type, buf, len, &packet_len);
1397         if (!packet) {
1398                 return;
1399         }
1400
1401         fd = swrap_get_pcap_fd(file_name);
1402         if (fd != -1) {
1403                 if (write(fd, packet, packet_len) != packet_len) {
1404                         free(packet);
1405                         return;
1406                 }
1407         }
1408
1409         free(packet);
1410 }
1411
1412 _PUBLIC_ int swrap_socket(int family, int type, int protocol)
1413 {
1414         struct socket_info *si;
1415         struct socket_info_fd *fi;
1416         int fd;
1417         int real_type = type;
1418 #ifdef SOCK_CLOEXEC
1419         real_type &= ~SOCK_CLOEXEC;
1420 #endif
1421 #ifdef SOCK_NONBLOCK
1422         real_type &= ~SOCK_NONBLOCK;
1423 #endif
1424
1425         if (!socket_wrapper_dir()) {
1426                 return real_socket(family, type, protocol);
1427         }
1428
1429         switch (family) {
1430         case AF_INET:
1431 #ifdef HAVE_IPV6
1432         case AF_INET6:
1433 #endif
1434                 break;
1435         case AF_UNIX:
1436                 return real_socket(family, type, protocol);
1437         default:
1438                 errno = EAFNOSUPPORT;
1439                 return -1;
1440         }
1441
1442         switch (real_type) {
1443         case SOCK_STREAM:
1444                 break;
1445         case SOCK_DGRAM:
1446                 break;
1447         default:
1448                 errno = EPROTONOSUPPORT;
1449                 return -1;
1450         }
1451
1452         switch (protocol) {
1453         case 0:
1454                 break;
1455         case 6:
1456                 if (real_type == SOCK_STREAM) {
1457                         break;
1458                 }
1459                 /*fall through*/
1460         case 17:
1461                 if (real_type == SOCK_DGRAM) {
1462                         break;
1463                 }
1464                 /*fall through*/
1465         default:
1466                 errno = EPROTONOSUPPORT;
1467                 return -1;
1468         }
1469
1470         /* We must call real_socket with type, from the caller, not the version we removed
1471            SOCK_CLOEXEC and SOCK_NONBLOCK from */
1472         fd = real_socket(AF_UNIX, type, 0);
1473
1474         if (fd == -1) return -1;
1475
1476         si = (struct socket_info *)calloc(1, sizeof(struct socket_info));
1477         if (si == NULL) {
1478                 errno = ENOMEM;
1479                 return -1;
1480         }
1481
1482         si->family = family;
1483
1484         /* however, the rest of the socket_wrapper code expects just
1485          * the type, not the flags */
1486         si->type = real_type;
1487         si->protocol = protocol;
1488
1489         fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
1490         if (fi == NULL) {
1491                 free(si);
1492                 errno = ENOMEM;
1493                 return -1;
1494         }
1495
1496         fi->fd = fd;
1497
1498         SWRAP_DLIST_ADD(si->fds, fi);
1499         SWRAP_DLIST_ADD(sockets, si);
1500
1501         return fd;
1502 }
1503
1504 _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
1505 {
1506         struct socket_info *parent_si, *child_si;
1507         struct socket_info_fd *child_fi;
1508         int fd;
1509         struct sockaddr_un un_addr;
1510         socklen_t un_addrlen = sizeof(un_addr);
1511         struct sockaddr_un un_my_addr;
1512         socklen_t un_my_addrlen = sizeof(un_my_addr);
1513         struct sockaddr *my_addr;
1514         socklen_t my_addrlen, len;
1515         int ret;
1516
1517         parent_si = find_socket_info(s);
1518         if (!parent_si) {
1519                 return real_accept(s, addr, addrlen);
1520         }
1521
1522         /* 
1523          * assume out sockaddr have the same size as the in parent
1524          * socket family
1525          */
1526         my_addrlen = socket_length(parent_si->family);
1527         if (my_addrlen <= 0) {
1528                 errno = EINVAL;
1529                 return -1;
1530         }
1531
1532         my_addr = (struct sockaddr *)malloc(my_addrlen);
1533         if (my_addr == NULL) {
1534                 return -1;
1535         }
1536
1537         memset(&un_addr, 0, sizeof(un_addr));
1538         memset(&un_my_addr, 0, sizeof(un_my_addr));
1539
1540         ret = real_accept(s, (struct sockaddr *)(void *)&un_addr, &un_addrlen);
1541         if (ret == -1) {
1542                 free(my_addr);
1543                 return ret;
1544         }
1545
1546         fd = ret;
1547
1548         len = my_addrlen;
1549         ret = sockaddr_convert_from_un(parent_si, &un_addr, un_addrlen,
1550                                        parent_si->family, my_addr, &len);
1551         if (ret == -1) {
1552                 free(my_addr);
1553                 close(fd);
1554                 return ret;
1555         }
1556
1557         child_si = (struct socket_info *)malloc(sizeof(struct socket_info));
1558         memset(child_si, 0, sizeof(*child_si));
1559
1560         child_fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
1561         if (child_fi == NULL) {
1562                 free(child_si);
1563                 free(my_addr);
1564                 close(fd);
1565                 errno = ENOMEM;
1566                 return -1;
1567         }
1568
1569         child_fi->fd = fd;
1570
1571         SWRAP_DLIST_ADD(child_si->fds, child_fi);
1572
1573         child_si->family = parent_si->family;
1574         child_si->type = parent_si->type;
1575         child_si->protocol = parent_si->protocol;
1576         child_si->bound = 1;
1577         child_si->is_server = 1;
1578         child_si->connected = 1;
1579
1580         child_si->peername_len = len;
1581         child_si->peername = sockaddr_dup(my_addr, len);
1582
1583         if (addr != NULL && addrlen != NULL) {
1584                 size_t copy_len = MIN(*addrlen, len);
1585                 if (copy_len > 0) {
1586                         memcpy(addr, my_addr, copy_len);
1587                 }
1588                 *addrlen = len;
1589         }
1590
1591         ret = real_getsockname(fd, (struct sockaddr *)(void *)&un_my_addr,
1592                                &un_my_addrlen);
1593         if (ret == -1) {
1594                 free(child_fi);
1595                 free(child_si);
1596                 close(fd);
1597                 return ret;
1598         }
1599
1600         len = my_addrlen;
1601         ret = sockaddr_convert_from_un(child_si, &un_my_addr, un_my_addrlen,
1602                                        child_si->family, my_addr, &len);
1603         if (ret == -1) {
1604                 free(child_fi);
1605                 free(child_si);
1606                 free(my_addr);
1607                 close(fd);
1608                 return ret;
1609         }
1610
1611         child_si->myname_len = len;
1612         child_si->myname = sockaddr_dup(my_addr, len);
1613         free(my_addr);
1614
1615         SWRAP_DLIST_ADD(sockets, child_si);
1616
1617         swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0);
1618         swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_RECV, NULL, 0);
1619         swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_ACK, NULL, 0);
1620
1621         return fd;
1622 }
1623
1624 static int autobind_start_init;
1625 static int autobind_start;
1626
1627 /* using sendto() or connect() on an unbound socket would give the
1628    recipient no way to reply, as unlike UDP and TCP, a unix domain
1629    socket can't auto-assign emphemeral port numbers, so we need to
1630    assign it here.
1631    Note: this might change the family from ipv6 to ipv4
1632 */
1633 static int swrap_auto_bind(int fd, struct socket_info *si, int family)
1634 {
1635         struct sockaddr_un un_addr;
1636         int i;
1637         char type;
1638         int ret;
1639         int port;
1640         struct stat st;
1641
1642         if (autobind_start_init != 1) {
1643                 autobind_start_init = 1;
1644                 autobind_start = getpid();
1645                 autobind_start %= 50000;
1646                 autobind_start += 10000;
1647         }
1648
1649         un_addr.sun_family = AF_UNIX;
1650
1651         switch (family) {
1652         case AF_INET: {
1653                 struct sockaddr_in in;
1654
1655                 switch (si->type) {
1656                 case SOCK_STREAM:
1657                         type = SOCKET_TYPE_CHAR_TCP;
1658                         break;
1659                 case SOCK_DGRAM:
1660                         type = SOCKET_TYPE_CHAR_UDP;
1661                         break;
1662                 default:
1663                     errno = ESOCKTNOSUPPORT;
1664                     return -1;
1665                 }
1666
1667                 memset(&in, 0, sizeof(in));
1668                 in.sin_family = AF_INET;
1669                 in.sin_addr.s_addr = htonl(127<<24 | 
1670                                            socket_wrapper_default_iface());
1671
1672                 si->myname_len = sizeof(in);
1673                 si->myname = sockaddr_dup(&in, si->myname_len);
1674                 break;
1675         }
1676 #ifdef HAVE_IPV6
1677         case AF_INET6: {
1678                 struct sockaddr_in6 in6;
1679
1680                 if (si->family != family) {
1681                         errno = ENETUNREACH;
1682                         return -1;
1683                 }
1684
1685                 switch (si->type) {
1686                 case SOCK_STREAM:
1687                         type = SOCKET_TYPE_CHAR_TCP_V6;
1688                         break;
1689                 case SOCK_DGRAM:
1690                         type = SOCKET_TYPE_CHAR_UDP_V6;
1691                         break;
1692                 default:
1693                         errno = ESOCKTNOSUPPORT;
1694                         return -1;
1695                 }
1696
1697                 memset(&in6, 0, sizeof(in6));
1698                 in6.sin6_family = AF_INET6;
1699                 in6.sin6_addr = *swrap_ipv6();
1700                 in6.sin6_addr.s6_addr[15] = socket_wrapper_default_iface();
1701                 si->myname_len = sizeof(in6);
1702                 si->myname = sockaddr_dup(&in6, si->myname_len);
1703                 break;
1704         }
1705 #endif
1706         default:
1707                 errno = ESOCKTNOSUPPORT;
1708                 return -1;
1709         }
1710
1711         if (autobind_start > 60000) {
1712                 autobind_start = 10000;
1713         }
1714
1715         for (i=0;i<1000;i++) {
1716                 port = autobind_start + i;
1717                 snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), 
1718                          "%s/"SOCKET_FORMAT, socket_wrapper_dir(),
1719                          type, socket_wrapper_default_iface(), port);
1720                 if (stat(un_addr.sun_path, &st) == 0) continue;
1721
1722                 ret = real_bind(fd, (struct sockaddr *)(void *)&un_addr,
1723                                 sizeof(un_addr));
1724                 if (ret == -1) return ret;
1725
1726                 si->tmp_path = strdup(un_addr.sun_path);
1727                 si->bound = 1;
1728                 autobind_start = port + 1;
1729                 break;
1730         }
1731         if (i == 1000) {
1732                 errno = ENFILE;
1733                 return -1;
1734         }
1735
1736         si->family = family;
1737         set_port(si->family, port, si->myname);
1738
1739         return 0;
1740 }
1741
1742
1743 _PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen)
1744 {
1745         int ret;
1746         struct sockaddr_un un_addr;
1747         struct socket_info *si = find_socket_info(s);
1748         int bcast = 0;
1749
1750         if (!si) {
1751                 return real_connect(s, serv_addr, addrlen);
1752         }
1753
1754         if (si->bound == 0) {
1755                 ret = swrap_auto_bind(s, si, serv_addr->sa_family);
1756                 if (ret == -1) return -1;
1757         }
1758
1759         if (si->family != serv_addr->sa_family) {
1760                 errno = EINVAL;
1761                 return -1;
1762         }
1763
1764         ret = sockaddr_convert_to_un(si, serv_addr,
1765                                      addrlen, &un_addr, 0, &bcast);
1766         if (ret == -1) return -1;
1767
1768         if (bcast) {
1769                 errno = ENETUNREACH;
1770                 return -1;
1771         }
1772
1773         if (si->type == SOCK_DGRAM) {
1774                 si->defer_connect = 1;
1775                 ret = 0;
1776         } else {
1777                 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0);
1778
1779                 ret = real_connect(s, (struct sockaddr *)(void *)&un_addr,
1780                                    sizeof(struct sockaddr_un));
1781         }
1782
1783         /* to give better errors */
1784         if (ret == -1 && errno == ENOENT) {
1785                 errno = EHOSTUNREACH;
1786         }
1787
1788         if (ret == 0) {
1789                 si->peername_len = addrlen;
1790                 si->peername = sockaddr_dup(serv_addr, addrlen);
1791                 si->connected = 1;
1792
1793                 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0);
1794                 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0);
1795         } else {
1796                 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0);
1797         }
1798
1799         return ret;
1800 }
1801
1802 _PUBLIC_ int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
1803 {
1804         int ret;
1805         struct sockaddr_un un_addr;
1806         struct socket_info *si = find_socket_info(s);
1807
1808         if (!si) {
1809                 return real_bind(s, myaddr, addrlen);
1810         }
1811
1812         si->myname_len = addrlen;
1813         si->myname = sockaddr_dup(myaddr, addrlen);
1814
1815         ret = sockaddr_convert_to_un(si, myaddr, addrlen, &un_addr, 1, &si->bcast);
1816         if (ret == -1) return -1;
1817
1818         unlink(un_addr.sun_path);
1819
1820         ret = real_bind(s, (struct sockaddr *)(void *)&un_addr,
1821                         sizeof(struct sockaddr_un));
1822
1823         if (ret == 0) {
1824                 si->bound = 1;
1825         }
1826
1827         return ret;
1828 }
1829
1830 _PUBLIC_ int swrap_listen(int s, int backlog)
1831 {
1832         int ret;
1833         struct socket_info *si = find_socket_info(s);
1834
1835         if (!si) {
1836                 return real_listen(s, backlog);
1837         }
1838
1839         ret = real_listen(s, backlog);
1840
1841         return ret;
1842 }
1843
1844 _PUBLIC_ int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
1845 {
1846         struct socket_info *si = find_socket_info(s);
1847
1848         if (!si) {
1849                 return real_getpeername(s, name, addrlen);
1850         }
1851
1852         if (!si->peername)
1853         {
1854                 errno = ENOTCONN;
1855                 return -1;
1856         }
1857
1858         memcpy(name, si->peername, si->peername_len);
1859         *addrlen = si->peername_len;
1860
1861         return 0;
1862 }
1863
1864 _PUBLIC_ int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
1865 {
1866         struct socket_info *si = find_socket_info(s);
1867
1868         if (!si) {
1869                 return real_getsockname(s, name, addrlen);
1870         }
1871
1872         memcpy(name, si->myname, si->myname_len);
1873         *addrlen = si->myname_len;
1874
1875         return 0;
1876 }
1877
1878 _PUBLIC_ int swrap_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
1879 {
1880         struct socket_info *si = find_socket_info(s);
1881
1882         if (!si) {
1883                 return real_getsockopt(s, level, optname, optval, optlen);
1884         }
1885
1886         if (level == SOL_SOCKET) {
1887                 return real_getsockopt(s, level, optname, optval, optlen);
1888         } 
1889
1890         errno = ENOPROTOOPT;
1891         return -1;
1892 }
1893
1894 _PUBLIC_ int swrap_setsockopt(int s, int  level,  int  optname,  const  void  *optval, socklen_t optlen)
1895 {
1896         struct socket_info *si = find_socket_info(s);
1897
1898         if (!si) {
1899                 return real_setsockopt(s, level, optname, optval, optlen);
1900         }
1901
1902         if (level == SOL_SOCKET) {
1903                 return real_setsockopt(s, level, optname, optval, optlen);
1904         }
1905
1906         switch (si->family) {
1907         case AF_INET:
1908                 return 0;
1909 #ifdef HAVE_IPV6
1910         case AF_INET6:
1911                 return 0;
1912 #endif
1913         default:
1914                 errno = ENOPROTOOPT;
1915                 return -1;
1916         }
1917 }
1918
1919 _PUBLIC_ int swrap_ioctl(int s, int r, void *p)
1920 {
1921         int ret;
1922         struct socket_info *si = find_socket_info(s);
1923         int value;
1924
1925         if (!si) {
1926                 return real_ioctl(s, r, p);
1927         }
1928
1929         ret = real_ioctl(s, r, p);
1930
1931         switch (r) {
1932         case FIONREAD:
1933                 value = *((int *)p);
1934                 if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
1935                         swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
1936                 } else if (value == 0) { /* END OF FILE */
1937                         swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
1938                 }
1939                 break;
1940         }
1941
1942         return ret;
1943 }
1944
1945 static ssize_t swrap_sendmsg_before(int fd,
1946                                     struct socket_info *si,
1947                                     struct msghdr *msg,
1948                                     struct iovec *tmp_iov,
1949                                     struct sockaddr_un *tmp_un,
1950                                     const struct sockaddr_un **to_un,
1951                                     const struct sockaddr **to,
1952                                     int *bcast)
1953 {
1954         size_t i, len = 0;
1955         ssize_t ret;
1956
1957         if (to_un) {
1958                 *to_un = NULL;
1959         }
1960         if (to) {
1961                 *to = NULL;
1962         }
1963         if (bcast) {
1964                 *bcast = 0;
1965         }
1966
1967         switch (si->type) {
1968         case SOCK_STREAM:
1969                 if (!si->connected) {
1970                         errno = ENOTCONN;
1971                         return -1;
1972                 }
1973
1974                 if (msg->msg_iovlen == 0) {
1975                         break;
1976                 }
1977
1978                 /*
1979                  * cut down to 1500 byte packets for stream sockets,
1980                  * which makes it easier to format PCAP capture files
1981                  * (as the caller will simply continue from here)
1982                  */
1983
1984                 for (i=0; i < msg->msg_iovlen; i++) {
1985                         size_t nlen;
1986                         nlen = len + msg->msg_iov[i].iov_len;
1987                         if (nlen > 1500) {
1988                                 break;
1989                         }
1990                 }
1991                 msg->msg_iovlen = i;
1992                 if (msg->msg_iovlen == 0) {
1993                         *tmp_iov = msg->msg_iov[0];
1994                         tmp_iov->iov_len = MIN(tmp_iov->iov_len, 1500);
1995                         msg->msg_iov = tmp_iov;
1996                         msg->msg_iovlen = 1;
1997                 }
1998                 break;
1999
2000         case SOCK_DGRAM:
2001                 if (si->connected) {
2002                         if (msg->msg_name) {
2003                                 errno = EISCONN;
2004                                 return -1;
2005                         }
2006                 } else {
2007                         const struct sockaddr *msg_name;
2008                         msg_name = (const struct sockaddr *)msg->msg_name;
2009
2010                         if (msg_name == NULL) {
2011                                 errno = ENOTCONN;
2012                                 return -1;
2013                         }
2014
2015
2016                         ret = sockaddr_convert_to_un(si, msg_name, msg->msg_namelen,
2017                                                      tmp_un, 0, bcast);
2018                         if (ret == -1) return -1;
2019
2020                         if (to_un) {
2021                                 *to_un = tmp_un;
2022                         }
2023                         if (to) {
2024                                 *to = msg_name;
2025                         }
2026                         msg->msg_name = tmp_un;
2027                         msg->msg_namelen = sizeof(*tmp_un);
2028                 }
2029
2030                 if (si->bound == 0) {
2031                         ret = swrap_auto_bind(fd, si, si->family);
2032                         if (ret == -1) return -1;
2033                 }
2034
2035                 if (!si->defer_connect) {
2036                         break;
2037                 }
2038
2039                 ret = sockaddr_convert_to_un(si, si->peername, si->peername_len,
2040                                              tmp_un, 0, NULL);
2041                 if (ret == -1) return -1;
2042
2043                 ret = real_connect(fd, (struct sockaddr *)(void *)tmp_un,
2044                                    sizeof(*tmp_un));
2045
2046                 /* to give better errors */
2047                 if (ret == -1 && errno == ENOENT) {
2048                         errno = EHOSTUNREACH;
2049                 }
2050
2051                 if (ret == -1) {
2052                         return ret;
2053                 }
2054
2055                 si->defer_connect = 0;
2056                 break;
2057         default:
2058                 errno = EHOSTUNREACH;
2059                 return -1;
2060         }
2061
2062         return 0;
2063 }
2064
2065 static void swrap_sendmsg_after(struct socket_info *si,
2066                                 struct msghdr *msg,
2067                                 const struct sockaddr *to,
2068                                 ssize_t ret)
2069 {
2070         int saved_errno = errno;
2071         size_t i, len = 0;
2072         uint8_t *buf;
2073         off_t ofs = 0;
2074         size_t avail = 0;
2075         size_t remain;
2076
2077         /* to give better errors */
2078         if (ret == -1 && saved_errno == ENOENT) {
2079                 saved_errno = EHOSTUNREACH;
2080         }
2081
2082         for (i=0; i < msg->msg_iovlen; i++) {
2083                 avail += msg->msg_iov[i].iov_len;
2084         }
2085
2086         if (ret == -1) {
2087                 remain = MIN(80, avail);
2088         } else {
2089                 remain = ret;
2090         }
2091
2092         /* we capture it as one single packet */
2093         buf = (uint8_t *)malloc(remain);
2094         if (!buf) {
2095                 /* we just not capture the packet */
2096                 errno = saved_errno;
2097                 return;
2098         }
2099
2100         for (i=0; i < msg->msg_iovlen; i++) {
2101                 size_t this_time = MIN(remain, msg->msg_iov[i].iov_len);
2102                 memcpy(buf + ofs,
2103                        msg->msg_iov[i].iov_base,
2104                        this_time);
2105                 ofs += this_time;
2106                 remain -= this_time;
2107         }
2108         len = ofs;
2109
2110         switch (si->type) {
2111         case SOCK_STREAM:
2112                 if (ret == -1) {
2113                         swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
2114                         swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
2115                 } else {
2116                         swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
2117                 }
2118                 break;
2119
2120         case SOCK_DGRAM:
2121                 if (si->connected) {
2122                         to = si->peername;
2123                 }
2124                 if (ret == -1) {
2125                         swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
2126                         swrap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);
2127                 } else {
2128                         swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
2129                 }
2130                 break;
2131         }
2132
2133         free(buf);
2134         errno = saved_errno;
2135 }
2136
2137 _PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
2138 {
2139         struct sockaddr_un un_addr;
2140         socklen_t un_addrlen = sizeof(un_addr);
2141         int ret;
2142         struct socket_info *si = find_socket_info(s);
2143         struct sockaddr_storage ss;
2144         socklen_t ss_len = sizeof(ss);
2145
2146         if (!si) {
2147                 return real_recvfrom(s, buf, len, flags, from, fromlen);
2148         }
2149
2150         if (!from) {
2151                 from = (struct sockaddr *)(void *)&ss;
2152                 fromlen = &ss_len;
2153         }
2154
2155         if (si->type == SOCK_STREAM) {
2156                 /* cut down to 1500 byte packets for stream sockets,
2157                  * which makes it easier to format PCAP capture files
2158                  * (as the caller will simply continue from here) */
2159                 len = MIN(len, 1500);
2160         }
2161
2162         /* irix 6.4 forgets to null terminate the sun_path string :-( */
2163         memset(&un_addr, 0, sizeof(un_addr));
2164         ret = real_recvfrom(s, buf, len, flags,
2165                             (struct sockaddr *)(void *)&un_addr, &un_addrlen);
2166         if (ret == -1) 
2167                 return ret;
2168
2169         if (sockaddr_convert_from_un(si, &un_addr, un_addrlen,
2170                                      si->family, from, fromlen) == -1) {
2171                 return -1;
2172         }
2173
2174         swrap_dump_packet(si, from, SWRAP_RECVFROM, buf, ret);
2175
2176         return ret;
2177 }
2178
2179
2180 _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
2181 {
2182         struct msghdr msg;
2183         struct iovec tmp;
2184         struct sockaddr_un un_addr;
2185         const struct sockaddr_un *to_un = NULL;
2186         ssize_t ret;
2187         struct socket_info *si = find_socket_info(s);
2188         int bcast = 0;
2189
2190         if (!si) {
2191                 return real_sendto(s, buf, len, flags, to, tolen);
2192         }
2193
2194         tmp.iov_base = discard_const_p(char, buf);
2195         tmp.iov_len = len;
2196
2197         ZERO_STRUCT(msg);
2198         msg.msg_name = discard_const_p(struct sockaddr, to); /* optional address */
2199         msg.msg_namelen = tolen;       /* size of address */
2200         msg.msg_iov = &tmp;            /* scatter/gather array */
2201         msg.msg_iovlen = 1;            /* # elements in msg_iov */
2202 #if 0 /* not available on solaris */
2203         msg.msg_control = NULL;        /* ancillary data, see below */
2204         msg.msg_controllen = 0;        /* ancillary data buffer len */
2205         msg.msg_flags = 0;             /* flags on received message */
2206 #endif
2207
2208         ret = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
2209         if (ret == -1) return -1;
2210
2211         buf = msg.msg_iov[0].iov_base;
2212         len = msg.msg_iov[0].iov_len;
2213
2214         if (bcast) {
2215                 struct stat st;
2216                 unsigned int iface;
2217                 unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port);
2218                 char type;
2219
2220                 type = SOCKET_TYPE_CHAR_UDP;
2221
2222                 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
2223                         snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT,
2224                                  socket_wrapper_dir(), type, iface, prt);
2225                         if (stat(un_addr.sun_path, &st) != 0) continue;
2226
2227                         /* ignore the any errors in broadcast sends */
2228                         real_sendto(s, buf, len, flags,
2229                                     (struct sockaddr *)(void *)&un_addr,
2230                                     sizeof(un_addr));
2231                 }
2232
2233                 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
2234
2235                 return len;
2236         }
2237
2238         ret = real_sendto(s, buf, len, flags, (struct sockaddr *)msg.msg_name,
2239                           msg.msg_namelen);
2240
2241         swrap_sendmsg_after(si, &msg, to, ret);
2242
2243         return ret;
2244 }
2245
2246 _PUBLIC_ ssize_t swrap_recv(int s, void *buf, size_t len, int flags)
2247 {
2248         int ret;
2249         struct socket_info *si = find_socket_info(s);
2250
2251         if (!si) {
2252                 return real_recv(s, buf, len, flags);
2253         }
2254
2255         if (si->type == SOCK_STREAM) {
2256                 /* cut down to 1500 byte packets for stream sockets,
2257                  * which makes it easier to format PCAP capture files
2258                  * (as the caller will simply continue from here) */
2259                 len = MIN(len, 1500);
2260         }
2261
2262         ret = real_recv(s, buf, len, flags);
2263         if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
2264                 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
2265         } else if (ret == 0) { /* END OF FILE */
2266                 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
2267         } else if (ret > 0) {
2268                 swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
2269         }
2270
2271         return ret;
2272 }
2273
2274 _PUBLIC_ ssize_t swrap_read(int s, void *buf, size_t len)
2275 {
2276         int ret;
2277         struct socket_info *si = find_socket_info(s);
2278
2279         if (!si) {
2280                 return real_read(s, buf, len);
2281         }
2282
2283         if (si->type == SOCK_STREAM) {
2284                 /* cut down to 1500 byte packets for stream sockets,
2285                  * which makes it easier to format PCAP capture files
2286                  * (as the caller will simply continue from here) */
2287                 len = MIN(len, 1500);
2288         }
2289
2290         ret = real_read(s, buf, len);
2291         if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
2292                 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
2293         } else if (ret == 0) { /* END OF FILE */
2294                 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
2295         } else if (ret > 0) {
2296                 swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
2297         }
2298
2299         return ret;
2300 }
2301
2302
2303 _PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
2304 {
2305         struct msghdr msg;
2306         struct iovec tmp;
2307         struct sockaddr_un un_addr;
2308         ssize_t ret;
2309         struct socket_info *si = find_socket_info(s);
2310
2311         if (!si) {
2312                 return real_send(s, buf, len, flags);
2313         }
2314
2315         tmp.iov_base = discard_const_p(char, buf);
2316         tmp.iov_len = len;
2317
2318         ZERO_STRUCT(msg);
2319         msg.msg_name = NULL;           /* optional address */
2320         msg.msg_namelen = 0;           /* size of address */
2321         msg.msg_iov = &tmp;            /* scatter/gather array */
2322         msg.msg_iovlen = 1;            /* # elements in msg_iov */
2323 #if 0 /* not available on solaris */
2324         msg.msg_control = NULL;        /* ancillary data, see below */
2325         msg.msg_controllen = 0;        /* ancillary data buffer len */
2326         msg.msg_flags = 0;             /* flags on received message */
2327 #endif
2328
2329         ret = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
2330         if (ret == -1) return -1;
2331
2332         buf = msg.msg_iov[0].iov_base;
2333         len = msg.msg_iov[0].iov_len;
2334
2335         ret = real_send(s, buf, len, flags);
2336
2337         swrap_sendmsg_after(si, &msg, NULL, ret);
2338
2339         return ret;
2340 }
2341
2342 _PUBLIC_ ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags)
2343 {
2344         struct msghdr msg;
2345         struct iovec tmp;
2346         struct sockaddr_un un_addr;
2347         const struct sockaddr_un *to_un = NULL;
2348         const struct sockaddr *to = NULL;
2349         ssize_t ret;
2350         struct socket_info *si = find_socket_info(s);
2351         int bcast = 0;
2352
2353         if (!si) {
2354                 return real_sendmsg(s, omsg, flags);
2355         }
2356
2357         tmp.iov_base = NULL;
2358         tmp.iov_len = 0;
2359
2360         msg = *omsg;
2361 #if 0
2362         msg.msg_name = omsg->msg_name;             /* optional address */
2363         msg.msg_namelen = omsg->msg_namelen;       /* size of address */
2364         msg.msg_iov = omsg->msg_iov;               /* scatter/gather array */
2365         msg.msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
2366         /* the following is not available on solaris */
2367         msg.msg_control = omsg->msg_control;       /* ancillary data, see below */
2368         msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
2369         msg.msg_flags = omsg->msg_flags;           /* flags on received message */
2370 #endif
2371
2372         ret = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
2373         if (ret == -1) return -1;
2374
2375         if (bcast) {
2376                 struct stat st;
2377                 unsigned int iface;
2378                 unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port);
2379                 char type;
2380                 size_t i, len = 0;
2381                 uint8_t *buf;
2382                 off_t ofs = 0;
2383                 size_t avail = 0;
2384                 size_t remain;
2385
2386                 for (i=0; i < msg.msg_iovlen; i++) {
2387                         avail += msg.msg_iov[i].iov_len;
2388                 }
2389
2390                 len = avail;
2391                 remain = avail;
2392
2393                 /* we capture it as one single packet */
2394                 buf = (uint8_t *)malloc(remain);
2395                 if (!buf) {
2396                         return -1;
2397                 }
2398
2399                 for (i=0; i < msg.msg_iovlen; i++) {
2400                         size_t this_time = MIN(remain, msg.msg_iov[i].iov_len);
2401                         memcpy(buf + ofs,
2402                                msg.msg_iov[i].iov_base,
2403                                this_time);
2404                         ofs += this_time;
2405                         remain -= this_time;
2406                 }
2407
2408                 type = SOCKET_TYPE_CHAR_UDP;
2409
2410                 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
2411                         snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT,
2412                                  socket_wrapper_dir(), type, iface, prt);
2413                         if (stat(un_addr.sun_path, &st) != 0) continue;
2414
2415                         msg.msg_name = &un_addr;           /* optional address */
2416                         msg.msg_namelen = sizeof(un_addr); /* size of address */
2417
2418                         /* ignore the any errors in broadcast sends */
2419                         real_sendmsg(s, &msg, flags);
2420                 }
2421
2422                 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
2423                 free(buf);
2424
2425                 return len;
2426         }
2427
2428         ret = real_sendmsg(s, &msg, flags);
2429
2430         swrap_sendmsg_after(si, &msg, to, ret);
2431
2432         return ret;
2433 }
2434
2435 int swrap_readv(int s, const struct iovec *vector, size_t count)
2436 {
2437         int ret;
2438         struct socket_info *si = find_socket_info(s);
2439         struct iovec v;
2440
2441         if (!si) {
2442                 return real_readv(s, vector, count);
2443         }
2444
2445         if (!si->connected) {
2446                 errno = ENOTCONN;
2447                 return -1;
2448         }
2449
2450         if (si->type == SOCK_STREAM && count > 0) {
2451                 /* cut down to 1500 byte packets for stream sockets,
2452                  * which makes it easier to format PCAP capture files
2453                  * (as the caller will simply continue from here) */
2454                 size_t i, len = 0;
2455
2456                 for (i=0; i < count; i++) {
2457                         size_t nlen;
2458                         nlen = len + vector[i].iov_len;
2459                         if (nlen > 1500) {
2460                                 break;
2461                         }
2462                 }
2463                 count = i;
2464                 if (count == 0) {
2465                         v = vector[0];
2466                         v.iov_len = MIN(v.iov_len, 1500);
2467                         vector = &v;
2468                         count = 1;
2469                 }
2470         }
2471
2472         ret = real_readv(s, vector, count);
2473         if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
2474                 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
2475         } else if (ret == 0) { /* END OF FILE */
2476                 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
2477         } else if (ret > 0) {
2478                 uint8_t *buf;
2479                 off_t ofs = 0;
2480                 size_t i;
2481                 size_t remain = ret;
2482
2483                 /* we capture it as one single packet */
2484                 buf = (uint8_t *)malloc(ret);
2485                 if (!buf) {
2486                         /* we just not capture the packet */
2487                         errno = 0;
2488                         return ret;
2489                 }
2490
2491                 for (i=0; i < count; i++) {
2492                         size_t this_time = MIN(remain, vector[i].iov_len);
2493                         memcpy(buf + ofs,
2494                                vector[i].iov_base,
2495                                this_time);
2496                         ofs += this_time;
2497                         remain -= this_time;
2498                 }
2499
2500                 swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
2501                 free(buf);
2502         }
2503
2504         return ret;
2505 }
2506
2507 int swrap_writev(int s, const struct iovec *vector, size_t count)
2508 {
2509         struct msghdr msg;
2510         struct iovec tmp;
2511         struct sockaddr_un un_addr;
2512         ssize_t ret;
2513         struct socket_info *si = find_socket_info(s);
2514
2515         if (!si) {
2516                 return real_writev(s, vector, count);
2517         }
2518
2519         tmp.iov_base = NULL;
2520         tmp.iov_len = 0;
2521
2522         ZERO_STRUCT(msg);
2523         msg.msg_name = NULL;           /* optional address */
2524         msg.msg_namelen = 0;           /* size of address */
2525         msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
2526         msg.msg_iovlen = count;        /* # elements in msg_iov */
2527 #if 0 /* not available on solaris */
2528         msg.msg_control = NULL;        /* ancillary data, see below */
2529         msg.msg_controllen = 0;        /* ancillary data buffer len */
2530         msg.msg_flags = 0;             /* flags on received message */
2531 #endif
2532
2533         ret = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
2534         if (ret == -1) return -1;
2535
2536         ret = real_writev(s, msg.msg_iov, msg.msg_iovlen);
2537
2538         swrap_sendmsg_after(si, &msg, NULL, ret);
2539
2540         return ret;
2541 }
2542
2543 _PUBLIC_ int swrap_close(int fd)
2544 {
2545         struct socket_info *si = find_socket_info(fd);
2546         struct socket_info_fd *fi;
2547         int ret;
2548
2549         if (!si) {
2550                 return real_close(fd);
2551         }
2552
2553         for (fi = si->fds; fi; fi = fi->next) {
2554                 if (fi->fd == fd) {
2555                         SWRAP_DLIST_REMOVE(si->fds, fi);
2556                         free(fi);
2557                         break;
2558                 }
2559         }
2560
2561         if (si->fds) {
2562                 /* there are still references left */
2563                 return real_close(fd);
2564         }
2565
2566         SWRAP_DLIST_REMOVE(sockets, si);
2567
2568         if (si->myname && si->peername) {
2569                 swrap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0);
2570         }
2571
2572         ret = real_close(fd);
2573
2574         if (si->myname && si->peername) {
2575                 swrap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0);
2576                 swrap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0);
2577         }
2578
2579         if (si->myname) free(si->myname);
2580         if (si->peername) free(si->peername);
2581         if (si->tmp_path) {
2582                 unlink(si->tmp_path);
2583                 free(si->tmp_path);
2584         }
2585         free(si);
2586
2587         return ret;
2588 }
2589
2590 _PUBLIC_ int swrap_dup(int fd)
2591 {
2592         struct socket_info *si;
2593         struct socket_info_fd *fi;
2594
2595         si = find_socket_info(fd);
2596
2597         if (!si) {
2598                 return real_dup(fd);
2599         }
2600
2601         fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
2602         if (fi == NULL) {
2603                 errno = ENOMEM;
2604                 return -1;
2605         }
2606
2607         fi->fd = real_dup(fd);
2608         if (fi->fd == -1) {
2609                 int saved_errno = errno;
2610                 free(fi);
2611                 errno = saved_errno;
2612                 return -1;
2613         }
2614
2615         SWRAP_DLIST_ADD(si->fds, fi);
2616         return fi->fd;
2617 }
2618
2619 _PUBLIC_ int swrap_dup2(int fd, int newfd)
2620 {
2621         struct socket_info *si;
2622         struct socket_info_fd *fi;
2623
2624         si = find_socket_info(fd);
2625
2626         if (!si) {
2627                 return real_dup2(fd, newfd);
2628         }
2629
2630         if (find_socket_info(newfd)) {
2631                 /* dup2() does an implicit close of newfd, which we
2632                  * need to emulate */
2633                 swrap_close(newfd);
2634         }
2635
2636         fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
2637         if (fi == NULL) {
2638                 errno = ENOMEM;
2639                 return -1;
2640         }
2641
2642         fi->fd = real_dup2(fd, newfd);
2643         if (fi->fd == -1) {
2644                 int saved_errno = errno;
2645                 free(fi);
2646                 errno = saved_errno;
2647                 return -1;
2648         }
2649
2650         SWRAP_DLIST_ADD(si->fds, fi);
2651         return fi->fd;
2652 }