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