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