bool getEDNSSubnetOptsFromString(const string& options, EDNSSubnetOpts* eso)
{
+ //cerr<<"options.size:"<<options.size()<<endl;
return getEDNSSubnetOptsFromString(options.c_str(), options.length(), eso);
}
bool getEDNSSubnetOptsFromString(const char* options, unsigned int len, EDNSSubnetOpts* eso)
{
- //cerr<<"options.size:"<<options.size()<<endl;
EDNSSubnetOptsWire esow;
static_assert (sizeof(esow) == 4, "sizeof(EDNSSubnetOptsWire) must be 4 bytes");
- if(len <= sizeof(esow))
+ if(len < sizeof(esow))
return false;
memcpy(&esow, options, sizeof(esow));
esow.family = ntohs(esow.family);
//cerr<<"Family when parsing from string: "<<esow.family<<endl;
ComboAddress address;
- unsigned int octetsin = ((esow.sourceMask - 1)>> 3)+1;
+ unsigned int octetsin = esow.sourceMask > 0 ? (((esow.sourceMask - 1)>> 3)+1) : 0;
//cerr<<"octetsin:"<<octetsin<<endl;
if(esow.family == 1) {
if(len != sizeof(esow)+octetsin)
return false;
memset(&address, 0, sizeof(address));
address.sin4.sin_family = AF_INET;
- memcpy(&address.sin4.sin_addr.s_addr, options+sizeof(esow), octetsin);
+ if(octetsin > 0)
+ memcpy(&address.sin4.sin_addr.s_addr, options+sizeof(esow), octetsin);
} else if(esow.family == 2) {
if(len != sizeof(esow)+octetsin)
return false;
return false;
memset(&address, 0, sizeof(address));
address.sin4.sin_family = AF_INET6;
- memcpy(&address.sin6.sin6_addr.s6_addr, options+sizeof(esow), octetsin);
+ if(octetsin > 0)
+ memcpy(&address.sin6.sin6_addr.s6_addr, options+sizeof(esow), octetsin);
}
else
return false;
- // cerr<<"Source address: "<<address.toString()<<", mask: "<<(int)esow.sourceMask<<endl;
+ //cerr<<"Source address: "<<address.toString()<<", mask: "<<(int)esow.sourceMask<<endl;
eso->source = Netmask(address, esow.sourceMask);
/* 'address' has more bits set (potentially) than scopeMask. This leads to odd looking netmasks that promise
more precision than they have. For this reason we truncate the address to scopeMask bits */