1/*
2 * Copyright (C) Jelmer Vernooij 2005 <jelmer@samba.org>
3 * Copyright (C) Stefan Metzmacher 2006 <metze@samba.org>
4 *
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 *
18 * 3. Neither the name of the author nor the names of its contributors
19 *    may be used to endorse or promote products derived from this software
20 *    without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 */
35
36/*
37   Socket wrapper library. Passes all socket communication over
38   unix domain sockets if the environment variable SOCKET_WRAPPER_DIR
39   is set.
40*/
41
42#define SOCKET_WRAPPER_NOT_REPLACE
43
44#ifdef _SAMBA_BUILD_
45
46#include "includes.h"
47#include "system/network.h"
48#include "system/filesys.h"
49
50#ifdef malloc
51#undef malloc
52#endif
53#ifdef calloc
54#undef calloc
55#endif
56#ifdef strdup
57#undef strdup
58#endif
59
60#else /* _SAMBA_BUILD_ */
61
62#ifdef HAVE_CONFIG_H
63#include <config.h>
64#endif
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 "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
178static 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
185static 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
199static 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
214struct 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
242static struct socket_info *sockets;
243
244
245static 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
257static 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
272static 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
342static 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
440static 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
548static 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
559static 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
593static 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
630enum 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
651struct 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
663struct 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
720static 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
771static 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
906static 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
932static 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
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
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
1372static int autobind_start_init;
1373static 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 */
1379static 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
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
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
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
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
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
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
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
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
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
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
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
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
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
1840static int
1841dup_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
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
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