From: Matthew Iselin Date: Mon, 25 Jul 2011 00:40:02 +0000 (+1000) Subject: [ipv6] check for a valid destination address in ipv6_rx X-Git-Url: http://git.etherboot.org/people/pcmattman/gpxe.git/commitdiff_plain [ipv6] check for a valid destination address in ipv6_rx Previously, gPXE would happily process any IPv6 packet transmitted to it, even if it was not targeted to the gPXE station. This caused issues with ICMPv6 echo requests in particular, but also wasted processing time on other traffic on the network. Now, the destination address is verified before too much processing is done. --- diff --git a/src/net/icmpv6.c b/src/net/icmpv6.c index d154c037..24f2ec5d 100644 --- a/src/net/icmpv6.c +++ b/src/net/icmpv6.c @@ -194,15 +194,6 @@ int icmp6_rx ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src, rc = 0; goto done; } - - /* Verify that we should even begin to process this packet. - * It must be either unicast, and targeted to us, or multicast. */ - if ( icmp6_net_protocol->check ( netdev, &dest->sin6_addr ) && - ( ! ( dest->sin6_addr.in6_u.u6_addr8[0] == 0xFF ) ) ) { - DBG ( "ICMPv6 packet is not targeted to us.\n" ); - rc = -EINVAL; - goto done; - } /* Verify checksum */ csum = tcpip_continue_chksum ( pshdr_csum, icmp6hdr, len ); diff --git a/src/net/ipv6.c b/src/net/ipv6.c index 58cb155d..6bea1357 100644 --- a/src/net/ipv6.c +++ b/src/net/ipv6.c @@ -35,9 +35,7 @@ struct net_protocol ipv6_protocol; char * inet6_ntoa ( struct in6_addr in6 ); -static int ipv6_process_nxt_hdr ( struct io_buffer *iobuf, uint8_t nxt_hdr, - struct sockaddr_tcpip *src, struct sockaddr_tcpip *dest, - struct net_device *netdev, uint16_t phcsm ); +static int ipv6_check ( struct net_device *netdev, const void *net_addr ); /* Unspecified IP6 address */ static struct in6_addr ip6_none = { @@ -701,6 +699,23 @@ static int ipv6_rx ( struct io_buffer *iobuf, goto drop; } + /* Construct socket address */ + memset ( &src, 0, sizeof ( src ) ); + src.sin6.sin_family = AF_INET6; + src.sin6.sin6_addr = ip6hdr->src; + memset ( &dest, 0, sizeof ( dest ) ); + dest.sin6.sin_family = AF_INET6; + dest.sin6.sin6_addr = ip6hdr->dest; + + /* Check destination - always allow multicast. */ + if ( dest.sin6.sin6_addr.s6_addr[0] != 0xFF ) { + if ( ipv6_check ( netdev, &dest.sin6.sin6_addr ) ) { + DBG ( "IP6: packet not for us\n" ); + rc = -EINVAL; + goto drop; + } + } + /* Print IP6 header for debugging */ ipv6_dump ( ip6hdr ); @@ -721,14 +736,6 @@ static int ipv6_rx ( struct io_buffer *iobuf, /* Ignore the traffic class and flow control values */ - /* Construct socket address */ - memset ( &src, 0, sizeof ( src ) ); - src.sin6.sin_family = AF_INET6; - src.sin6.sin6_addr = ip6hdr->src; - memset ( &dest, 0, sizeof ( dest ) ); - dest.sin6.sin_family = AF_INET6; - dest.sin6.sin6_addr = ip6hdr->dest; - /* Calculate the psuedo-header checksum before the IP6 header is * stripped away. */ phcsm = ipv6_tx_csum ( iobuf, TCPIP_EMPTY_CSUM );