diff options
Diffstat (limited to 'data-ipa-cfg-mgr/hal/src')
-rw-r--r-- | data-ipa-cfg-mgr/hal/src/CtUpdateAmbassador.cpp | 123 | ||||
-rw-r--r-- | data-ipa-cfg-mgr/hal/src/HAL.cpp | 617 | ||||
-rw-r--r-- | data-ipa-cfg-mgr/hal/src/IpaEventRelay.cpp | 83 | ||||
-rw-r--r-- | data-ipa-cfg-mgr/hal/src/LocalLogBuffer.cpp | 126 | ||||
-rw-r--r-- | data-ipa-cfg-mgr/hal/src/OffloadStatistics.cpp | 57 | ||||
-rw-r--r-- | data-ipa-cfg-mgr/hal/src/PrefixParser.cpp | 391 |
6 files changed, 0 insertions, 1397 deletions
diff --git a/data-ipa-cfg-mgr/hal/src/CtUpdateAmbassador.cpp b/data-ipa-cfg-mgr/hal/src/CtUpdateAmbassador.cpp deleted file mode 100644 index 4843fe2..0000000 --- a/data-ipa-cfg-mgr/hal/src/CtUpdateAmbassador.cpp +++ /dev/null @@ -1,123 +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. - */ -#ifndef DBG - #define DBG false -#endif /* DBG */ -#define LOG_TAG "IPAHALService/CtUpdateAmbassador" - -/* External Includes */ -#include <arpa/inet.h> -#include <cutils/log.h> - -/* HIDL Includes */ -#include <android/hardware/tetheroffload/control/1.0/ITetheringOffloadCallback.h> - -/* Internal Includes */ -#include "CtUpdateAmbassador.h" - -/* Namespace pollution avoidance */ -using ::android::hardware::tetheroffload::control::V1_0::ITetheringOffloadCallback; -using ::android::hardware::tetheroffload::control::V1_0::NetworkProtocol; -using HALIpAddrPortPair = ::android::hardware::tetheroffload::control::V1_0::IPv4AddrPortPair; -using HALNatTimeoutUpdate = ::android::hardware::tetheroffload::control::V1_0::NatTimeoutUpdate; - -using IpaIpAddrPortPair = ::IOffloadManager::ConntrackTimeoutUpdater::IpAddrPortPair; -using IpaNatTimeoutUpdate = ::IOffloadManager::ConntrackTimeoutUpdater::NatTimeoutUpdate; -using IpaL4Protocol = ::IOffloadManager::ConntrackTimeoutUpdater::L4Protocol; - - -CtUpdateAmbassador::CtUpdateAmbassador( - const ::android::sp<ITetheringOffloadCallback>& cb) : mFramework(cb) { -} /* CtUpdateAmbassador */ - -void CtUpdateAmbassador::updateTimeout(IpaNatTimeoutUpdate in) { - if (DBG) { - ALOGD("updateTimeout(src={%#010X, %#04X}, dest={%#010X, %#04X}, Proto=%d)", - in.src.ipAddr, in.src.port, in.dst.ipAddr, in.dst.port, - in.proto); - } - HALNatTimeoutUpdate out; - if (!translate(in, out)) { - /* Cannot log the input outside of DBG flag because it contains sensitive - * information. This will lead to a two step debug if the information - * cannot be gleaned from IPACM logs. The other option is to improve this - * with the use of our local log. That would likely still be hard to - * instruct testers to collect logs, because, assuming timeout updates - * are numerous, it will overrun the ring quickly. Therefore, the tester - * would have to know the exact moment as issue occurred. Or we make the - * ring massive. This would lead to a significant memory overhead. - * Because of this overhead, we would likely not want to check in a change - * with it and once we provide a debug build for increasing buffer size, - * why not just define the DBG flag? - */ - ALOGE("Failed to translate timeout event :("); - } else { - mFramework->updateTimeout(out); - } -} /* updateTimeout */ - -bool CtUpdateAmbassador::translate(IpaNatTimeoutUpdate in, HALNatTimeoutUpdate &out) { - return translate(in.src, out.src) - && translate(in.dst, out.dst) - && L4ToNetwork(in.proto, out.proto); -} /* translate */ - -bool CtUpdateAmbassador::translate(IpaIpAddrPortPair in, HALIpAddrPortPair& out) { - char ipAddrStr[INET_ADDRSTRLEN]; - - if (inet_ntop(AF_INET, &(in.ipAddr), ipAddrStr, INET_ADDRSTRLEN) == nullptr) { - /* errno would be valid here with EAFNOSUPPORT or ENOSPC, neither should really - * be possible in our scenario though. - */ - return false; - } - - out.addr = ipAddrStr; - out.port = in.port; - - return true; -} /* translate */ - -bool CtUpdateAmbassador::L4ToNetwork(IpaL4Protocol in, NetworkProtocol &out) { - bool ret = false; - switch(in) { - case IpaL4Protocol::TCP: - ret = true; - out = NetworkProtocol::TCP; - break; - case IpaL4Protocol::UDP: - ret = true; - out = NetworkProtocol::UDP; - break; - default: - ret = false; - break; - } - return ret; -} /* L4ToNetwork */ diff --git a/data-ipa-cfg-mgr/hal/src/HAL.cpp b/data-ipa-cfg-mgr/hal/src/HAL.cpp deleted file mode 100644 index 3f1a41f..0000000 --- a/data-ipa-cfg-mgr/hal/src/HAL.cpp +++ /dev/null @@ -1,617 +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. - */ -#ifndef DBG - #define DBG true -#endif /* DBG */ -#define LOG_TAG "IPAHALService" - -/* HIDL Includes */ -#include <hwbinder/IPCThreadState.h> -#include <hwbinder/ProcessState.h> - -/* Kernel Includes */ -#include <linux/netfilter/nfnetlink_compat.h> - -/* External Includes */ -#include <cutils/log.h> -#include <cstring> -#include <sys/socket.h> -#include <sys/types.h> -#include <vector> - -/* Internal Includes */ -#include "HAL.h" -#include "LocalLogBuffer.h" -#include "PrefixParser.h" - -/* Namespace pollution avoidance */ -using ::android::hardware::Void; -using ::android::status_t; - -using RET = ::IOffloadManager::RET; -using Prefix = ::IOffloadManager::Prefix; - -using ::std::map; -using ::std::vector; - - -/* ------------------------------ PUBLIC ------------------------------------ */ -HAL* HAL::makeIPAHAL(int version, IOffloadManager* mgr) { - android::hardware::ProcessState::initWithMmapSize((size_t)(2 * KERNEL_PAGE)); - - if (DBG) - ALOGI("makeIPAHAL(%d, %s)", version, - (mgr != nullptr) ? "provided" : "null"); - if (nullptr == mgr) return NULL; - else if (version != 1) return NULL; - HAL* ret = new HAL(mgr); - if (nullptr == ret) return NULL; - configureRpcThreadpool(1, false); - ret->registerAsSystemService("ipacm"); - return ret; -} /* makeIPAHAL */ - - -/* ------------------------------ PRIVATE ----------------------------------- */ -HAL::HAL(IOffloadManager* mgr) : mLogs("HAL Function Calls", 50) { - mIPA = mgr; - mCb.clear(); - mCbIpa = nullptr; - mCbCt = nullptr; -} /* HAL */ - -void HAL::registerAsSystemService(const char* name) { - status_t ret = 0; - - ret = IOffloadControl::registerAsService(); - if (ret != 0) ALOGE("Failed to register IOffloadControl (%d) name(%s)", ret, name); - else if (DBG) { - ALOGI("Successfully registered IOffloadControl"); - } - - ret = IOffloadConfig::registerAsService(); - if (ret != 0) ALOGE("Failed to register IOffloadConfig (%d)", ret); - else if (DBG) { - ALOGI("Successfully registered IOffloadConfig"); - } -} /* registerAsSystemService */ - -void HAL::doLogcatDump() { - ALOGD("mHandles"); - ALOGD("========"); - /* @TODO This will segfault if they aren't initialized and I don't currently - * care to check for initialization in a function that isn't used anyways - * ALOGD("fd1->%d", mHandle1->data[0]); - * ALOGD("fd2->%d", mHandle2->data[0]); - */ - ALOGD("========"); -} /* doLogcatDump */ - -HAL::BoolResult HAL::makeInputCheckFailure(string customErr) { - BoolResult ret; - ret.success = false; - ret.errMsg = "Failed Input Checks: " + customErr; - return ret; -} /* makeInputCheckFailure */ - -HAL::BoolResult HAL::ipaResultToBoolResult(RET in) { - BoolResult ret; - ret.success = (in >= RET::SUCCESS); - switch (in) { - case RET::FAIL_TOO_MANY_PREFIXES: - ret.errMsg = "Too Many Prefixes Provided"; - break; - case RET::FAIL_UNSUPPORTED: - ret.errMsg = "Unsupported by Hardware"; - break; - case RET::FAIL_INPUT_CHECK: - ret.errMsg = "Failed Input Checks"; - break; - case RET::FAIL_HARDWARE: - ret.errMsg = "Hardware did not accept"; - break; - case RET::FAIL_TRY_AGAIN: - ret.errMsg = "Try Again"; - break; - case RET::SUCCESS: - ret.errMsg = "Successful"; - break; - case RET::SUCCESS_DUPLICATE_CONFIG: - ret.errMsg = "Successful: Was a duplicate configuration"; - break; - case RET::SUCCESS_NO_OP: - ret.errMsg = "Successful: No action needed"; - break; - case RET::SUCCESS_OPTIMIZED: - ret.errMsg = "Successful: Performed optimized version of action"; - break; - default: - ret.errMsg = "Unknown Error"; - break; - } - return ret; -} /* ipaResultToBoolResult */ - -/* This will likely always result in doubling the number of loops the execution - * goes through. Obviously that is suboptimal. But if we first translate - * away from all HIDL specific code, then we can avoid sprinkling HIDL - * dependencies everywhere. - */ -vector<string> HAL::convertHidlStrToStdStr(hidl_vec<hidl_string> in) { - vector<string> ret; - for (size_t i = 0; i < in.size(); i++) { - string add = in[i]; - ret.push_back(add); - } - return ret; -} /* convertHidlStrToStdStr */ - -void HAL::registerEventListeners() { - registerIpaCb(); - registerCtCb(); -} /* registerEventListeners */ - -void HAL::registerIpaCb() { - if (isInitialized() && mCbIpa == nullptr) { - LocalLogBuffer::FunctionLog fl("registerEventListener"); - mCbIpa = new IpaEventRelay(mCb); - mIPA->registerEventListener(mCbIpa); - mLogs.addLog(fl); - } else { - ALOGE("Failed to registerIpaCb (isInitialized()=%s, (mCbIpa == nullptr)=%s)", - isInitialized() ? "true" : "false", - (mCbIpa == nullptr) ? "true" : "false"); - } -} /* registerIpaCb */ - -void HAL::registerCtCb() { - if (isInitialized() && mCbCt == nullptr) { - LocalLogBuffer::FunctionLog fl("registerCtTimeoutUpdater"); - mCbCt = new CtUpdateAmbassador(mCb); - mIPA->registerCtTimeoutUpdater(mCbCt); - mLogs.addLog(fl); - } else { - ALOGE("Failed to registerCtCb (isInitialized()=%s, (mCbCt == nullptr)=%s)", - isInitialized() ? "true" : "false", - (mCbCt == nullptr) ? "true" : "false"); - } -} /* registerCtCb */ - -void HAL::unregisterEventListeners() { - unregisterIpaCb(); - unregisterCtCb(); -} /* unregisterEventListeners */ - -void HAL::unregisterIpaCb() { - if (mCbIpa != nullptr) { - LocalLogBuffer::FunctionLog fl("unregisterEventListener"); - mIPA->unregisterEventListener(mCbIpa); - mCbIpa = nullptr; - mLogs.addLog(fl); - } else { - ALOGE("Failed to unregisterIpaCb"); - } -} /* unregisterIpaCb */ - -void HAL::unregisterCtCb() { - if (mCbCt != nullptr) { - LocalLogBuffer::FunctionLog fl("unregisterCtTimeoutUpdater"); - mIPA->unregisterCtTimeoutUpdater(mCbCt); - mCbCt = nullptr; - mLogs.addLog(fl); - } else { - ALOGE("Failed to unregisterCtCb"); - } -} /* unregisterCtCb */ - -void HAL::clearHandles() { - ALOGI("clearHandles()"); - /* @TODO handle this more gracefully... also remove the log - * - * Things that would be nice, but I can't do: - * [1] Destroy the object (it's on the stack) - * [2] Call freeHandle (it's private) - * - * Things I can do but are hacks: - * [1] Look at code and notice that setTo immediately calls freeHandle - */ - mHandle1.setTo(nullptr, true); - mHandle2.setTo(nullptr, true); -} /* clearHandles */ - -bool HAL::isInitialized() { - return mCb.get() != nullptr; -} /* isInitialized */ - - -/* -------------------------- IOffloadConfig -------------------------------- */ -Return<void> HAL::setHandles( - const hidl_handle &fd1, - const hidl_handle &fd2, - setHandles_cb hidl_cb -) { - LocalLogBuffer::FunctionLog fl(__func__); - - if (fd1->numFds != 1) { - BoolResult res = makeInputCheckFailure("Must provide exactly one FD per handle (fd1)"); - hidl_cb(res.success, res.errMsg); - fl.setResult(res.success, res.errMsg); - - mLogs.addLog(fl); - return Void(); - } - - if (fd2->numFds != 1) { - BoolResult res = makeInputCheckFailure("Must provide exactly one FD per handle (fd2)"); - hidl_cb(res.success, res.errMsg); - fl.setResult(res.success, res.errMsg); - - mLogs.addLog(fl); - return Void(); - } - - /* The = operator calls freeHandle internally. Therefore, if we were using - * these handles previously, they're now gone... forever. But hopefully the - * new ones kick in very quickly. - * - * After freeing anything previously held, it will dup the FD so we have our - * own copy. - */ - mHandle1 = fd1; - mHandle2 = fd2; - - /* Log the DUPed FD instead of the actual input FD so that we can lookup - * this value in ls -l /proc/<pid>/<fd> - */ - fl.addArg("fd1", mHandle1->data[0]); - fl.addArg("fd2", mHandle2->data[0]); - - /* Try to provide each handle to IPACM. Destroy our DUPed hidl_handles if - * IPACM does not like either input. This keeps us from leaking FDs or - * providing half solutions. - * - * @TODO unfortunately, this does not cover duplicate configs where IPACM - * thinks it is still holding on to a handle that we would have freed above. - * It also probably means that IPACM would not know about the first FD being - * freed if it rejects the second FD. - */ - RET ipaReturn = mIPA->provideFd(mHandle1->data[0], UDP_SUBSCRIPTIONS); - if (ipaReturn == RET::SUCCESS) { - ipaReturn = mIPA->provideFd(mHandle2->data[0], TCP_SUBSCRIPTIONS); - } - - if (ipaReturn != RET::SUCCESS) { - ALOGE("IPACM failed to accept the FDs (%d %d)", mHandle1->data[0], - mHandle2->data[0]); - clearHandles(); - } else { - /* @TODO remove logs after stabilization */ - ALOGI("IPACM was provided two FDs (%d, %d)", mHandle1->data[0], - mHandle2->data[0]); - } - - BoolResult res = ipaResultToBoolResult(ipaReturn); - hidl_cb(res.success, res.errMsg); - - fl.setResult(res.success, res.errMsg); - mLogs.addLog(fl); - return Void(); -} /* setHandles */ - - -/* -------------------------- IOffloadControl ------------------------------- */ -Return<void> HAL::initOffload -( - const ::android::sp<ITetheringOffloadCallback>& cb, - initOffload_cb hidl_cb -) { - LocalLogBuffer::FunctionLog fl(__func__); - - if (isInitialized()) { - BoolResult res = makeInputCheckFailure("Already initialized"); - hidl_cb(res.success, res.errMsg); - fl.setResult(res.success, res.errMsg); - mLogs.addLog(fl); - } else { - /* Should storing the CB be a function? */ - mCb = cb; - registerEventListeners(); - BoolResult res = ipaResultToBoolResult(RET::SUCCESS); - hidl_cb(res.success, res.errMsg); - fl.setResult(res.success, res.errMsg); - mLogs.addLog(fl); - } - - return Void(); -} /* initOffload */ - -Return<void> HAL::stopOffload -( - stopOffload_cb hidl_cb -) { - LocalLogBuffer::FunctionLog fl(__func__); - - if (!isInitialized()) { - BoolResult res = makeInputCheckFailure("Was never initialized"); - hidl_cb(res.success, res.errMsg); - fl.setResult(res.success, res.errMsg); - mLogs.addLog(fl); - } else { - /* Should removing the CB be a function? */ - mCb.clear(); - unregisterEventListeners(); - - RET ipaReturn = mIPA->stopAllOffload(); - if (ipaReturn != RET::SUCCESS) { - /* Ignore IPAs return value here and provide why stopAllOffload - * failed. However, if IPA failed to clearAllFds, then we can't - * clear our map because they may still be in use. - */ - RET ret = mIPA->clearAllFds(); - if (ret == RET::SUCCESS) { - clearHandles(); - } - } else { - ipaReturn = mIPA->clearAllFds(); - /* If IPA fails, they may still be using these for some reason. */ - if (ipaReturn == RET::SUCCESS) { - clearHandles(); - } else { - ALOGE("IPACM failed to return success for clearAllFds so they will not be released..."); - } - } - - BoolResult res = ipaResultToBoolResult(ipaReturn); - hidl_cb(res.success, res.errMsg); - - fl.setResult(res.success, res.errMsg); - mLogs.addLog(fl); - } - - return Void(); -} /* stopOffload */ - -Return<void> HAL::setLocalPrefixes -( - const hidl_vec<hidl_string>& prefixes, - setLocalPrefixes_cb hidl_cb -) { - BoolResult res; - PrefixParser parser; - vector<string> prefixesStr = convertHidlStrToStdStr(prefixes); - - LocalLogBuffer::FunctionLog fl(__func__); - fl.addArg("prefixes", prefixesStr); - - memset(&res,0,sizeof(BoolResult)); - - if (!isInitialized()) { - BoolResult res = makeInputCheckFailure("Not initialized"); - } else if(prefixesStr.size() < 1) { - res = ipaResultToBoolResult(RET::FAIL_INPUT_CHECK); - } else if (!parser.add(prefixesStr)) { - res = makeInputCheckFailure(parser.getLastErrAsStr()); - } else { - res = ipaResultToBoolResult(RET::SUCCESS); - } - - hidl_cb(res.success, res.errMsg); - fl.setResult(res.success, res.errMsg); - mLogs.addLog(fl); - return Void(); -} /* setLocalPrefixes */ - -Return<void> HAL::getForwardedStats -( - const hidl_string& upstream, - getForwardedStats_cb hidl_cb -) { - LocalLogBuffer::FunctionLog fl(__func__); - fl.addArg("upstream", upstream); - - OffloadStatistics ret; - RET ipaReturn = mIPA->getStats(upstream.c_str(), true, ret); - if (ipaReturn == RET::SUCCESS) { - hidl_cb(ret.getTotalRxBytes(), ret.getTotalTxBytes()); - fl.setResult(ret.getTotalRxBytes(), ret.getTotalTxBytes()); - } else { - /* @TODO Ensure the output is zeroed, but this is probably not enough to - * tell Framework that an error has occurred. If, for example, they had - * not yet polled for statistics previously, they may incorrectly assume - * that simply no statistics have transpired on hardware path. - * - * Maybe ITetheringOffloadCallback:onEvent(OFFLOAD_STOPPED_ERROR) is - * enough to handle this case, time will tell. - */ - hidl_cb(0, 0); - fl.setResult(0, 0); - } - - mLogs.addLog(fl); - return Void(); -} /* getForwardedStats */ - -Return<void> HAL::setDataLimit -( - const hidl_string& upstream, - uint64_t limit, - setDataLimit_cb hidl_cb -) { - LocalLogBuffer::FunctionLog fl(__func__); - fl.addArg("upstream", upstream); - fl.addArg("limit", limit); - - if (!isInitialized()) { - BoolResult res = makeInputCheckFailure("Not initialized (setDataLimit)"); - hidl_cb(res.success, res.errMsg); - fl.setResult(res.success, res.errMsg); - } else { - RET ipaReturn = mIPA->setQuota(upstream.c_str(), limit); - if(ipaReturn == RET::FAIL_TRY_AGAIN) { - ipaReturn = RET::SUCCESS; - } - BoolResult res = ipaResultToBoolResult(ipaReturn); - hidl_cb(res.success, res.errMsg); - fl.setResult(res.success, res.errMsg); - } - - mLogs.addLog(fl); - return Void(); -} /* setDataLimit */ - -Return<void> HAL::setUpstreamParameters -( - const hidl_string& iface, - const hidl_string& v4Addr, - const hidl_string& v4Gw, - const hidl_vec<hidl_string>& v6Gws, - setUpstreamParameters_cb hidl_cb -) { - vector<string> v6GwStrs = convertHidlStrToStdStr(v6Gws); - - LocalLogBuffer::FunctionLog fl(__func__); - fl.addArg("iface", iface); - fl.addArg("v4Addr", v4Addr); - fl.addArg("v4Gw", v4Gw); - fl.addArg("v6Gws", v6GwStrs); - - PrefixParser v4AddrParser; - PrefixParser v4GwParser; - PrefixParser v6GwParser; - - /* @TODO maybe we should enforce that these addresses and gateways are fully - * qualified here. But then, how do we allow them to be empty/null as well - * while still preserving a sane API on PrefixParser? - */ - if (!isInitialized()) { - BoolResult res = makeInputCheckFailure("Not initialized (setUpstreamParameters)"); - hidl_cb(res.success, res.errMsg); - fl.setResult(res.success, res.errMsg); - } else if (!v4AddrParser.addV4(v4Addr) && !v4Addr.empty()) { - BoolResult res = makeInputCheckFailure(v4AddrParser.getLastErrAsStr()); - hidl_cb(res.success, res.errMsg); - fl.setResult(res.success, res.errMsg); - } else if (!v4GwParser.addV4(v4Gw) && !v4Gw.empty()) { - BoolResult res = makeInputCheckFailure(v4GwParser.getLastErrAsStr()); - hidl_cb(res.success, res.errMsg); - fl.setResult(res.success, res.errMsg); - } else if (v6GwStrs.size() >= 1 && !v6GwParser.addV6(v6GwStrs)) { - BoolResult res = makeInputCheckFailure(v6GwParser.getLastErrAsStr()); - hidl_cb(res.success, res.errMsg); - fl.setResult(res.success, res.errMsg); - } else if (iface.size()>= 1) { - RET ipaReturn = mIPA->setUpstream( - iface.c_str(), - v4GwParser.getFirstPrefix(), - v6GwParser.getFirstPrefix()); - BoolResult res = ipaResultToBoolResult(ipaReturn); - hidl_cb(res.success, res.errMsg); - fl.setResult(res.success, res.errMsg); - } else { - /* send NULL iface string when upstream down */ - RET ipaReturn = mIPA->setUpstream( - NULL, - v4GwParser.getFirstPrefix(IP_FAM::V4), - v6GwParser.getFirstPrefix(IP_FAM::V6)); - BoolResult res = ipaResultToBoolResult(ipaReturn); - hidl_cb(res.success, res.errMsg); - fl.setResult(res.success, res.errMsg); - } - - mLogs.addLog(fl); - return Void(); -} /* setUpstreamParameters */ - -Return<void> HAL::addDownstream -( - const hidl_string& iface, - const hidl_string& prefix, - addDownstream_cb hidl_cb -) { - LocalLogBuffer::FunctionLog fl(__func__); - fl.addArg("iface", iface); - fl.addArg("prefix", prefix); - - PrefixParser prefixParser; - - if (!isInitialized()) { - BoolResult res = makeInputCheckFailure("Not initialized (setUpstreamParameters)"); - hidl_cb(res.success, res.errMsg); - fl.setResult(res.success, res.errMsg); - } - else if (!prefixParser.add(prefix)) { - BoolResult res = makeInputCheckFailure(prefixParser.getLastErrAsStr()); - hidl_cb(res.success, res.errMsg); - fl.setResult(res.success, res.errMsg); - } else { - RET ipaReturn = mIPA->addDownstream( - iface.c_str(), - prefixParser.getFirstPrefix()); - BoolResult res = ipaResultToBoolResult(ipaReturn); - hidl_cb(res.success, res.errMsg); - fl.setResult(res.success, res.errMsg); - } - - mLogs.addLog(fl); - return Void(); -} /* addDownstream */ - -Return<void> HAL::removeDownstream -( - const hidl_string& iface, - const hidl_string& prefix, - removeDownstream_cb hidl_cb -) { - LocalLogBuffer::FunctionLog fl(__func__); - fl.addArg("iface", iface); - fl.addArg("prefix", prefix); - - PrefixParser prefixParser; - - if (!isInitialized()) { - BoolResult res = makeInputCheckFailure("Not initialized (setUpstreamParameters)"); - hidl_cb(res.success, res.errMsg); - fl.setResult(res.success, res.errMsg); - } - else if (!prefixParser.add(prefix)) { - BoolResult res = makeInputCheckFailure(prefixParser.getLastErrAsStr()); - hidl_cb(res.success, res.errMsg); - fl.setResult(res.success, res.errMsg); - } else { - RET ipaReturn = mIPA->removeDownstream( - iface.c_str(), - prefixParser.getFirstPrefix()); - BoolResult res = ipaResultToBoolResult(ipaReturn); - hidl_cb(res.success, res.errMsg); - fl.setResult(res.success, res.errMsg); - } - - mLogs.addLog(fl); - return Void(); -} /* removeDownstream */ diff --git a/data-ipa-cfg-mgr/hal/src/IpaEventRelay.cpp b/data-ipa-cfg-mgr/hal/src/IpaEventRelay.cpp deleted file mode 100644 index 788b152..0000000 --- a/data-ipa-cfg-mgr/hal/src/IpaEventRelay.cpp +++ /dev/null @@ -1,83 +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. - */ -#define LOG_TAG "IPAHALService/IpaEventRelay" -/* External Includes */ -#include <cutils/log.h> - -/* HIDL Includes */ -#include <android/hardware/tetheroffload/control/1.0/ITetheringOffloadCallback.h> - -/* Internal Includes */ -#include "IpaEventRelay.h" - -/* Namespace pollution avoidance */ -using ::android::hardware::tetheroffload::control::V1_0::ITetheringOffloadCallback; -using ::android::hardware::tetheroffload::control::V1_0::OffloadCallbackEvent; - - -IpaEventRelay::IpaEventRelay( - const ::android::sp<ITetheringOffloadCallback>& cb) : mFramework(cb) { -} /* IpaEventRelay */ - -void IpaEventRelay::onOffloadStarted() { - ALOGI("onOffloadStarted()"); - mFramework->onEvent(OffloadCallbackEvent::OFFLOAD_STARTED); -} /* onOffloadStarted */ - -void IpaEventRelay::onOffloadStopped(StoppedReason reason) { - ALOGI("onOffloadStopped(%d)", reason); - switch (reason) { - case REQUESTED: - /* - * No way to communicate this to Framework right now, they make an - * assumption that offload is stopped when they remove the - * configuration. - */ - break; - case ERROR: - mFramework->onEvent(OffloadCallbackEvent::OFFLOAD_STOPPED_ERROR); - break; - case UNSUPPORTED: - mFramework->onEvent(OffloadCallbackEvent::OFFLOAD_STOPPED_UNSUPPORTED); - break; - default: - ALOGE("Unknown stopped reason(%d)", reason); - break; - } -} /* onOffloadStopped */ - -void IpaEventRelay::onOffloadSupportAvailable() { - ALOGI("onOffloadSupportAvailable()"); - mFramework->onEvent(OffloadCallbackEvent::OFFLOAD_SUPPORT_AVAILABLE); -} /* onOffloadSupportAvailable */ - -void IpaEventRelay::onLimitReached() { - ALOGI("onLimitReached()"); - mFramework->onEvent(OffloadCallbackEvent::OFFLOAD_STOPPED_LIMIT_REACHED); -} /* onLimitReached */ diff --git a/data-ipa-cfg-mgr/hal/src/LocalLogBuffer.cpp b/data-ipa-cfg-mgr/hal/src/LocalLogBuffer.cpp deleted file mode 100644 index f556e40..0000000 --- a/data-ipa-cfg-mgr/hal/src/LocalLogBuffer.cpp +++ /dev/null @@ -1,126 +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. - */ -#define LOG_TAG "IPAHALService/dump" - -/* External Includes */ -#include <cutils/log.h> -#include <deque> -#include <string> -#include <sys/types.h> -#include <vector> - -/* Internal Includes */ -#include "LocalLogBuffer.h" - -/* Namespace pollution avoidance */ -using ::std::deque; -using ::std::string; -using ::std::vector; - - -LocalLogBuffer::FunctionLog::FunctionLog(string funcName) : mName(funcName) { - mArgsProvided = false; -} /* FunctionLog */ - -LocalLogBuffer::FunctionLog::FunctionLog(const FunctionLog& other) : - mName(other.mName) { - mArgsProvided = other.mArgsProvided; - /* Is this right? How do you copy stringstreams without wizardry? */ - mSSArgs.str(other.mSSArgs.str()); - mSSReturn.str(other.mSSReturn.str()); -} /* FunctionLog */ - -void LocalLogBuffer::FunctionLog::addArg(string kw, string arg) { - maybeAddArgsComma(); - mSSArgs << kw << "=" << arg; -} /* addArg */ - -void LocalLogBuffer::FunctionLog::addArg(string kw, vector<string> args) { - maybeAddArgsComma(); - mSSArgs << kw << "=["; - for (size_t i = 0; i < args.size(); i++) { - mSSArgs << args[i]; - if (i < (args.size() - 1)) - mSSArgs << ", "; - } - mSSArgs << "]"; -} /* addArg */ - -void LocalLogBuffer::FunctionLog::addArg(string kw, uint64_t arg) { - maybeAddArgsComma(); - mSSArgs << kw << "=" << arg; -} /* addArg */ - -void LocalLogBuffer::FunctionLog::maybeAddArgsComma() { - if (!mArgsProvided) { - mArgsProvided = true; - } else { - mSSArgs << ", "; - } -} /* maybeAddArgsComma */ - -void LocalLogBuffer::FunctionLog::setResult(bool success, string msg) { - mSSReturn << "[" << ((success) ? "success" : "failure") << ", " << msg - << "]"; -} /* setResult */ - -void LocalLogBuffer::FunctionLog::setResult(vector<unsigned int> ret) { - mSSReturn << "["; - for (size_t i = 0; i < ret.size(); i++) { - mSSReturn << ret[i]; - if (i < (ret.size() - 1)) - mSSReturn << ", "; - } - mSSReturn << "]"; -} /* setResult */ - -void LocalLogBuffer::FunctionLog::setResult(uint64_t rx, uint64_t tx) { - mSSReturn << "[rx=" << rx << ", tx=" << tx << "]"; -} /* setResult */ - -string LocalLogBuffer::FunctionLog::toString() { - stringstream ret; - ret << mName << "(" << mSSArgs.str() << ") returned " << mSSReturn.str(); - return ret.str(); -} /* toString */ - -LocalLogBuffer::LocalLogBuffer(string name, int maxLogs) : mName(name), - mMaxLogs(maxLogs) { -} /* LocalLogBuffer */ - -void LocalLogBuffer::addLog(FunctionLog log) { - while (mLogs.size() > mMaxLogs) - mLogs.pop_front(); - mLogs.push_back(log); -} /* addLog */ - -void LocalLogBuffer::toLogcat() { - for (size_t i = 0; i < mLogs.size(); i++) - ALOGD("%s: %s", mName.c_str(), mLogs[i].toString().c_str()); -} /* toLogcat */ diff --git a/data-ipa-cfg-mgr/hal/src/OffloadStatistics.cpp b/data-ipa-cfg-mgr/hal/src/OffloadStatistics.cpp deleted file mode 100644 index 8f8beb6..0000000 --- a/data-ipa-cfg-mgr/hal/src/OffloadStatistics.cpp +++ /dev/null @@ -1,57 +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. - */ -#include <string.h> -#include <sys/types.h> - -#include "OffloadStatistics.h" - - -/* ------------------------------ PUBLIC ------------------------------------ */ -OffloadStatistics::OffloadStatistics() { - this->upstream = "UNSET"; - this->rx = 0; - this->tx = 0; -} /* OffloadStatistics */ - -OffloadStatistics::OffloadStatistics -( - std::string upstream -) { - this->upstream = upstream; - this->rx = 0; - this->tx =0; -} /* OffloadStatistics */ - -uint64_t OffloadStatistics::getTotalRxBytes() { - return rx; -} /* getTotalRxBytes */ - -uint64_t OffloadStatistics::getTotalTxBytes() { - return tx; -} /* getTotalTxBytes */ 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 */ |