transporthandler: Use stdplus network functions

These are shared with phosphor-networkd.

Change-Id: I2dc796f195c733b5b5b4edcfd59186e3ef30b515
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/transporthandler.cpp b/transporthandler.cpp
index d54fac8..dc602af 100644
--- a/transporthandler.cpp
+++ b/transporthandler.cpp
@@ -1,8 +1,10 @@
 #include "transporthandler.hpp"
 
+#include <stdplus/net/addr/subnet.hpp>
 #include <stdplus/raw.hpp>
 
 #include <array>
+#include <fstream>
 
 using phosphor::logging::commit;
 using phosphor::logging::elog;
@@ -167,17 +169,6 @@
     return log<level>(std::forward<Args>(args)...);
 }
 
-ether_addr stringToMAC(const char* mac)
-{
-    const ether_addr* ret = ether_aton(mac);
-    if (ret == nullptr)
-    {
-        log<level::ERR>("Invalid MAC Address", entry("MAC=%s", mac));
-        elog<InternalFailure>();
-    }
-    return *ret;
-}
-
 /** @brief Get / Set the Property value from phosphor-networkd EthernetInterface
  */
 template <typename T>
@@ -201,11 +192,12 @@
  *  @param[in] params - The parameters for the channel
  *  @return The configured mac address
  */
-ether_addr getMACProperty(sdbusplus::bus_t& bus, const ChannelParams& params)
+stdplus::EtherAddr getMACProperty(sdbusplus::bus_t& bus,
+                                  const ChannelParams& params)
 {
-    auto macStr = std::get<std::string>(getDbusProperty(
-        bus, params.service, params.ifPath, INTF_MAC, "MACAddress"));
-    return stringToMAC(macStr.c_str());
+    auto prop = getDbusProperty(bus, params.service, params.ifPath, INTF_MAC,
+                                "MACAddress");
+    return stdplus::fromStr<stdplus::EtherAddr>(std::get<std::string>(prop));
 }
 
 /** @brief Sets the system value for MAC address on the given interface
@@ -215,11 +207,10 @@
  *  @param[in] mac    - MAC address to apply
  */
 void setMACProperty(sdbusplus::bus_t& bus, const ChannelParams& params,
-                    const ether_addr& mac)
+                    stdplus::EtherAddr mac)
 {
-    std::string macStr = ether_ntoa(&mac);
     setDbusProperty(bus, params.service, params.ifPath, INTF_MAC, "MACAddress",
-                    macStr);
+                    stdplus::toStr(mac));
 }
 
 void deleteObjectIfExists(sdbusplus::bus_t& bus, const std::string& service,
@@ -258,8 +249,7 @@
  */
 template <int family>
 void createIfAddr(sdbusplus::bus_t& bus, const ChannelParams& params,
-                  const typename AddrFamily<family>::addr& address,
-                  uint8_t prefix)
+                  typename AddrFamily<family>::addr address, uint8_t prefix)
 {
     auto newreq = bus.new_method_call(params.service.c_str(),
                                       params.logicalPath.c_str(),
@@ -267,7 +257,8 @@
     std::string protocol =
         sdbusplus::common::xyz::openbmc_project::network::convertForMessage(
             AddrFamily<family>::protocol);
-    newreq.append(protocol, addrToString<family>(address), prefix, "");
+    stdplus::ToStrHandle<stdplus::ToStr<typename AddrFamily<family>::addr>> tsh;
+    newreq.append(protocol, tsh(address), prefix, "");
     bus.call_noreply(newreq);
 }
 
@@ -290,7 +281,7 @@
  *  @param[in] prefix  - The new address prefix if specified
  */
 void reconfigureIfAddr4(sdbusplus::bus_t& bus, const ChannelParams& params,
-                        const std::optional<in_addr>& address,
+                        std::optional<stdplus::In4Addr> address,
                         std::optional<uint8_t> prefix)
 {
     auto ifaddr = getIfAddr4(bus, params);
@@ -305,13 +296,10 @@
         fallbackPrefix = ifaddr->prefix;
         deleteObjectIfExists(bus, params.service, ifaddr->path);
     }
-
-    if (struct in_addr nullIPv4{0};
-        (address == std::nullopt && prefix != std::nullopt) ||
-        (address != std::nullopt &&
-         (address.value().s_addr != nullIPv4.s_addr)))
+    auto addr = address.value_or(ifaddr->address);
+    if (addr != stdplus::In4Addr{})
     {
-        createIfAddr<AF_INET>(bus, params, address.value_or(ifaddr->address),
+        createIfAddr<AF_INET>(bus, params, addr,
                               prefix.value_or(fallbackPrefix));
     }
 }
@@ -340,7 +328,7 @@
 
 template <int family>
 void reconfigureGatewayMAC(sdbusplus::bus_t& bus, const ChannelParams& params,
-                           const ether_addr& mac)
+                           stdplus::EtherAddr mac)
 {
     auto gateway = getGatewayProperty<family>(bus, params);
     if (!gateway)
@@ -385,7 +373,7 @@
  *  @param[in] prefix  - The new address prefix
  */
 void reconfigureIfAddr6(sdbusplus::bus_t& bus, const ChannelParams& params,
-                        uint8_t idx, const in6_addr& address, uint8_t prefix)
+                        uint8_t idx, stdplus::In6Addr address, uint8_t prefix)
 {
     deconfigureIfAddr6(bus, params, idx);
     createIfAddr<AF_INET6>(bus, params, address, prefix);
@@ -430,7 +418,7 @@
 {
     auto source = IPv6Source::Static;
     bool enabled = false;
-    in6_addr addr{};
+    stdplus::In6Addr addr{};
     uint8_t prefix{};
     auto status = IPv6AddressStatus::Disabled;
 
@@ -446,7 +434,7 @@
 
     ret.pack(set);
     ret.pack(types::enum_cast<uint4_t>(source), uint3_t{}, enabled);
-    ret.pack(std::string_view(reinterpret_cast<char*>(&addr), sizeof(addr)));
+    ret.pack(stdplus::raw::asView<char>(addr));
     ret.pack(prefix);
     ret.pack(types::enum_cast<uint8_t>(status));
 }
@@ -595,46 +583,6 @@
     }
 }
 
