int IpAddrInRange(struct u_range *range, struct u_addr *addr) { u_int32_t mask; u_int8_t bmask; int i; if (u_rangeempty(range)) return (1); //For compatibility we think that empty range includes any ip. if (range->addr.family != addr->family) return (0); switch (range->addr.family) { case AF_INET: mask = range->width ? htonl(~0 << (32 - range->width)) : 0; return ((addr->u.ip4.s_addr & mask) == (range->addr.u.ip4.s_addr & mask)); break; case AF_INET6: for (i = 0; i < ((range->width + 7) / 8); i++) { if ((i * 8 + 7) < range->width) { if (addr->u.ip6.s6_addr[i] != range->addr.u.ip6.s6_addr[i]) return 0; } else { bmask = (range->width == i * 8) ? 0 : (~0 << (8 - range->width)); if ((addr->u.ip6.s6_addr[i] & bmask) != (range->addr.u.ip6.s6_addr[i] & bmask)) return 0; } } return 1; break; } return 0; }
static void IpcpConfigure(Fsm fp) { Bund b = (Bund)fp->arg; IpcpState const ipcp = &b->ipcp; char buf[48]; /* FSM stuff */ ipcp->peer_reject = 0; /* Get allowed IP addresses from config and/or from current bundle */ if (ipcp->conf.self_ippool[0]) { if (IPPoolGet(ipcp->conf.self_ippool, &ipcp->self_allow.addr)) { Log(LG_IPCP, ("[%s] IPCP: Can't get IP from pool \"%s\" for self", b->name, ipcp->conf.self_ippool)); } else { Log(LG_IPCP, ("[%s] IPCP: Got IP %s from pool \"%s\" for self", b->name, u_addrtoa(&ipcp->self_allow.addr, buf, sizeof(buf)), ipcp->conf.self_ippool)); ipcp->self_allow.width = 32; ipcp->self_ippool_used = 1; } } else ipcp->self_allow = ipcp->conf.self_allow; if ((b->params.range_valid) && (!u_rangeempty(&b->params.range))) ipcp->peer_allow = b->params.range; else if (b->params.ippool[0]) { /* Get IP from pool if needed */ if (IPPoolGet(b->params.ippool, &ipcp->peer_allow.addr)) { Log(LG_IPCP, ("[%s] IPCP: Can't get IP from pool \"%s\" for peer", b->name, b->params.ippool)); } else { Log(LG_IPCP, ("[%s] IPCP: Got IP %s from pool \"%s\" for peer", b->name, u_addrtoa(&ipcp->peer_allow.addr, buf, sizeof(buf)), b->params.ippool)); ipcp->peer_allow.width = 32; b->params.ippool_used = 1; } } else if (ipcp->conf.ippool[0]) { if (IPPoolGet(ipcp->conf.ippool, &ipcp->peer_allow.addr)) { Log(LG_IPCP, ("[%s] IPCP: Can't get IP from pool \"%s\"", b->name, ipcp->conf.ippool)); } else { Log(LG_IPCP, ("[%s] IPCP: Got IP %s from pool \"%s\" for peer", b->name, u_addrtoa(&ipcp->peer_allow.addr, buf, sizeof(buf)), ipcp->conf.ippool)); ipcp->peer_allow.width = 32; ipcp->ippool_used = 1; } } else ipcp->peer_allow = ipcp->conf.peer_allow; /* Initially request addresses as specified by config */ u_addrtoin_addr(&ipcp->self_allow.addr, &ipcp->want_addr); u_addrtoin_addr(&ipcp->peer_allow.addr, &ipcp->peer_addr); #ifdef USE_NG_VJC /* Van Jacobson compression */ ipcp->peer_comp.proto = 0; ipcp->peer_comp.maxchan = IPCP_VJCOMP_DEFAULT_MAXCHAN; ipcp->peer_comp.compcid = 0; ipcp->want_comp.proto = (b->params.vjc_enable || Enabled(&ipcp->conf.options, IPCP_CONF_VJCOMP)) ? htons(PROTO_VJCOMP) : 0; ipcp->want_comp.maxchan = IPCP_VJCOMP_MAX_MAXCHAN; /* If any of our links are unable to give receive error indications, we must tell the peer not to compress the slot-id in VJCOMP packets (cf. RFC1144). To be on the safe side, we always say this. */ ipcp->want_comp.compcid = 0; #endif /* DNS and NBNS servers */ memset(&ipcp->want_dns, 0, sizeof(ipcp->want_dns)); memset(&ipcp->want_nbns, 0, sizeof(ipcp->want_nbns)); }