diff options
| author | Ratan Gupta <ratagupt@in.ibm.com> | 2017-04-21 10:38:05 +0530 |
|---|---|---|
| committer | Patrick Williams <patrick@stwcx.xyz> | 2017-05-23 11:58:44 +0000 |
| commit | 738a67fe79e3460541592cc64b139f0d2f5bd4d4 (patch) | |
| tree | 5ea3a5b7466e698866756cedcd642d794b0153b8 | |
| parent | 82549ccaa0f6373f664b260c7461adfd9f7665ba (diff) | |
| download | phosphor-networkd-738a67fe79e3460541592cc64b139f0d2f5bd4d4.tar.gz phosphor-networkd-738a67fe79e3460541592cc64b139f0d2f5bd4d4.zip | |
Convert IPv4 subnet mask into prefix length
Resolves openbmc/openbmc#1292
Change-Id: I9b24e98589bd68cc59893b5e43b514bd0bec3f26
Signed-off-by: Ratan Gupta <ratagupt@in.ibm.com>
| -rw-r--r-- | network_manager.cpp | 62 | ||||
| -rw-r--r-- | network_manager.hpp | 6 |
2 files changed, 61 insertions, 7 deletions
diff --git a/network_manager.cpp b/network_manager.cpp index 7362943..e0ebdfc 100644 --- a/network_manager.cpp +++ b/network_manager.cpp @@ -4,7 +4,10 @@ #include <phosphor-logging/log.hpp> #include <algorithm> +#include <bitset> #include <experimental/filesystem> +#include <map> + #include <arpa/inet.h> #include <dirent.h> #include <net/if.h> @@ -23,18 +26,21 @@ Manager::Manager(sdbusplus::bus::bus& bus, const char* objPath): { auto interfaceInfoList = getInterfaceAddrs(); - for( const auto& intfInfo : interfaceInfoList ) + for (const auto& intfInfo : interfaceInfoList) + { fs::path objectPath = std::string(OBJ_NETWORK); objectPath /= intfInfo.first; this->interfaces.emplace(std::make_pair( - intfInfo.first, - std::make_unique< - phosphor::network::EthernetInterface > - (bus, objectPath.c_str(), - false,intfInfo.second))); + intfInfo.first, + std::make_unique< + phosphor::network::EthernetInterface> + (bus, + objectPath.string(), + false, + intfInfo.second))); } } @@ -92,6 +98,8 @@ IntfAddrMap Manager::getInterfaceAddrs() const intfName = ifa->ifa_name; AddrInfo info; char ip[INET6_ADDRSTRLEN] = { 0 }; + char subnetMask[INET6_ADDRSTRLEN] = { 0 }; + uint16_t prefix = { 0 }; if (ifa->ifa_addr->sa_family == AF_INET) { @@ -100,6 +108,14 @@ IntfAddrMap Manager::getInterfaceAddrs() const &(((struct sockaddr_in*)(ifa->ifa_addr))->sin_addr), ip, sizeof(ip)); + + inet_ntop(ifa->ifa_addr->sa_family, + &(((struct sockaddr_in*)(ifa->ifa_netmask))->sin_addr), + subnetMask, + sizeof(subnetMask)); + + prefix = toCidr(subnetMask); + } else { @@ -108,15 +124,49 @@ IntfAddrMap Manager::getInterfaceAddrs() const ip, sizeof(ip)); + inet_ntop(ifa->ifa_addr->sa_family, + &(((struct sockaddr_in6*)(ifa->ifa_netmask))->sin6_addr), + subnetMask, + sizeof(subnetMask)); + + //TODO: convert v6 mask into cidr + } info.addrType = ifa->ifa_addr->sa_family; info.ipaddress = ip; + info.prefix = prefix; addrList.emplace_back(info); } } intfMap.emplace(intfName, addrList); return intfMap; } + +uint8_t Manager::toCidr(const char* subnetMask) const +{ + uint32_t buff = 0; + + auto rc = inet_pton(AF_INET, subnetMask, &buff); + if (rc <= 0) + { + log<level::ERR>("inet_pton failed:", + entry("Mask=%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("Mask=%s", subnetMask)); + return 0; + } +} }//namespace network }//namespace phosphor diff --git a/network_manager.hpp b/network_manager.hpp index 3d745ce..f37544c 100644 --- a/network_manager.hpp +++ b/network_manager.hpp @@ -29,7 +29,8 @@ using VLANCreateIface = using IntfName = std::string; -struct AddrInfo { +struct AddrInfo +{ short addrType; std::string ipaddress; }; @@ -78,6 +79,9 @@ class Manager : public details::VLANCreateIface */ IntfAddrMap getInterfaceAddrs() const; + /** @brief converts the given subnet into prefix notation **/ + uint8_t toCidr(const char* subnetMask) const; + /** @brief Persistent map of EthernetInterface dbus objects and their names */ std::map<IntfName, std::unique_ptr<EthernetInterface>> interfaces; |

