--- ndisc.c Sat May 5 18:33:29 2001 +++ ndisc.c.full Sat May 5 19:46:18 2001 @@ -798,6 +798,11 @@ return; } + /* XXX: RFC2461 8.1: + * The IP source address of the Redirect MUST be the same as the current + * first-hop router for the specified ICMP Destination Address. + */ + /* passed validation tests */ /* @@ -988,8 +993,14 @@ return 0; } + /* XXX: RFC2461 Validation of [all ndisc messages]: + * All included ndisc options MUST be of non-zero length + * (Some checking in ndisc_find_option) + */ + switch (msg->icmph.icmp6_type) { case NDISC_NEIGHBOUR_SOLICITATION: + /* XXX: import nd_neighbor_solicit from glibc netinet/icmp6.h */ if (skb->nh.ipv6h->payload_len < 8+16) { if (net_ratelimit()) printk(KERN_WARNING "ICMP NS: packet too short\n"); @@ -1002,6 +1013,18 @@ return 0; } + /* XXX: RFC2461 7.1.1: + * If the IP source address is the unspecified address, there + * MUST NOT be source link-layer address option in the message. + * + * NOTE! Linux kernel < 2.4.4 broke this rule. + */ + + /* XXX: RFC2461 7.1.1: + * If the IP source address is the unspecified address, the IP + * destination address MUST be a solicited-node multicast address. + */ + if ((ifp = ipv6_get_ifaddr(&msg->target, dev)) != NULL) { int addr_type = ipv6_addr_type(saddr); @@ -1107,6 +1130,7 @@ return 0; case NDISC_NEIGHBOUR_ADVERTISEMENT: + /* XXX: import nd_neighbor_advert from glibc netinet/icmp6.h */ if (skb->nh.ipv6h->payload_len < 16+8 ) { if (net_ratelimit()) printk(KERN_WARNING "ICMP NA: packet too short\n"); @@ -1168,6 +1192,7 @@ break; case NDISC_ROUTER_ADVERTISEMENT: + /* XXX: import nd_router_advert from glibc netinet/icmp6.h */ if (skb->nh.ipv6h->payload_len < 8+4+4) { if (net_ratelimit()) printk(KERN_WARNING "ICMP RA: packet too short\n"); @@ -1177,6 +1202,7 @@ break; case NDISC_REDIRECT: + /* XXX: import nd_redirect from glibc netinet/icmp6.h */ if (skb->nh.ipv6h->payload_len < 8+16+16) { if (net_ratelimit()) printk(KERN_WARNING "ICMP redirect: packet too short\n"); @@ -1188,6 +1214,7 @@ case NDISC_ROUTER_SOLICITATION: /* No RS support in the kernel, but we do some required checks */ + /* XXX: import nd_router_solicit from glibc netinet/icmp6.h */ if (skb->nh.ipv6h->payload_len < 8) { if (net_ratelimit()) printk(KERN_WARNING "ICMP RS: packet too short\n");