diff options
| author | Ratan Gupta <ratagupt@in.ibm.com> | 2017-05-09 18:35:36 +0530 |
|---|---|---|
| committer | Ratan Gupta <ratagupt@in.ibm.com> | 2017-06-07 08:18:17 +0530 |
| commit | c41692c402dc2f2cef0fae16b964d6194dbabfd7 (patch) | |
| tree | 1179f446ad06c41a6fde47924023d6a2edc3c3d0 | |
| parent | 719f83af9d799e3fac1b0e23241531372f43d38f (diff) | |
| download | phosphor-networkd-c41692c402dc2f2cef0fae16b964d6194dbabfd7.tar.gz phosphor-networkd-c41692c402dc2f2cef0fae16b964d6194dbabfd7.zip | |
Convert IPv6 subnet mask into prefix length
Change-Id: I7921400b3f83876c5d3cb1440fcbf926551cebcb
Signed-off-by: Ratan Gupta <ratagupt@in.ibm.com>
| -rw-r--r-- | network_manager.cpp | 85 | ||||
| -rw-r--r-- | network_manager.hpp | 13 |
2 files changed, 84 insertions, 14 deletions
diff --git a/network_manager.cpp b/network_manager.cpp index 95e1476..e140208 100644 --- a/network_manager.cpp +++ b/network_manager.cpp @@ -152,7 +152,6 @@ IntfAddrMap Manager::getInterfaceAddrs() const AddrInfo info; char ip[INET6_ADDRSTRLEN] = { 0 }; char subnetMask[INET6_ADDRSTRLEN] = { 0 }; - uint16_t prefix = { 0 }; if (ifa->ifa_addr->sa_family == AF_INET) { @@ -167,8 +166,6 @@ IntfAddrMap Manager::getInterfaceAddrs() const subnetMask, sizeof(subnetMask)); - prefix = toCidr(subnetMask); - } else { @@ -182,13 +179,13 @@ IntfAddrMap Manager::getInterfaceAddrs() const subnetMask, sizeof(subnetMask)); - //TODO: convert v6 mask into cidr - } info.addrType = ifa->ifa_addr->sa_family; info.ipaddress = ip; - info.prefix = prefix; + + info.prefix = toCidr(info.addrType, subnetMask); + addrList.emplace_back(info); } } @@ -196,16 +193,20 @@ IntfAddrMap Manager::getInterfaceAddrs() const return intfMap; } -uint8_t Manager::toCidr(const char* subnetMask) const +uint8_t Manager::toCidr(int addressFamily, const std::string& subnetMask) const { uint32_t buff = 0; - auto rc = inet_pton(AF_INET, subnetMask, &buff); + 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("Mask=%s", subnetMask)); - return 0; + entry("SUBNETMASK=%s", subnetMask.c_str())); } buff = be32toh(buff); @@ -217,9 +218,71 @@ uint8_t Manager::toCidr(const char* subnetMask) const else { log<level::ERR>("Invalid Mask", - entry("Mask=%s", subnetMask)); + 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 fe7debb..d0cb779 100644 --- a/network_manager.hpp +++ b/network_manager.hpp @@ -81,10 +81,17 @@ class Manager : public details::VLANCreateIface IntfAddrMap getInterfaceAddrs() const; /** @brief converts the given subnet into prefix notation - * @param[in] subnetMask - Subnet Mask. - * @returns prefix length. + * @param[in] addressFamily - IP address family(AF_INET/AF_INET6) + * @param[in] subnetMask - SubnetMask which needs to be converted. + * @returns prefix. */ - uint8_t toCidr(const char* subnetMask) const; + 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; |

