summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNagaraju Goruganti <ngorugan@in.ibm.com>2017-10-03 08:43:08 -0500
committerBrad Bishop <bradleyb@fuzziesquirrel.com>2017-10-11 23:16:31 +0000
commit66b974d2d679ece3aa67032bbc13ac166702cede (patch)
tree4c31f2c253a8b2d289aad27970a31e0a13611d03
parentc9645fe5c874930445bca6ba51ac9daee916c99b (diff)
downloadphosphor-networkd-66b974d2d679ece3aa67032bbc13ac166702cede.tar.gz
phosphor-networkd-66b974d2d679ece3aa67032bbc13ac166702cede.zip
IP Address use case validation
-validates IPAddress/gateway using inet_pton api. -validates prefix length for ipv4/ipv6. -if dhcp is enabled, it won't allow to set ip/gateway. Resolves openbmc/openbmc#1671 Change-Id: I76c1d9d11dfb59002eb1310d87e94ee622714a4a Signed-off-by: Nagaraju Goruganti <ngorugan@in.ibm.com>
-rw-r--r--ethernet_interface.cpp37
-rw-r--r--ipaddress.cpp19
-rw-r--r--test/test_util.cpp17
-rw-r--r--util.cpp37
-rw-r--r--util.hpp23
5 files changed, 120 insertions, 13 deletions
diff --git a/ethernet_interface.cpp b/ethernet_interface.cpp
index ffaac74..5a7c61c 100644
--- a/ethernet_interface.cpp
+++ b/ethernet_interface.cpp
@@ -33,6 +33,7 @@ namespace network
using namespace phosphor::logging;
using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+using Argument = xyz::openbmc_project::Common::InvalidArgument;
EthernetInterface::EthernetInterface(sdbusplus::bus::bus& bus,
const std::string& objPath,
@@ -78,7 +79,7 @@ void EthernetInterface::createIPAddressObjects()
{
origin = IP::AddressOrigin::DHCP;
}
- else if (isLinkLocal(addr.ipaddress))
+ else if (isLinkLocalIP(addr.ipaddress))
{
origin = IP::AddressOrigin::LinkLocal;
}
@@ -113,12 +114,42 @@ void EthernetInterface::iP(IP::Protocol protType,
if (dHCPEnabled())
{
log<level::INFO>("DHCP enabled on the interface"),
- entry("INTERFACE=%s",interfaceName().c_str());
- return;
+ entry("INTERFACE=%s", interfaceName().c_str());
+ dHCPEnabled(false);
}
+
IP::AddressOrigin origin = IP::AddressOrigin::Static;
+ int addressFamily = (protType == IP::Protocol::IPv4) ? AF_INET : AF_INET6;
+
+ if (!isValidIP(addressFamily, ipaddress))
+ {
+ log<level::ERR>("Not a valid IP address"),
+ entry("ADDRESS=%s", ipaddress.c_str());
+ elog<InvalidArgument>(Argument::ARGUMENT_NAME("ipaddress"),
+ Argument::ARGUMENT_VALUE(ipaddress.c_str()));
+ }
+
+ if (!gateway.empty() && (!isValidIP(addressFamily, gateway)))
+ {
+ log<level::ERR>("Not a valid Gateway"),
+ entry("GATEWAY=%s", gateway.c_str());
+ elog<InvalidArgument>(Argument::ARGUMENT_NAME("gateway"),
+ Argument::ARGUMENT_VALUE(gateway.c_str()));
+ }
+
+ if (!isValidPrefix(addressFamily, prefixLength))
+ {
+ log<level::ERR>("PrefixLength is not correct "),
+ entry("PREFIXLENGTH=%d", gateway.c_str());
+ elog<InvalidArgument>(Argument::ARGUMENT_NAME("prefixLength"),
+ Argument::ARGUMENT_VALUE(std::to_string(
+ prefixLength).c_str()));
+ return;
+ }
+
+
std::string objectPath = generateObjectPath(protType,
ipaddress,
prefixLength,
diff --git a/ipaddress.cpp b/ipaddress.cpp
index b2407ef..4daccd5 100644
--- a/ipaddress.cpp
+++ b/ipaddress.cpp
@@ -1,7 +1,10 @@
#include "ipaddress.hpp"
#include "ethernet_interface.hpp"
+#include "util.hpp"
+#include "xyz/openbmc_project/Common/error.hpp"
#include <phosphor-logging/log.hpp>
+#include <phosphor-logging/elog-errors.hpp>
namespace phosphor
{
@@ -9,6 +12,7 @@ namespace network
{
using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
IPAddress::IPAddress(sdbusplus::bus::bus& bus,
const char* objPath,
@@ -34,6 +38,21 @@ IPAddress::IPAddress(sdbusplus::bus::bus& bus,
void IPAddress::delete_()
{
+ if (parent.dHCPEnabled())
+ {
+ log<level::ERR>("DHCP enabled on the interface"),
+ entry("INTERFACE=%s", parent.interfaceName().c_str());
+ elog<InternalFailure>();
+ }
+
+ if (isLinkLocalIP(address()))
+ {
+ log<level::ERR>("Can not delete the LinkLocal address"),
+ entry("INTERFACE=%s ADDRESS=%s",
+ parent.interfaceName().c_str(), address().c_str());
+ elog<InternalFailure>();
+ }
+
parent.deleteObject(address());
}
diff --git a/test/test_util.cpp b/test/test_util.cpp
index 9b1d34a..1c78b64 100644
--- a/test/test_util.cpp
+++ b/test/test_util.cpp
@@ -64,13 +64,22 @@ TEST_F(TestUtil, convertV6MasktoPrefix)
TEST_F(TestUtil, isLinkLocaladdress)
{
std::string ipaddress = "fe80:fec0::";
- EXPECT_TRUE(isLinkLocal(ipaddress));
+ EXPECT_TRUE(isLinkLocalIP(ipaddress));
- ipaddress = "2000:4567:789::";
- EXPECT_FALSE(isLinkLocal(ipaddress));
+ ipaddress = "2000:fe80:789::";
+ EXPECT_FALSE(isLinkLocalIP(ipaddress));
ipaddress = "2000:fe80::";
- EXPECT_FALSE(isLinkLocal(ipaddress));
+ EXPECT_FALSE(isLinkLocalIP(ipaddress));
+
+ ipaddress = "169.254.3.3";
+ EXPECT_TRUE(isLinkLocalIP(ipaddress));
+
+ ipaddress = "3.169.254.3";
+ EXPECT_FALSE(isLinkLocalIP(ipaddress));
+
+ ipaddress = "3.3.169.254";
+ EXPECT_FALSE(isLinkLocalIP(ipaddress));
}
TEST_F(TestUtil, convertPrefixToMask)
diff --git a/util.cpp b/util.cpp
index 48b5fcb..31bdd65 100644
--- a/util.cpp
+++ b/util.cpp
@@ -202,12 +202,39 @@ std::string getNetworkID(int addressFamily, const std::string& ipaddress,
return networkString;
}
-bool isLinkLocal(const std::string& address)
+bool isLinkLocalIP(const std::string& address)
{
- std::string linklocal = "fe80";
- return std::mismatch(linklocal.begin(), linklocal.end(),
- address.begin()).first == linklocal.end() ?
- true : false;
+ return address.find(IPV4_PREFIX) == 0 || address.find(IPV6_PREFIX) == 0;
+}
+
+bool isValidIP(int addressFamily, const std::string& address)
+{
+ unsigned char buf[sizeof(struct in6_addr)];
+
+ return inet_pton(addressFamily, address.c_str(), buf) > 0;
+}
+
+bool isValidPrefix(int addressFamily, uint8_t prefixLength)
+{
+ if (addressFamily == AF_INET)
+ {
+ if (prefixLength < IPV4_MIN_PREFIX_LENGTH ||
+ prefixLength > IPV4_MAX_PREFIX_LENGTH)
+ {
+ return false;
+ }
+ }
+
+ if (addressFamily == AF_INET6)
+ {
+ if (prefixLength < IPV4_MIN_PREFIX_LENGTH ||
+ prefixLength > IPV6_MAX_PREFIX_LENGTH)
+ {
+ return false;
+ }
+ }
+
+ return true;
}
IntfAddrMap getInterfaceAddrs()
diff --git a/util.hpp b/util.hpp
index 669c68f..ff91d17 100644
--- a/util.hpp
+++ b/util.hpp
@@ -11,6 +11,13 @@ namespace phosphor
{
namespace network
{
+
+constexpr auto IPV4_MIN_PREFIX_LENGTH = 1;
+constexpr auto IPV4_MAX_PREFIX_LENGTH = 32;
+constexpr auto IPV6_MAX_PREFIX_LENGTH = 64;
+constexpr auto IPV4_PREFIX = "169.254";
+constexpr auto IPV6_PREFIX = "fe80";
+
namespace mac_address
{
@@ -81,7 +88,21 @@ std::string toMask(int addressFamily, uint8_t prefix);
* @param[in] address - IP address.
* @returns true if it is linklocal otherwise false.
*/
-bool isLinkLocal(const std::string& address);
+bool isLinkLocalIP(const std::string& address);
+
+/* @brief checks that the given ip address valid or not.
+ * @param[in] addressFamily - IP address family(AF_INET/AF_INET6).
+ * @param[in] address - IP address.
+ * @returns true if it is valid otherwise false.
+ */
+bool isValidIP(int addressFamily, const std::string& address);
+
+/* @brief checks that the given prefix is valid or not.
+ * @param[in] addressFamily - IP address family(AF_INET/AF_INET6).
+ * @param[in] prefix - prefix length.
+ * @returns true if it is valid otherwise false.
+ */
+bool isValidPrefix(int addressFamily, uint8_t prefixLength);
/* @brief gets the network section of the ip adress.
* @param[in] addressFamily - IP address family(AF_INET/AF_INET6).
OpenPOWER on IntegriCloud