summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt3
-rw-r--r--hscript/network.cc12
-rw-r--r--util/net.hh19
3 files changed, 24 insertions, 10 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ffb117f..79a5db1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -14,7 +14,8 @@ add_definitions(-DVERSTR="${PROJECT_VERSION}")
if(MSVC)
add_compile_options(/W4 /WX)
else()
- add_compile_options(-Wall -Wextra -Wno-unused-parameter -Werror)
+ add_compile_options(-Wall -Wextra -Wno-unused-parameter -Wno-unused-function
+ -Werror)
endif()
diff --git a/hscript/network.cc b/hscript/network.cc
index 49cebb5..c8bc93e 100644
--- a/hscript/network.cc
+++ b/hscript/network.cc
@@ -24,6 +24,7 @@
# define IFNAMSIZ 16
#endif
#include "network.hh"
+#include "util/net.hh"
#include "util/output.hh"
using namespace Horizon::Keys;
@@ -183,7 +184,8 @@ Key *NetAddress::parseFromData(const std::string &data, int lineno, int *errors,
/* There are two kinds of prefixes for IPv4: prefix length, like IPv6,
* and mask, which is the old style used by i.e. Windows. */
- if(::inet_pton(AF_INET, prefix.c_str(), &addr_buf) != 1) {
+ real_prefix = subnet_mask_to_cidr(prefix.c_str());
+ if(real_prefix < 1) {
try {
real_prefix = std::stoi(prefix);
} catch(const std::exception &) {
@@ -193,14 +195,6 @@ Key *NetAddress::parseFromData(const std::string &data, int lineno, int *errors,
"a network mask or prefix length is required");
return nullptr;
}
- } else {
- uint32_t tmp;
- memcpy(&tmp, addr_buf, 4);
- tmp = ntohl(tmp);
- real_prefix = 1;
- while((tmp <<= 1) & 0x80000000) {
- real_prefix++;
- }
}
if(real_prefix < 1 || real_prefix > 32) {
diff --git a/util/net.hh b/util/net.hh
index 89e5303..3c5c38e 100644
--- a/util/net.hh
+++ b/util/net.hh
@@ -14,6 +14,8 @@
#define __HORIZON_NET_HH_
#include <algorithm>
+#include <arpa/inet.h> /* inet_pton */
+#include <cstring> /* memcpy */
#include <string>
/*! Determine if a string starts with a valid, supported protocol
@@ -33,4 +35,21 @@ static bool is_valid_url(const std::string &url) {
return false;
}
+static int subnet_mask_to_cidr(const char *mask) {
+ char addr_buf[4];
+ uint32_t tmp;
+ int real_prefix = ::inet_pton(AF_INET, mask, &addr_buf);
+
+ /* helpfully, we need to init real_prefix to 1 anyway;
+ * if inet_pton doesn't return 1, we failed to convert */
+ if(real_prefix == 1) {
+ memcpy(&tmp, addr_buf, 4);
+ tmp = ntohl(tmp);
+ while((tmp <<= 1) & 0x80000000) {
+ real_prefix++;
+ }
+ }
+ return real_prefix;
+}
+
#endif /* !__HORIZON_NET_HH */