diff options
Diffstat (limited to 'data-ipa-cfg-mgr/hal/src/PrefixParser.cpp')
-rw-r--r-- | data-ipa-cfg-mgr/hal/src/PrefixParser.cpp | 391 |
1 files changed, 0 insertions, 391 deletions
diff --git a/data-ipa-cfg-mgr/hal/src/PrefixParser.cpp b/data-ipa-cfg-mgr/hal/src/PrefixParser.cpp deleted file mode 100644 index ff55147..0000000 --- a/data-ipa-cfg-mgr/hal/src/PrefixParser.cpp +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Copyright (c) 2017, The Linux Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * * Neither the name of The Linux Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* External Includes */ -#include <arpa/inet.h> -#include <netinet/in.h> -#include <netinet/ip.h> -#include <string.h> -#include <sys/socket.h> -#include <sys/types.h> -#include <vector> - -/* Internal Includes */ -#include "IOffloadManager.h" -#include "PrefixParser.h" - -/* Avoiding namespace pollution */ -using IP_FAM = ::IOffloadManager::IP_FAM; -using Prefix = ::IOffloadManager::Prefix; - -using ::std::string; -using ::std::vector; - - -/* ------------------------------ PUBLIC ------------------------------------ */ -PrefixParser::PrefixParser() { - mLastErr = "No Err"; -} /* PrefixParser */ - -bool PrefixParser::add(vector<string> in) { - return add(in, IP_FAM::INVALID); -} /* add */ - -bool PrefixParser::add(string in) { - return add(in, IP_FAM::INVALID); -} /* add */ - -bool PrefixParser::addV4(string in) { - return add(in, IP_FAM::V4); -} /* addV4 */ - -bool PrefixParser::addV4(vector<string> in) { - return add(in, IP_FAM::V4); -} /* addV4 */ - -bool PrefixParser::addV6(string in) { - return add(in, IP_FAM::V6); -} /* addV6 */ - -bool PrefixParser::addV6(vector<string> in) { - for (size_t i = 0; i < in.size(); i++) { - if (!addV6(in[i])) - return false; - } - return true; -} /* addV6 */ - -int PrefixParser::size() { - return mPrefixes.size(); -} /* size */ - -bool PrefixParser::allAreFullyQualified() { - for (size_t i = 0; i < mPrefixes.size(); i++) { - if (mPrefixes[i].fam == IP_FAM::V4) { - uint32_t masked = mPrefixes[i].v4Addr & mPrefixes[i].v4Mask; - if (masked != mPrefixes[i].v4Addr) - return false; - } else { - uint32_t masked[4]; - masked[0] = mPrefixes[i].v6Addr[0] & mPrefixes[i].v6Mask[0]; - masked[1] = mPrefixes[i].v6Addr[1] & mPrefixes[i].v6Mask[1]; - masked[2] = mPrefixes[i].v6Addr[2] & mPrefixes[i].v6Mask[2]; - masked[3] = mPrefixes[i].v6Addr[3] & mPrefixes[i].v6Mask[3]; - for (int j = 0; j < 4; j++) { - if (masked[j] != mPrefixes[i].v6Addr[j]) - return false; - } - } - } - return true; -} /* allAreFullyQualified */ - -Prefix PrefixParser::getFirstPrefix() { - if (size() >= 1) - return mPrefixes[0]; - return makeBlankPrefix(IP_FAM::INVALID); -} /* getFirstPrefix */ - -Prefix PrefixParser::getFirstPrefix(IP_FAM famHint) { - if (size() >= 1) - return mPrefixes[0]; - return makeBlankPrefix(famHint); -} /* getFirstPrefix */ - -string PrefixParser::getLastErrAsStr() { - return mLastErr; -} /* getLastErrAsStr */ - - -/* ------------------------------ PRIVATE ----------------------------------- */ -bool PrefixParser::add(vector<string> in, IP_FAM famHint) { - if (in.size() == 0) - return false; - - for (size_t i = 0; i < in.size(); i++) { - if (!add(in[i], famHint)) - return false; - } - return true; -} /* add */ - -bool PrefixParser::add(string in, IP_FAM famHint) { - if (in.length() == 0) { - mLastErr = "Failed to parse string, length = 0..."; - return false; - } - - if (famHint == IP_FAM::INVALID) - famHint = guessIPFamily(in); - - string subnet; - string addr; - - if (!splitIntoAddrAndMask(in, addr, subnet)) { - mLastErr = "Failed to split into Address and Mask(" + in + ")"; - return false; - } - - int mask = parseSubnetMask(subnet, famHint); - if (!isMaskValid(mask, famHint)) { - mLastErr = "Invalid mask"; - return false; - } - - Prefix pre = makeBlankPrefix(famHint); - - if (famHint == IP_FAM::V4) { - if (!parseV4Addr(addr, pre)) { - mLastErr = "Failed to parse V4 Address(" + addr + ")"; - return false; - } - } else if (!parseV6Addr(addr, pre)) { - mLastErr = "Failed to parse V6 Address(" + addr + ")"; - return false; - } - - if (famHint == IP_FAM::V4 && !populateV4Mask(mask, pre)) { - mLastErr = "Failed to populate IPv4 Mask(" + std::to_string(mask) - + ", " + addr + ")"; - return false; - } else if (!populateV6Mask(mask, pre)) { - mLastErr = "Failed to populate IPv6 Mask(" + std::to_string(mask) - + ", " + addr + ")"; - return false; - } - - mPrefixes.push_back(pre); - return true; -} /* add */ - -/* Assumption (based on man inet_pton) - * - * X represents a hex character - * d represents a base 10 digit - * / represents the start of the subnet mask - * (assume that it can be left off of all below combinations) - * - * IPv4 Addresses always look like the following: - * ddd.ddd.ddd.ddd/dd - * - * IPv6 Addresses can look a few different ways: - * x:x:x:x:x:x:x:x/ddd - * x::x/ddd - * x:x:x:x:x:x:d.d.d.d/ddd - * - * Therefore, if a presentation of an IP Address contains a colon, then it - * may not be a valid IPv6, but, it is definitely not valid IPv4. If a - * presentation of an IP Address does not contain a colon, then it may not be - * a valid IPv4, but, it is definitely not IPv6. - */ -IP_FAM PrefixParser::guessIPFamily(string in) { - size_t found = in.find(":"); - if (found != string::npos) - return IP_FAM::V6; - return IP_FAM::V4; -} /* guessIPFamily */ - -bool PrefixParser::splitIntoAddrAndMask(string in, string &addr, string &mask) { - size_t pos = in.find("/"); - - if (pos != string::npos && pos >= 1) { - /* addr is now everything up until the first / */ - addr = in.substr(0, pos); - } else if (pos == string::npos) { - /* There is no /, so the entire input is an address */ - addr = in; - } else { - /* There was nothing before the /, not recoverable */ - return false; - } - - if (pos != string::npos && pos < in.size()) { - /* There is a / and it is not the last character. Everything after / - * must be the subnet. - */ - mask = in.substr(pos + 1); - } else if (pos != string::npos && pos == in.size()) { - /* There is a /, but it is the last character. This is garbage, but, - * we may still be able to interpret the address so we will throw it - * out. - */ - mask = ""; - } else if (pos == string::npos) { - /* There is no /, therefore, there is no subnet */ - mask = ""; - } else { - /* This really shouldn't be possible because it would imply that find - * returned a position larger than the size of the input. Just - * preserving sanity that mask is always initialized. - */ - mask = ""; - } - - return true; -} /* splitIntoAddrAndMask */ - -int PrefixParser::parseSubnetMask(string in, IP_FAM famHint) { - if (in.empty()) - /* Treat no subnet mask as fully qualified */ - return (famHint == IP_FAM::V6) ? 128 : 32; - return atoi(in.c_str()); -} /* parseSubnetMask */ - -bool PrefixParser::parseV4Addr(string in, Prefix &out) { - struct sockaddr_in sa; - - int ret = inet_pton(AF_INET, in.c_str(), &(sa.sin_addr)); - - if (ret < 0) { - /* errno would be valid */ - return false; - } else if (ret == 0) { - /* input was not a valid IP address */ - return false; - } - - /* Address in network byte order */ - out.v4Addr = htonl(sa.sin_addr.s_addr); - return true; -} /* parseV4Addr */ - -bool PrefixParser::parseV6Addr(string in, Prefix &out) { - struct sockaddr_in6 sa; - - int ret = inet_pton(AF_INET6, in.c_str(), &(sa.sin6_addr)); - - if (ret < 0) { - /* errno would be valid */ - return false; - } else if (ret == 0) { - /* input was not a valid IP address */ - return false; - } - - /* Translate unsigned chars to unsigned ints to match IPA - * - * TODO there must be a better way to do this beyond bit fiddling - * Maybe a Union since we've already made the assumption that the data - * structures match? - */ - out.v6Addr[0] = (sa.sin6_addr.s6_addr[0] << 24) | - (sa.sin6_addr.s6_addr[1] << 16) | - (sa.sin6_addr.s6_addr[2] << 8) | - (sa.sin6_addr.s6_addr[3]); - out.v6Addr[1] = (sa.sin6_addr.s6_addr[4] << 24) | - (sa.sin6_addr.s6_addr[5] << 16) | - (sa.sin6_addr.s6_addr[6] << 8) | - (sa.sin6_addr.s6_addr[7]); - out.v6Addr[2] = (sa.sin6_addr.s6_addr[8] << 24) | - (sa.sin6_addr.s6_addr[9] << 16) | - (sa.sin6_addr.s6_addr[10] << 8) | - (sa.sin6_addr.s6_addr[11]); - out.v6Addr[3] = (sa.sin6_addr.s6_addr[12] << 24) | - (sa.sin6_addr.s6_addr[13] << 16) | - (sa.sin6_addr.s6_addr[14] << 8) | - (sa.sin6_addr.s6_addr[15]); - return true; -} /* parseV6Addr */ - -bool PrefixParser::populateV4Mask(int mask, Prefix &out) { - if (mask < 0 || mask > 32) - return false; - out.v4Mask = createMask(mask); - return true; -} /* populateV4Mask */ - -bool PrefixParser::populateV6Mask(int mask, Prefix &out) { - if (mask < 0 || mask > 128) - return false; - - for (int i = 0; i < 4; i++) { - out.v6Mask[i] = createMask(mask); - mask = (mask > 32) ? mask - 32 : 0; - } - - return true; -} /* populateV6Mask */ - -uint32_t PrefixParser::createMask(int mask) { - uint32_t ret = 0; - - if (mask >= 32) { - ret = ~ret; - return ret; - } - - for (int i = 0; i < 32; i++) { - if (i < mask) - ret = (ret << 1) | 1; - else - ret = (ret << 1); - } - - return ret; -} /* createMask */ - -Prefix PrefixParser::makeBlankPrefix(IP_FAM famHint) { - Prefix ret; - - ret.fam = famHint; - - ret.v4Addr = 0; - ret.v4Mask = 0; - - ret.v6Addr[0] = 0; - ret.v6Addr[1] = 0; - ret.v6Addr[2] = 0; - ret.v6Addr[3] = 0; - - ret.v6Mask[0] = 0; - ret.v6Mask[1] = 0; - ret.v6Mask[2] = 0; - ret.v6Mask[3] = 0; - - return ret; -} /* makeBlankPrefix */ - -bool PrefixParser::isMaskValid(int mask, IP_FAM fam) { - if (mask < 0) { - mLastErr = "Failed parse subnet mask(" + std::to_string(mask) + ")"; - return false; - } else if (mask == 0) { - mLastErr = "Subnet mask cannot be 0(" + std::to_string(mask) + ")"; - return false; - } else if (fam == IP_FAM::V4 && mask > 32) { - mLastErr = "Interpreted address as V4 but mask was too large(" - + std::to_string(mask) + ")"; - return false; - } else if (fam == IP_FAM::V6 && mask > 128) { - mLastErr = "Interpreted address as V6 but mask was too large(" - + std::to_string(mask) + ")"; - return false; - } - - return true; -} /* isMaskValid */ |