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