Add the network utility file
Moving utility functions from network manager to
util.cpp.
Added few more utility functions.
Change-Id: I2e73c873e9a3bea543d6979463b2181e8374e12e
Signed-off-by: Ratan Gupta <ratagupt@in.ibm.com>
diff --git a/Makefile.am b/Makefile.am
index 6c5aec9..f2a9174 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -15,7 +15,8 @@
network_config.hpp \
network_manager.hpp \
ipaddress.hpp \
- types.hpp
+ types.hpp \
+ util.hpp
phosphor_network_manager_SOURCES = \
ethernet_interface.cpp \
@@ -24,7 +25,8 @@
network_manager.cpp \
network_manager_main.cpp \
xyz/openbmc_project/Network/VLAN/Create/server.cpp \
- xyz/openbmc_project/Network/IP/Create/server.cpp
+ xyz/openbmc_project/Network/IP/Create/server.cpp \
+ util.cpp
CLEANFILES = \
xyz/openbmc_project/Network/VLAN/Create/server.cpp \
diff --git a/ethernet_interface.hpp b/ethernet_interface.hpp
index f9bd895..6ef1ec9 100644
--- a/ethernet_interface.hpp
+++ b/ethernet_interface.hpp
@@ -2,6 +2,7 @@
#include "ipaddress.hpp"
#include "types.hpp"
+#include "util.hpp"
#include "xyz/openbmc_project/Network/EthernetInterface/server.hpp"
#include "xyz/openbmc_project/Network/IP/Create/server.hpp"
diff --git a/network_manager.cpp b/network_manager.cpp
index 8ea82d5..a4a9b54 100644
--- a/network_manager.cpp
+++ b/network_manager.cpp
@@ -105,9 +105,9 @@
IntfAddrMap Manager::getInterfaceAddrs() const
{
- IntfAddrMap intfMap;
- AddrList addrList;
- struct ifaddrs* ifaddr;
+ IntfAddrMap intfMap{};
+ AddrList addrList{};
+ struct ifaddrs* ifaddr = nullptr;
using namespace sdbusplus::xyz::openbmc_project::Common::Error;
// attempt to fill struct with ifaddrs
@@ -122,7 +122,7 @@
details::AddrPtr ifaddrPtr(ifaddr);
ifaddr = nullptr;
- std::string intfName;
+ std::string intfName{};
for (ifaddrs* ifa = ifaddrPtr.get(); ifa != nullptr; ifa = ifa->ifa_next)
{
@@ -151,7 +151,7 @@
addrList.clear();
}
intfName = ifa->ifa_name;
- AddrInfo info;
+ AddrInfo info{};
char ip[INET6_ADDRSTRLEN] = { 0 };
char subnetMask[INET6_ADDRSTRLEN] = { 0 };
@@ -185,9 +185,7 @@
info.addrType = ifa->ifa_addr->sa_family;
info.ipaddress = ip;
-
- info.prefix = toCidr(info.addrType, subnetMask);
-
+ info.prefix = toCidr(info.addrType, std::string(subnetMask));
addrList.emplace_back(info);
}
}
@@ -195,96 +193,5 @@
return intfMap;
}
-uint8_t Manager::toCidr(int addressFamily, const std::string& subnetMask) const
-{
- uint32_t buff = 0;
-
- if (addressFamily == AF_INET6)
- {
- return toV6Cidr(std::string(subnetMask));
- }
-
- auto rc = inet_pton(addressFamily, subnetMask.c_str(), &buff);
- if (rc <= 0)
- {
- log<level::ERR>("inet_pton failed:",
- entry("SUBNETMASK=%s", subnetMask.c_str()));
- }
-
- buff = be32toh(buff);
- // total no of bits - total no of leading zero == total no of ones
- if (((sizeof(buff) * 8) - (__builtin_ctz(buff))) == __builtin_popcount(buff))
- {
- return __builtin_popcount(buff);
- }
- else
- {
- log<level::ERR>("Invalid Mask",
- entry("SUBNETMASK=%s", subnetMask.c_str()));
- return 0;
- }
-}
-
-uint8_t Manager::toV6Cidr(const std::string& subnetMask) const
-{
- uint8_t pos {};
- uint8_t prevPos {};
- uint8_t cidr {};
- uint16_t buff {};
-
- log<level::INFO>("toV6Cidr called with",
- entry("SUBNETMASK=%s", subnetMask));
- do
- {
- //subnet mask look like ffff:ffff::
- // or ffff:c000::
- pos = subnetMask.find(":", prevPos);
- if (pos == std::string::npos)
- {
- return cidr;
- }
-
- auto str = subnetMask.substr(prevPos, (pos - prevPos));
- prevPos = pos + 1;
-
- // String length is 0
- if (!str.length())
- {
- return cidr;
- }
- //converts it into number.
- if (sscanf(str.c_str(), "%hx", &buff) <= 0)
- {
- log<level::ERR>("Invalid SubnetMask",
- entry("SUBNETMASK=%s", subnetMask));
-
- return 0;
- }
-
- // convert the number into bitset
- // and check for how many ones are there.
- // if we don't have all the ones then make
- // sure that all the ones should be left justify.
-
- if (__builtin_popcount(buff) != 16)
- {
- if (((sizeof(buff) * 8) - (__builtin_ctz(buff))) != __builtin_popcount(buff))
- {
- log<level::ERR>("Invalid SubnetMask",
- entry("SUBNETMASK=%s", subnetMask));
-
- return 0;
- }
- cidr += __builtin_popcount(buff);
- return cidr;
- }
- cidr += 16;
-
- }
- while (1);
-
- return cidr;
-}
-
}//namespace network
}//namespace phosphor
diff --git a/network_manager.hpp b/network_manager.hpp
index d0cb779..553951c 100644
--- a/network_manager.hpp
+++ b/network_manager.hpp
@@ -80,19 +80,6 @@
*/
IntfAddrMap getInterfaceAddrs() const;
- /** @brief converts the given subnet into prefix notation
- * @param[in] addressFamily - IP address family(AF_INET/AF_INET6)
- * @param[in] subnetMask - SubnetMask which needs to be converted.
- * @returns prefix.
- */
- uint8_t toCidr(int addressFamily, const std::string& subnetMask) const;
-
- /** @brief converts the given V6 subnet into prefix notation
- * @param[in] subnetMask - SubnetMask which needs to be converted.
- * @returns prefix.
- */
- uint8_t toV6Cidr(const std::string& subnetMask) const;
-
/** @brief Persistent map of EthernetInterface dbus objects and their names */
std::map<IntfName, std::unique_ptr<EthernetInterface>> interfaces;
diff --git a/util.cpp b/util.cpp
new file mode 100644
index 0000000..740d4a7
--- /dev/null
+++ b/util.cpp
@@ -0,0 +1,144 @@
+#include <arpa/inet.h>
+#include <dirent.h>
+#include <net/if.h>
+
+#include <iostream>
+#include <list>
+#include <string>
+#include <algorithm>
+#include <phosphor-logging/log.hpp>
+
+namespace phosphor
+{
+namespace network
+{
+namespace
+{
+
+using namespace phosphor::logging;
+
+uint8_t toV6Cidr(const std::string& subnetMask)
+{
+ uint8_t pos = 0;
+ uint8_t prevPos = 0;
+ uint8_t cidr = 0;
+ uint16_t buff {};
+ do
+ {
+ //subnet mask look like ffff:ffff::
+ // or ffff:c000::
+ pos = subnetMask.find(":", prevPos);
+ if (pos == std::string::npos)
+ {
+ break;
+ }
+
+ auto str = subnetMask.substr(prevPos, (pos - prevPos));
+ prevPos = pos + 1;
+
+ // String length is 0
+ if (!str.length())
+ {
+ return cidr;
+ }
+ //converts it into number.
+ if (sscanf(str.c_str(), "%hx", &buff) <= 0)
+ {
+ log<level::ERR>("Invalid Mask",
+ entry("SUBNETMASK=%s", subnetMask));
+
+ return 0;
+ }
+
+ // convert the number into bitset
+ // and check for how many ones are there.
+ // if we don't have all the ones then make
+ // sure that all the ones should be left justify.
+
+ if (__builtin_popcount(buff) != 16)
+ {
+ if (((sizeof(buff) * 8) - (__builtin_ctz(buff))) != __builtin_popcount(buff))
+ {
+ log<level::ERR>("Invalid Mask",
+ entry("SUBNETMASK=%s", subnetMask));
+
+ return 0;
+ }
+ cidr += __builtin_popcount(buff);
+ return cidr;
+ }
+
+ cidr += 16;
+ }
+ while (1);
+
+ return cidr;
+}
+}// anonymous namespace
+
+uint8_t toCidr(int addressFamily, const std::string& subnetMask)
+{
+ if (addressFamily == AF_INET6)
+ {
+ return toV6Cidr(subnetMask);
+ }
+
+ uint32_t buff;
+
+ auto rc = inet_pton(addressFamily, subnetMask.c_str(), &buff);
+ if (rc <= 0)
+ {
+ log<level::ERR>("inet_pton failed:",
+ entry("SUBNETMASK=%s", subnetMask));
+ return 0;
+ }
+
+ buff = be32toh(buff);
+ // total no of bits - total no of leading zero == total no of ones
+ if (((sizeof(buff) * 8) - (__builtin_ctz(buff))) == __builtin_popcount(buff))
+ {
+ return __builtin_popcount(buff);
+ }
+ else
+ {
+ log<level::ERR>("Invalid Mask",
+ entry("SUBNETMASK=%s", subnetMask));
+ return 0;
+ }
+}
+
+std::string toMask(int addressFamily, uint8_t prefix)
+{
+ if (addressFamily == AF_INET6)
+ {
+ //TODO:- conversion for v6
+ return "";
+ }
+
+ if (prefix < 1 || prefix > 30)
+ {
+ log<level::ERR>("Invalid Prefix",
+ entry("PREFIX=%d", prefix));
+ return "";
+ }
+ /* Create the netmask from the number of bits */
+ unsigned long mask = 0;
+ for (auto i = 0 ; i < prefix ; i++)
+ {
+ mask |= 1 << (31 - i);
+ }
+ struct in_addr netmask;
+ netmask.s_addr = htonl(mask);
+ return inet_ntoa(netmask);
+}
+
+bool isLinkLocal(const std::string& address)
+{
+ std::string linklocal = "fe80";
+ return std::mismatch(linklocal.begin(), linklocal.end(),
+ address.begin()).first == linklocal.end() ?
+ true : false;
+}
+
+}//namespace network
+}//namespace phosphor
diff --git a/util.hpp b/util.hpp
new file mode 100644
index 0000000..c305724
--- /dev/null
+++ b/util.hpp
@@ -0,0 +1,61 @@
+#pragma once
+
+#include <unistd.h>
+
+namespace phosphor
+{
+namespace network
+{
+
+/* @brief converts the given subnet into prefix notation.
+ * @param[in] addressFamily - IP address family(AF_INET/AF_INET6).
+ * @param[in] mask - Subnet Mask.
+ * @returns prefix.
+ */
+uint8_t toCidr(int addressFamily, const std::string& mask);
+
+/* @brief converts the prefix into subnetmask.
+ * @param[in] addressFamily - IP address family(AF_INET/AF_INET6).
+ * @param[in] prefix - prefix length.
+ * @returns subnet mask.
+ */
+std::string toMask(int addressFamily, uint8_t prefix);
+
+/* @brief checks that the given ip address is link local or not.
+ * @param[in] address - IP address.
+ * @returns true if it is linklocal otherwise false.
+ */
+bool isLinkLocal(const std::string& address);
+
+} //namespace network
+
+class Descriptor
+{
+ private:
+ /** default value */
+ int fd = -1;
+
+ public:
+ Descriptor() = delete;
+ Descriptor(const Descriptor&) = delete;
+ Descriptor& operator=(const Descriptor&) = delete;
+ Descriptor(Descriptor&&) = delete;
+ Descriptor& operator=(Descriptor&&) = delete;
+
+ Descriptor(int fd) : fd(fd) {}
+
+ ~Descriptor()
+ {
+ if (fd >= 0)
+ {
+ close(fd);
+ }
+ }
+
+ int operator()() const
+ {
+ return fd;
+ }
+};
+
+} //namespace phosphor