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