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.
-
- /* 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 );
/* Verify checksum */
csum = tcpip_continue_chksum ( pshdr_csum, icmp6hdr, len );
char * inet6_ntoa ( struct in6_addr in6 );
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 = {
/* Unspecified IP6 address */
static struct in6_addr ip6_none = {
+ /* 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 );
/* Print IP6 header for debugging */
ipv6_dump ( ip6hdr );
/* Ignore the traffic class and flow control values */
/* 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 );
/* Calculate the psuedo-header checksum before the IP6 header is
* stripped away. */
phcsm = ipv6_tx_csum ( iobuf, TCPIP_EMPTY_CSUM );