-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
IP: fix minor errors, expand network categorization utilities.
- Loading branch information
1 parent
5cb7e29
commit e5a9536
Showing
6 changed files
with
264 additions
and
51 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// Copyright Network Geographics 2014 | ||
/** @file | ||
Shared utilities for IP address classes. | ||
*/ | ||
|
||
#pragma once | ||
#include <netinet/in.h> | ||
|
||
#include "swoc/swoc_version.h" | ||
|
||
// These have to be global namespace, unfortunately. | ||
inline bool | ||
operator==(in6_addr const& lhs, in6_addr const& rhs) { | ||
return 0 == memcmp(&lhs, &rhs, sizeof(in6_addr)); | ||
} | ||
|
||
inline bool | ||
operator!=(in6_addr const& lhs, in6_addr const& rhs) { | ||
return 0 != memcmp(&lhs, &rhs, sizeof(in6_addr)); | ||
} | ||
|
||
namespace swoc { inline namespace SWOC_VERSION_NS { | ||
|
||
/// Internal IP address utilities. | ||
namespace ip { | ||
|
||
inline bool is_loopback_host_order(in_addr_t addr) { | ||
return (addr & 0xFF000000) == 0x7F000000; | ||
} | ||
|
||
inline bool is_link_local_host_order(in_addr_t addr) { | ||
return (addr & 0xFFFF0000) == 0xA9FE0000; // 169.254.0.0/16 | ||
} | ||
|
||
inline bool is_multicast_host_order(in_addr_t addr) { | ||
return IN_MULTICAST(addr); | ||
} | ||
|
||
inline bool is_private_host_order(in_addr_t addr) { | ||
return (((addr & 0xFF000000) == 0x0A000000) || // 10.0.0.0/8 | ||
((addr & 0xFFC00000) == 0x64400000) || // 100.64.0.0/10 | ||
((addr & 0xFFF00000) == 0xAC100000) || // 172.16.0.0/12 | ||
((addr & 0xFFFF0000) == 0xC0A80000) // 192.168.0.0/16 | ||
); | ||
} | ||
|
||
// There really is no "host order" for IPv6, so only the network order utilities are defined. | ||
// @c IP6Addr uses an idiosyncratic ordering for performance, not really useful to expose to | ||
// clients. | ||
|
||
inline bool is_loopback_network_order(in6_addr const& addr) { | ||
return addr == in6addr_loopback; | ||
} | ||
|
||
inline bool is_multicast_network_order(in6_addr const& addr) { | ||
return addr.s6_addr[0] == 0xFF; | ||
} | ||
|
||
inline bool is_link_local_network_order(in6_addr const& addr) { | ||
return addr.s6_addr[0] == 0xFE && (addr.s6_addr[1] & 0xC0) == 0x80; // fe80::/10 | ||
} | ||
|
||
inline bool is_private_network_order(in6_addr const& addr) { | ||
return (addr.s6_addr[0] & 0xFE) == 0xFC; // fc00::/7 | ||
} | ||
|
||
#if BYTE_ORDER == LITTLE_ENDIAN | ||
|
||
inline bool is_loopback_network_order(in_addr_t addr) { | ||
return (addr & 0xFF) == 0x7F; | ||
} | ||
|
||
inline bool is_private_network_order(in_addr_t addr) { | ||
return (((addr & 0xFF) == 0x0A) || // 10.0.0.0/8 | ||
((addr & 0xC0FF) == 0x4064) || // 100.64.0.0/10 | ||
((addr & 0xF0FF) == 0x10AC) || // 172.16.0.0/12 | ||
((addr & 0xFFFF) == 0xA8C0) // 192.168.0.0/16 | ||
); | ||
} | ||
|
||
inline bool is_link_local_network_order(in_addr_t addr) { | ||
return (addr & 0xFFFF) == 0xFEA9; // 169.254.0.0/16 | ||
} | ||
|
||
inline bool is_multicast_network_order(in_addr_t addr) { | ||
return (addr & 0xF0) == 0xE0; | ||
} | ||
|
||
#else | ||
|
||
inline bool is_loopback_network_order(in_addr_t addr) { | ||
return is_loopback_host_order(addr); | ||
} | ||
|
||
inline bool is_link_local_network_order(inaddr_t addr) { | ||
return is_link_local_host_order(addr); | ||
} | ||
|
||
inline bool is_private_network_order(in_addr_t addr) { | ||
return is_link_local_host_order(addr); | ||
} | ||
|
||
inline bool is_multicast_network_order(in_addr_t addr) { | ||
return is_multicast_host_order(addr); | ||
} | ||
|
||
#endif | ||
|
||
/** Check if the address in a socket address is a loopback address.. | ||
* @return @c true if so, @c false if not. | ||
*/ | ||
inline bool is_loopback(sockaddr const * sa) { | ||
return ( sa->sa_family == AF_INET && is_loopback_network_order(reinterpret_cast<sockaddr_in const *>(sa)->sin_addr.s_addr)) || | ||
( sa->sa_family == AF_INET6 && is_loopback_network_order(reinterpret_cast<sockaddr_in6 const *>(sa)->sin6_addr)) | ||
; | ||
} | ||
|
||
/** Check if the address in a socket address is multicast. | ||
* @return @c true if so, @c false if not. | ||
*/ | ||
inline bool is_multicast(sockaddr const * sa) { | ||
return ( sa->sa_family == AF_INET && is_multicast_network_order(reinterpret_cast<sockaddr_in const *>(sa)->sin_addr.s_addr)) || | ||
( sa->sa_family == AF_INET6 && is_multicast_network_order(reinterpret_cast<sockaddr_in6 const *>(sa)->sin6_addr)) | ||
; | ||
} | ||
|
||
/** Check if the IP address in a socket address is link local. | ||
* @return @c true if link local, @c false if not. | ||
*/ | ||
inline bool is_link_local(sockaddr const* sa) { | ||
return ( sa->sa_family == AF_INET && is_link_local_network_order(reinterpret_cast<sockaddr_in const *>(sa)->sin_addr.s_addr)) || | ||
( sa->sa_family == AF_INET6 && is_link_local_network_order(reinterpret_cast<sockaddr_in6 const *>(sa)->sin6_addr)) | ||
; | ||
} | ||
|
||
/** Check if the IP address in a socket address is private (non-routable) | ||
* @return @c true if private, @c false if not. | ||
*/ | ||
inline bool is_private(sockaddr const* sa) { | ||
return ( sa->sa_family == AF_INET && is_private_network_order(reinterpret_cast<sockaddr_in const *>(sa)->sin_addr.s_addr)) || | ||
( sa->sa_family == AF_INET6 && is_private_network_order(reinterpret_cast<sockaddr_in6 const *>(sa)->sin6_addr)) | ||
; | ||
} | ||
|
||
} // hnamespace ip | ||
|
||
}} // namespace swoc::SWOC_VERSION_NS |
Oops, something went wrong.