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