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