-/** @brief Turns a prefix into a netmask
- *
- *  @param[in] prefix - The prefix length
- *  @return The netmask
- */
-in_addr prefixToNetmask(uint8_t prefix)
-{
-    if (prefix > 32)
-    {
-        log<level::ERR>("Invalid prefix", entry("PREFIX=%" PRIu8, prefix));
-        elog<InternalFailure>();
-    }
-    if (prefix == 0)
-    {
-        // Avoids 32-bit lshift by 32 UB
-        return {};
-    }
-    return {htobe32(~UINT32_C(0) << (32 - prefix))};
-}
-
-/** @brief Turns a a netmask into a prefix length
- *
- *  @param[in] netmask - The netmask in byte form
- *  @return The prefix length
- */
-uint8_t netmaskToPrefix(in_addr netmask)
-{
-    uint32_t x = be32toh(netmask.s_addr);
-    if ((~x & (~x + 1)) != 0)
-    {
-        char maskStr[INET_ADDRSTRLEN];
-        inet_ntop(AF_INET, &netmask, maskStr, sizeof(maskStr));
-        log<level::ERR>("Invalid netmask", entry("NETMASK=%s", maskStr));
-        elog<InternalFailure>();
-    }
-    return static_cast<bool>(x)
-               ? AddrFamily<AF_INET>::defaultPrefix - __builtin_ctz(x)
-               : 0;
-}
-
 // We need to store this value so it can be returned to the client
 // It is volatile so safe to store in daemon memory.
 static std::unordered_map<uint8_t, SetStatus> setStatus;
@@ -833,7 +781,7 @@
             {
                 return responseCommandNotAvailable();
             }
