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