hdr->flags |= htons(NHRP_FLAG_REGISTRATION_NAT);
ext = nhrp_ext_push(zb, hdr, NHRP_EXTENSION_NAT_ADDRESS);
cie = nhrp_cie_push(zb, NHRP_CODE_SUCCESS, &nifp->nbma, &if_ad->addr);
- cie->prefix_length = 8 * sockunion_get_addrlen(&nifp->nbma);
+ cie->prefix_length = 8 * sockunion_get_addrlen(&if_ad->addr);
nhrp_ext_complete(zb, ext);
nhrp_packet_complete(zb, hdr);
struct nhrp_extension_header *ext;
struct nhrp_cache *c;
union sockunion cie_nbma, cie_proto, *proto_addr, *nbma_addr, *nbma_natoa;
- int holdtime, natted = 0;
+ int holdtime, prefix_len, hostprefix_len, natted = 0;
size_t paylen;
void *pay;
debugf(NHRP_DEBUG_COMMON, "Parsing and replying to Registration Req");
+ hostprefix_len = 8 * sockunion_get_addrlen(&p->if_ad->addr);
if (!sockunion_same(&p->src_nbma, &p->peer->vc->remote.nbma))
natted = 1;
zbuf_init(&payload, pay, paylen, paylen);
while ((cie = nhrp_cie_pull(&payload, hdr, &cie_nbma, &cie_proto)) != NULL) {
- if (cie->prefix_length != 0xff && !(p->hdr->flags & htons(NHRP_FLAG_REGISTRATION_UNIQUE))) {
+ prefix_len = cie->prefix_length;
+ if (prefix_len == 0 || prefix_len >= hostprefix_len)
+ prefix_len = hostprefix_len;
+
+ if (prefix_len != hostprefix_len && !(p->hdr->flags & htons(NHRP_FLAG_REGISTRATION_UNIQUE))) {
cie->code = NHRP_CODE_BINDING_NON_UNIQUE;
continue;
}
/* We currently support only unique prefix registrations */
- if (cie->prefix_length != 0xff) {
+ if (prefix_len != hostprefix_len) {
cie->code = NHRP_CODE_ADMINISTRATIVELY_PROHIBITED;
continue;
}
prefix.prefixlen = cie->prefix_length;
/* Sanity check prefix length */
- if (prefix.prefixlen >= 8*prefix_blen(&prefix)) {
+ if (prefix.prefixlen >= 8*prefix_blen(&prefix) || prefix.prefixlen == 0) {
prefix.prefixlen = 8*prefix_blen(&prefix);
} else if (nhrp_route_address(NULL, &pp->dst_proto, &route_prefix, NULL) == NHRP_ROUTE_NBMA_NEXTHOP) {
if (prefix.prefixlen < route_prefix.prefixlen)