Add support for sendmsg() in socket_wrapper
[ira/wip.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/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_send send
125 #define real_readv readv
126 #define real_writev writev
127 #define real_socket socket
128 #define real_close close
129 #endif
130
131 #ifdef HAVE_GETTIMEOFDAY_TZ
132 #define swrapGetTimeOfDay(tval) gettimeofday(tval,NULL)
133 #else
134 #define swrapGetTimeOfDay(tval) gettimeofday(tval)
135 #endif
136
137 /* we need to use a very terse format here as IRIX 6.4 silently
138    truncates names to 16 chars, so if we use a longer name then we
139    can't tell which port a packet came from with recvfrom() 
140    
141    with this format we have 8 chars left for the directory name
142 */
143 #define SOCKET_FORMAT "%c%02X%04X"
144 #define SOCKET_TYPE_CHAR_TCP            'T'
145 #define SOCKET_TYPE_CHAR_UDP            'U'
146 #define SOCKET_TYPE_CHAR_TCP_V6         'X'
147 #define SOCKET_TYPE_CHAR_UDP_V6         'Y'
148
149 #define MAX_WRAPPED_INTERFACES 16
150
151 #ifdef HAVE_IPV6
152 /*
153  * FD00::5357:5FXX
154  */
155 static const struct in6_addr *swrap_ipv6(void)
156 {
157         static struct in6_addr v;
158         static int initialized;
159         int ret;
160
161         if (initialized) {
162                 return &v;
163         }
164         initialized = 1;
165
166         ret = inet_pton(AF_INET6, "FD00::5357:5F00", &v);
167         if (ret <= 0) {
168                 abort();
169         }
170
171         return &v;
172 }
173 #endif
174
175 static struct sockaddr *sockaddr_dup(const void *data, socklen_t len)
176 {
177         struct sockaddr *ret = (struct sockaddr *)malloc(len);
178         memcpy(ret, data, len);
179         return ret;
180 }
181
182 static void set_port(int family, int prt, struct sockaddr *addr)
183 {
184         switch (family) {
185         case AF_INET:
186                 ((struct sockaddr_in *)addr)->sin_port = htons(prt);
187                 break;
188 #ifdef HAVE_IPV6
189         case AF_INET6:
190                 ((struct sockaddr_in6 *)addr)->sin6_port = htons(prt);
191                 break;
192 #endif
193         }
194 }
195
196 static size_t socket_length(int family)
197 {
198         switch (family) {
199         case AF_INET:
200                 return sizeof(struct sockaddr_in);
201 #ifdef HAVE_IPV6
202         case AF_INET6:
203                 return sizeof(struct sockaddr_in6);
204 #endif
205         }
206         return 0;
207 }
208
209
210
211 struct socket_info
212 {
213         int fd;
214
215         int family;
216         int type;
217         int protocol;
218         int bound;
219         int bcast;
220         int is_server;
221         int connected;
222         int defer_connect;
223
224         char *path;
225         char *tmp_path;
226
227         struct sockaddr *myname;
228         socklen_t myname_len;
229
230         struct sockaddr *peername;
231         socklen_t peername_len;
232
233         struct {
234                 unsigned long pck_snd;
235                 unsigned long pck_rcv;
236         } io;
237
238         struct socket_info *prev, *next;
239 };
240
241 static struct socket_info *sockets;
242
243 const char *socket_wrapper_dir(void)
244 {
245         const char *s = getenv("SOCKET_WRAPPER_DIR");
246         if (s == NULL) {
247                 return NULL;
248         }
249         if (strncmp(s, "./", 2) == 0) {
250                 s += 2;
251         }
252         return s;
253 }
254
255 unsigned int socket_wrapper_default_iface(void)
256 {
257         const char *s = getenv("SOCKET_WRAPPER_DEFAULT_IFACE");
258         if (s) {
259                 unsigned int iface;
260                 if (sscanf(s, "%u", &iface) == 1) {
261                         if (iface >= 1 && iface <= MAX_WRAPPED_INTERFACES) {
262                                 return iface;
263                         }
264                 }
265         }
266
267         return 1;/* 127.0.0.1 */
268 }
269
270 static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, socklen_t *len)
271 {
272         unsigned int iface;
273         unsigned int prt;
274         const char *p;
275         char type;
276
277         p = strrchr(un->sun_path, '/');
278         if (p) p++; else p = un->sun_path;
279
280         if (sscanf(p, SOCKET_FORMAT, &type, &iface, &prt) != 3) {
281                 errno = EINVAL;
282                 return -1;
283         }
284
285         if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
286                 errno = EINVAL;
287                 return -1;
288         }
289
290         if (prt > 0xFFFF) {
291                 errno = EINVAL;
292                 return -1;
293         }
294
295         switch(type) {
296         case SOCKET_TYPE_CHAR_TCP:
297         case SOCKET_TYPE_CHAR_UDP: {
298                 struct sockaddr_in *in2 = (struct sockaddr_in *)in;
299                 
300                 if ((*len) < sizeof(*in2)) {
301                     errno = EINVAL;
302                     return -1;
303                 }
304
305                 memset(in2, 0, sizeof(*in2));
306                 in2->sin_family = AF_INET;
307                 in2->sin_addr.s_addr = htonl((127<<24) | iface);
308                 in2->sin_port = htons(prt);
309
310                 *len = sizeof(*in2);
311                 break;
312         }
313 #ifdef HAVE_IPV6
314         case SOCKET_TYPE_CHAR_TCP_V6:
315         case SOCKET_TYPE_CHAR_UDP_V6: {
316                 struct sockaddr_in6 *in2 = (struct sockaddr_in6 *)in;
317                 
318                 if ((*len) < sizeof(*in2)) {
319                         errno = EINVAL;
320                         return -1;
321                 }
322
323                 memset(in2, 0, sizeof(*in2));
324                 in2->sin6_family = AF_INET6;
325                 in2->sin6_addr = *swrap_ipv6();
326                 in2->sin6_addr.s6_addr[15] = iface;
327                 in2->sin6_port = htons(prt);
328
329                 *len = sizeof(*in2);
330                 break;
331         }
332 #endif
333         default:
334                 errno = EINVAL;
335                 return -1;
336         }
337
338         return 0;
339 }
340
341 static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un,
342                                 int *bcast)
343 {
344         char type = '\0';
345         unsigned int prt;
346         unsigned int iface;
347         int is_bcast = 0;
348
349         if (bcast) *bcast = 0;
350
351         switch (si->family) {
352         case AF_INET: {
353                 const struct sockaddr_in *in = 
354                     (const struct sockaddr_in *)inaddr;
355                 unsigned int addr = ntohl(in->sin_addr.s_addr);
356                 char u_type = '\0';
357                 char b_type = '\0';
358                 char a_type = '\0';
359
360                 switch (si->type) {
361                 case SOCK_STREAM:
362                         u_type = SOCKET_TYPE_CHAR_TCP;
363                         break;
364                 case SOCK_DGRAM:
365                         u_type = SOCKET_TYPE_CHAR_UDP;
366                         a_type = SOCKET_TYPE_CHAR_UDP;
367                         b_type = SOCKET_TYPE_CHAR_UDP;
368                         break;
369                 }
370
371                 prt = ntohs(in->sin_port);
372                 if (a_type && addr == 0xFFFFFFFF) {
373                         /* 255.255.255.255 only udp */
374                         is_bcast = 2;
375                         type = a_type;
376                         iface = socket_wrapper_default_iface();
377                 } else if (b_type && addr == 0x7FFFFFFF) {
378                         /* 127.255.255.255 only udp */
379                         is_bcast = 1;
380                         type = b_type;
381                         iface = socket_wrapper_default_iface();
382                 } else if ((addr & 0xFFFFFF00) == 0x7F000000) {
383                         /* 127.0.0.X */
384                         is_bcast = 0;
385                         type = u_type;
386                         iface = (addr & 0x000000FF);
387                 } else {
388                         errno = ENETUNREACH;
389                         return -1;
390                 }
391                 if (bcast) *bcast = is_bcast;
392                 break;
393         }
394 #ifdef HAVE_IPV6
395         case AF_INET6: {
396                 const struct sockaddr_in6 *in = 
397                     (const struct sockaddr_in6 *)inaddr;
398                 struct in6_addr cmp;
399
400                 switch (si->type) {
401                 case SOCK_STREAM:
402                         type = SOCKET_TYPE_CHAR_TCP_V6;
403                         break;
404                 case SOCK_DGRAM:
405                         type = SOCKET_TYPE_CHAR_UDP_V6;
406                         break;
407                 }
408
409                 /* XXX no multicast/broadcast */
410
411                 prt = ntohs(in->sin6_port);
412
413                 cmp = in->sin6_addr;
414                 cmp.s6_addr[15] = 0;
415                 if (IN6_ARE_ADDR_EQUAL(swrap_ipv6(), &cmp)) {
416                         iface = in->sin6_addr.s6_addr[15];
417                 } else {
418                         errno = ENETUNREACH;
419                         return -1;
420                 }
421
422                 break;
423         }
424 #endif
425         default:
426                 errno = ENETUNREACH;
427                 return -1;
428         }
429
430         if (prt == 0) {
431                 errno = EINVAL;
432                 return -1;
433         }
434
435         if (is_bcast) {
436                 snprintf(un->sun_path, sizeof(un->sun_path), "%s/EINVAL", 
437                          socket_wrapper_dir());
438                 /* the caller need to do more processing */
439                 return 0;
440         }
441
442         snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, 
443                  socket_wrapper_dir(), type, iface, prt);
444
445         return 0;
446 }
447
448 static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un,
449                                int *bcast)
450 {
451         char type = '\0';
452         unsigned int prt;
453         unsigned int iface;
454         struct stat st;
455         int is_bcast = 0;
456
457         if (bcast) *bcast = 0;
458
459         switch (si->family) {
460         case AF_INET: {
461                 const struct sockaddr_in *in = 
462                     (const struct sockaddr_in *)inaddr;
463                 unsigned int addr = ntohl(in->sin_addr.s_addr);
464                 char u_type = '\0';
465                 char d_type = '\0';
466                 char b_type = '\0';
467                 char a_type = '\0';
468
469                 prt = ntohs(in->sin_port);
470
471                 switch (si->type) {
472                 case SOCK_STREAM:
473                         u_type = SOCKET_TYPE_CHAR_TCP;
474                         d_type = SOCKET_TYPE_CHAR_TCP;
475                         break;
476                 case SOCK_DGRAM:
477                         u_type = SOCKET_TYPE_CHAR_UDP;
478                         d_type = SOCKET_TYPE_CHAR_UDP;
479                         a_type = SOCKET_TYPE_CHAR_UDP;
480                         b_type = SOCKET_TYPE_CHAR_UDP;
481                         break;
482                 }
483
484                 if (addr == 0) {
485                         /* 0.0.0.0 */
486                         is_bcast = 0;
487                         type = d_type;
488                         iface = socket_wrapper_default_iface();
489                 } else if (a_type && addr == 0xFFFFFFFF) {
490                         /* 255.255.255.255 only udp */
491                         is_bcast = 2;
492                         type = a_type;
493                         iface = socket_wrapper_default_iface();
494                 } else if (b_type && addr == 0x7FFFFFFF) {
495                         /* 127.255.255.255 only udp */
496                         is_bcast = 1;
497                         type = b_type;
498                         iface = socket_wrapper_default_iface();
499                 } else if ((addr & 0xFFFFFF00) == 0x7F000000) {
500                         /* 127.0.0.X */
501                         is_bcast = 0;
502                         type = u_type;
503                         iface = (addr & 0x000000FF);
504                 } else {
505                         errno = EADDRNOTAVAIL;
506                         return -1;
507                 }
508                 break;
509         }
510 #ifdef HAVE_IPV6
511         case AF_INET6: {
512                 const struct sockaddr_in6 *in = 
513                     (const struct sockaddr_in6 *)inaddr;
514                 struct in6_addr cmp;
515
516                 switch (si->type) {
517                 case SOCK_STREAM:
518                         type = SOCKET_TYPE_CHAR_TCP_V6;
519                         break;
520                 case SOCK_DGRAM:
521                         type = SOCKET_TYPE_CHAR_UDP_V6;
522                         break;
523                 }
524
525                 /* XXX no multicast/broadcast */
526
527                 prt = ntohs(in->sin6_port);
528
529                 cmp = in->sin6_addr;
530                 cmp.s6_addr[15] = 0;
531                 if (IN6_IS_ADDR_UNSPECIFIED(&in->sin6_addr)) {
532                         iface = socket_wrapper_default_iface();
533                 } else if (IN6_ARE_ADDR_EQUAL(swrap_ipv6(), &cmp)) {
534                         iface = in->sin6_addr.s6_addr[15];
535                 } else {
536                         errno = EADDRNOTAVAIL;
537                         return -1;
538                 }
539
540                 break;
541         }
542 #endif
543         default:
544                 errno = EADDRNOTAVAIL;
545                 return -1;
546         }
547
548
549         if (bcast) *bcast = is_bcast;
550
551         if (prt == 0) {
552                 /* handle auto-allocation of ephemeral ports */
553                 for (prt = 5001; prt < 10000; prt++) {
554                         snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, 
555                                  socket_wrapper_dir(), type, iface, prt);
556                         if (stat(un->sun_path, &st) == 0) continue;
557
558                         set_port(si->family, prt, si->myname);
559                         break;
560                 }
561                 if (prt == 10000) {
562                         errno = ENFILE;
563                         return -1;
564                 }
565         }
566
567         snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, 
568                  socket_wrapper_dir(), type, iface, prt);
569         return 0;
570 }
571
572 static struct socket_info *find_socket_info(int fd)
573 {
574         struct socket_info *i;
575         for (i = sockets; i; i = i->next) {
576                 if (i->fd == fd) 
577                         return i;
578         }
579
580         return NULL;
581 }
582
583 static int sockaddr_convert_to_un(struct socket_info *si, const struct sockaddr *in_addr, socklen_t in_len, 
584                                   struct sockaddr_un *out_addr, int alloc_sock, int *bcast)
585 {
586         if (!out_addr)
587                 return 0;
588
589         out_addr->sun_family = AF_UNIX;
590
591         switch (in_addr->sa_family) {
592         case AF_INET:
593 #ifdef HAVE_IPV6
594         case AF_INET6:
595 #endif
596                 switch (si->type) {
597                 case SOCK_STREAM:
598                 case SOCK_DGRAM:
599                         break;
600                 default:
601                         errno = ESOCKTNOSUPPORT;
602                         return -1;
603                 }
604                 if (alloc_sock) {
605                         return convert_in_un_alloc(si, in_addr, out_addr, bcast);
606                 } else {
607                         return convert_in_un_remote(si, in_addr, out_addr, bcast);
608                 }
609         default:
610                 break;
611         }
612         
613         errno = EAFNOSUPPORT;
614         return -1;
615 }
616
617 static int sockaddr_convert_from_un(const struct socket_info *si, 
618                                     const struct sockaddr_un *in_addr, 
619                                     socklen_t un_addrlen,
620                                     int family,
621                                     struct sockaddr *out_addr,
622                                     socklen_t *out_addrlen)
623 {
624         if (out_addr == NULL || out_addrlen == NULL) 
625                 return 0;
626
627         if (un_addrlen == 0) {
628                 *out_addrlen = 0;
629                 return 0;
630         }
631
632         switch (family) {
633         case AF_INET:
634 #ifdef HAVE_IPV6
635         case AF_INET6:
636 #endif
637                 switch (si->type) {
638                 case SOCK_STREAM:
639                 case SOCK_DGRAM:
640                         break;
641                 default:
642                         errno = ESOCKTNOSUPPORT;
643                         return -1;
644                 }
645                 return convert_un_in(in_addr, out_addr, out_addrlen);
646         default:
647                 break;
648         }
649
650         errno = EAFNOSUPPORT;
651         return -1;
652 }
653
654 enum swrap_packet_type {
655         SWRAP_CONNECT_SEND,
656         SWRAP_CONNECT_UNREACH,
657         SWRAP_CONNECT_RECV,
658         SWRAP_CONNECT_ACK,
659         SWRAP_ACCEPT_SEND,
660         SWRAP_ACCEPT_RECV,
661         SWRAP_ACCEPT_ACK,
662         SWRAP_RECVFROM,
663         SWRAP_SENDTO,
664         SWRAP_SENDTO_UNREACH,
665         SWRAP_PENDING_RST,
666         SWRAP_RECV,
667         SWRAP_RECV_RST,
668         SWRAP_SEND,
669         SWRAP_SEND_RST,
670         SWRAP_CLOSE_SEND,
671         SWRAP_CLOSE_RECV,
672         SWRAP_CLOSE_ACK
673 };
674
675 struct swrap_file_hdr {
676         uint32_t        magic;
677         uint16_t        version_major;
678         uint16_t        version_minor;
679         int32_t         timezone;
680         uint32_t        sigfigs;
681         uint32_t        frame_max_len;
682 #define SWRAP_FRAME_LENGTH_MAX 0xFFFF
683         uint32_t        link_type;
684 };
685 #define SWRAP_FILE_HDR_SIZE 24
686
687 struct swrap_packet_frame {
688         uint32_t seconds;
689         uint32_t micro_seconds;
690         uint32_t recorded_length;
691         uint32_t full_length;
692 };
693 #define SWRAP_PACKET_FRAME_SIZE 16
694
695 union swrap_packet_ip {
696         struct {
697                 uint8_t         ver_hdrlen;
698                 uint8_t         tos;
699                 uint16_t        packet_length;
700                 uint16_t        identification;
701                 uint8_t         flags;
702                 uint8_t         fragment;
703                 uint8_t         ttl;
704                 uint8_t         protocol;
705                 uint16_t        hdr_checksum;
706                 uint32_t        src_addr;
707                 uint32_t        dest_addr;
708         } v4;
709 #define SWRAP_PACKET_IP_V4_SIZE 20
710         struct {
711                 uint8_t         ver_prio;
712                 uint8_t         flow_label_high;
713                 uint16_t        flow_label_low;
714                 uint16_t        payload_length;
715                 uint8_t         next_header;
716                 uint8_t         hop_limit;
717                 uint8_t         src_addr[16];
718                 uint8_t         dest_addr[16];
719         } v6;
720 #define SWRAP_PACKET_IP_V6_SIZE 40
721 };
722 #define SWRAP_PACKET_IP_SIZE 40
723
724 union swrap_packet_payload {
725         struct {
726                 uint16_t        source_port;
727                 uint16_t        dest_port;
728                 uint32_t        seq_num;
729                 uint32_t        ack_num;
730                 uint8_t         hdr_length;
731                 uint8_t         control;
732                 uint16_t        window;
733                 uint16_t        checksum;
734                 uint16_t        urg;
735         } tcp;
736 #define SWRAP_PACKET_PAYLOAD_TCP_SIZE 20
737         struct {
738                 uint16_t        source_port;
739                 uint16_t        dest_port;
740                 uint16_t        length;
741                 uint16_t        checksum;
742         } udp;
743 #define SWRAP_PACKET_PAYLOAD_UDP_SIZE 8
744         struct {
745                 uint8_t         type;
746                 uint8_t         code;
747                 uint16_t        checksum;
748                 uint32_t        unused;
749         } icmp4;
750 #define SWRAP_PACKET_PAYLOAD_ICMP4_SIZE 8
751         struct {
752                 uint8_t         type;
753                 uint8_t         code;
754                 uint16_t        checksum;
755                 uint32_t        unused;
756         } icmp6;
757 #define SWRAP_PACKET_PAYLOAD_ICMP6_SIZE 8
758 };
759 #define SWRAP_PACKET_PAYLOAD_SIZE 20
760
761 #define SWRAP_PACKET_MIN_ALLOC \
762         (SWRAP_PACKET_FRAME_SIZE + \
763          SWRAP_PACKET_IP_SIZE + \
764          SWRAP_PACKET_PAYLOAD_SIZE)
765
766 static const char *socket_wrapper_pcap_file(void)
767 {
768         static int initialized = 0;
769         static const char *s = NULL;
770         static const struct swrap_file_hdr h;
771         static const struct swrap_packet_frame f;
772         static const union swrap_packet_ip i;
773         static const union swrap_packet_payload p;
774
775         if (initialized == 1) {
776                 return s;
777         }
778         initialized = 1;
779
780         /*
781          * TODO: don't use the structs use plain buffer offsets
782          *       and PUSH_U8(), PUSH_U16() and PUSH_U32()
783          * 
784          * for now make sure we disable PCAP support
785          * if the struct has alignment!
786          */
787         if (sizeof(h) != SWRAP_FILE_HDR_SIZE) {
788                 return NULL;
789         }
790         if (sizeof(f) != SWRAP_PACKET_FRAME_SIZE) {
791                 return NULL;
792         }
793         if (sizeof(i) != SWRAP_PACKET_IP_SIZE) {
794                 return NULL;
795         }
796         if (sizeof(i.v4) != SWRAP_PACKET_IP_V4_SIZE) {
797                 return NULL;
798         }
799         if (sizeof(i.v6) != SWRAP_PACKET_IP_V6_SIZE) {
800                 return NULL;
801         }
802         if (sizeof(p) != SWRAP_PACKET_PAYLOAD_SIZE) {
803                 return NULL;
804         }
805         if (sizeof(p.tcp) != SWRAP_PACKET_PAYLOAD_TCP_SIZE) {
806                 return NULL;
807         }
808         if (sizeof(p.udp) != SWRAP_PACKET_PAYLOAD_UDP_SIZE) {
809                 return NULL;
810         }
811         if (sizeof(p.icmp4) != SWRAP_PACKET_PAYLOAD_ICMP4_SIZE) {
812                 return NULL;
813         }
814         if (sizeof(p.icmp6) != SWRAP_PACKET_PAYLOAD_ICMP6_SIZE) {
815                 return NULL;
816         }
817
818         s = getenv("SOCKET_WRAPPER_PCAP_FILE");
819         if (s == NULL) {
820                 return NULL;
821         }
822         if (strncmp(s, "./", 2) == 0) {
823                 s += 2;
824         }
825         return s;
826 }
827
828 static uint8_t *swrap_packet_init(struct timeval *tval,
829                                   const struct sockaddr *src,
830                                   const struct sockaddr *dest,
831                                   int socket_type,
832                                   const uint8_t *payload,
833                                   size_t payload_len,
834                                   unsigned long tcp_seqno,
835                                   unsigned long tcp_ack,
836                                   unsigned char tcp_ctl,
837                                   int unreachable,
838                                   size_t *_packet_len)
839 {
840         uint8_t *base;
841         uint8_t *buf;
842         struct swrap_packet_frame *frame;
843         union swrap_packet_ip *ip;
844         union swrap_packet_payload *pay;
845         size_t packet_len;
846         size_t alloc_len;
847         size_t nonwire_len = sizeof(*frame);
848         size_t wire_hdr_len = 0;
849         size_t wire_len = 0;
850         size_t ip_hdr_len = 0;
851         size_t icmp_hdr_len = 0;
852         size_t icmp_truncate_len = 0;
853         uint8_t protocol = 0, icmp_protocol = 0;
854         const struct sockaddr_in *src_in = NULL;
855         const struct sockaddr_in *dest_in = NULL;
856 #ifdef HAVE_IPV6
857         const struct sockaddr_in6 *src_in6 = NULL;
858         const struct sockaddr_in6 *dest_in6 = NULL;
859 #endif
860         uint16_t src_port;
861         uint16_t dest_port;
862
863         switch (src->sa_family) {
864         case AF_INET:
865                 src_in = (const struct sockaddr_in *)src;
866                 dest_in = (const struct sockaddr_in *)dest;
867                 src_port = src_in->sin_port;
868                 dest_port = dest_in->sin_port;
869                 ip_hdr_len = sizeof(ip->v4);
870                 break;
871 #ifdef HAVE_IPV6
872         case AF_INET6:
873                 src_in6 = (const struct sockaddr_in6 *)src;
874                 dest_in6 = (const struct sockaddr_in6 *)dest;
875                 src_port = src_in6->sin6_port;
876                 dest_port = dest_in6->sin6_port;
877                 ip_hdr_len = sizeof(ip->v6);
878                 break;
879 #endif
880         default:
881                 return NULL;
882         }
883
884         switch (socket_type) {
885         case SOCK_STREAM:
886                 protocol = 0x06; /* TCP */
887                 wire_hdr_len = ip_hdr_len + sizeof(pay->tcp);
888                 wire_len = wire_hdr_len + payload_len;
889                 break;
890
891         case SOCK_DGRAM:
892                 protocol = 0x11; /* UDP */
893                 wire_hdr_len = ip_hdr_len + sizeof(pay->udp);
894                 wire_len = wire_hdr_len + payload_len;
895                 break;
896
897         default:
898                 return NULL;
899         }
900
901         if (unreachable) {
902                 icmp_protocol = protocol;
903                 switch (src->sa_family) {
904                 case AF_INET:
905                         protocol = 0x01; /* ICMPv4 */
906                         icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp4);
907                         break;
908 #ifdef HAVE_IPV6
909                 case AF_INET6:
910                         protocol = 0x3A; /* ICMPv6 */
911                         icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp6);
912                         break;
913 #endif
914                 }
915                 if (wire_len > 64 ) {
916                         icmp_truncate_len = wire_len - 64;
917                 }
918                 wire_hdr_len += icmp_hdr_len;
919                 wire_len += icmp_hdr_len;
920         }
921
922         packet_len = nonwire_len + wire_len;
923         alloc_len = packet_len;
924         if (alloc_len < SWRAP_PACKET_MIN_ALLOC) {
925                 alloc_len = SWRAP_PACKET_MIN_ALLOC;
926         }
927
928         base = (uint8_t *)malloc(alloc_len);
929         if (!base) return NULL;
930
931         buf = base;
932
933         frame = (struct swrap_packet_frame *)buf;
934         frame->seconds          = tval->tv_sec;
935         frame->micro_seconds    = tval->tv_usec;
936         frame->recorded_length  = wire_len - icmp_truncate_len;
937         frame->full_length      = wire_len - icmp_truncate_len;
938         buf += SWRAP_PACKET_FRAME_SIZE;
939
940         ip = (union swrap_packet_ip *)buf;
941         switch (src->sa_family) {
942         case AF_INET:
943                 ip->v4.ver_hdrlen       = 0x45; /* version 4 and 5 * 32 bit words */
944                 ip->v4.tos              = 0x00;
945                 ip->v4.packet_length    = htons(wire_len - icmp_truncate_len);
946                 ip->v4.identification   = htons(0xFFFF);
947                 ip->v4.flags            = 0x40; /* BIT 1 set - means don't fraqment */
948                 ip->v4.fragment         = htons(0x0000);
949                 ip->v4.ttl              = 0xFF;
950                 ip->v4.protocol         = protocol;
951                 ip->v4.hdr_checksum     = htons(0x0000);
952                 ip->v4.src_addr         = src_in->sin_addr.s_addr;
953                 ip->v4.dest_addr        = dest_in->sin_addr.s_addr;
954                 buf += SWRAP_PACKET_IP_V4_SIZE;
955                 break;
956 #ifdef HAVE_IPV6
957         case AF_INET6:
958                 ip->v6.ver_prio         = 0x60; /* version 4 and 5 * 32 bit words */
959                 ip->v6.flow_label_high  = 0x00;
960                 ip->v6.flow_label_low   = 0x0000;
961                 ip->v6.payload_length   = htons(wire_len - icmp_truncate_len);//TODO
962                 ip->v6.next_header      = protocol;
963                 memcpy(ip->v6.src_addr, src_in6->sin6_addr.s6_addr, 16);
964                 memcpy(ip->v6.dest_addr, dest_in6->sin6_addr.s6_addr, 16);
965                 buf += SWRAP_PACKET_IP_V6_SIZE;
966                 break;
967 #endif
968         }
969
970         if (unreachable) {
971                 pay = (union swrap_packet_payload *)buf;
972                 switch (src->sa_family) {
973                 case AF_INET:
974                         pay->icmp4.type         = 0x03; /* destination unreachable */
975                         pay->icmp4.code         = 0x01; /* host unreachable */
976                         pay->icmp4.checksum     = htons(0x0000);
977                         pay->icmp4.unused       = htonl(0x00000000);
978                         buf += SWRAP_PACKET_PAYLOAD_ICMP4_SIZE;
979
980                         /* set the ip header in the ICMP payload */
981                         ip = (union swrap_packet_ip *)buf;
982                         ip->v4.ver_hdrlen       = 0x45; /* version 4 and 5 * 32 bit words */
983                         ip->v4.tos              = 0x00;
984                         ip->v4.packet_length    = htons(wire_len - icmp_hdr_len);
985                         ip->v4.identification   = htons(0xFFFF);
986                         ip->v4.flags            = 0x40; /* BIT 1 set - means don't fraqment */
987                         ip->v4.fragment         = htons(0x0000);
988                         ip->v4.ttl              = 0xFF;
989                         ip->v4.protocol         = icmp_protocol;
990                         ip->v4.hdr_checksum     = htons(0x0000);
991                         ip->v4.src_addr         = dest_in->sin_addr.s_addr;
992                         ip->v4.dest_addr        = src_in->sin_addr.s_addr;
993                         buf += SWRAP_PACKET_IP_V4_SIZE;
994
995                         src_port = dest_in->sin_port;
996                         dest_port = src_in->sin_port;
997                         break;
998 #ifdef HAVE_IPV6
999                 case AF_INET6:
1000                         pay->icmp6.type         = 0x01; /* destination unreachable */
1001                         pay->icmp6.code         = 0x03; /* address unreachable */
1002                         pay->icmp6.checksum     = htons(0x0000);
1003                         pay->icmp6.unused       = htonl(0x00000000);
1004                         buf += SWRAP_PACKET_PAYLOAD_ICMP6_SIZE;
1005
1006                         /* set the ip header in the ICMP payload */
1007                         ip = (union swrap_packet_ip *)buf;
1008                         ip->v6.ver_prio         = 0x60; /* version 4 and 5 * 32 bit words */
1009                         ip->v6.flow_label_high  = 0x00;
1010                         ip->v6.flow_label_low   = 0x0000;
1011                         ip->v6.payload_length   = htons(wire_len - icmp_truncate_len);//TODO
1012                         ip->v6.next_header      = protocol;
1013                         memcpy(ip->v6.src_addr, dest_in6->sin6_addr.s6_addr, 16);
1014                         memcpy(ip->v6.dest_addr, src_in6->sin6_addr.s6_addr, 16);
1015                         buf += SWRAP_PACKET_IP_V6_SIZE;
1016
1017                         src_port = dest_in6->sin6_port;
1018                         dest_port = src_in6->sin6_port;
1019                         break;
1020 #endif
1021                 }
1022         }
1023
1024         pay = (union swrap_packet_payload *)buf;
1025
1026         switch (socket_type) {
1027         case SOCK_STREAM:
1028                 pay->tcp.source_port    = src_port;
1029                 pay->tcp.dest_port      = dest_port;
1030                 pay->tcp.seq_num        = htonl(tcp_seqno);
1031                 pay->tcp.ack_num        = htonl(tcp_ack);
1032                 pay->tcp.hdr_length     = 0x50; /* 5 * 32 bit words */
1033                 pay->tcp.control        = tcp_ctl;
1034                 pay->tcp.window         = htons(0x7FFF);
1035                 pay->tcp.checksum       = htons(0x0000);
1036                 pay->tcp.urg            = htons(0x0000);
1037                 buf += SWRAP_PACKET_PAYLOAD_TCP_SIZE;
1038
1039                 break;
1040
1041         case SOCK_DGRAM:
1042                 pay->udp.source_port    = src_port;
1043                 pay->udp.dest_port      = dest_port;
1044                 pay->udp.length         = htons(8 + payload_len);
1045                 pay->udp.checksum       = htons(0x0000);
1046                 buf += SWRAP_PACKET_PAYLOAD_UDP_SIZE;
1047
1048                 break;
1049         }
1050
1051         if (payload && payload_len > 0) {
1052                 memcpy(buf, payload, payload_len);
1053         }
1054
1055         *_packet_len = packet_len - icmp_truncate_len;
1056         return base;
1057 }
1058
1059 static int swrap_get_pcap_fd(const char *fname)
1060 {
1061         static int fd = -1;
1062
1063         if (fd != -1) return fd;
1064
1065         fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0644);
1066         if (fd != -1) {
1067                 struct swrap_file_hdr file_hdr;
1068                 file_hdr.magic          = 0xA1B2C3D4;
1069                 file_hdr.version_major  = 0x0002;       
1070                 file_hdr.version_minor  = 0x0004;
1071                 file_hdr.timezone       = 0x00000000;
1072                 file_hdr.sigfigs        = 0x00000000;
1073                 file_hdr.frame_max_len  = SWRAP_FRAME_LENGTH_MAX;
1074                 file_hdr.link_type      = 0x0065; /* 101 RAW IP */
1075
1076                 if (write(fd, &file_hdr, sizeof(file_hdr)) != sizeof(file_hdr)) {
1077                         close(fd);
1078                         fd = -1;
1079                 }
1080                 return fd;
1081         }
1082
1083         fd = open(fname, O_WRONLY|O_APPEND, 0644);
1084
1085         return fd;
1086 }
1087
1088 static uint8_t *swrap_marshall_packet(struct socket_info *si,
1089                                       const struct sockaddr *addr,
1090                                       enum swrap_packet_type type,
1091                                       const void *buf, size_t len,
1092                                       size_t *packet_len)
1093 {
1094         const struct sockaddr *src_addr;
1095         const struct sockaddr *dest_addr;
1096         unsigned long tcp_seqno = 0;
1097         unsigned long tcp_ack = 0;
1098         unsigned char tcp_ctl = 0;
1099         int unreachable = 0;
1100
1101         struct timeval tv;
1102
1103         switch (si->family) {
1104         case AF_INET:
1105                 break;
1106 #ifdef HAVE_IPV6
1107         case AF_INET6:
1108                 break;
1109 #endif
1110         default:
1111                 return NULL;
1112         }
1113
1114         switch (type) {
1115         case SWRAP_CONNECT_SEND:
1116                 if (si->type != SOCK_STREAM) return NULL;
1117
1118                 src_addr = si->myname;
1119                 dest_addr = addr;
1120
1121                 tcp_seqno = si->io.pck_snd;
1122                 tcp_ack = si->io.pck_rcv;
1123                 tcp_ctl = 0x02; /* SYN */
1124
1125                 si->io.pck_snd += 1;
1126
1127                 break;
1128
1129         case SWRAP_CONNECT_RECV:
1130                 if (si->type != SOCK_STREAM) return NULL;
1131
1132                 dest_addr = si->myname;
1133                 src_addr = addr;
1134
1135                 tcp_seqno = si->io.pck_rcv;
1136                 tcp_ack = si->io.pck_snd;
1137                 tcp_ctl = 0x12; /** SYN,ACK */
1138
1139                 si->io.pck_rcv += 1;
1140
1141                 break;
1142
1143         case SWRAP_CONNECT_UNREACH:
1144                 if (si->type != SOCK_STREAM) return NULL;
1145
1146                 dest_addr = si->myname;
1147                 src_addr = addr;
1148
1149                 /* Unreachable: resend the data of SWRAP_CONNECT_SEND */
1150                 tcp_seqno = si->io.pck_snd - 1;
1151                 tcp_ack = si->io.pck_rcv;
1152                 tcp_ctl = 0x02; /* SYN */
1153                 unreachable = 1;
1154
1155                 break;
1156
1157         case SWRAP_CONNECT_ACK:
1158                 if (si->type != SOCK_STREAM) return NULL;
1159
1160                 src_addr = si->myname;
1161                 dest_addr = addr;
1162
1163                 tcp_seqno = si->io.pck_snd;
1164                 tcp_ack = si->io.pck_rcv;
1165                 tcp_ctl = 0x10; /* ACK */
1166
1167                 break;
1168
1169         case SWRAP_ACCEPT_SEND:
1170                 if (si->type != SOCK_STREAM) return NULL;
1171
1172                 dest_addr = si->myname;
1173                 src_addr = addr;
1174
1175                 tcp_seqno = si->io.pck_rcv;
1176                 tcp_ack = si->io.pck_snd;
1177                 tcp_ctl = 0x02; /* SYN */
1178
1179                 si->io.pck_rcv += 1;
1180
1181                 break;
1182
1183         case SWRAP_ACCEPT_RECV:
1184                 if (si->type != SOCK_STREAM) return NULL;
1185
1186                 src_addr = si->myname;
1187                 dest_addr = addr;
1188
1189                 tcp_seqno = si->io.pck_snd;
1190                 tcp_ack = si->io.pck_rcv;
1191                 tcp_ctl = 0x12; /* SYN,ACK */
1192
1193                 si->io.pck_snd += 1;
1194
1195                 break;
1196
1197         case SWRAP_ACCEPT_ACK:
1198                 if (si->type != SOCK_STREAM) return NULL;
1199
1200                 dest_addr = si->myname;
1201                 src_addr = addr;
1202
1203                 tcp_seqno = si->io.pck_rcv;
1204                 tcp_ack = si->io.pck_snd;
1205                 tcp_ctl = 0x10; /* ACK */
1206
1207                 break;
1208
1209         case SWRAP_SEND:
1210                 src_addr = si->myname;
1211                 dest_addr = si->peername;
1212
1213                 tcp_seqno = si->io.pck_snd;
1214                 tcp_ack = si->io.pck_rcv;
1215                 tcp_ctl = 0x18; /* PSH,ACK */
1216
1217                 si->io.pck_snd += len;
1218
1219                 break;
1220
1221         case SWRAP_SEND_RST:
1222                 dest_addr = si->myname;
1223                 src_addr = si->peername;
1224
1225                 if (si->type == SOCK_DGRAM) {
1226                         return swrap_marshall_packet(si, si->peername,
1227                                           SWRAP_SENDTO_UNREACH,
1228                                           buf, len, packet_len);
1229                 }
1230
1231                 tcp_seqno = si->io.pck_rcv;
1232                 tcp_ack = si->io.pck_snd;
1233                 tcp_ctl = 0x14; /** RST,ACK */
1234
1235                 break;
1236
1237         case SWRAP_PENDING_RST:
1238                 dest_addr = si->myname;
1239                 src_addr = si->peername;
1240
1241                 if (si->type == SOCK_DGRAM) {
1242                         return NULL;
1243                 }
1244
1245                 tcp_seqno = si->io.pck_rcv;
1246                 tcp_ack = si->io.pck_snd;
1247                 tcp_ctl = 0x14; /* RST,ACK */
1248
1249                 break;
1250
1251         case SWRAP_RECV:
1252                 dest_addr = si->myname;
1253                 src_addr = si->peername;
1254
1255                 tcp_seqno = si->io.pck_rcv;
1256                 tcp_ack = si->io.pck_snd;
1257                 tcp_ctl = 0x18; /* PSH,ACK */
1258
1259                 si->io.pck_rcv += len;
1260
1261                 break;
1262
1263         case SWRAP_RECV_RST:
1264                 dest_addr = si->myname;
1265                 src_addr = si->peername;
1266
1267                 if (si->type == SOCK_DGRAM) {
1268                         return NULL;
1269                 }
1270
1271                 tcp_seqno = si->io.pck_rcv;
1272                 tcp_ack = si->io.pck_snd;
1273                 tcp_ctl = 0x14; /* RST,ACK */
1274
1275                 break;
1276
1277         case SWRAP_SENDTO:
1278                 src_addr = si->myname;
1279                 dest_addr = addr;
1280
1281                 si->io.pck_snd += len;
1282
1283                 break;
1284
1285         case SWRAP_SENDTO_UNREACH:
1286                 dest_addr = si->myname;
1287                 src_addr = addr;
1288
1289                 unreachable = 1;
1290
1291                 break;
1292
1293         case SWRAP_RECVFROM:
1294                 dest_addr = si->myname;
1295                 src_addr = addr;
1296
1297                 si->io.pck_rcv += len;
1298
1299                 break;
1300
1301         case SWRAP_CLOSE_SEND:
1302                 if (si->type != SOCK_STREAM) return NULL;
1303
1304                 src_addr = si->myname;
1305                 dest_addr = si->peername;
1306
1307                 tcp_seqno = si->io.pck_snd;
1308                 tcp_ack = si->io.pck_rcv;
1309                 tcp_ctl = 0x11; /* FIN, ACK */
1310
1311                 si->io.pck_snd += 1;
1312
1313                 break;
1314
1315         case SWRAP_CLOSE_RECV:
1316                 if (si->type != SOCK_STREAM) return NULL;
1317
1318                 dest_addr = si->myname;
1319                 src_addr = si->peername;
1320
1321                 tcp_seqno = si->io.pck_rcv;
1322                 tcp_ack = si->io.pck_snd;
1323                 tcp_ctl = 0x11; /* FIN,ACK */
1324
1325                 si->io.pck_rcv += 1;
1326
1327                 break;
1328
1329         case SWRAP_CLOSE_ACK:
1330                 if (si->type != SOCK_STREAM) return NULL;
1331
1332                 src_addr = si->myname;
1333                 dest_addr = si->peername;
1334
1335                 tcp_seqno = si->io.pck_snd;
1336                 tcp_ack = si->io.pck_rcv;
1337                 tcp_ctl = 0x10; /* ACK */
1338
1339                 break;
1340         default:
1341                 return NULL;
1342         }
1343
1344         swrapGetTimeOfDay(&tv);
1345
1346         return swrap_packet_init(&tv, src_addr, dest_addr, si->type,
1347                                  (const uint8_t *)buf, len,
1348                                  tcp_seqno, tcp_ack, tcp_ctl, unreachable,
1349                                  packet_len);
1350 }
1351
1352 static void swrap_dump_packet(struct socket_info *si,
1353                               const struct sockaddr *addr,
1354                               enum swrap_packet_type type,
1355                               const void *buf, size_t len)
1356 {
1357         const char *file_name;
1358         uint8_t *packet;
1359         size_t packet_len = 0;
1360         int fd;
1361
1362         file_name = socket_wrapper_pcap_file();
1363         if (!file_name) {
1364                 return;
1365         }
1366
1367         packet = swrap_marshall_packet(si, addr, type, buf, len, &packet_len);
1368         if (!packet) {
1369                 return;
1370         }
1371
1372         fd = swrap_get_pcap_fd(file_name);
1373         if (fd != -1) {
1374                 if (write(fd, packet, packet_len) != packet_len) {
1375                         free(packet);
1376                         return;
1377                 }
1378         }
1379
1380         free(packet);
1381 }
1382
1383 _PUBLIC_ int swrap_socket(int family, int type, int protocol)
1384 {
1385         struct socket_info *si;
1386         int fd;
1387
1388         if (!socket_wrapper_dir()) {
1389                 return real_socket(family, type, protocol);
1390         }
1391
1392         switch (family) {
1393         case AF_INET:
1394 #ifdef HAVE_IPV6
1395         case AF_INET6:
1396 #endif
1397                 break;
1398         case AF_UNIX:
1399                 return real_socket(family, type, protocol);
1400         default:
1401                 errno = EAFNOSUPPORT;
1402                 return -1;
1403         }
1404
1405         switch (type) {
1406         case SOCK_STREAM:
1407                 break;
1408         case SOCK_DGRAM:
1409                 break;
1410         default:
1411                 errno = EPROTONOSUPPORT;
1412                 return -1;
1413         }
1414
1415         switch (protocol) {
1416         case 0:
1417                 break;
1418         case 6:
1419                 if (type == SOCK_STREAM) {
1420                         break;
1421                 }
1422                 /*fall through*/
1423         case 17:
1424                 if (type == SOCK_DGRAM) {
1425                         break;
1426                 }
1427                 /*fall through*/
1428         default:
1429                 errno = EPROTONOSUPPORT;
1430                 return -1;
1431         }
1432
1433         fd = real_socket(AF_UNIX, type, 0);
1434
1435         if (fd == -1) return -1;
1436
1437         si = (struct socket_info *)calloc(1, sizeof(struct socket_info));
1438
1439         si->family = family;
1440         si->type = type;
1441         si->protocol = protocol;
1442         si->fd = fd;
1443
1444         SWRAP_DLIST_ADD(sockets, si);
1445
1446         return si->fd;
1447 }
1448
1449 _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
1450 {
1451         struct socket_info *parent_si, *child_si;
1452         int fd;
1453         struct sockaddr_un un_addr;
1454         socklen_t un_addrlen = sizeof(un_addr);
1455         struct sockaddr_un un_my_addr;
1456         socklen_t un_my_addrlen = sizeof(un_my_addr);
1457         struct sockaddr *my_addr;
1458         socklen_t my_addrlen, len;
1459         int ret;
1460
1461         parent_si = find_socket_info(s);
1462         if (!parent_si) {
1463                 return real_accept(s, addr, addrlen);
1464         }
1465
1466         /* 
1467          * assume out sockaddr have the same size as the in parent
1468          * socket family
1469          */
1470         my_addrlen = socket_length(parent_si->family);
1471         if (my_addrlen <= 0) {
1472                 errno = EINVAL;
1473                 return -1;
1474         }
1475
1476         my_addr = (struct sockaddr *)malloc(my_addrlen);
1477         if (my_addr == NULL) {
1478                 return -1;
1479         }
1480
1481         memset(&un_addr, 0, sizeof(un_addr));
1482         memset(&un_my_addr, 0, sizeof(un_my_addr));
1483
1484         ret = real_accept(s, (struct sockaddr *)&un_addr, &un_addrlen);
1485         if (ret == -1) {
1486                 free(my_addr);
1487                 return ret;
1488         }
1489
1490         fd = ret;
1491
1492         len = my_addrlen;
1493         ret = sockaddr_convert_from_un(parent_si, &un_addr, un_addrlen,
1494                                        parent_si->family, my_addr, &len);
1495         if (ret == -1) {
1496                 free(my_addr);
1497                 close(fd);
1498                 return ret;
1499         }
1500
1501         child_si = (struct socket_info *)malloc(sizeof(struct socket_info));
1502         memset(child_si, 0, sizeof(*child_si));
1503
1504         child_si->fd = fd;
1505         child_si->family = parent_si->family;
1506         child_si->type = parent_si->type;
1507         child_si->protocol = parent_si->protocol;
1508         child_si->bound = 1;
1509         child_si->is_server = 1;
1510         child_si->connected = 1;
1511
1512         child_si->peername_len = len;
1513         child_si->peername = sockaddr_dup(my_addr, len);
1514
1515         if (addr != NULL && addrlen != NULL) {
1516             *addrlen = len;
1517             if (*addrlen >= len)
1518                 memcpy(addr, my_addr, len);
1519             *addrlen = 0;
1520         }
1521
1522         ret = real_getsockname(fd, (struct sockaddr *)&un_my_addr, &un_my_addrlen);
1523         if (ret == -1) {
1524                 free(child_si);
1525                 close(fd);
1526                 return ret;
1527         }
1528
1529         len = my_addrlen;
1530         ret = sockaddr_convert_from_un(child_si, &un_my_addr, un_my_addrlen,
1531                                        child_si->family, my_addr, &len);
1532         if (ret == -1) {
1533                 free(child_si);
1534                 free(my_addr);
1535                 close(fd);
1536                 return ret;
1537         }
1538
1539         child_si->myname_len = len;
1540         child_si->myname = sockaddr_dup(my_addr, len);
1541         free(my_addr);
1542
1543         SWRAP_DLIST_ADD(sockets, child_si);
1544
1545         swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0);
1546         swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_RECV, NULL, 0);
1547         swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_ACK, NULL, 0);
1548
1549         return fd;
1550 }
1551
1552 static int autobind_start_init;
1553 static int autobind_start;
1554
1555 /* using sendto() or connect() on an unbound socket would give the
1556    recipient no way to reply, as unlike UDP and TCP, a unix domain
1557    socket can't auto-assign emphemeral port numbers, so we need to
1558    assign it here.
1559    Note: this might change the family from ipv6 to ipv4
1560 */
1561 static int swrap_auto_bind(struct socket_info *si, int family)
1562 {
1563         struct sockaddr_un un_addr;
1564         int i;
1565         char type;
1566         int ret;
1567         int port;
1568         struct stat st;
1569
1570         if (autobind_start_init != 1) {
1571                 autobind_start_init = 1;
1572                 autobind_start = getpid();
1573                 autobind_start %= 50000;
1574                 autobind_start += 10000;
1575         }
1576
1577         un_addr.sun_family = AF_UNIX;
1578
1579         switch (family) {
1580         case AF_INET: {
1581                 struct sockaddr_in in;
1582
1583                 switch (si->type) {
1584                 case SOCK_STREAM:
1585                         type = SOCKET_TYPE_CHAR_TCP;
1586                         break;
1587                 case SOCK_DGRAM:
1588                         type = SOCKET_TYPE_CHAR_UDP;
1589                         break;
1590                 default:
1591                     errno = ESOCKTNOSUPPORT;
1592                     return -1;
1593                 }
1594
1595                 memset(&in, 0, sizeof(in));
1596                 in.sin_family = AF_INET;
1597                 in.sin_addr.s_addr = htonl(127<<24 | 
1598                                            socket_wrapper_default_iface());
1599
1600                 si->myname_len = sizeof(in);
1601                 si->myname = sockaddr_dup(&in, si->myname_len);
1602                 break;
1603         }
1604 #ifdef HAVE_IPV6
1605         case AF_INET6: {
1606                 struct sockaddr_in6 in6;
1607
1608                 if (si->family != family) {
1609                         errno = ENETUNREACH;
1610                         return -1;
1611                 }
1612
1613                 switch (si->type) {
1614                 case SOCK_STREAM:
1615                         type = SOCKET_TYPE_CHAR_TCP_V6;
1616                         break;
1617                 case SOCK_DGRAM:
1618                         type = SOCKET_TYPE_CHAR_UDP_V6;
1619                         break;
1620                 default:
1621                         errno = ESOCKTNOSUPPORT;
1622                         return -1;
1623                 }
1624
1625                 memset(&in6, 0, sizeof(in6));
1626                 in6.sin6_family = AF_INET6;
1627                 in6.sin6_addr = *swrap_ipv6();
1628                 in6.sin6_addr.s6_addr[15] = socket_wrapper_default_iface();
1629                 si->myname_len = sizeof(in6);
1630                 si->myname = sockaddr_dup(&in6, si->myname_len);
1631                 break;
1632         }
1633 #endif
1634         default:
1635                 errno = ESOCKTNOSUPPORT;
1636                 return -1;
1637         }
1638
1639         if (autobind_start > 60000) {
1640                 autobind_start = 10000;
1641         }
1642
1643         for (i=0;i<1000;i++) {
1644                 port = autobind_start + i;
1645                 snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), 
1646                          "%s/"SOCKET_FORMAT, socket_wrapper_dir(),
1647                          type, socket_wrapper_default_iface(), port);
1648                 if (stat(un_addr.sun_path, &st) == 0) continue;
1649                 
1650                 ret = real_bind(si->fd, (struct sockaddr *)&un_addr, sizeof(un_addr));
1651                 if (ret == -1) return ret;
1652
1653                 si->tmp_path = strdup(un_addr.sun_path);
1654                 si->bound = 1;
1655                 autobind_start = port + 1;
1656                 break;
1657         }
1658         if (i == 1000) {
1659                 errno = ENFILE;
1660                 return -1;
1661         }
1662
1663         si->family = family;
1664         set_port(si->family, port, si->myname);
1665
1666         return 0;
1667 }
1668
1669
1670 _PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen)
1671 {
1672         int ret;
1673         struct sockaddr_un un_addr;
1674         struct socket_info *si = find_socket_info(s);
1675
1676         if (!si) {
1677                 return real_connect(s, serv_addr, addrlen);
1678         }
1679
1680         if (si->bound == 0) {
1681                 ret = swrap_auto_bind(si, serv_addr->sa_family);
1682                 if (ret == -1) return -1;
1683         }
1684
1685         if (si->family != serv_addr->sa_family) {
1686                 errno = EINVAL;
1687                 return -1;
1688         }
1689
1690         ret = sockaddr_convert_to_un(si, (const struct sockaddr *)serv_addr, addrlen, &un_addr, 0, NULL);
1691         if (ret == -1) return -1;
1692
1693         if (si->type == SOCK_DGRAM) {
1694                 si->defer_connect = 1;
1695                 ret = 0;
1696         } else {
1697                 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0);
1698
1699                 ret = real_connect(s, (struct sockaddr *)&un_addr,
1700                                    sizeof(struct sockaddr_un));
1701         }
1702
1703         /* to give better errors */
1704         if (ret == -1 && errno == ENOENT) {
1705                 errno = EHOSTUNREACH;
1706         }
1707
1708         if (ret == 0) {
1709                 si->peername_len = addrlen;
1710                 si->peername = sockaddr_dup(serv_addr, addrlen);
1711                 si->connected = 1;
1712
1713                 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0);
1714                 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0);
1715         } else {
1716                 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0);
1717         }
1718
1719         return ret;
1720 }
1721
1722 _PUBLIC_ int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
1723 {
1724         int ret;
1725         struct sockaddr_un un_addr;
1726         struct socket_info *si = find_socket_info(s);
1727
1728         if (!si) {
1729                 return real_bind(s, myaddr, addrlen);
1730         }
1731
1732         si->myname_len = addrlen;
1733         si->myname = sockaddr_dup(myaddr, addrlen);
1734
1735         ret = sockaddr_convert_to_un(si, (const struct sockaddr *)myaddr, addrlen, &un_addr, 1, &si->bcast);
1736         if (ret == -1) return -1;
1737
1738         unlink(un_addr.sun_path);
1739
1740         ret = real_bind(s, (struct sockaddr *)&un_addr,
1741                         sizeof(struct sockaddr_un));
1742
1743         if (ret == 0) {
1744                 si->bound = 1;
1745         }
1746
1747         return ret;
1748 }
1749
1750 _PUBLIC_ int swrap_listen(int s, int backlog)
1751 {
1752         int ret;
1753         struct socket_info *si = find_socket_info(s);
1754
1755         if (!si) {
1756                 return real_listen(s, backlog);
1757         }
1758
1759         ret = real_listen(s, backlog);
1760
1761         return ret;
1762 }
1763
1764 _PUBLIC_ int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
1765 {
1766         struct socket_info *si = find_socket_info(s);
1767
1768         if (!si) {
1769                 return real_getpeername(s, name, addrlen);
1770         }
1771
1772         if (!si->peername)
1773         {
1774                 errno = ENOTCONN;
1775                 return -1;
1776         }
1777
1778         memcpy(name, si->peername, si->peername_len);
1779         *addrlen = si->peername_len;
1780
1781         return 0;
1782 }
1783
1784 _PUBLIC_ int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
1785 {
1786         struct socket_info *si = find_socket_info(s);
1787
1788         if (!si) {
1789                 return real_getsockname(s, name, addrlen);
1790         }
1791
1792         memcpy(name, si->myname, si->myname_len);
1793         *addrlen = si->myname_len;
1794
1795         return 0;
1796 }
1797
1798 _PUBLIC_ int swrap_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
1799 {
1800         struct socket_info *si = find_socket_info(s);
1801
1802         if (!si) {
1803                 return real_getsockopt(s, level, optname, optval, optlen);
1804         }
1805
1806         if (level == SOL_SOCKET) {
1807                 return real_getsockopt(s, level, optname, optval, optlen);
1808         } 
1809
1810         errno = ENOPROTOOPT;
1811         return -1;
1812 }
1813
1814 _PUBLIC_ int swrap_setsockopt(int s, int  level,  int  optname,  const  void  *optval, socklen_t optlen)
1815 {
1816         struct socket_info *si = find_socket_info(s);
1817
1818         if (!si) {
1819                 return real_setsockopt(s, level, optname, optval, optlen);
1820         }
1821
1822         if (level == SOL_SOCKET) {
1823                 return real_setsockopt(s, level, optname, optval, optlen);
1824         }
1825
1826         switch (si->family) {
1827         case AF_INET:
1828                 return 0;
1829         default:
1830                 errno = ENOPROTOOPT;
1831                 return -1;
1832         }
1833 }
1834
1835 _PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
1836 {
1837         struct sockaddr_un un_addr;
1838         socklen_t un_addrlen = sizeof(un_addr);
1839         int ret;
1840         struct socket_info *si = find_socket_info(s);
1841         struct sockaddr_storage ss;
1842         socklen_t ss_len = sizeof(ss);
1843
1844         if (!si) {
1845                 return real_recvfrom(s, buf, len, flags, from, fromlen);
1846         }
1847
1848         if (!from) {
1849                 from = (struct sockaddr *)&ss;
1850                 fromlen = &ss_len;
1851         }
1852
1853         len = MIN(len, 1500);
1854
1855         /* irix 6.4 forgets to null terminate the sun_path string :-( */
1856         memset(&un_addr, 0, sizeof(un_addr));
1857         ret = real_recvfrom(s, buf, len, flags, (struct sockaddr *)&un_addr, &un_addrlen);
1858         if (ret == -1) 
1859                 return ret;
1860
1861         if (sockaddr_convert_from_un(si, &un_addr, un_addrlen,
1862                                      si->family, from, fromlen) == -1) {
1863                 return -1;
1864         }
1865
1866         swrap_dump_packet(si, from, SWRAP_RECVFROM, buf, ret);
1867
1868         return ret;
1869 }
1870
1871
1872 _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
1873 {
1874         struct sockaddr_un un_addr;
1875         int ret;
1876         struct socket_info *si = find_socket_info(s);
1877         int bcast = 0;
1878
1879         if (!si) {
1880                 return real_sendto(s, buf, len, flags, to, tolen);
1881         }
1882
1883         if (si->connected) {
1884                 if (to) {
1885                         errno = EISCONN;
1886                         return -1;
1887                 }
1888
1889                 to = si->peername;
1890                 tolen = si->peername_len;
1891         }
1892
1893         len = MIN(len, 1500);
1894
1895         switch (si->type) {
1896         case SOCK_STREAM:
1897                 ret = real_send(s, buf, len, flags);
1898                 break;
1899         case SOCK_DGRAM:
1900                 if (si->bound == 0) {
1901                         ret = swrap_auto_bind(si, si->family);
1902                         if (ret == -1) return -1;
1903                 }
1904                 
1905                 ret = sockaddr_convert_to_un(si, to, tolen, &un_addr, 0, &bcast);
1906                 if (ret == -1) return -1;
1907                 
1908                 if (bcast) {
1909                         struct stat st;
1910                         unsigned int iface;
1911                         unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port);
1912                         char type;
1913                         
1914                         type = SOCKET_TYPE_CHAR_UDP;
1915                         
1916                         for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
1917                                 snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT, 
1918                                          socket_wrapper_dir(), type, iface, prt);
1919                                 if (stat(un_addr.sun_path, &st) != 0) continue;
1920                                 
1921                                 /* ignore the any errors in broadcast sends */
1922                                 real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr));
1923                         }
1924                         
1925                         swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
1926                         
1927                         return len;
1928                 }
1929
1930                 if (si->defer_connect) {
1931                         ret = real_connect(s, (struct sockaddr *)&un_addr,
1932                                            sizeof(un_addr));
1933
1934                         /* to give better errors */
1935                         if (ret == -1 && errno == ENOENT) {
1936                                 errno = EHOSTUNREACH;
1937                         }
1938
1939                         if (ret == -1) {
1940                                 return ret;
1941                         }
1942                         si->defer_connect = 0;
1943                 }
1944
1945                 ret = real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr));
1946                 break;
1947         default:
1948                 ret = -1;
1949                 errno = EHOSTUNREACH;
1950                 break;
1951         }
1952                 
1953         /* to give better errors */
1954         if (ret == -1 && errno == ENOENT) {
1955                 errno = EHOSTUNREACH;
1956         }
1957
1958         if (ret == -1) {
1959                 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
1960                 swrap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);
1961         } else {
1962                 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, ret);
1963         }
1964
1965         return ret;
1966 }
1967
1968 _PUBLIC_ int swrap_ioctl(int s, int r, void *p)
1969 {
1970         int ret;
1971         struct socket_info *si = find_socket_info(s);
1972         int value;
1973
1974         if (!si) {
1975                 return real_ioctl(s, r, p);
1976         }
1977
1978         ret = real_ioctl(s, r, p);
1979
1980         switch (r) {
1981         case FIONREAD:
1982                 value = *((int *)p);
1983                 if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
1984                         swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
1985                 } else if (value == 0) { /* END OF FILE */
1986                         swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
1987                 }
1988                 break;
1989         }
1990
1991         return ret;
1992 }
1993
1994 _PUBLIC_ ssize_t swrap_recv(int s, void *buf, size_t len, int flags)
1995 {
1996         int ret;
1997         struct socket_info *si = find_socket_info(s);
1998
1999         if (!si) {
2000                 return real_recv(s, buf, len, flags);
2001         }
2002
2003         len = MIN(len, 1500);
2004
2005         ret = real_recv(s, buf, len, flags);
2006         if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
2007                 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
2008         } else if (ret == 0) { /* END OF FILE */
2009                 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
2010         } else if (ret > 0) {
2011                 swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
2012         }
2013
2014         return ret;
2015 }
2016
2017
2018 _PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
2019 {
2020         int ret;
2021         struct socket_info *si = find_socket_info(s);
2022
2023         if (!si) {
2024                 return real_send(s, buf, len, flags);
2025         }
2026
2027         len = MIN(len, 1500);
2028
2029         if (si->defer_connect) {
2030                 struct sockaddr_un un_addr;
2031                 int bcast = 0;
2032
2033                 if (si->bound == 0) {
2034                         ret = swrap_auto_bind(si, si->family);
2035                         if (ret == -1) return -1;
2036                 }
2037
2038                 ret = sockaddr_convert_to_un(si, si->peername, si->peername_len,
2039                                              &un_addr, 0, &bcast);
2040                 if (ret == -1) return -1;
2041
2042                 ret = real_connect(s, (struct sockaddr *)&un_addr,
2043                                    sizeof(un_addr));
2044
2045                 /* to give better errors */
2046                 if (ret == -1 && errno == ENOENT) {
2047                         errno = EHOSTUNREACH;
2048                 }
2049
2050                 if (ret == -1) {
2051                         return ret;
2052                 }
2053                 si->defer_connect = 0;
2054         }
2055
2056         ret = real_send(s, buf, len, flags);
2057
2058         if (ret == -1) {
2059                 swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
2060                 swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
2061         } else {
2062                 swrap_dump_packet(si, NULL, SWRAP_SEND, buf, ret);
2063         }
2064
2065         return ret;
2066 }
2067
2068 _PUBLIC_ ssize_t swrap_sendmsg(int s, const struct msghdr *msg, int flags)
2069 {
2070         int ret;
2071         uint8_t *buf;
2072         off_t ofs = 0;
2073         size_t i;
2074         size_t remain;
2075         
2076         struct socket_info *si = find_socket_info(s);
2077
2078         if (!si) {
2079                 return real_sendmsg(s, msg, flags);
2080         }
2081
2082         if (si->defer_connect) {
2083                 struct sockaddr_un un_addr;
2084                 int bcast = 0;
2085
2086                 if (si->bound == 0) {
2087                         ret = swrap_auto_bind(si, si->family);
2088                         if (ret == -1) return -1;
2089                 }
2090
2091                 ret = sockaddr_convert_to_un(si, si->peername, si->peername_len,
2092                                              &un_addr, 0, &bcast);
2093                 if (ret == -1) return -1;
2094
2095                 ret = real_connect(s, (struct sockaddr *)&un_addr,
2096                                    sizeof(un_addr));
2097
2098                 /* to give better errors */
2099                 if (ret == -1 && errno == ENOENT) {
2100                         errno = EHOSTUNREACH;
2101                 }
2102
2103                 if (ret == -1) {
2104                         return ret;
2105                 }
2106                 si->defer_connect = 0;
2107         }
2108
2109         ret = real_sendmsg(s, msg, flags);
2110         remain = ret;
2111                 
2112         /* we capture it as one single packet */
2113         buf = (uint8_t *)malloc(ret);
2114         if (!buf) {
2115                 /* we just not capture the packet */
2116                 errno = 0;
2117                 return ret;
2118         }
2119         
2120         for (i=0; i < msg->msg_iovlen; i++) {
2121                 size_t this_time = MIN(remain, msg->msg_iov[i].iov_len);
2122                 memcpy(buf + ofs,
2123                        msg->msg_iov[i].iov_base,
2124                        this_time);
2125                 ofs += this_time;
2126                 remain -= this_time;
2127         }
2128         
2129         swrap_dump_packet(si, NULL, SWRAP_SEND, buf, ret);
2130         free(buf);
2131         if (ret == -1) {
2132                 swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
2133         }
2134
2135         return ret;
2136 }
2137
2138 int swrap_readv(int s, const struct iovec *vector, size_t count)
2139 {
2140         int ret;
2141         struct socket_info *si = find_socket_info(s);
2142         struct iovec v;
2143
2144         if (!si) {
2145                 return real_readv(s, vector, count);
2146         }
2147
2148         /* we read 1500 bytes as maximum */
2149         if (count > 0) {
2150                 size_t i, len = 0;
2151
2152                 for (i=0; i < count; i++) {
2153                         size_t nlen;
2154                         nlen = len + vector[i].iov_len;
2155                         if (nlen > 1500) {
2156                                 break;
2157                         }
2158                 }
2159                 count = i;
2160                 if (count == 0) {
2161                         v = vector[0];
2162                         v.iov_len = MIN(v.iov_len, 1500);
2163                         vector = &v;
2164                         count = 1;
2165                 }
2166         }
2167
2168         ret = real_readv(s, vector, count);
2169         if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
2170                 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
2171         } else if (ret == 0) { /* END OF FILE */
2172                 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
2173         } else if (ret > 0) {
2174                 uint8_t *buf;
2175                 off_t ofs = 0;
2176                 size_t i;
2177                 size_t remain = ret;
2178
2179                 /* we capture it as one single packet */
2180                 buf = (uint8_t *)malloc(ret);
2181                 if (!buf) {
2182                         /* we just not capture the packet */
2183                         errno = 0;
2184                         return ret;
2185                 }
2186
2187                 for (i=0; i < count; i++) {
2188                         size_t this_time = MIN(remain, vector[i].iov_len);
2189                         memcpy(buf + ofs,
2190                                vector[i].iov_base,
2191                                this_time);
2192                         ofs += this_time;
2193                         remain -= this_time;
2194                 }
2195
2196                 swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
2197                 free(buf);
2198         }
2199
2200         return ret;
2201 }
2202
2203 int swrap_writev(int s, const struct iovec *vector, size_t count)
2204 {
2205         int ret;
2206         struct socket_info *si = find_socket_info(s);
2207         struct iovec v;
2208
2209         if (!si) {
2210                 return real_writev(s, vector, count);
2211         }
2212
2213         /* we write 1500 bytes as maximum */
2214         if (count > 0) {
2215                 size_t i, len = 0;
2216
2217                 for (i=0; i < count; i++) {
2218                         size_t nlen;
2219                         nlen = len + vector[i].iov_len;
2220                         if (nlen > 1500) {
2221                                 break;
2222                         }
2223                 }
2224                 count = i;
2225                 if (count == 0) {
2226                         v = vector[0];
2227                         v.iov_len = MIN(v.iov_len, 1500);
2228                         vector = &v;
2229                         count = 1;
2230                 }
2231         }
2232
2233         ret = real_writev(s, vector, count);
2234         if (ret == -1) {
2235                 swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
2236         } else {
2237                 uint8_t *buf;
2238                 off_t ofs = 0;
2239                 size_t i;
2240                 size_t remain = ret;
2241
2242                 /* we capture it as one single packet */
2243                 buf = (uint8_t *)malloc(ret);
2244                 if (!buf) {
2245                         /* we just not capture the packet */
2246                         errno = 0;
2247                         return ret;
2248                 }
2249
2250                 for (i=0; i < count; i++) {
2251                         size_t this_time = MIN(remain, vector[i].iov_len);
2252                         memcpy(buf + ofs,
2253                                vector[i].iov_base,
2254                                this_time);
2255                         ofs += this_time;
2256                         remain -= this_time;
2257                 }
2258
2259                 swrap_dump_packet(si, NULL, SWRAP_SEND, buf, ret);
2260                 free(buf);
2261         }
2262
2263         return ret;
2264 }
2265
2266 _PUBLIC_ int swrap_close(int fd)
2267 {
2268         struct socket_info *si = find_socket_info(fd);
2269         int ret;
2270
2271         if (!si) {
2272                 return real_close(fd);
2273         }
2274
2275         SWRAP_DLIST_REMOVE(sockets, si);
2276
2277         if (si->myname && si->peername) {
2278                 swrap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0);
2279         }
2280
2281         ret = real_close(fd);
2282
2283         if (si->myname && si->peername) {
2284                 swrap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0);
2285                 swrap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0);
2286         }
2287
2288         if (si->path) free(si->path);
2289         if (si->myname) free(si->myname);
2290         if (si->peername) free(si->peername);
2291         if (si->tmp_path) {
2292                 unlink(si->tmp_path);
2293                 free(si->tmp_path);
2294         }
2295         free(si);
2296
2297         return ret;
2298 }