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