[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha7-149-g27cf239

Stefan Metzmacher metze at samba.org
Wed Mar 4 07:35:46 GMT 2009


The branch, master has been updated
       via  27cf23958b02b05becce6e7c68347f6fea5b7845 (commit)
       via  b99bb962aa70f8584212f18ba6368513e7485f5e (commit)
       via  8ae34cc9946e54297e800190980af32ef56c4ca1 (commit)
       via  40da086fe0e2f12d7e23ca75711ceceecbd61105 (commit)
       via  d52e81311733c7f119b5765eddb37eb2554ce281 (commit)
       via  c51e5a23fbeda9ece5697c3c5b60a813ec33010e (commit)
      from  8ee0cc24b8302097bccae7891cb6f9c0547a1815 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 27cf23958b02b05becce6e7c68347f6fea5b7845
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Mar 3 16:45:41 2009 +0100

    socket_wrapper: add multiple interface support for ipv6
    
    We use FD00::5357:5FXX in the same way we use 127.0.0.XX
    
    metze

commit b99bb962aa70f8584212f18ba6368513e7485f5e
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Mar 3 15:43:22 2009 +0100

    socket_wrapper: add ipv6 pcap support
    
    metze

commit 8ae34cc9946e54297e800190980af32ef56c4ca1
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Mar 3 15:17:26 2009 +0100

    socket_wrapper: pass down sockaddr instead of sockaddr_in to prepare pcap support for ipv6
    
    metze

commit 40da086fe0e2f12d7e23ca75711ceceecbd61105
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Mar 3 14:58:53 2009 +0100

    socket_wrapper: prepare pcap support for ipv6 traffic
    
    metze

commit d52e81311733c7f119b5765eddb37eb2554ce281
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Mar 3 19:23:25 2009 +0100

    s4:blackbox/test_ldb: make use of the $VALGRIND envvar
    
    metze

commit c51e5a23fbeda9ece5697c3c5b60a813ec33010e
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Mar 3 19:20:43 2009 +0100

    socket_wrapper: don't crash if we get EAGAIN from real_recv()
    
    This fixes a crash in the ldaps tests with socket wrapper pcap support.
    
    metze

-----------------------------------------------------------------------

Summary of changes:
 lib/socket_wrapper/socket_wrapper.c |  569 ++++++++++++++++++++++-------------
 testprogs/blackbox/test_ldb.sh      |    2 +-
 2 files changed, 364 insertions(+), 207 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/socket_wrapper/socket_wrapper.c b/lib/socket_wrapper/socket_wrapper.c
index 1e39277..f9ef48e 100644
--- a/lib/socket_wrapper/socket_wrapper.c
+++ b/lib/socket_wrapper/socket_wrapper.c
@@ -145,7 +145,16 @@
 
 #define MAX_WRAPPED_INTERFACES 16
 
-#define SW_IPV6_ADDRESS 1
+#ifdef HAVE_IPV6
+/*
+ * FD00::5357:5FXX
+ */
+static const struct in6_addr swrap_ipv6 =
+{ { {
+0xFD,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x53,0x57,0x5F,0x00
+} } };
+#endif
 
 static struct sockaddr *sockaddr_dup(const void *data, socklen_t len)
 {
@@ -295,7 +304,8 @@ static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, sock
 
 		memset(in2, 0, sizeof(*in2));
 		in2->sin6_family = AF_INET6;
-		in2->sin6_addr.s6_addr[0] = SW_IPV6_ADDRESS;
+		in2->sin6_addr = swrap_ipv6;
+		in2->sin6_addr.s6_addr[15] = iface;
 		in2->sin6_port = htons(prt);
 
 		*len = sizeof(*in2);
@@ -367,6 +377,7 @@ static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *i
 	case AF_INET6: {
 		const struct sockaddr_in6 *in = 
 		    (const struct sockaddr_in6 *)inaddr;
+		struct in6_addr cmp;
 
 		switch (si->type) {
 		case SOCK_STREAM:
@@ -380,8 +391,16 @@ static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *i
 		/* XXX no multicast/broadcast */
 
 		prt = ntohs(in->sin6_port);
-		iface = SW_IPV6_ADDRESS;
-		
+
+		cmp = in->sin6_addr;
+		cmp.s6_addr[15] = 0;
+		if (IN6_ARE_ADDR_EQUAL(&swrap_ipv6, &cmp)) {
+			iface = in->sin6_addr.s6_addr[15];
+		} else {
+			errno = ENETUNREACH;
+			return -1;
+		}
+
 		break;
 	}
 #endif
@@ -474,6 +493,7 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *in
 	case AF_INET6: {
 		const struct sockaddr_in6 *in = 
 		    (const struct sockaddr_in6 *)inaddr;
+		struct in6_addr cmp;
 
 		switch (si->type) {
 		case SOCK_STREAM:
@@ -487,13 +507,21 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *in
 		/* XXX no multicast/broadcast */
 
 		prt = ntohs(in->sin6_port);
-		iface = SW_IPV6_ADDRESS;
-		
+
+		cmp = in->sin6_addr;
+		cmp.s6_addr[15] = 0;
+		if (IN6_ARE_ADDR_EQUAL(&swrap_ipv6, &cmp)) {
+			iface = in->sin6_addr.s6_addr[15];
+		} else {
+			errno = EADDRNOTAVAIL;
+			return -1;
+		}
+
 		break;
 	}
 #endif
 	default:
-		errno = ENETUNREACH;
+		errno = EADDRNOTAVAIL;
 		return -1;
 	}
 
@@ -636,69 +664,93 @@ struct swrap_file_hdr {
 };
 #define SWRAP_FILE_HDR_SIZE 24
 
-struct swrap_packet {
+struct swrap_packet_frame {
+	uint32_t seconds;
+	uint32_t micro_seconds;
+	uint32_t recorded_length;
+	uint32_t full_length;
+};
+#define SWRAP_PACKET_FRAME_SIZE 16
+
+union swrap_packet_ip {
+	struct {
+		uint8_t		ver_hdrlen;
+		uint8_t		tos;
+		uint16_t	packet_length;
+		uint16_t	identification;
+		uint8_t		flags;
+		uint8_t		fragment;
+		uint8_t		ttl;
+		uint8_t		protocol;
+		uint16_t	hdr_checksum;
+		uint32_t	src_addr;
+		uint32_t	dest_addr;
+	} v4;
+#define SWRAP_PACKET_IP_V4_SIZE 20
 	struct {
-		uint32_t seconds;
-		uint32_t micro_seconds;
-		uint32_t recorded_length;
-		uint32_t full_length;
-	} frame;
-#define SWRAP_PACKET__FRAME_SIZE 16
+		uint8_t		ver_prio;
+		uint8_t		flow_label_high;
+		uint16_t	flow_label_low;
+		uint16_t	payload_length;
+		uint8_t		next_header;
+		uint8_t		hop_limit;
+		uint8_t		src_addr[16];
+		uint8_t		dest_addr[16];
+	} v6;
+#define SWRAP_PACKET_IP_V6_SIZE 40
+};
+#define SWRAP_PACKET_IP_SIZE 40
 
+union swrap_packet_payload {
+	struct {
+		uint16_t	source_port;
+		uint16_t	dest_port;
+		uint32_t	seq_num;
+		uint32_t	ack_num;
+		uint8_t		hdr_length;
+		uint8_t		control;
+		uint16_t	window;
+		uint16_t	checksum;
+		uint16_t	urg;
+	} tcp;
+#define SWRAP_PACKET_PAYLOAD_TCP_SIZE 20
 	struct {
-		struct {
-			uint8_t		ver_hdrlen;
-			uint8_t		tos;
-			uint16_t	packet_length;
-			uint16_t	identification;
-			uint8_t		flags;
-			uint8_t		fragment;
-			uint8_t		ttl;
-			uint8_t		protocol;
-			uint16_t	hdr_checksum;
-			uint32_t	src_addr;
-			uint32_t	dest_addr;
-		} hdr;
-#define SWRAP_PACKET__IP_HDR_SIZE 20
-
-		union {
-			struct {
-				uint16_t	source_port;
-				uint16_t	dest_port;
-				uint32_t	seq_num;
-				uint32_t	ack_num;
-				uint8_t		hdr_length;
-				uint8_t		control;
-				uint16_t	window;
-				uint16_t	checksum;
-				uint16_t	urg;
-			} tcp;
-#define SWRAP_PACKET__IP_P_TCP_SIZE 20
-			struct {
-				uint16_t	source_port;
-				uint16_t	dest_port;
-				uint16_t	length;
-				uint16_t	checksum;
-			} udp;
-#define SWRAP_PACKET__IP_P_UDP_SIZE 8
-			struct {
-				uint8_t		type;
-				uint8_t		code;
-				uint16_t	checksum;
-				uint32_t	unused;
-			} icmp;
-#define SWRAP_PACKET__IP_P_ICMP_SIZE 8
-		} p;
-	} ip;
+		uint16_t	source_port;
+		uint16_t	dest_port;
+		uint16_t	length;
+		uint16_t	checksum;
+	} udp;
+#define SWRAP_PACKET_PAYLOAD_UDP_SIZE 8
+	struct {
+		uint8_t		type;
+		uint8_t		code;
+		uint16_t	checksum;
+		uint32_t	unused;
+	} icmp4;
+#define SWRAP_PACKET_PAYLOAD_ICMP4_SIZE 8
+	struct {
+		uint8_t		type;
+		uint8_t		code;
+		uint16_t	checksum;
+		uint32_t	unused;
+	} icmp6;
+#define SWRAP_PACKET_PAYLOAD_ICMP6_SIZE 8
 };
-#define SWRAP_PACKET_SIZE 56
+#define SWRAP_PACKET_PAYLOAD_SIZE 20
+
+#define SWRAP_PACKET_MIN_ALLOC \
+	(SWRAP_PACKET_FRAME_SIZE + \
+	 SWRAP_PACKET_IP_SIZE + \
+	 SWRAP_PACKET_PAYLOAD_SIZE)
 
 static const char *socket_wrapper_pcap_file(void)
 {
 	static int initialized = 0;
 	static const char *s = NULL;
-	static const struct swrap_file_hdr h = { 0, };
-	static const struct swrap_packet p = { { 0, }, { { 0, }, { { 0, } } } };
+	static const struct swrap_file_hdr h;
+	static const struct swrap_packet_frame f;
+	static const union swrap_packet_ip i;
+	static const union swrap_packet_payload p;
 
 	if (initialized == 1) {
 		return s;
@@ -715,22 +767,31 @@ static const char *socket_wrapper_pcap_file(void)
 	if (sizeof(h) != SWRAP_FILE_HDR_SIZE) {
 		return NULL;
 	}
-	if (sizeof(p) != SWRAP_PACKET_SIZE) {
+	if (sizeof(f) != SWRAP_PACKET_FRAME_SIZE) {
+		return NULL;
+	}
+	if (sizeof(i) != SWRAP_PACKET_IP_SIZE) {
 		return NULL;
 	}
-	if (sizeof(p.frame) != SWRAP_PACKET__FRAME_SIZE) {
+	if (sizeof(i.v4) != SWRAP_PACKET_IP_V4_SIZE) {
 		return NULL;
 	}
-	if (sizeof(p.ip.hdr) != SWRAP_PACKET__IP_HDR_SIZE) {
+	if (sizeof(i.v6) != SWRAP_PACKET_IP_V6_SIZE) {
 		return NULL;
 	}
-	if (sizeof(p.ip.p.tcp) != SWRAP_PACKET__IP_P_TCP_SIZE) {
+	if (sizeof(p) != SWRAP_PACKET_PAYLOAD_SIZE) {
 		return NULL;
 	}
-	if (sizeof(p.ip.p.udp) != SWRAP_PACKET__IP_P_UDP_SIZE) {
+	if (sizeof(p.tcp) != SWRAP_PACKET_PAYLOAD_TCP_SIZE) {
 		return NULL;
 	}
-	if (sizeof(p.ip.p.icmp) != SWRAP_PACKET__IP_P_ICMP_SIZE) {
+	if (sizeof(p.udp) != SWRAP_PACKET_PAYLOAD_UDP_SIZE) {
+		return NULL;
+	}
+	if (sizeof(p.icmp4) != SWRAP_PACKET_PAYLOAD_ICMP4_SIZE) {
+		return NULL;
+	}
+	if (sizeof(p.icmp6) != SWRAP_PACKET_PAYLOAD_ICMP6_SIZE) {
 		return NULL;
 	}
 
@@ -744,41 +805,72 @@ static const char *socket_wrapper_pcap_file(void)
 	return s;
 }
 
-static struct swrap_packet *swrap_packet_init(struct timeval *tval,
-					      const struct sockaddr_in *src_addr,
-					      const struct sockaddr_in *dest_addr,
-					      int socket_type,
-					      const unsigned char *payload,
-					      size_t payload_len,
-					      unsigned long tcp_seqno,
-					      unsigned long tcp_ack,
-					      unsigned char tcp_ctl,
-					      int unreachable,
-					      size_t *_packet_len)
+static uint8_t *swrap_packet_init(struct timeval *tval,
+				  const struct sockaddr *src,
+				  const struct sockaddr *dest,
+				  int socket_type,
+				  const uint8_t *payload,
+				  size_t payload_len,
+				  unsigned long tcp_seqno,
+				  unsigned long tcp_ack,
+				  unsigned char tcp_ctl,
+				  int unreachable,
+				  size_t *_packet_len)
 {
-	struct swrap_packet *ret;
-	struct swrap_packet *packet;
+	uint8_t *base;
+	uint8_t *buf;
+	struct swrap_packet_frame *frame;
+	union swrap_packet_ip *ip;
+	union swrap_packet_payload *pay;
 	size_t packet_len;
 	size_t alloc_len;
-	size_t nonwire_len = sizeof(packet->frame);
+	size_t nonwire_len = sizeof(*frame);
 	size_t wire_hdr_len = 0;
 	size_t wire_len = 0;
+	size_t ip_hdr_len = 0;
 	size_t icmp_hdr_len = 0;
 	size_t icmp_truncate_len = 0;
-	unsigned char protocol = 0, icmp_protocol = 0;
-	unsigned short src_port = src_addr->sin_port;
-	unsigned short dest_port = dest_addr->sin_port;
+	uint8_t protocol = 0, icmp_protocol = 0;
+	const struct sockaddr_in *src_in;
+	const struct sockaddr_in *dest_in;
+#ifdef HAVE_IPV6
+	const struct sockaddr_in6 *src_in6;
+	const struct sockaddr_in6 *dest_in6;
+#endif
+	uint16_t src_port;
+	uint16_t dest_port;
+
+	switch (src->sa_family) {
+	case AF_INET:
+		src_in = (const struct sockaddr_in *)src;
+		dest_in = (const struct sockaddr_in *)dest;
+		src_port = src_in->sin_port;
+		dest_port = dest_in->sin_port;
+		ip_hdr_len = sizeof(ip->v4);
+		break;
+#ifdef HAVE_IPV6
+	case AF_INET6:
+		src_in6 = (const struct sockaddr_in6 *)src;
+		dest_in6 = (const struct sockaddr_in6 *)dest;
+		src_port = src_in6->sin6_port;
+		dest_port = dest_in6->sin6_port;
+		ip_hdr_len = sizeof(ip->v6);
+		break;
+#endif
+	default:
+		return NULL;
+	}
 
 	switch (socket_type) {
 	case SOCK_STREAM:
 		protocol = 0x06; /* TCP */
-		wire_hdr_len = sizeof(packet->ip.hdr) + sizeof(packet->ip.p.tcp);
+		wire_hdr_len = ip_hdr_len + sizeof(pay->tcp);
 		wire_len = wire_hdr_len + payload_len;
 		break;
 
 	case SOCK_DGRAM:
 		protocol = 0x11; /* UDP */
-		wire_hdr_len = sizeof(packet->ip.hdr) + sizeof(packet->ip.p.udp);
+		wire_hdr_len = ip_hdr_len + sizeof(pay->udp);
 		wire_len = wire_hdr_len + payload_len;
 		break;
 
@@ -788,98 +880,160 @@ static struct swrap_packet *swrap_packet_init(struct timeval *tval,
 
 	if (unreachable) {
 		icmp_protocol = protocol;
-		protocol = 0x01; /* ICMP */
+		switch (src->sa_family) {
+		case AF_INET:
+			protocol = 0x01; /* ICMPv4 */
+			icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp4);
+			break;
+#ifdef HAVE_IPV6
+		case AF_INET6:
+			protocol = 0x3A; /* ICMPv6 */
+			icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp6);
+			break;
+#endif
+		}
 		if (wire_len > 64 ) {
 			icmp_truncate_len = wire_len - 64;
 		}
-		icmp_hdr_len = sizeof(packet->ip.hdr) + sizeof(packet->ip.p.icmp);
 		wire_hdr_len += icmp_hdr_len;
 		wire_len += icmp_hdr_len;
 	}
 
 	packet_len = nonwire_len + wire_len;
 	alloc_len = packet_len;
-	if (alloc_len < sizeof(struct swrap_packet)) {
-		alloc_len = sizeof(struct swrap_packet);
-	}
-	ret = (struct swrap_packet *)malloc(alloc_len);
-	if (!ret) return NULL;
-
-	packet = ret;
-
-	packet->frame.seconds		= tval->tv_sec;
-	packet->frame.micro_seconds	= tval->tv_usec;
-	packet->frame.recorded_length	= wire_len - icmp_truncate_len;
-	packet->frame.full_length	= wire_len - icmp_truncate_len;
-
-	packet->ip.hdr.ver_hdrlen	= 0x45; /* version 4 and 5 * 32 bit words */
-	packet->ip.hdr.tos		= 0x00;
-	packet->ip.hdr.packet_length	= htons(wire_len - icmp_truncate_len);
-	packet->ip.hdr.identification	= htons(0xFFFF);
-	packet->ip.hdr.flags		= 0x40; /* BIT 1 set - means don't fraqment */
-	packet->ip.hdr.fragment		= htons(0x0000);
-	packet->ip.hdr.ttl		= 0xFF;
-	packet->ip.hdr.protocol		= protocol;
-	packet->ip.hdr.hdr_checksum	= htons(0x0000);
-	packet->ip.hdr.src_addr		= src_addr->sin_addr.s_addr;
-	packet->ip.hdr.dest_addr	= dest_addr->sin_addr.s_addr;
+	if (alloc_len < SWRAP_PACKET_MIN_ALLOC) {
+		alloc_len = SWRAP_PACKET_MIN_ALLOC;
+	}
+
+	base = (uint8_t *)malloc(alloc_len);
+	if (!base) return NULL;
+
+	buf = base;
+
+	frame = (struct swrap_packet_frame *)buf;
+	frame->seconds		= tval->tv_sec;
+	frame->micro_seconds	= tval->tv_usec;
+	frame->recorded_length	= wire_len - icmp_truncate_len;
+	frame->full_length	= wire_len - icmp_truncate_len;
+	buf += SWRAP_PACKET_FRAME_SIZE;
+
+	ip = (union swrap_packet_ip *)buf;
+	switch (src->sa_family) {
+	case AF_INET:
+		ip->v4.ver_hdrlen	= 0x45; /* version 4 and 5 * 32 bit words */
+		ip->v4.tos		= 0x00;
+		ip->v4.packet_length	= htons(wire_len - icmp_truncate_len);
+		ip->v4.identification	= htons(0xFFFF);
+		ip->v4.flags		= 0x40; /* BIT 1 set - means don't fraqment */
+		ip->v4.fragment		= htons(0x0000);
+		ip->v4.ttl		= 0xFF;
+		ip->v4.protocol		= protocol;
+		ip->v4.hdr_checksum	= htons(0x0000);
+		ip->v4.src_addr		= src_in->sin_addr.s_addr;
+		ip->v4.dest_addr	= dest_in->sin_addr.s_addr;
+		buf += SWRAP_PACKET_IP_V4_SIZE;
+		break;
+#ifdef HAVE_IPV6
+	case AF_INET6:
+		ip->v6.ver_prio		= 0x60; /* version 4 and 5 * 32 bit words */
+		ip->v6.flow_label_high	= 0x00;
+		ip->v6.flow_label_low	= 0x0000;
+		ip->v6.payload_length	= htons(wire_len - icmp_truncate_len);//TODO
+		ip->v6.next_header	= protocol;
+		memcpy(ip->v6.src_addr, src_in6->sin6_addr.s6_addr, 16);
+		memcpy(ip->v6.dest_addr, dest_in6->sin6_addr.s6_addr, 16);
+		buf += SWRAP_PACKET_IP_V6_SIZE;
+		break;
+#endif
+	}
 
 	if (unreachable) {
-		packet->ip.p.icmp.type		= 0x03; /* destination unreachable */
-		packet->ip.p.icmp.code		= 0x01; /* host unreachable */
-		packet->ip.p.icmp.checksum	= htons(0x0000);
-		packet->ip.p.icmp.unused	= htonl(0x00000000);
-
-		/* set the ip header in the ICMP payload */
-		packet = (struct swrap_packet *)(((unsigned char *)ret) + icmp_hdr_len);
-		packet->ip.hdr.ver_hdrlen	= 0x45; /* version 4 and 5 * 32 bit words */
-		packet->ip.hdr.tos		= 0x00;
-		packet->ip.hdr.packet_length	= htons(wire_len - icmp_hdr_len);
-		packet->ip.hdr.identification	= htons(0xFFFF);
-		packet->ip.hdr.flags		= 0x40; /* BIT 1 set - means don't fraqment */
-		packet->ip.hdr.fragment		= htons(0x0000);
-		packet->ip.hdr.ttl		= 0xFF;
-		packet->ip.hdr.protocol		= icmp_protocol;
-		packet->ip.hdr.hdr_checksum	= htons(0x0000);
-		packet->ip.hdr.src_addr		= dest_addr->sin_addr.s_addr;
-		packet->ip.hdr.dest_addr	= src_addr->sin_addr.s_addr;
-
-		src_port = dest_addr->sin_port;
-		dest_port = src_addr->sin_port;
+		pay = (union swrap_packet_payload *)buf;
+		switch (src->sa_family) {
+		case AF_INET:
+			pay->icmp4.type		= 0x03; /* destination unreachable */
+			pay->icmp4.code		= 0x01; /* host unreachable */
+			pay->icmp4.checksum	= htons(0x0000);
+			pay->icmp4.unused	= htonl(0x00000000);
+			buf += SWRAP_PACKET_PAYLOAD_ICMP4_SIZE;
+
+			/* set the ip header in the ICMP payload */
+			ip = (union swrap_packet_ip *)buf;


-- 
Samba Shared Repository


More information about the samba-cvs mailing list