X-Git-Url: https://www.tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Froute.c;h=a3e92020ce4bcc47c2aa10be772990b92cb73c61;hb=5ec513ec0ffc735e30c559a03378659ba4cc4515;hp=a130e690d50f2b6cf14ef95160330c2592afe97e;hpb=f6e87ab476a0faf8b124ecaaa27f967d825e6457;p=tinc diff --git a/src/route.c b/src/route.c index a130e690..a3e92020 100644 --- a/src/route.c +++ b/src/route.c @@ -406,6 +406,15 @@ static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *pac type = DATA(packet)[16] << 8 | DATA(packet)[17]; } + /* IP in IP (RFC 2003) packet */ + if(type == ETH_P_IP && DATA(packet)[start + 9] == 4) { + start += 20; + } + + if(packet->len <= start + 20) { + return; + } + if(type == ETH_P_IP && DATA(packet)[start + 9] == 6) { start += (DATA(packet)[start] & 0xf) * 4; } else if(type == ETH_P_IPV6 && DATA(packet)[start + 6] == 6) { @@ -642,11 +651,13 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet) { } if(!subnet->owner->status.reachable) { - return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_UNREACH); + route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_UNREACH); + return; } if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) { - return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO); + route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO); + return; } if(decrement_ttl && source != myself && subnet->owner != myself) @@ -666,7 +677,8 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet) { } if(directonly && subnet->owner != via) { - return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO); + route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO); + return; } if(via && packet->len > MAX(via->mtu, 590) && via != myself) { @@ -733,11 +745,13 @@ static void route_ipv6(node_t *source, vpn_packet_t *packet) { } if(!subnet->owner->status.reachable) { - return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE); + route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE); + return; } if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) { - return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN); + route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN); + return; } if(decrement_ttl && source != myself && subnet->owner != myself) @@ -757,7 +771,8 @@ static void route_ipv6(node_t *source, vpn_packet_t *packet) { } if(directonly && subnet->owner != via) { - return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN); + route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN); + return; } if(via && packet->len > MAX(via->mtu, 1294) && via != myself) {