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