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