-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcidr_utils.cpp
More file actions
60 lines (53 loc) · 1.54 KB
/
cidr_utils.cpp
File metadata and controls
60 lines (53 loc) · 1.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include "cidr_utils.h"
#include <arpa/inet.h>
#include <netinet/in.h>
namespace netcidr {
static bool parse_cidr(const std::string& cidr, uint32_t& net, uint32_t& mask) {
// Split at /
auto slash = cidr.find('/');
if (slash == std::string::npos)
return false;
std::string ip = cidr.substr(0, slash);
std::string bits = cidr.substr(slash+1);
int prefix = std::stoi(bits);
if (prefix < 0 || prefix > 32)
return false;
in_addr addr{};
if (inet_pton(AF_INET, ip.c_str(), &addr) != 1)
return false;
uint32_t h = ntohl(addr.s_addr);
uint32_t m = (prefix == 0) ? 0 : (0xFFFFFFFFu << (32 - prefix));
net = h & m;
mask = m;
return true;
}
std::vector<uint32_t> enumerate_ipv4_hosts(const std::string& cidr) {
uint32_t net=0, mask=0;
if (!parse_cidr(cidr, net, mask))
return {};
uint32_t first = net;
uint32_t last = net | (~mask);
std::vector<uint32_t> out;
// enumerate from first to last inclusive
for (uint32_t ip = first; ip <= last; ++ip) {
out.push_back(ip);
if (ip == 0xFFFFFFFFu)
break;
}
return out;
}
std::string ip_to_string(uint32_t ip) {
in_addr a{};
a.s_addr = htonl(ip);
char buf[INET_ADDRSTRLEN];
if (!inet_ntop(AF_INET, &a, buf, sizeof(buf)))
return "0.0.0.0";
return std::string(buf);
}
uint32_t ip_from_string(const std::string& s) {
in_addr a{};
if (inet_pton(AF_INET, s.c_str(), &a) != 1)
return 0;
return ntohl(a.s_addr);
}
} // namespace netcidr