13 #include <arpa/inet.h> 17 const uint32_t CIDR_MASK_MAP[33] = {
18 0x00000000, 0x00000080, 0x000000c0, 0x000000e0, 0x000000f0, 0x000000f8,
19 0x000000fc, 0x000000fe, 0x000000ff, 0x000080ff, 0x0000c0ff, 0x0000e0ff,
20 0x0000f0ff, 0x0000f8ff, 0x0000fcff, 0x0000feff, 0x0000ffff, 0x0080ffff,
21 0x00c0ffff, 0x00e0ffff, 0x00f0ffff, 0x00f8ffff, 0x00fcffff, 0x00feffff,
22 0x00ffffff, 0x80ffffff, 0xc0ffffff, 0xe0ffffff, 0xf0ffffff, 0xf8ffffff,
23 0xfcffffff, 0xfeffffff, 0xffffffff
34 if (cidr > 32)
throw "bad_route_length";
35 return CIDR_MASK_MAP[cidr];
55 if (length > 32)
throw "bad_route_length";
57 this->prefix = prefix;
58 this->length = length;
69 if (length > 32)
throw "bad_route_length";
71 this->length = length;
72 inet_pton(AF_INET, prefix, &(this->prefix));
85 if (buf_sz < 1)
return -1;
86 length = getValue<uint8_t>(&buffer);
87 size_t prefix_buf_len = (length + 7) / 8;
88 if (prefix_buf_len + 1 > buf_sz)
return -1;
90 memcpy(&prefix, buffer, prefix_buf_len);
91 return prefix_buf_len + 1;
104 size_t prefix_buf_len = (length + 7) / 8;
105 if (buf_sz < 1 + prefix_buf_len)
return -1;
106 putValue<uint8_t>(&buffer, length);
107 memcpy(buffer, &prefix, prefix_buf_len);
108 return prefix_buf_len + 1;
121 if (length > 32)
return false;
122 return (address & CIDR_MASK_MAP[length]) == prefix;
135 bool Prefix4::Includes (uint32_t prefix_a, uint8_t length_a, uint32_t prefix_b, uint8_t length_b) {
136 if (length_a > 32 || length_b > 32)
return false;
137 if (length_b < length_a)
return false;
138 return (prefix_b & CIDR_MASK_MAP[length_a]) == prefix_a;
149 return (address & CIDR_MASK_MAP[length]) == prefix;
160 uint32_t address_int = 0;
161 if (inet_pton(AF_INET, address, &address_int) <= 0)
return false;
174 if (length > 32)
return false;
175 if (length < this->length)
return false;
176 return (prefix & CIDR_MASK_MAP[this->length]) == this->prefix;
187 if (other.afi != IPV4)
return false;
189 return includes (other_4.prefix, other_4.length);
201 uint32_t prefix_int = 0;
202 if (inet_pton(AF_INET, prefix, &prefix_int) <= 0)
return false;
203 return includes(prefix_int, length);
214 if (other.afi != IPV4)
return false;
216 return other_4.prefix == prefix && other_4.length == length;
219 bool Prefix4::operator> (
const Prefix &other)
const {
220 if (other.afi != IPV4)
return false;
222 return length < other_4.length;
225 bool Prefix4::operator< (
const Prefix &other)
const {
226 if (other.afi != IPV4)
return false;
228 return length > other_4.length;
231 bool Prefix4::operator>= (
const Prefix &other)
const {
232 return !(*
this < other);
235 bool Prefix4::operator<= (
const Prefix &other)
const {
236 return !(*
this > other);
239 bool Prefix4::operator!= (
const Prefix &other)
const {
240 return !(*
this == other);
252 if (length > 32)
return false;
253 this->length = length;
254 this->prefix = prefix;
266 this->prefix = prefix;
278 if (length > 32)
return false;
279 this->length = length;
308 if (length > 32)
throw "bad_route_length";
309 return CIDR_MASK_MAP[length];
uint32_t getPrefix() const
Get prefix.
uint32_t getMask() const
Get netmask.
static bool Includes(uint32_t prefix, uint8_t length, uint32_t address)
Test if an address is inside a prefix.
bool set(uint32_t prefix, uint8_t length)
Set Prefix4.
bool setLength(uint8_t length)
Set netmask.
bool includes(uint32_t address) const
Test if an address is inside this prefix.
bool operator==(const Prefix &other) const
Test if two routes are equals.
uint8_t getLength() const
Get netmask.
uint32_t cidr_to_mask(uint8_t cidr)
Convert netmask in CIDR notation to network bytes integer.
Prefix4()
Construct a new Prefix4 object.
bool setPrefix(uint32_t prefix)
Set prefix.
IPv4 Route/Prefix related utilities.
Buffer operation helpers.
IPv4 Route/Prefix related utilities.
ssize_t write(uint8_t *buffer, size_t buf_sz) const
Write a IPv4 prefix to NLRI buffer.
Route/Prefix related utilities.
ssize_t parse(const uint8_t *buffer, size_t buf_sz)
Parse a IPv4 NLRI prefix from buffer.