-            auto ip = unpackT<in_addr>(req);
+            auto ip = unpackT<stdplus::In4Addr>(req);
             unpackFinal(req);
             channelCall<reconfigureIfAddr4>(channel, ip, std::nullopt);
             return responseSuccess();
@@ -872,7 +820,7 @@
         }
         case LanParam::MAC:
         {
-            auto mac = unpackT<ether_addr>(req);
+            auto mac = unpackT<stdplus::EtherAddr>(req);
             unpackFinal(req);
             channelCall<setMACProperty>(channel, mac);
             return responseSuccess();
@@ -883,10 +831,9 @@
             {
                 return responseCommandNotAvailable();
             }
-            auto netmask = unpackT<in_addr>(req);
+            auto pfx = stdplus::maskToPfx(unpackT<stdplus::In4Addr>(req));
             unpackFinal(req);
-            channelCall<reconfigureIfAddr4>(channel, std::nullopt,
-                                            netmaskToPrefix(netmask));
+            channelCall<reconfigureIfAddr4>(channel, std::nullopt, pfx);
             return responseSuccess();
         }
         case LanParam::Gateway1:
@@ -895,14 +842,14 @@
             {
                 return responseCommandNotAvailable();
             }
-            auto gateway = unpackT<in_addr>(req);
+            auto gateway = unpackT<stdplus::In4Addr>(req);
             unpackFinal(req);
             channelCall<setGatewayProperty<AF_INET>>(channel, gateway);
             return responseSuccess();
         }
         case LanParam::Gateway1MAC:
         {
-            auto gatewayMAC = unpackT<ether_addr>(req);
+            auto gatewayMAC = unpackT<stdplus::EtherAddr>(req);
             unpackFinal(req);
             channelCall<reconfigureGatewayMAC<AF_INET>>(channel, gatewayMAC);
             return responseSuccess();
@@ -976,7 +923,7 @@
             {
                 return responseReqDataLenInvalid();
             }
-            auto ip = unpackT<in6_addr>(req);
+            auto ip = unpackT<stdplus::In6Addr>(req);
             if (req.unpack(prefix, status) != 0)
             {
                 return responseReqDataLenInvalid();
@@ -1029,14 +976,14 @@
         }
         case LanParam::IPv6StaticRouter1IP:
         {
-            auto gateway = unpackT<in6_addr>(req);
+            auto gateway = unpackT<stdplus::In6Addr>(req);
             unpackFinal(req);
             channelCall<setGatewayProperty<AF_INET6>>(channel, gateway);
             return responseSuccess();
         }
         case LanParam::IPv6StaticRouter1MAC:
         {
-            auto mac = unpackT<ether_addr>(req);
+            auto mac = unpackT<stdplus::EtherAddr>(req);
             unpackFinal(req);
             channelCall<reconfigureGatewayMAC<AF_INET6>>(channel, mac);
             return responseSuccess();
@@ -1057,7 +1004,7 @@
         }
         case LanParam::IPv6StaticRouter1PrefixValue:
         {
-            unpackT<in6_addr>(req);
+            unpackT<stdplus::In6Addr>(req);
             unpackFinal(req);
             // Accept any prefix value since our prefix length has to be 0
             return responseSuccess();
@@ -1198,7 +1145,7 @@
         case LanParam::IP:
         {
             auto ifaddr = channelCall<getIfAddr4>(channel);
-            in_addr addr{};
+            stdplus::In4Addr addr{};
             if (ifaddr)
             {
                 addr = ifaddr->address;
@@ -1216,7 +1163,7 @@
         }
         case LanParam::MAC:
         {
-            ether_addr mac = channelCall<getMACProperty>(channel);
+            auto mac = channelCall<getMACProperty>(channel);
             ret.pack(stdplus::raw::asView<char>(mac));
             return responseSuccess(std::move(ret));
         }
@@ -1228,21 +1175,20 @@
             {
                 prefix = ifaddr->prefix;
             }
-            in_addr netmask = prefixToNetmask(prefix);
+            auto netmask = stdplus::pfxToMask<stdplus::In4Addr>(prefix);
             ret.pack(stdplus::raw::asView<char>(netmask));
             return responseSuccess(std::move(ret));
         }
         case LanParam::Gateway1:
         {
-            auto gateway =
-                channelCall<getGatewayProperty<AF_INET>>(channel).value_or(
-                    in_addr{});
-            ret.pack(stdplus::raw::asView<char>(gateway));
+            auto gateway = channelCall<getGatewayProperty<AF_INET>>(channel);
+            ret.pack(stdplus::raw::asView<char>(
+                gateway.value_or(stdplus::In4Addr{})));
             return responseSuccess(std::move(ret));
         }
         case LanParam::Gateway1MAC:
         {
-            ether_addr mac{};
+            stdplus::EtherAddr mac{};
             auto neighbor = channelCall<getGatewayNeighbor<AF_INET>>(channel);
             if (neighbor)
             {
@@ -1346,19 +1292,19 @@
         }
         case LanParam::IPv6StaticRouter1IP:
         {
-            in6_addr gateway{};
+            stdplus::In6Addr gateway{};
             if (!channelCall<getEthProp<bool>>(channel, "IPv6AcceptRA"))
             {
                 gateway =
                     channelCall<getGatewayProperty<AF_INET6>>(channel).value_or(
-                        in6_addr{});
+                        stdplus::In6Addr{});
             }
             ret.pack(stdplus::raw::asView<char>(gateway));
             return responseSuccess(std::move(ret));
         }
         case LanParam::IPv6StaticRouter1MAC:
         {
-            ether_addr mac{};
+            stdplus::EtherAddr mac{};
             auto neighbor = channelCall<getGatewayNeighbor<AF_INET6>>(channel);
             if (neighbor)
             {
@@ -1374,8 +1320,7 @@
         }
         case LanParam::IPv6StaticRouter1PrefixValue:
         {
-            in6_addr prefix{};
-            ret.pack(stdplus::raw::asView<char>(prefix));
+            ret.pack(stdplus::raw::asView<char>(stdplus::In6Addr{}));
             return responseSuccess(std::move(ret));
         }
         case LanParam::cipherSuitePrivilegeLevels:
diff --git a/transporthandler.hpp b/transporthandler.hpp
index e34fb51..019311b 100644
--- a/transporthandler.hpp
+++ b/transporthandler.hpp
@@ -3,9 +3,6 @@
 #include "app/channel.hpp"
 #include "user_channel/cipher_mgmt.hpp"
 
-#include <arpa/inet.h>
-#include <netinet/ether.h>
-
 #include <ipmid/api-types.hpp>
 #include <ipmid/api.hpp>
 #include <ipmid/message.hpp>
@@ -17,17 +14,16 @@
 #include <phosphor-logging/log.hpp>
 #include <sdbusplus/bus.hpp>
 #include <sdbusplus/exception.hpp>
-#include <stdplus/raw.hpp>
+#include <stdplus/net/addr/ether.hpp>
+#include <stdplus/net/addr/ip.hpp>
+#include <stdplus/str/conv.hpp>
 #include <user_channel/channel_layer.hpp>
 #include <xyz/openbmc_project/Common/error.hpp>
 #include <xyz/openbmc_project/Network/EthernetInterface/server.hpp>
 #include <xyz/openbmc_project/Network/IP/server.hpp>
 #include <xyz/openbmc_project/Network/Neighbor/server.hpp>
 
-#include <bitset>
 #include <cinttypes>
-#include <cstdint>
-#include <fstream>
 #include <functional>
 #include <optional>
 #include <string>
@@ -35,7 +31,6 @@
 #include <unordered_map>
 #include <unordered_set>
 #include <utility>
-#include <vector>
 
 namespace ipmi
 {
@@ -222,7 +217,7 @@
 template <>
 struct AddrFamily<AF_INET>
 {
-    using addr = in_addr;
+    using addr = stdplus::In4Addr;
     static constexpr auto protocol =
         sdbusplus::server::xyz::openbmc_project::network::IP::Protocol::IPv4;
     static constexpr size_t maxStrLen = INET6_ADDRSTRLEN;
@@ -234,7 +229,7 @@
 template <>
 struct AddrFamily<AF_INET6>
 {
-    using addr = in6_addr;
+    using addr = stdplus::In6Addr;
     static constexpr auto protocol =
         sdbusplus::server::xyz::openbmc_project::network::IP::Protocol::IPv6;
     static constexpr size_t maxStrLen = INET6_ADDRSTRLEN;
@@ -248,7 +243,7 @@
 {
     std::string path;
     typename AddrFamily<family>::addr ip;
-    ether_addr mac;
+    stdplus::EtherAddr mac;
 };
 
 /** @brief Interface IP Address configuration parameters */
@@ -358,66 +353,6 @@
     }
 };
 
-/** @brief Turns an IP address string into the network byte order form
- *         NOTE: This version strictly validates family matches
- *
- *  @param[in] address - The string form of the address
- *  @return A network byte order address or none if conversion failed
- */
-template <int family>
-std::optional<typename AddrFamily<family>::addr>
-    maybeStringToAddr(const char* address)
-{
-    typename AddrFamily<family>::addr ret;
-    if (inet_pton(family, address, &ret) == 1)
-    {
-        return ret;
-    }
-    return std::nullopt;
-}
-
-/** @brief Turns an IP address string into the network byte order form
- *         NOTE: This version strictly validates family matches
- *
- *  @param[in] address - The string form of the address
- *  @return A network byte order address
- */
-template <int family>
-typename AddrFamily<family>::addr stringToAddr(const char* address)
-{
-    auto ret = maybeStringToAddr<family>(address);
-    if (!ret)
-    {
-        phosphor::logging::log<phosphor::logging::level::ERR>(
-            "Failed to convert IP Address",
-            phosphor::logging::entry("FAMILY=%d", family),
-            phosphor::logging::entry("ADDRESS=%s", address));
-        phosphor::logging::elog<
-            sdbusplus::error::xyz::openbmc_project::common::InternalFailure>();
-    }
-    return *ret;
-}
-
-/** @brief Turns an IP address in network byte order into a string
- *
- *  @param[in] address - The string form of the address
- *  @return A network byte order address
- */
-template <int family>
-std::string addrToString(const typename AddrFamily<family>::addr& address)
-{
-    std::string ret(AddrFamily<family>::maxStrLen, '\0');
-    inet_ntop(family, &address, ret.data(), ret.size());
-    ret.resize(strlen(ret.c_str()));
-    return ret;
-}
-
-/** @brief Converts a human readable MAC string into MAC bytes
- *
- *  @param[in] mac - The MAC string
- *  @return MAC in bytes
- */
-ether_addr stringToMAC(const char* mac);
 /** @brief Searches the ip object lookup cache for an address matching
  *         the input parameters. NOTE: The index lacks stability across address
  *         changes since the network daemon has no notion of stable indicies.
@@ -440,9 +375,13 @@
 {
     for (const auto& [path, properties] : ips)
     {
-        const auto& addrStr = std::get<std::string>(properties.at("Address"));
-        auto addr = maybeStringToAddr<family>(addrStr.c_str());
-        if (!addr)
+        std::optional<typename AddrFamily<family>::addr> addr;
+        try
+        {
+            addr.emplace(stdplus::fromStr<typename AddrFamily<family>::addr>(
+                std::get<std::string>(properties.at("Address"))));
+        }
+        catch (...)
         {
             continue;
         }
@@ -502,7 +441,7 @@
  *  @param[in] prefix  - The new address prefix
  */
 void reconfigureIfAddr6(sdbusplus::bus_t& bus, const ChannelParams& params,
-                        uint8_t idx, const in6_addr& address, uint8_t prefix);
+                        uint8_t idx, stdplus::In6Addr address, uint8_t prefix);
 
 /** @brief Retrieves the current gateway for the address family on the system
  *         NOTE: The gateway is per channel instead of the system wide one.
@@ -523,13 +462,13 @@
     {
         return std::nullopt;
     }
-    return stringToAddr<family>(gatewayStr.c_str());
+    return stdplus::fromStr<typename AddrFamily<family>::addr>(gatewayStr);
 }
 
 template <int family>
 std::optional<IfNeigh<family>>
     findStaticNeighbor(sdbusplus::bus_t&, const ChannelParams&,
-                       const typename AddrFamily<family>::addr& ip,
+                       typename AddrFamily<family>::addr ip,
                        ObjectLookupCache& neighbors)
 {
     using sdbusplus::server::xyz::openbmc_project::network::Neighbor;
@@ -538,13 +477,17 @@
             Neighbor::State::Permanent);
     for (const auto& [path, neighbor] : neighbors)
     {
-        const auto& ipStr = std::get<std::string>(neighbor.at("IPAddress"));
-        auto neighIP = maybeStringToAddr<family>(ipStr.c_str());
-        if (!neighIP)
+        std::optional<typename AddrFamily<family>::addr> neighIP;
+        try
+        {
+            neighIP.emplace(stdplus::fromStr<typename AddrFamily<family>::addr>(
+                std::get<std::string>(neighbor.at("IPAddress"))));
+        }
+        catch (...)
         {
             continue;
         }
-        if (!stdplus::raw::equal(*neighIP, ip))
+        if (*neighIP != ip)
         {
             continue;
         }
@@ -556,8 +499,8 @@
         IfNeigh<family> ret;
         ret.path = path;
         ret.ip = ip;
-        const auto& macStr = std::get<std::string>(neighbor.at("MACAddress"));
-        ret.mac = stringToMAC(macStr.c_str());
+        ret.mac = stdplus::fromStr<stdplus::EtherAddr>(
+            std::get<std::string>(neighbor.at("MACAddress")));
         return ret;
     }
 
@@ -566,14 +509,16 @@
 
 template <int family>
 void createNeighbor(sdbusplus::bus_t& bus, const ChannelParams& params,
-                    const typename AddrFamily<family>::addr& address,
-                    const ether_addr& mac)
+                    typename AddrFamily<family>::addr address,
+                    stdplus::EtherAddr mac)
 {
     auto newreq = bus.new_method_call(params.service.c_str(),
                                       params.logicalPath.c_str(),
                                       INTF_NEIGHBOR_CREATE_STATIC, "Neighbor");
-    std::string macStr = ether_ntoa(&mac);
-    newreq.append(addrToString<family>(address), macStr);
+    stdplus::ToStrHandle<stdplus::ToStr<stdplus::EtherAddr>> macToStr;
+    stdplus::ToStrHandle<stdplus::ToStr<typename AddrFamily<family>::addr>>
+        addrToStr;
+    newreq.append(addrToStr(address), macToStr(mac));
     bus.call_noreply(newreq);
 }
 
@@ -595,7 +540,7 @@
  */
 template <int family>
 void setGatewayProperty(sdbusplus::bus_t& bus, const ChannelParams& params,
-                        const typename AddrFamily<family>::addr& address)
+                        typename AddrFamily<family>::addr address)
 {
     // Save the old gateway MAC address if it exists so we can recreate it
     auto gateway = getGatewayProperty<family>(bus, params);
@@ -609,7 +554,7 @@
     auto objPath = "/xyz/openbmc_project/network/" + params.ifname;
     setDbusProperty(bus, params.service, objPath, INTF_ETHERNET,
                     AddrFamily<family>::propertyGateway,
-                    addrToString<family>(address));
+                    stdplus::toStr(address));
 
     // Restore the gateway MAC if we had one
     if (neighbor)