Skip to content

Commit 5a5adce

Browse files
Lukas HutakLukas955
authored andcommitted
fdsdump: ipaddr: define component
1 parent 301c4bb commit 5a5adce

File tree

2 files changed

+182
-0
lines changed

2 files changed

+182
-0
lines changed

src/tools/fdsdump/src/ipaddr.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
2+
#include <stdexcept>
3+
#include "ipaddr.hpp"
4+
5+
IPAddr::IPAddr(const std::string &str)
6+
{
7+
struct in_addr ip4;
8+
struct in6_addr ip6;
9+
10+
if (inet_pton(AF_INET, str.c_str(), &ip4) == 1) {
11+
u64[0] = 0;
12+
u32[2] = htonl(0x0000FFFF);
13+
memcpy(&u32[3], &ip4, 4U);
14+
return;
15+
}
16+
17+
if (inet_pton(AF_INET6, str.c_str(), &ip6) == 1) {
18+
memcpy(&u8[0], &ip6, 16U);
19+
return;
20+
}
21+
22+
throw std::invalid_argument("IPAddr: Not an IP address!");
23+
}
24+
25+
std::string
26+
IPAddr::to_string() const
27+
{
28+
char buffer[INET6_ADDRSTRLEN];
29+
if (is_ip4()) {
30+
inet_ntop(AF_INET, &u32[3], buffer, sizeof(buffer));
31+
} else {
32+
inet_ntop(AF_INET6, &u8[0], buffer, sizeof(buffer));
33+
}
34+
return std::string(buffer);
35+
}
36+

src/tools/fdsdump/src/ipaddr.hpp

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
2+
#pragma once
3+
4+
#include <arpa/inet.h>
5+
#include <cassert>
6+
#include <cstdint>
7+
#include <cstring>
8+
#include <string>
9+
#include <iostream>
10+
11+
/**
12+
* @brief IPv4/IPv6 address representation
13+
*/
14+
union IPAddr {
15+
uint8_t u8[16];
16+
uint16_t u16[8];
17+
uint32_t u32[4];
18+
uint64_t u64[2];
19+
20+
/**
21+
* @brief Default constructor (zeroes)
22+
*/
23+
IPAddr()
24+
{
25+
memset(this, 0, sizeof(*this));
26+
}
27+
28+
/**
29+
* @brief Create an IPv4/IPv6 address from a string
30+
* @param[in] str IP address in text form
31+
* @throw std::invalid_argument if the IP address is not valid
32+
*/
33+
explicit IPAddr(const std::string &str);
34+
35+
/**
36+
* @brief Create an IPv4 address (from 4 bytes array)
37+
*/
38+
explicit IPAddr(const uint32_t ip4)
39+
{
40+
u64[0] = 0;
41+
u32[2] = htonl(0x0000FFFF);
42+
u32[3] = ip4;
43+
};
44+
45+
/**
46+
* @brief Create an IPv6 address (from 16 bytes array)
47+
*/
48+
explicit IPAddr(const uint8_t ip6[16])
49+
{
50+
std::memcpy(&u8[0], &ip6[0], 16U);
51+
};
52+
53+
/**
54+
* @brief Check if the address is IPv4
55+
*/
56+
bool
57+
is_ip4() const
58+
{
59+
return u64[0] == 0 && u32[2] == htonl(0x0000FFFF);
60+
};
61+
62+
/**
63+
* @brief Check if the address is IPv6
64+
*/
65+
bool
66+
is_ip6() const
67+
{
68+
return !is_ip4();
69+
};
70+
71+
/**
72+
* @brief Get IPv4 address as one 32b number
73+
* @returns Address in network byte order.
74+
*/
75+
uint32_t get_ip4_as_uint() const
76+
{
77+
return u32[3];
78+
};
79+
80+
/**
81+
* @brief Get pointer to byte array of IPv4 address
82+
* @note Address is in network byte order!
83+
* @returns Pointer to the first byte of IP address data structure.
84+
*/
85+
uint8_t *
86+
get_ip4_as_bytes()
87+
{
88+
return &u8[12];
89+
};
90+
91+
/**
92+
* @brief Get pointer to byte array of IPv6 address
93+
* @note Address is in network byte order!
94+
* @returns Pointer to the first byte of IP address data structure.
95+
*/
96+
uint8_t *
97+
get_ip6_as_bytes()
98+
{
99+
return &u8[0];
100+
};
101+
102+
/**
103+
* @brief Convert IP address to string
104+
*/
105+
std::string to_string() const;
106+
107+
// Standard comparison operators
108+
inline bool
109+
operator==(const IPAddr &other) const
110+
{
111+
return memcmp(this, &other, sizeof(*this)) == 0;
112+
};
113+
114+
inline bool
115+
operator!=(const IPAddr &other) const
116+
{
117+
return memcmp(this, &other, sizeof(*this)) != 0;
118+
};
119+
120+
inline bool
121+
operator<(const IPAddr &other) const
122+
{
123+
return memcmp(this, &other, sizeof(*this)) < 0;
124+
};
125+
126+
inline bool
127+
operator>(const IPAddr &other) const
128+
{
129+
return memcmp(this, &other, sizeof(*this)) > 0;
130+
};
131+
132+
inline bool
133+
operator<=(const IPAddr &other) const
134+
{
135+
return memcmp(this, &other, sizeof(*this)) <= 0;
136+
};
137+
138+
inline bool
139+
operator>=(const IPAddr &other) const
140+
{
141+
return memcmp(this, &other, sizeof(*this)) >= 0;
142+
};
143+
};
144+
145+
static_assert(sizeof(IPAddr) == 16U, "Unexpected union size!");
146+

0 commit comments

Comments
 (0)