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