From: Thomas Gelf Date: Wed, 14 Oct 2015 10:11:04 +0000 (+0200) Subject: Improve error handling in cidr_match function X-Git-Tag: v2.4.0~208 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=29188a4a10cc4da19babe577710b27580eaf3cd6;p=icinga2 Improve error handling in cidr_match function refs #10354 Signed-off-by: Gunnar Beutner --- diff --git a/lib/base/utility.cpp b/lib/base/utility.cpp index 60ed577ca..510d0d001 100644 --- a/lib/base/utility.cpp +++ b/lib/base/utility.cpp @@ -143,6 +143,26 @@ bool Utility::Match(const String& pattern, const String& text) return (match(pattern.CStr(), text.CStr()) == 0); } +static bool ParseIp(const String& ip, char addr[16], int *proto) +{ + if (inet_pton(AF_INET, ip.CStr(), addr + 12) == 1) { + /* IPv4-mapped IPv6 address (::ffff:) */ + memset(addr, 0, 10); + memset(addr + 10, 0xff, 2); + *proto = AF_INET; + + return true; + } + + if (inet_pton(AF_INET6, ip.CStr(), addr) == 1) { + *proto = AF_INET6; + + return true; + } + + return false; +} + static void ParseIpMask(const String& ip, char mask[16], int *bits) { String::SizeType slashp = ip.FindFirstOf("/"); @@ -156,23 +176,20 @@ static void ParseIpMask(const String& ip, char mask[16], int *bits) *bits = Convert::ToLong(ip.SubStr(slashp + 1)); } - /* IPv4-mapped IPv6 address (::ffff:) */ - memset(mask, 0, 10); - memset(mask + 10, 0xff, 2); - if (inet_pton(AF_INET, uip.CStr(), mask + 12) < 1) { - if (inet_pton(AF_INET6, uip.CStr(), mask) < 1) { - BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid IP address specified.")); - } - } else + int proto; + + if (!ParseIp(uip, mask, &proto)) + BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid IP address specified.")); + + if (proto == AF_INET) *bits += 96; if (slashp == String::NPos) *bits = 128; - if (*bits > 128) - BOOST_THROW_EXCEPTION(std::invalid_argument("Mask must not be greater than 128.")); + if (*bits > 128 || *bits < 0) + BOOST_THROW_EXCEPTION(std::invalid_argument("Mask must be between 0 and 128.")); - /* TODO: validate mask */ for (int i = 0; i < 16; i++) { int lbits = *bits - i * 8; @@ -204,17 +221,17 @@ static bool IpMaskCheck(char addr[16], char mask[16], int bits) bool Utility::CidrMatch(const String& pattern, const String& ip) { - char mask[16], addr[16]; + char mask[16]; int bits; - try { - ParseIpMask(ip, addr, &bits); - } catch (const std::exception&) { - return false; - } - ParseIpMask(pattern, mask, &bits); + char addr[16]; + int proto; + + if (!ParseIp(ip, addr, &proto)) + return false; + return IpMaskCheck(addr, mask, bits); }