summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--test/test_util.cpp24
-rw-r--r--util.cpp26
-rw-r--r--util.hpp8
3 files changed, 58 insertions, 0 deletions
diff --git a/test/test_util.cpp b/test/test_util.cpp
index 25953a1..0e58081 100644
--- a/test/test_util.cpp
+++ b/test/test_util.cpp
@@ -45,6 +45,30 @@ TEST_F(TestUtil, MacToString)
EXPECT_EQ("70:FF:84:09:35:09", mac_address::toString(mac2));
}
+TEST_F(TestUtil, AddrFromBuf)
+{
+ std::string tooSmall(1, 'a');
+ std::string tooLarge(24, 'a');
+
+ struct in_addr ip1;
+ EXPECT_EQ(1, inet_pton(AF_INET, "192.168.10.1", &ip1));
+ std::string_view buf1(reinterpret_cast<char*>(&ip1), sizeof(ip1));
+ InAddrAny res1 = addrFromBuf(AF_INET, buf1);
+ EXPECT_EQ(0, memcmp(&ip1, &std::get<struct in_addr>(res1), sizeof(ip1)));
+ EXPECT_THROW(addrFromBuf(AF_INET, tooSmall), std::runtime_error);
+ EXPECT_THROW(addrFromBuf(AF_INET, tooLarge), std::runtime_error);
+ EXPECT_THROW(addrFromBuf(AF_UNSPEC, buf1), std::runtime_error);
+
+ struct in6_addr ip2;
+ EXPECT_EQ(1, inet_pton(AF_INET6, "fdd8:b5ad:9d93:94ee::2:1", &ip2));
+ std::string_view buf2(reinterpret_cast<char*>(&ip2), sizeof(ip2));
+ InAddrAny res2 = addrFromBuf(AF_INET6, buf2);
+ EXPECT_EQ(0, memcmp(&ip2, &std::get<struct in6_addr>(res2), sizeof(ip2)));
+ EXPECT_THROW(addrFromBuf(AF_INET6, tooSmall), std::runtime_error);
+ EXPECT_THROW(addrFromBuf(AF_INET6, tooLarge), std::runtime_error);
+ EXPECT_THROW(addrFromBuf(AF_UNSPEC, buf2), std::runtime_error);
+}
+
TEST_F(TestUtil, IpToString)
{
struct in_addr ip1;
diff --git a/util.cpp b/util.cpp
index db164e6..b1300fb 100644
--- a/util.cpp
+++ b/util.cpp
@@ -204,6 +204,32 @@ std::string getNetworkID(int addressFamily, const std::string& ipaddress,
return networkString;
}
+InAddrAny addrFromBuf(int addressFamily, std::string_view buf)
+{
+ if (addressFamily == AF_INET)
+ {
+ struct in_addr ret;
+ if (buf.size() != sizeof(ret))
+ {
+ throw std::runtime_error("Buf not in_addr sized");
+ }
+ memcpy(&ret, buf.data(), sizeof(ret));
+ return ret;
+ }
+ else if (addressFamily == AF_INET6)
+ {
+ struct in6_addr ret;
+ if (buf.size() != sizeof(ret))
+ {
+ throw std::runtime_error("Buf not in6_addr sized");
+ }
+ memcpy(&ret, buf.data(), sizeof(ret));
+ return ret;
+ }
+
+ throw std::runtime_error("Unsupported address family");
+}
+
std::string toString(const InAddrAny& addr)
{
std::string ip;
diff --git a/util.hpp b/util.hpp
index 537c6a0..a07fa49 100644
--- a/util.hpp
+++ b/util.hpp
@@ -9,6 +9,7 @@
#include <regex>
#include <sdbusplus/bus.hpp>
#include <string>
+#include <string_view>
namespace phosphor
{
@@ -93,6 +94,13 @@ constexpr auto timeSynchdService = "systemd-timesyncd.service";
*/
uint8_t toCidr(int addressFamily, const std::string& mask);
+/* @brief converts a sockaddr for the specified address family into
+ * a type_safe InAddrAny.
+ * @param[in] addressFamily - The address family of the buf
+ * @param[in] buf - The network byte order address
+ */
+InAddrAny addrFromBuf(int addressFamily, std::string_view buf);
+
/* @brief converts the ip bytes into a string representation
* @param[in] addr - input ip address to convert.
* @returns String representation of the ip.
OpenPOWER on IntegriCloud