15 TRACE(
"Executing netmask_to_bitmask()")
16 if (a_netmask ==
nullptr)
17 throw std::runtime_error(UPnPsdk_LOGEXCEPT(
18 "MSG1059")
"No network socket address information given.\n");
22 switch (a_netmask->ss_family) {
25 for (
size_t i{}; i <
sizeof(in6_addr); i++) {
26 uint8_t s6addr =
reinterpret_cast<const ::sockaddr_in6*
>(a_netmask)
27 ->sin6_addr.s6_addr[i];
39 for (
int i{
sizeof(in6_addr) - 1}; i >= 0; i--) {
40 uint8_t s6addr =
reinterpret_cast<const ::sockaddr_in6*
>(a_netmask)
41 ->sin6_addr.s6_addr[i];
45 while ((s6addr & 1) == 0) {
53 if (bitmask + nullbits != 128) {
54 char ip_str[INET6_ADDRSTRLEN]{};
57 &
reinterpret_cast<const ::sockaddr_in6*
>(a_netmask)->sin6_addr,
58 ip_str,
sizeof(ip_str));
59 throw std::runtime_error(
61 "MSG1067")
"Invalid ip-address prefix bitmask \"[" +
62 std::string(ip_str) +
"]\".\n");
67 in_addr_t saddr = ntohl(
68 reinterpret_cast<const ::sockaddr_in*
>(a_netmask)->sin_addr.s_addr);
69 in_addr_t saddr0 = saddr;
76 for (
int i{}; (saddr0 & 1) == 0 && i < 32; i++) {
81 if (bitmask + nullbits != 32) {
82 char ip_str[INET_ADDRSTRLEN]{};
85 &
reinterpret_cast<const ::sockaddr_in*
>(a_netmask)->sin_addr,
86 ip_str,
sizeof(ip_str));
87 throw std::runtime_error(
88 UPnPsdk_LOGEXCEPT(
"MSG1069")
"Invalid ip-address netmask \"" +
89 std::string(ip_str) +
"\".\n");
97 throw std::runtime_error(
98 UPnPsdk_LOGEXCEPT(
"MSG1028")
"Unsupported address family(" +
99 std::to_string(a_netmask->ss_family) +
"), only AF_INET6(" +
100 std::to_string(AF_INET6) +
"), AF_INET(" + std::to_string(AF_INET) +
101 "), or AF_UNSPEC(" + std::to_string(AF_UNSPEC) +
") are valid.\n");
109 const unsigned int a_prefixlength,
111 TRACE(
"Executing bitmask_to_netmask()")
112 if (a_saddr ==
nullptr)
113 throw std::runtime_error(UPnPsdk_LOGEXCEPT(
114 "MSG1070")
"No associated socket address for the netmask given.\n");
116 switch (a_saddr->ss_family) {
126 if (a_prefixlength > 128)
127 throw std::runtime_error(
129 "MSG1124")
"Invalid IPv6 address prefix bitmask(" +
130 std::to_string(a_prefixlength) +
") exceeds 128.\n");
133 unsigned int ones_bytes{a_prefixlength / 8};
137 for (; i < ones_bytes; i++)
138 netmask6.s6_addr[i] =
static_cast<uint8_t
>(~0);
143 netmask6.s6_addr[i] =
static_cast<uint8_t
>(~0);
146 netmask6.s6_addr[i] <<= (8 - (a_prefixlength % 8));
151 netmask6.s6_addr[i] = 0;
156 a_saddrObj.
sin6.sin6_family = AF_INET6;
157 memcpy(&a_saddrObj.
sin6.sin6_addr, &netmask6,
158 sizeof(a_saddrObj.
sin6.sin6_addr));
163 if (a_prefixlength > 32) {
164 throw std::runtime_error(
166 "MSG1125")
"Invalid IPv4 address prefix bitmask(" +
167 std::to_string(a_prefixlength) +
") exceeds 32.\n");
170 ::sockaddr_in saddr{};
171 saddr.sin_family = AF_INET;
172 if (a_prefixlength) {
173 in_addr_t bitshift{~0u};
174 bitshift <<= (32 - a_prefixlength);
175 saddr.sin_addr.s_addr = htonl(bitshift);
178 a_saddrObj.
sin = saddr;
186 throw std::runtime_error(
187 UPnPsdk_LOGEXCEPT(
"MSG1126")
"Unsupported address family(" +
188 std::to_string(a_saddr->ss_family) +
"), only AF_INET6(" +
189 std::to_string(AF_INET6) +
"), AF_INET(" + std::to_string(AF_INET) +
190 "), or AF_UNSPEC(" + std::to_string(AF_UNSPEC) +
") are valid.\n");
199 : m_na_platformPtr(a_na_platformPtr) {
200 TRACE2(
this,
" Construct CNetadapter()")
203CNetadapter::~CNetadapter() {
204 TRACE2(
this,
" Destruct CNetadapter()")
216 m_na_platformPtr->sockaddr(a_saddr);
220 m_na_platformPtr->socknetmask(a_snetmask);
224 return m_na_platformPtr->bitmask();
227void CNetadapter::reset() noexcept {
229 m_state = Find::finish;
230 m_na_platformPtr->reset();
235 TRACE2(
this,
" Executing CNetadapter::find_first()")
242 if (a_name_or_addr.empty()) {
244 if (this->
index() == 0)
250 m_state = Find::best;
261 if (a_name_or_addr ==
"loopback") {
266 m_state = Find::loopback;
280 if (this->
name() == a_name_or_addr) {
283 m_find_index = this->
index();
284 m_state = Find::index;
297 input_saObj = std::string(a_name_or_addr);
298 }
catch (std::exception&) {
304 if (nad_saObj == input_saObj) {
306 m_state = Find::finish;
315 TRACE2(
this,
" Executing CNetadapter::find_first(" +
316 std::to_string(a_index) +
")")
318 if (this->
index() == 0)
323 if (this->
index() == a_index) {
326 m_find_index = a_index;
327 m_state = Find::index;
337 TRACE2(
this,
" Executing CNetadapter::find_next()")
352 case Find::loopback: {
363 if (
index == m_find_index) {
372 m_state = Find::finish;
UPnPsdk_API CNetadapter(PNetadapter_platform a_na_platformPtr=std::make_shared< CNetadapter_platform >())
Constructor.
UPnPsdk_API void get_first()
Load a list of network adapters from the operating system and select its first entry.
UPnPsdk_API void socknetmask(SSockaddr &a_snetmask) const
Get socket address netmask from current selected list entry.
UPnPsdk_API void sockaddr(SSockaddr &a_saddr) const
Get socket address from current selected list entry.
UPnPsdk_API bool find_next()
Find next ip address from local network adapters.
UPnPsdk_API unsigned int index() const
Get index number from current selected list entry.
UPnPsdk_API std::string name() const
Get network adapter name from current selected list entry.
UPnPsdk_API bool get_next()
Select next entry from the network adapter list that was initial loaded with get_first().
UPnPsdk_API bool find_first(std::string_view a_name_or_addr="")
Find local network adapter with given name or ip address.
UPnPsdk_API unsigned int bitmask() const
Get prefix length from the ip address of the current selected local network adapter.
uint8_t netmask_to_bitmask(const ::sockaddr_storage *a_netmask)
Get prefix bit number from a network address mask.
void bitmask_to_netmask(const ::sockaddr_storage *a_saddr, const unsigned int a_prefixlength, SSockaddr &a_saddrObj)
Get network address mask from address prefix bit number.
Reengineered Object Oriented UPnP+ program code.
std::shared_ptr< INetadapter > PNetadapter_platform
Smart pointer to hold the injected pointer to the netadapter object for the current used platform.
Manage information about network adapters.
Trivial ::sockaddr structures enhanced with methods.
sockaddr_in & sin
Reference to sockaddr_in struct.
sockaddr_in6 & sin6
Reference to sockaddr_in6 struct.
bool is_loopback() const
Get if the socket address is a loopback address.
Define macro for synced logging to the console for detailed info and debug.