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 <me...@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 <me...@samba.org> Date: Tue Mar 3 15:43:22 2009 +0100 socket_wrapper: add ipv6 pcap support metze commit 8ae34cc9946e54297e800190980af32ef56c4ca1 Author: Stefan Metzmacher <me...@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 <me...@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 <me...@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 <me...@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