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