diff options
Diffstat (limited to 'dom/system/gonk/NetworkUtils.cpp')
-rw-r--r-- | dom/system/gonk/NetworkUtils.cpp | 2973 |
1 files changed, 0 insertions, 2973 deletions
diff --git a/dom/system/gonk/NetworkUtils.cpp b/dom/system/gonk/NetworkUtils.cpp deleted file mode 100644 index d661368b88..0000000000 --- a/dom/system/gonk/NetworkUtils.cpp +++ /dev/null @@ -1,2973 +0,0 @@ -/* Copyright 2012 Mozilla Foundation and Mozilla contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "NetworkUtils.h" - -#include "mozilla/Sprintf.h" -#include "SystemProperty.h" - -#include <android/log.h> -#include <limits> -#include "mozilla/dom/network/NetUtils.h" -#include "mozilla/fallible.h" -#include "base/task.h" - -#include <errno.h> -#include <string.h> -#include <sys/types.h> // struct addrinfo -#include <sys/socket.h> // getaddrinfo(), freeaddrinfo() -#include <netdb.h> -#include <arpa/inet.h> // inet_ntop() - -#define _DEBUG 0 - -#define WARN(args...) __android_log_print(ANDROID_LOG_WARN, "NetworkUtils", ## args) -#define ERROR(args...) __android_log_print(ANDROID_LOG_ERROR, "NetworkUtils", ## args) - -#if _DEBUG -#define NU_DBG(args...) __android_log_print(ANDROID_LOG_DEBUG, "NetworkUtils" , ## args) -#else -#define NU_DBG(args...) -#endif - -using namespace mozilla::dom; -using namespace mozilla::ipc; -using mozilla::system::Property; - -static const char* PERSIST_SYS_USB_CONFIG_PROPERTY = "persist.sys.usb.config"; -static const char* SYS_USB_CONFIG_PROPERTY = "sys.usb.config"; -static const char* SYS_USB_STATE_PROPERTY = "sys.usb.state"; - -static const char* USB_FUNCTION_RNDIS = "rndis"; -static const char* USB_FUNCTION_ADB = "adb"; - -// Use this command to continue the function chain. -static const char* DUMMY_COMMAND = "tether status"; - -// IPV6 Tethering is not supported in AOSP, use the property to -// identify vendor specific support in IPV6. We can remove this flag -// once upstream Android support IPV6 in tethering. -static const char* IPV6_TETHERING = "ro.tethering.ipv6"; - -// Retry 20 times (2 seconds) for usb state transition. -static const uint32_t USB_FUNCTION_RETRY_TIMES = 20; -// Check "sys.usb.state" every 100ms. -static const uint32_t USB_FUNCTION_RETRY_INTERVAL = 100; - -// 1xx - Requested action is proceeding -static const uint32_t NETD_COMMAND_PROCEEDING = 100; -// 2xx - Requested action has been successfully completed -static const uint32_t NETD_COMMAND_OKAY = 200; -// 4xx - The command is accepted but the requested action didn't -// take place. -static const uint32_t NETD_COMMAND_FAIL = 400; -// 5xx - The command syntax or parameters error -static const uint32_t NETD_COMMAND_ERROR = 500; -// 6xx - Unsolicited broadcasts -static const uint32_t NETD_COMMAND_UNSOLICITED = 600; - -// Broadcast messages -static const uint32_t NETD_COMMAND_INTERFACE_CHANGE = 600; -static const uint32_t NETD_COMMAND_BANDWIDTH_CONTROLLER = 601; - -static const char* INTERFACE_DELIMIT = ","; -static const char* USB_CONFIG_DELIMIT = ","; -static const char* NETD_MESSAGE_DELIMIT = " "; - -static const uint32_t BUF_SIZE = 1024; - -static const int32_t SUCCESS = 0; - -static uint32_t SDK_VERSION; -static uint32_t SUPPORT_IPV6_TETHERING; - -struct IFProperties { - char gateway[Property::VALUE_MAX_LENGTH]; - char dns1[Property::VALUE_MAX_LENGTH]; - char dns2[Property::VALUE_MAX_LENGTH]; -}; - -struct CurrentCommand { - CommandChain* chain; - CommandCallback callback; - char command[MAX_COMMAND_SIZE]; -}; - -typedef Tuple3<NetdCommand*, CommandChain*, CommandCallback> QueueData; - -#define GET_CURRENT_NETD_COMMAND (gCommandQueue.IsEmpty() ? nullptr : gCommandQueue[0].a) -#define GET_CURRENT_CHAIN (gCommandQueue.IsEmpty() ? nullptr : gCommandQueue[0].b) -#define GET_CURRENT_CALLBACK (gCommandQueue.IsEmpty() ? nullptr : gCommandQueue[0].c) -#define GET_CURRENT_COMMAND (gCommandQueue.IsEmpty() ? nullptr : gCommandQueue[0].a->mData) - -// A macro for native function call return value check. -// For native function call, non-zero return value means failure. -#define RETURN_IF_FAILED(rv) do { \ - if (SUCCESS != rv) { \ - return rv; \ - } \ -} while (0); - -#define WARN_IF_FAILED(rv) do { \ - if (SUCCESS != rv) { \ - WARN("Error (%d) occurred in %s (%s:%d)", rv, __PRETTY_FUNCTION__, __FILE__, __LINE__); \ - } \ -} while (0); - -static NetworkUtils* gNetworkUtils; -static nsTArray<QueueData> gCommandQueue; -static CurrentCommand gCurrentCommand; -static bool gPending = false; -static nsTArray<nsCString> gReason; -static NetworkParams *gWifiTetheringParms = 0; - -static nsTArray<CommandChain*> gCommandChainQueue; - -const CommandFunc NetworkUtils::sWifiEnableChain[] = { - NetworkUtils::clearWifiTetherParms, - NetworkUtils::wifiFirmwareReload, - NetworkUtils::startAccessPointDriver, - NetworkUtils::setAccessPoint, - NetworkUtils::startSoftAP, - NetworkUtils::setConfig, - NetworkUtils::tetherInterface, - NetworkUtils::addInterfaceToLocalNetwork, - NetworkUtils::addRouteToLocalNetwork, - NetworkUtils::setIpForwardingEnabled, - NetworkUtils::tetheringStatus, - NetworkUtils::startTethering, - NetworkUtils::setDnsForwarders, - NetworkUtils::enableNat, - NetworkUtils::wifiTetheringSuccess -}; - -const CommandFunc NetworkUtils::sWifiDisableChain[] = { - NetworkUtils::clearWifiTetherParms, - NetworkUtils::stopSoftAP, - NetworkUtils::stopAccessPointDriver, - NetworkUtils::wifiFirmwareReload, - NetworkUtils::untetherInterface, - NetworkUtils::removeInterfaceFromLocalNetwork, - NetworkUtils::preTetherInterfaceList, - NetworkUtils::postTetherInterfaceList, - NetworkUtils::disableNat, - NetworkUtils::setIpForwardingEnabled, - NetworkUtils::stopTethering, - NetworkUtils::wifiTetheringSuccess -}; - -const CommandFunc NetworkUtils::sWifiFailChain[] = { - NetworkUtils::clearWifiTetherParms, - NetworkUtils::stopSoftAP, - NetworkUtils::setIpForwardingEnabled, - NetworkUtils::stopTethering -}; - -const CommandFunc NetworkUtils::sWifiRetryChain[] = { - NetworkUtils::clearWifiTetherParms, - NetworkUtils::stopSoftAP, - NetworkUtils::stopTethering, - - // sWifiEnableChain: - NetworkUtils::wifiFirmwareReload, - NetworkUtils::startAccessPointDriver, - NetworkUtils::setAccessPoint, - NetworkUtils::startSoftAP, - NetworkUtils::setConfig, - NetworkUtils::tetherInterface, - NetworkUtils::addInterfaceToLocalNetwork, - NetworkUtils::addRouteToLocalNetwork, - NetworkUtils::setIpForwardingEnabled, - NetworkUtils::tetheringStatus, - NetworkUtils::startTethering, - NetworkUtils::setDnsForwarders, - NetworkUtils::enableNat, - NetworkUtils::wifiTetheringSuccess -}; - -const CommandFunc NetworkUtils::sWifiOperationModeChain[] = { - NetworkUtils::wifiFirmwareReload, - NetworkUtils::wifiOperationModeSuccess -}; - -const CommandFunc NetworkUtils::sUSBEnableChain[] = { - NetworkUtils::setConfig, - NetworkUtils::enableNat, - NetworkUtils::setIpForwardingEnabled, - NetworkUtils::tetherInterface, - NetworkUtils::addInterfaceToLocalNetwork, - NetworkUtils::addRouteToLocalNetwork, - NetworkUtils::tetheringStatus, - NetworkUtils::startTethering, - NetworkUtils::setDnsForwarders, - NetworkUtils::addUpstreamInterface, - NetworkUtils::usbTetheringSuccess -}; - -const CommandFunc NetworkUtils::sUSBDisableChain[] = { - NetworkUtils::untetherInterface, - NetworkUtils::removeInterfaceFromLocalNetwork, - NetworkUtils::preTetherInterfaceList, - NetworkUtils::postTetherInterfaceList, - NetworkUtils::removeUpstreamInterface, - NetworkUtils::disableNat, - NetworkUtils::setIpForwardingEnabled, - NetworkUtils::stopTethering, - NetworkUtils::usbTetheringSuccess -}; - -const CommandFunc NetworkUtils::sUSBFailChain[] = { - NetworkUtils::stopSoftAP, - NetworkUtils::setIpForwardingEnabled, - NetworkUtils::stopTethering -}; - -const CommandFunc NetworkUtils::sUpdateUpStreamChain[] = { - NetworkUtils::cleanUpStream, - NetworkUtils::removeUpstreamInterface, - NetworkUtils::createUpStream, - NetworkUtils::addUpstreamInterface, - NetworkUtils::updateUpStreamSuccess -}; - -const CommandFunc NetworkUtils::sStartDhcpServerChain[] = { - NetworkUtils::setConfig, - NetworkUtils::startTethering, - NetworkUtils::setDhcpServerSuccess -}; - -const CommandFunc NetworkUtils::sStopDhcpServerChain[] = { - NetworkUtils::stopTethering, - NetworkUtils::setDhcpServerSuccess -}; - -const CommandFunc NetworkUtils::sNetworkInterfaceEnableAlarmChain[] = { - NetworkUtils::enableAlarm, - NetworkUtils::setQuota, - NetworkUtils::setAlarm, - NetworkUtils::networkInterfaceAlarmSuccess -}; - -const CommandFunc NetworkUtils::sNetworkInterfaceDisableAlarmChain[] = { - NetworkUtils::removeQuota, - NetworkUtils::disableAlarm, - NetworkUtils::networkInterfaceAlarmSuccess -}; - -const CommandFunc NetworkUtils::sNetworkInterfaceSetAlarmChain[] = { - NetworkUtils::setAlarm, - NetworkUtils::networkInterfaceAlarmSuccess -}; - -const CommandFunc NetworkUtils::sGetInterfacesChain[] = { - NetworkUtils::getInterfaceList, - NetworkUtils::getInterfacesSuccess -}; - -const CommandFunc NetworkUtils::sGetInterfaceConfigChain[] = { - NetworkUtils::getConfig, - NetworkUtils::getInterfaceConfigSuccess -}; - -const CommandFunc NetworkUtils::sSetInterfaceConfigChain[] = { - NetworkUtils::setConfig, - NetworkUtils::setInterfaceConfigSuccess -}; - -const CommandFunc NetworkUtils::sTetheringInterfaceSetAlarmChain[] = { - NetworkUtils::setGlobalAlarm, - NetworkUtils::removeAlarm, - NetworkUtils::networkInterfaceAlarmSuccess -}; - -const CommandFunc NetworkUtils::sTetheringInterfaceRemoveAlarmChain[] = { - NetworkUtils::removeGlobalAlarm, - NetworkUtils::setAlarm, - NetworkUtils::networkInterfaceAlarmSuccess -}; - -const CommandFunc NetworkUtils::sTetheringGetStatusChain[] = { - NetworkUtils::tetheringStatus, - NetworkUtils::defaultAsyncSuccessHandler -}; - -/** - * Helper function to get the mask from given prefix length. - */ -static uint32_t makeMask(const uint32_t prefixLength) -{ - uint32_t mask = 0; - for (uint32_t i = 0; i < prefixLength; ++i) { - mask |= (0x80000000 >> i); - } - return ntohl(mask); -} - -/** - * Helper function to get the network part of an ip from prefix. - * param ip must be in network byte order. - */ -static char* getNetworkAddr(const uint32_t ip, const uint32_t prefix) -{ - uint32_t mask = 0, subnet = 0; - - mask = ~mask << (32 - prefix); - mask = htonl(mask); - subnet = ip & mask; - - struct in_addr addr; - addr.s_addr = subnet; - - return inet_ntoa(addr); -} - -/** - * Helper function to split string by seperator, store split result as an nsTArray. - */ -static void split(char* str, const char* sep, nsTArray<nsCString>& result) -{ - char *s = strtok(str, sep); - while (s != nullptr) { - result.AppendElement(s); - s = strtok(nullptr, sep); - } -} - -static void split(char* str, const char* sep, nsTArray<nsString>& result) -{ - char *s = strtok(str, sep); - while (s != nullptr) { - result.AppendElement(NS_ConvertUTF8toUTF16(s)); - s = strtok(nullptr, sep); - } -} - -/** - * Helper function that implement join function. - */ -static void join(nsTArray<nsCString>& array, - const char* sep, - const uint32_t maxlen, - char* result) -{ -#define CHECK_LENGTH(len, add, max) len += add; \ - if (len > max - 1) \ - return; \ - - uint32_t len = 0; - uint32_t seplen = strlen(sep); - - if (array.Length() > 0) { - CHECK_LENGTH(len, strlen(array[0].get()), maxlen) - strcpy(result, array[0].get()); - - for (uint32_t i = 1; i < array.Length(); i++) { - CHECK_LENGTH(len, seplen, maxlen) - strcat(result, sep); - - CHECK_LENGTH(len, strlen(array[i].get()), maxlen) - strcat(result, array[i].get()); - } - } - -#undef CHECK_LEN -} - -static void convertUTF8toUTF16(nsTArray<nsCString>& narrow, - nsTArray<nsString>& wide, - uint32_t length) -{ - for (uint32_t i = 0; i < length; i++) { - wide.AppendElement(NS_ConvertUTF8toUTF16(narrow[i].get())); - } -} - -/** - * Helper function to get network interface properties from the system property table. - */ -static void getIFProperties(const char* ifname, IFProperties& prop) -{ - char key[Property::KEY_MAX_LENGTH]; - snprintf(key, Property::KEY_MAX_LENGTH - 1, "net.%s.gw", ifname); - Property::Get(key, prop.gateway, ""); - snprintf(key, Property::KEY_MAX_LENGTH - 1, "net.%s.dns1", ifname); - Property::Get(key, prop.dns1, ""); - snprintf(key, Property::KEY_MAX_LENGTH - 1, "net.%s.dns2", ifname); - Property::Get(key, prop.dns2, ""); -} - -static int getIpType(const char *aIp) { - struct addrinfo hint, *ip_info = NULL; - - memset(&hint, 0, sizeof(hint)); - hint.ai_family = AF_UNSPEC; - hint.ai_flags = AI_NUMERICHOST; - - if (getaddrinfo(aIp, NULL, &hint, &ip_info)) { - return AF_UNSPEC; - } - - int type = ip_info->ai_family; - freeaddrinfo(ip_info); - - return type; -} - -static void postMessage(NetworkResultOptions& aResult) -{ - MOZ_ASSERT(gNetworkUtils); - MOZ_ASSERT(gNetworkUtils->getMessageCallback()); - - if (*(gNetworkUtils->getMessageCallback())) - (*(gNetworkUtils->getMessageCallback()))(aResult); -} - -static void postMessage(NetworkParams& aOptions, NetworkResultOptions& aResult) -{ - MOZ_ASSERT(gNetworkUtils); - MOZ_ASSERT(gNetworkUtils->getMessageCallback()); - - aResult.mId = aOptions.mId; - - if (*(gNetworkUtils->getMessageCallback())) - (*(gNetworkUtils->getMessageCallback()))(aResult); -} - -void NetworkUtils::runNextQueuedCommandChain() -{ - if (gCommandChainQueue.IsEmpty()) { - NU_DBG("No command chain left in the queue. Done!"); - return; - } - NU_DBG("Process the queued command chain."); - CommandChain* nextChain = gCommandChainQueue[0]; - NetworkResultOptions newResult; - next(nextChain, false, newResult); -} - -void NetworkUtils::next(CommandChain* aChain, bool aError, NetworkResultOptions& aResult) -{ - if (aError) { - ErrorCallback onError = aChain->getErrorCallback(); - if(onError) { - aResult.mError = true; - (*onError)(aChain->getParams(), aResult); - } - delete aChain; - gCommandChainQueue.RemoveElementAt(0); - runNextQueuedCommandChain(); - return; - } - CommandFunc f = aChain->getNextCommand(); - if (!f) { - delete aChain; - gCommandChainQueue.RemoveElementAt(0); - runNextQueuedCommandChain(); - return; - } - - (*f)(aChain, next, aResult); -} - -CommandResult::CommandResult(int32_t aResultCode) - : mIsPending(false) -{ - // This is usually not a netd command. We treat the return code - // typical linux convention, which uses 0 to indicate success. - mResult.mError = (aResultCode == SUCCESS ? false : true); - mResult.mResultCode = aResultCode; - if (aResultCode != SUCCESS) { - // The returned value is sometimes negative, make sure we pass a positive - // error number to strerror. - enum { STRERROR_R_BUF_SIZE = 1024, }; - char strerrorBuf[STRERROR_R_BUF_SIZE]; - strerror_r(abs(aResultCode), strerrorBuf, STRERROR_R_BUF_SIZE); - mResult.mReason = NS_ConvertUTF8toUTF16(strerrorBuf); - } -} - -CommandResult::CommandResult(const mozilla::dom::NetworkResultOptions& aResult) - : mResult(aResult) - , mIsPending(false) -{ -} - -CommandResult::CommandResult(const Pending&) - : mIsPending(true) -{ -} - -bool CommandResult::isPending() const -{ - return mIsPending; -} - -/** - * Send command to netd. - */ -void NetworkUtils::nextNetdCommand() -{ - if (gCommandQueue.IsEmpty() || gPending) { - return; - } - - gCurrentCommand.chain = GET_CURRENT_CHAIN; - gCurrentCommand.callback = GET_CURRENT_CALLBACK; - snprintf(gCurrentCommand.command, MAX_COMMAND_SIZE - 1, "%s", GET_CURRENT_COMMAND); - - NU_DBG("Sending \'%s\' command to netd.", gCurrentCommand.command); - SendNetdCommand(GET_CURRENT_NETD_COMMAND); - - gCommandQueue.RemoveElementAt(0); - gPending = true; -} - -/** - * Composite NetdCommand sent to netd - * - * @param aCommand Command sent to netd to execute. - * @param aChain Store command chain data, ex. command parameter. - * @param aCallback Callback function to be executed when the result of - * this command is returned from netd. - */ -void NetworkUtils::doCommand(const char* aCommand, CommandChain* aChain, CommandCallback aCallback) -{ - NU_DBG("Preparing to send \'%s\' command...", aCommand); - - NetdCommand* netdCommand = new NetdCommand(); - - // Android JB version adds sequence number to netd command. - if (SDK_VERSION >= 16) { - snprintf((char*)netdCommand->mData, MAX_COMMAND_SIZE - 1, "0 %s", aCommand); - } else { - snprintf((char*)netdCommand->mData, MAX_COMMAND_SIZE - 1, "%s", aCommand); - } - netdCommand->mSize = strlen((char*)netdCommand->mData) + 1; - - gCommandQueue.AppendElement(QueueData(netdCommand, aChain, aCallback)); - - nextNetdCommand(); -} - -/* - * Netd command function - */ -#define GET_CHAR(prop) NS_ConvertUTF16toUTF8(aChain->getParams().prop).get() -#define GET_FIELD(prop) aChain->getParams().prop - -void NetworkUtils::wifiFirmwareReload(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - snprintf(command, MAX_COMMAND_SIZE - 1, "softap fwreload %s %s", GET_CHAR(mIfname), GET_CHAR(mMode)); - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::startAccessPointDriver(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - // Skip the command for sdk version >= 16. - if (SDK_VERSION >= 16) { - aResult.mResultCode = 0; - aResult.mResultReason = NS_ConvertUTF8toUTF16(""); - aCallback(aChain, false, aResult); - return; - } - - char command[MAX_COMMAND_SIZE]; - snprintf(command, MAX_COMMAND_SIZE - 1, "softap start %s", GET_CHAR(mIfname)); - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::stopAccessPointDriver(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - // Skip the command for sdk version >= 16. - if (SDK_VERSION >= 16) { - aResult.mResultCode = 0; - aResult.mResultReason = NS_ConvertUTF8toUTF16(""); - aCallback(aChain, false, aResult); - return; - } - - char command[MAX_COMMAND_SIZE]; - snprintf(command, MAX_COMMAND_SIZE - 1, "softap stop %s", GET_CHAR(mIfname)); - - doCommand(command, aChain, aCallback); -} - -/** - * Command format for sdk version < 16 - * Arguments: - * argv[2] - wlan interface - * argv[3] - SSID - * argv[4] - Security - * argv[5] - Key - * argv[6] - Channel - * argv[7] - Preamble - * argv[8] - Max SCB - * - * Command format for sdk version >= 16 - * Arguments: - * argv[2] - wlan interface - * argv[3] - SSID - * argv[4] - Security - * argv[5] - Key - * - * Command format for sdk version >= 18 - * Arguments: - * argv[2] - wlan interface - * argv[3] - SSID - * argv[4] - Broadcast/Hidden - * argv[5] - Channel - * argv[6] - Security - * argv[7] - Key - */ -void NetworkUtils::setAccessPoint(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - nsCString ssid(GET_CHAR(mSsid)); - nsCString key(GET_CHAR(mKey)); - - escapeQuote(ssid); - escapeQuote(key); - - if (SDK_VERSION >= 19) { - snprintf(command, MAX_COMMAND_SIZE - 1, "softap set %s \"%s\" broadcast 6 %s \"%s\"", - GET_CHAR(mIfname), - ssid.get(), - GET_CHAR(mSecurity), - key.get()); - } else if (SDK_VERSION >= 16) { - snprintf(command, MAX_COMMAND_SIZE - 1, "softap set %s \"%s\" %s \"%s\"", - GET_CHAR(mIfname), - ssid.get(), - GET_CHAR(mSecurity), - key.get()); - } else { - snprintf(command, MAX_COMMAND_SIZE - 1, "softap set %s %s \"%s\" %s \"%s\" 6 0 8", - GET_CHAR(mIfname), - GET_CHAR(mWifictrlinterfacename), - ssid.get(), - GET_CHAR(mSecurity), - key.get()); - } - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::cleanUpStream(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - snprintf(command, MAX_COMMAND_SIZE - 1, "nat disable %s %s 0", GET_CHAR(mPreInternalIfname), GET_CHAR(mPreExternalIfname)); - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::createUpStream(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - snprintf(command, MAX_COMMAND_SIZE - 1, "nat enable %s %s 0", GET_CHAR(mCurInternalIfname), GET_CHAR(mCurExternalIfname)); - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::startSoftAP(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - const char* command= "softap startap"; - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::stopSoftAP(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - const char* command= "softap stopap"; - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::clearWifiTetherParms(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - delete gWifiTetheringParms; - gWifiTetheringParms = 0; - next(aChain, false, aResult); -} - -void NetworkUtils::enableAlarm(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - const char* command= "bandwidth enable"; - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::disableAlarm(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - const char* command= "bandwidth disable"; - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::setQuota(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - snprintf(command, MAX_COMMAND_SIZE - 1, "bandwidth setiquota %s % " PRId64, GET_CHAR(mIfname), INT64_MAX); - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::removeQuota(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - snprintf(command, MAX_COMMAND_SIZE - 1, "bandwidth removeiquota %s", GET_CHAR(mIfname)); - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::setAlarm(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - snprintf(command, MAX_COMMAND_SIZE - 1, "bandwidth setinterfacealert %s %lld", - GET_CHAR(mIfname), GET_FIELD(mThreshold)); - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::removeAlarm(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - snprintf(command, MAX_COMMAND_SIZE - 1, "bandwidth removeinterfacealert %s", GET_CHAR(mIfname)); - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::setGlobalAlarm(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - - snprintf(command, MAX_COMMAND_SIZE - 1, "bandwidth setglobalalert %lld", GET_FIELD(mThreshold)); - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::removeGlobalAlarm(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - - snprintf(command, MAX_COMMAND_SIZE - 1, "bandwidth removeglobalalert"); - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::tetherInterface(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - snprintf(command, MAX_COMMAND_SIZE - 1, "tether interface add %s", GET_CHAR(mIfname)); - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::addInterfaceToLocalNetwork(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - // Skip the command for sdk version < 20. - if (SDK_VERSION < 20) { - aResult.mResultCode = 0; - aResult.mResultReason = NS_ConvertUTF8toUTF16(""); - aCallback(aChain, false, aResult); - return; - } - - char command[MAX_COMMAND_SIZE]; - snprintf(command, MAX_COMMAND_SIZE - 1, "network interface add local %s", - GET_CHAR(mInternalIfname)); - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::addRouteToLocalNetwork(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - // Skip the command for sdk version < 20. - if (SDK_VERSION < 20) { - aResult.mResultCode = 0; - aResult.mResultReason = NS_ConvertUTF8toUTF16(""); - aCallback(aChain, false, aResult); - return; - } - - char command[MAX_COMMAND_SIZE]; - uint32_t prefix = atoi(GET_CHAR(mPrefix)); - uint32_t ip = inet_addr(GET_CHAR(mIp)); - char* networkAddr = getNetworkAddr(ip, prefix); - - snprintf(command, MAX_COMMAND_SIZE - 1, "network route add local %s %s/%s", - GET_CHAR(mInternalIfname), networkAddr, GET_CHAR(mPrefix)); - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::preTetherInterfaceList(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - if (SDK_VERSION >= 16) { - snprintf(command, MAX_COMMAND_SIZE - 1, "tether interface list"); - } else { - snprintf(command, MAX_COMMAND_SIZE - 1, "tether interface list 0"); - } - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::postTetherInterfaceList(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - // Send the dummy command to continue the function chain. - char command[MAX_COMMAND_SIZE]; - snprintf(command, MAX_COMMAND_SIZE - 1, "%s", DUMMY_COMMAND); - - char buf[BUF_SIZE]; - NS_ConvertUTF16toUTF8 reason(aResult.mResultReason); - - size_t length = reason.Length() + 1 < BUF_SIZE ? reason.Length() + 1 : BUF_SIZE; - memcpy(buf, reason.get(), length); - split(buf, INTERFACE_DELIMIT, GET_FIELD(mInterfaceList)); - - doCommand(command, aChain, aCallback); -} - -bool isCommandChainIPv6(CommandChain* aChain, const char *externalInterface) { - // Check by gateway address - if (getIpType(GET_CHAR(mGateway)) == AF_INET6) { - return true; - } - - uint32_t length = GET_FIELD(mGateways).Length(); - for (uint32_t i = 0; i < length; i++) { - NS_ConvertUTF16toUTF8 autoGateway(GET_FIELD(mGateways)[i]); - if(getIpType(autoGateway.get()) == AF_INET6) { - return true; - } - } - - // Check by external inteface address - FILE *file = fopen("/proc/net/if_inet6", "r"); - if (!file) { - return false; - } - - bool isIPv6 = false; - char interface[32]; - while(fscanf(file, "%*s %*s %*s %*s %*s %32s", interface)) { - if (strcmp(interface, externalInterface) == 0) { - isIPv6 = true; - break; - } - } - - fclose(file); - return isIPv6; -} - -void NetworkUtils::addUpstreamInterface(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - nsCString interface(GET_CHAR(mExternalIfname)); - if (!interface.get()[0]) { - interface = GET_CHAR(mCurExternalIfname); - } - - if (SUPPORT_IPV6_TETHERING == 0 || !isCommandChainIPv6(aChain, interface.get())) { - aCallback(aChain, false, aResult); - return; - } - - char command[MAX_COMMAND_SIZE]; - snprintf(command, MAX_COMMAND_SIZE - 1, "tether interface add_upstream %s", - interface.get()); - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::removeUpstreamInterface(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - nsCString interface(GET_CHAR(mExternalIfname)); - if (!interface.get()[0]) { - interface = GET_CHAR(mPreExternalIfname); - } - - if (SUPPORT_IPV6_TETHERING == 0 || !isCommandChainIPv6(aChain, interface.get())) { - aCallback(aChain, false, aResult); - return; - } - - char command[MAX_COMMAND_SIZE]; - snprintf(command, MAX_COMMAND_SIZE - 1, "tether interface remove_upstream %s", - interface.get()); - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::setIpForwardingEnabled(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - - if (GET_FIELD(mEnable)) { - snprintf(command, MAX_COMMAND_SIZE - 1, "ipfwd enable"); - } else { - // Don't disable ip forwarding because others interface still need it. - // Send the dummy command to continue the function chain. - if (GET_FIELD(mInterfaceList).Length() > 1) { - snprintf(command, MAX_COMMAND_SIZE - 1, "%s", DUMMY_COMMAND); - } else { - snprintf(command, MAX_COMMAND_SIZE - 1, "ipfwd disable"); - } - } - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::tetheringStatus(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - const char* command= "tether status"; - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::stopTethering(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - - // Don't stop tethering because others interface still need it. - // Send the dummy to continue the function chain. - if (GET_FIELD(mInterfaceList).Length() > 1) { - snprintf(command, MAX_COMMAND_SIZE - 1, "%s", DUMMY_COMMAND); - } else { - snprintf(command, MAX_COMMAND_SIZE - 1, "tether stop"); - } - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::startTethering(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - - // We don't need to start tethering again. - // Send the dummy command to continue the function chain. - if (aResult.mResultReason.Find("started") != kNotFound) { - snprintf(command, MAX_COMMAND_SIZE - 1, "%s", DUMMY_COMMAND); - } else { - // If usbStartIp/usbEndIp is not valid, don't append them since - // the trailing white spaces will be parsed to extra empty args - // See: http://androidxref.com/4.3_r2.1/xref/system/core/libsysutils/src/FrameworkListener.cpp#78 - if (!GET_FIELD(mUsbStartIp).IsEmpty() && !GET_FIELD(mUsbEndIp).IsEmpty()) { - snprintf(command, MAX_COMMAND_SIZE - 1, "tether start %s %s %s %s", - GET_CHAR(mWifiStartIp), GET_CHAR(mWifiEndIp), - GET_CHAR(mUsbStartIp), GET_CHAR(mUsbEndIp)); - } else { - snprintf(command, MAX_COMMAND_SIZE - 1, "tether start %s %s", - GET_CHAR(mWifiStartIp), GET_CHAR(mWifiEndIp)); - } - } - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::untetherInterface(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - snprintf(command, MAX_COMMAND_SIZE - 1, "tether interface remove %s", GET_CHAR(mIfname)); - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::removeInterfaceFromLocalNetwork(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - // Skip the command for sdk version < 20. - if (SDK_VERSION < 20) { - aResult.mResultCode = 0; - aResult.mResultReason = NS_ConvertUTF8toUTF16(""); - aCallback(aChain, false, aResult); - return; - } - - char command[MAX_COMMAND_SIZE]; - snprintf(command, MAX_COMMAND_SIZE - 1, "network interface remove local %s", - GET_CHAR(mIfname)); - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::setDnsForwarders(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - - if (SDK_VERSION >= 20) { - snprintf(command, MAX_COMMAND_SIZE - 1, "tether dns set %d %s %s", - GET_FIELD(mNetId), GET_CHAR(mDns1), GET_CHAR(mDns2)); - } else { - snprintf(command, MAX_COMMAND_SIZE - 1, "tether dns set %s %s", - GET_CHAR(mDns1), GET_CHAR(mDns2)); - } - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::enableNat(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - - if (!GET_FIELD(mIp).IsEmpty() && !GET_FIELD(mPrefix).IsEmpty()) { - uint32_t prefix = atoi(GET_CHAR(mPrefix)); - uint32_t ip = inet_addr(GET_CHAR(mIp)); - char* networkAddr = getNetworkAddr(ip, prefix); - - // address/prefix will only take effect when secondary routing table exists. - snprintf(command, MAX_COMMAND_SIZE - 1, "nat enable %s %s 1 %s/%s", - GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname), networkAddr, - GET_CHAR(mPrefix)); - } else { - snprintf(command, MAX_COMMAND_SIZE - 1, "nat enable %s %s 0", - GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname)); - } - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::disableNat(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - - if (!GET_FIELD(mIp).IsEmpty() && !GET_FIELD(mPrefix).IsEmpty()) { - uint32_t prefix = atoi(GET_CHAR(mPrefix)); - uint32_t ip = inet_addr(GET_CHAR(mIp)); - char* networkAddr = getNetworkAddr(ip, prefix); - - snprintf(command, MAX_COMMAND_SIZE - 1, "nat disable %s %s 1 %s/%s", - GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname), networkAddr, - GET_CHAR(mPrefix)); - } else { - snprintf(command, MAX_COMMAND_SIZE - 1, "nat disable %s %s 0", - GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname)); - } - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::setDefaultInterface(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - snprintf(command, MAX_COMMAND_SIZE - 1, "resolver setdefaultif %s", GET_CHAR(mIfname)); - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::removeDefaultRoute(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - if (GET_FIELD(mLoopIndex) >= GET_FIELD(mGateways).Length()) { - aCallback(aChain, false, aResult); - return; - } - - char command[MAX_COMMAND_SIZE]; - nsTArray<nsString>& gateways = GET_FIELD(mGateways); - NS_ConvertUTF16toUTF8 autoGateway(gateways[GET_FIELD(mLoopIndex)]); - - int type = getIpType(autoGateway.get()); - snprintf(command, MAX_COMMAND_SIZE - 1, "network route remove %d %s %s/0 %s", - GET_FIELD(mNetId), GET_CHAR(mIfname), - type == AF_INET6 ? "::" : "0.0.0.0", autoGateway.get()); - - struct MyCallback { - static void callback(CommandCallback::CallbackType aOriginalCallback, - CommandChain* aChain, - bool aError, - mozilla::dom::NetworkResultOptions& aResult) - { - NS_ConvertUTF16toUTF8 reason(aResult.mResultReason); - NU_DBG("removeDefaultRoute's reason: %s", reason.get()); - if (aError && !reason.EqualsASCII("removeRoute() failed (No such process)")) { - return aOriginalCallback(aChain, aError, aResult); - } - - GET_FIELD(mLoopIndex)++; - return removeDefaultRoute(aChain, aOriginalCallback, aResult); - } - }; - - CommandCallback wrappedCallback(MyCallback::callback, aCallback); - doCommand(command, aChain, wrappedCallback); -} - -void NetworkUtils::setInterfaceDns(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - int written; - - if (SDK_VERSION >= 20) { - written = SprintfLiteral(command, "resolver setnetdns %d %s", - GET_FIELD(mNetId), GET_CHAR(mDomain)); - } else { - written = SprintfLiteral(command, "resolver setifdns %s %s", - GET_CHAR(mIfname), GET_CHAR(mDomain)); - } - - nsTArray<nsString>& dnses = GET_FIELD(mDnses); - uint32_t length = dnses.Length(); - - for (uint32_t i = 0; i < length; i++) { - NS_ConvertUTF16toUTF8 autoDns(dnses[i]); - - int ret = snprintf(command + written, sizeof(command) - written, " %s", autoDns.get()); - if (ret <= 1) { - command[written] = '\0'; - continue; - } - - if (((size_t)ret + written) >= sizeof(command)) { - command[written] = '\0'; - break; - } - - written += ret; - } - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::getInterfaceList(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - snprintf(command, MAX_COMMAND_SIZE - 1, "interface list"); - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::getConfig(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - snprintf(command, MAX_COMMAND_SIZE - 1, "interface getcfg %s", GET_CHAR(mIfname)); - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::setConfig(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - if (SDK_VERSION >= 16) { - snprintf(command, MAX_COMMAND_SIZE - 1, "interface setcfg %s %s %s %s", - GET_CHAR(mIfname), - GET_CHAR(mIp), - GET_CHAR(mPrefix), - GET_CHAR(mLink)); - } else { - snprintf(command, MAX_COMMAND_SIZE - 1, "interface setcfg %s %s %s [%s]", - GET_CHAR(mIfname), - GET_CHAR(mIp), - GET_CHAR(mPrefix), - GET_CHAR(mLink)); - } - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::clearAddrForInterface(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - snprintf(command, MAX_COMMAND_SIZE - 1, "interface clearaddrs %s", GET_CHAR(mIfname)); - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::createNetwork(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - snprintf(command, MAX_COMMAND_SIZE - 1, "network create %d", GET_FIELD(mNetId)); - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::destroyNetwork(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - snprintf(command, MAX_COMMAND_SIZE - 1, "network destroy %d", GET_FIELD(mNetId)); - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::addInterfaceToNetwork(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - snprintf(command, MAX_COMMAND_SIZE - 1, "network interface add %d %s", - GET_FIELD(mNetId), GET_CHAR(mIfname)); - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::addRouteToInterface(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - struct MyCallback { - static void callback(CommandCallback::CallbackType aOriginalCallback, - CommandChain* aChain, - bool aError, - mozilla::dom::NetworkResultOptions& aResult) - { - NS_ConvertUTF16toUTF8 reason(aResult.mResultReason); - NU_DBG("addRouteToInterface's reason: %s", reason.get()); - if (aError && reason.EqualsASCII("addRoute() failed (File exists)")) { - NU_DBG("Ignore \"File exists\" error when adding host route."); - return aOriginalCallback(aChain, false, aResult); - } - aOriginalCallback(aChain, aError, aResult); - } - }; - - CommandCallback wrappedCallback(MyCallback::callback, aCallback); - modifyRouteOnInterface(aChain, wrappedCallback, aResult, true); -} - -void NetworkUtils::removeRouteFromInterface(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - modifyRouteOnInterface(aChain, aCallback, aResult, false); -} - -void NetworkUtils::modifyRouteOnInterface(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult, - bool aDoAdd) -{ - char command[MAX_COMMAND_SIZE]; - - // AOSP adds host route to its interface table but it doesn't work for - // B2G because we cannot set fwmark per application. So, we add - // all host routes to legacy_system table except scope link route. - - nsCString ipOrSubnetIp = NS_ConvertUTF16toUTF8(GET_FIELD(mIp)); - nsCString gatewayOrEmpty; - const char* legacyOrEmpty = "legacy 0 "; // Add to legacy by default. - if (GET_FIELD(mGateway).IsEmpty()) { - ipOrSubnetIp = getSubnetIp(ipOrSubnetIp, GET_FIELD(mPrefixLength)); - legacyOrEmpty = ""; // Add to interface table for scope link route. - } else { - gatewayOrEmpty = nsCString(" ") + NS_ConvertUTF16toUTF8(GET_FIELD(mGateway)); - } - - const char* action = aDoAdd ? "add" : "remove"; - - snprintf(command, MAX_COMMAND_SIZE - 1, "network route %s%s %d %s %s/%d%s", - legacyOrEmpty, action, - GET_FIELD(mNetId), GET_CHAR(mIfname), ipOrSubnetIp.get(), - GET_FIELD(mPrefixLength), gatewayOrEmpty.get()); - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::addDefaultRouteToNetwork(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - if (GET_FIELD(mLoopIndex) >= GET_FIELD(mGateways).Length()) { - aCallback(aChain, false, aResult); - return; - } - - char command[MAX_COMMAND_SIZE]; - nsTArray<nsString>& gateways = GET_FIELD(mGateways); - NS_ConvertUTF16toUTF8 autoGateway(gateways[GET_FIELD(mLoopIndex)]); - - int type = getIpType(autoGateway.get()); - snprintf(command, MAX_COMMAND_SIZE - 1, "network route add %d %s %s/0 %s", - GET_FIELD(mNetId), GET_CHAR(mIfname), - type == AF_INET6 ? "::" : "0.0.0.0", autoGateway.get()); - - struct MyCallback { - static void callback(CommandCallback::CallbackType aOriginalCallback, - CommandChain* aChain, - bool aError, - mozilla::dom::NetworkResultOptions& aResult) - { - NS_ConvertUTF16toUTF8 reason(aResult.mResultReason); - NU_DBG("addDefaultRouteToNetwork's reason: %s", reason.get()); - if (aError && !reason.EqualsASCII("addRoute() failed (File exists)")) { - return aOriginalCallback(aChain, aError, aResult); - } - - GET_FIELD(mLoopIndex)++; - return addDefaultRouteToNetwork(aChain, aOriginalCallback, aResult); - } - }; - - CommandCallback wrappedCallback(MyCallback::callback, aCallback); - doCommand(command, aChain, wrappedCallback); -} - -void NetworkUtils::setDefaultNetwork(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - snprintf(command, MAX_COMMAND_SIZE - 1, "network default set %d", GET_FIELD(mNetId)); - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::addRouteToSecondaryTable(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) { - - char command[MAX_COMMAND_SIZE]; - - if (SDK_VERSION >= 20) { - snprintf(command, MAX_COMMAND_SIZE - 1, - "network route add %d %s %s/%s %s", - GET_FIELD(mNetId), - GET_CHAR(mIfname), - GET_CHAR(mIp), - GET_CHAR(mPrefix), - GET_CHAR(mGateway)); - } else { - snprintf(command, MAX_COMMAND_SIZE - 1, - "interface route add %s secondary %s %s %s", - GET_CHAR(mIfname), - GET_CHAR(mIp), - GET_CHAR(mPrefix), - GET_CHAR(mGateway)); - } - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::removeRouteFromSecondaryTable(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) { - char command[MAX_COMMAND_SIZE]; - - if (SDK_VERSION >= 20) { - snprintf(command, MAX_COMMAND_SIZE - 1, - "network route remove %d %s %s/%s %s", - GET_FIELD(mNetId), - GET_CHAR(mIfname), - GET_CHAR(mIp), - GET_CHAR(mPrefix), - GET_CHAR(mGateway)); - } else { - snprintf(command, MAX_COMMAND_SIZE - 1, - "interface route remove %s secondary %s %s %s", - GET_CHAR(mIfname), - GET_CHAR(mIp), - GET_CHAR(mPrefix), - GET_CHAR(mGateway)); - } - - doCommand(command, aChain, aCallback); -} - -void NetworkUtils::setIpv6Enabled(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult, - bool aEnabled) -{ - char command[MAX_COMMAND_SIZE]; - snprintf(command, MAX_COMMAND_SIZE - 1, "interface ipv6 %s %s", - GET_CHAR(mIfname), aEnabled ? "enable" : "disable"); - - struct MyCallback { - static void callback(CommandCallback::CallbackType aOriginalCallback, - CommandChain* aChain, - bool aError, - mozilla::dom::NetworkResultOptions& aResult) - { - aOriginalCallback(aChain, false, aResult); - } - }; - - CommandCallback wrappedCallback(MyCallback::callback, aCallback); - doCommand(command, aChain, wrappedCallback); -} - -void NetworkUtils::enableIpv6(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - setIpv6Enabled(aChain, aCallback, aResult, true); -} - -void NetworkUtils::disableIpv6(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - setIpv6Enabled(aChain, aCallback, aResult, false); -} - -void NetworkUtils::setMtu(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char command[MAX_COMMAND_SIZE]; - snprintf(command, MAX_COMMAND_SIZE - 1, "interface setmtu %s %ld", - GET_CHAR(mIfname), GET_FIELD(mMtu)); - - doCommand(command, aChain, aCallback); -} - -#undef GET_CHAR -#undef GET_FIELD - -/* - * Netd command success/fail function - */ -#define ASSIGN_FIELD(prop) aResult.prop = aChain->getParams().prop; -#define ASSIGN_FIELD_VALUE(prop, value) aResult.prop = value; - -template<size_t N> -void NetworkUtils::runChain(const NetworkParams& aParams, - const CommandFunc (&aCmds)[N], - ErrorCallback aError) -{ - CommandChain* chain = new CommandChain(aParams, aCmds, N, aError); - gCommandChainQueue.AppendElement(chain); - - if (gCommandChainQueue.Length() > 1) { - NU_DBG("%d command chains are queued. Wait!", gCommandChainQueue.Length()); - return; - } - - NetworkResultOptions result; - NetworkUtils::next(gCommandChainQueue[0], false, result); -} - -// Called to clean up the command chain and process the queued command chain if any. -void NetworkUtils::finalizeSuccess(CommandChain* aChain, - NetworkResultOptions& aResult) -{ - next(aChain, false, aResult); -} - -void NetworkUtils::wifiTetheringFail(NetworkParams& aOptions, NetworkResultOptions& aResult) -{ - // Notify the main thread. - postMessage(aOptions, aResult); - - // If one of the stages fails, we try roll back to ensure - // we don't leave the network systems in limbo. - ASSIGN_FIELD_VALUE(mEnable, false) - runChain(aOptions, sWifiFailChain, nullptr); -} - -void NetworkUtils::wifiTetheringSuccess(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - ASSIGN_FIELD(mEnable) - - if (aChain->getParams().mEnable) { - MOZ_ASSERT(!gWifiTetheringParms); - gWifiTetheringParms = new NetworkParams(aChain->getParams()); - } - postMessage(aChain->getParams(), aResult); - finalizeSuccess(aChain, aResult); -} - -void NetworkUtils::usbTetheringFail(NetworkParams& aOptions, - NetworkResultOptions& aResult) -{ - // Notify the main thread. - postMessage(aOptions, aResult); - // Try to roll back to ensure - // we don't leave the network systems in limbo. - // This parameter is used to disable ipforwarding. - { - aOptions.mEnable = false; - runChain(aOptions, sUSBFailChain, nullptr); - } - - // Disable usb rndis function. - { - NetworkParams options; - options.mEnable = false; - options.mReport = false; - gNetworkUtils->enableUsbRndis(options); - } -} - -void NetworkUtils::usbTetheringSuccess(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - ASSIGN_FIELD(mEnable) - postMessage(aChain->getParams(), aResult); - finalizeSuccess(aChain, aResult); -} - -void NetworkUtils::networkInterfaceAlarmFail(NetworkParams& aOptions, NetworkResultOptions& aResult) -{ - postMessage(aOptions, aResult); -} - -void NetworkUtils::networkInterfaceAlarmSuccess(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - // TODO : error is not used , and it is conflict with boolean type error. - // params.error = parseFloat(params.resultReason); - postMessage(aChain->getParams(), aResult); - finalizeSuccess(aChain, aResult); -} - -void NetworkUtils::updateUpStreamFail(NetworkParams& aOptions, NetworkResultOptions& aResult) -{ - postMessage(aOptions, aResult); -} - -void NetworkUtils::updateUpStreamSuccess(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - ASSIGN_FIELD(mCurExternalIfname) - ASSIGN_FIELD(mCurInternalIfname) - postMessage(aChain->getParams(), aResult); - finalizeSuccess(aChain, aResult); -} - -void NetworkUtils::setDhcpServerFail(NetworkParams& aOptions, NetworkResultOptions& aResult) -{ - aResult.mSuccess = false; - postMessage(aOptions, aResult); -} - -void NetworkUtils::setDhcpServerSuccess(CommandChain* aChain, CommandCallback aCallback, NetworkResultOptions& aResult) -{ - aResult.mSuccess = true; - postMessage(aChain->getParams(), aResult); - finalizeSuccess(aChain, aResult); -} - -void NetworkUtils::wifiOperationModeFail(NetworkParams& aOptions, NetworkResultOptions& aResult) -{ - postMessage(aOptions, aResult); -} - -void NetworkUtils::wifiOperationModeSuccess(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - postMessage(aChain->getParams(), aResult); - finalizeSuccess(aChain, aResult); -} - -void NetworkUtils::setDnsFail(NetworkParams& aOptions, NetworkResultOptions& aResult) -{ - postMessage(aOptions, aResult); -} - -void NetworkUtils::defaultAsyncSuccessHandler(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - NU_DBG("defaultAsyncSuccessHandler"); - aResult.mRet = true; - postMessage(aChain->getParams(), aResult); - finalizeSuccess(aChain, aResult); -} - -void NetworkUtils::defaultAsyncFailureHandler(NetworkParams& aOptions, NetworkResultOptions& aResult) -{ - aResult.mRet = false; - postMessage(aOptions, aResult); -} - -void NetworkUtils::getInterfacesFail(NetworkParams& aOptions, NetworkResultOptions& aResult) -{ - postMessage(aOptions, aResult); -} - -void NetworkUtils::getInterfacesSuccess(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char buf[BUF_SIZE]; - NS_ConvertUTF16toUTF8 reason(aResult.mResultReason); - memcpy(buf, reason.get(), strlen(reason.get())); - - nsTArray<nsCString> result; - split(buf, INTERFACE_DELIMIT, result); - - nsTArray<nsString> interfaceList; - uint32_t length = result.Length(); - convertUTF8toUTF16(result, interfaceList, length); - - aResult.mInterfaceList.Construct(); - for (uint32_t i = 0; i < length; i++) { - aResult.mInterfaceList.Value().AppendElement(interfaceList[i], fallible_t()); - } - - postMessage(aChain->getParams(), aResult); - finalizeSuccess(aChain, aResult); -} - -void NetworkUtils::getInterfaceConfigFail(NetworkParams& aOptions, - NetworkResultOptions& aResult) -{ - postMessage(aOptions, aResult); -} - -void NetworkUtils::getInterfaceConfigSuccess(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - char buf[BUF_SIZE]; - NS_ConvertUTF16toUTF8 reason(aResult.mResultReason); - memcpy(buf, reason.get(), strlen(reason.get())); - - nsTArray<nsCString> result; - split(buf, NETD_MESSAGE_DELIMIT, result); - - ASSIGN_FIELD_VALUE(mMacAddr, NS_ConvertUTF8toUTF16(result[0])) - ASSIGN_FIELD_VALUE(mIpAddr, NS_ConvertUTF8toUTF16(result[1])) - ASSIGN_FIELD_VALUE(mPrefixLength, atol(result[2].get())) - - if (result[3].Find("up")) { - ASSIGN_FIELD_VALUE(mFlag, NS_ConvertUTF8toUTF16("up")) - } else { - ASSIGN_FIELD_VALUE(mFlag, NS_ConvertUTF8toUTF16("down")) - } - - postMessage(aChain->getParams(), aResult); - finalizeSuccess(aChain, aResult); -} - -void NetworkUtils::setInterfaceConfigFail(NetworkParams& aOptions, - NetworkResultOptions& aResult) -{ - postMessage(aOptions, aResult); -} - -void NetworkUtils::setInterfaceConfigSuccess(CommandChain* aChain, - CommandCallback aCallback, - NetworkResultOptions& aResult) -{ - postMessage(aChain->getParams(), aResult); - finalizeSuccess(aChain, aResult); -} - -#undef ASSIGN_FIELD -#undef ASSIGN_FIELD_VALUE - -NetworkUtils::NetworkUtils(MessageCallback aCallback) - : mMessageCallback(aCallback) -{ - mNetUtils = new NetUtils(); - - char value[Property::VALUE_MAX_LENGTH]; - Property::Get("ro.build.version.sdk", value, nullptr); - SDK_VERSION = atoi(value); - - Property::Get(IPV6_TETHERING, value, "0"); - SUPPORT_IPV6_TETHERING = atoi(value); - - gNetworkUtils = this; -} - -NetworkUtils::~NetworkUtils() -{ -} - -#define GET_CHAR(prop) NS_ConvertUTF16toUTF8(aOptions.prop).get() -#define GET_FIELD(prop) aOptions.prop - -// Hoist this type definition to global to avoid template -// instantiation error on gcc 4.4 used by ICS emulator. -typedef CommandResult (NetworkUtils::*CommandHandler)(NetworkParams&); -struct CommandHandlerEntry -{ - const char* mCommandName; - CommandHandler mCommandHandler; -}; - -void NetworkUtils::ExecuteCommand(NetworkParams aOptions) -{ - const static CommandHandlerEntry - COMMAND_HANDLER_TABLE[] = { - - // For command 'testCommand', BUILD_ENTRY(testCommand) will generate - // {"testCommand", NetworkUtils::testCommand} - #define BUILD_ENTRY(c) {#c, &NetworkUtils::c} - - BUILD_ENTRY(removeNetworkRoute), - BUILD_ENTRY(setDNS), - BUILD_ENTRY(setDefaultRoute), - BUILD_ENTRY(removeDefaultRoute), - BUILD_ENTRY(addHostRoute), - BUILD_ENTRY(removeHostRoute), - BUILD_ENTRY(addSecondaryRoute), - BUILD_ENTRY(removeSecondaryRoute), - BUILD_ENTRY(setNetworkInterfaceAlarm), - BUILD_ENTRY(enableNetworkInterfaceAlarm), - BUILD_ENTRY(disableNetworkInterfaceAlarm), - BUILD_ENTRY(setTetheringAlarm), - BUILD_ENTRY(removeTetheringAlarm), - BUILD_ENTRY(getTetheringStatus), - BUILD_ENTRY(setWifiOperationMode), - BUILD_ENTRY(setDhcpServer), - BUILD_ENTRY(setWifiTethering), - BUILD_ENTRY(setUSBTethering), - BUILD_ENTRY(enableUsbRndis), - BUILD_ENTRY(updateUpStream), - BUILD_ENTRY(configureInterface), - BUILD_ENTRY(dhcpRequest), - BUILD_ENTRY(stopDhcp), - BUILD_ENTRY(enableInterface), - BUILD_ENTRY(disableInterface), - BUILD_ENTRY(resetConnections), - BUILD_ENTRY(createNetwork), - BUILD_ENTRY(destroyNetwork), - BUILD_ENTRY(getNetId), - BUILD_ENTRY(getInterfaces), - BUILD_ENTRY(getInterfaceConfig), - BUILD_ENTRY(setInterfaceConfig), - BUILD_ENTRY(setMtu), - - #undef BUILD_ENTRY - }; - - // Loop until we find the command name which matches aOptions.mCmd. - CommandHandler handler = nullptr; - for (size_t i = 0; i < mozilla::ArrayLength(COMMAND_HANDLER_TABLE); i++) { - if (aOptions.mCmd.EqualsASCII(COMMAND_HANDLER_TABLE[i].mCommandName)) { - handler = COMMAND_HANDLER_TABLE[i].mCommandHandler; - break; - } - } - - if (!handler) { - // Command not found in COMMAND_HANDLER_TABLE. - WARN("unknown message: %s", NS_ConvertUTF16toUTF8(aOptions.mCmd).get()); - return; - } - - // The handler would return one of the following 3 values - // to be wrapped to CommandResult: - // - // 1) |int32_t| for mostly synchronous native function calls. - // 2) |NetworkResultOptions| to populate additional results. (e.g. dhcpRequest) - // 3) |CommandResult::Pending| to indicate the result is not - // obtained yet. - // - // If the handler returns "Pending", the handler should take the - // responsibility for posting result to main thread. - CommandResult commandResult = (this->*handler)(aOptions); - if (!commandResult.isPending()) { - postMessage(aOptions, commandResult.mResult); - } -} - -/** - * Handle received data from netd. - */ -void NetworkUtils::onNetdMessage(NetdCommand* aCommand) -{ - char* data = (char*)aCommand->mData; - - // get code & reason. - char* result = strtok(data, NETD_MESSAGE_DELIMIT); - - if (!result) { - nextNetdCommand(); - return; - } - uint32_t code = atoi(result); - - if (!isBroadcastMessage(code) && SDK_VERSION >= 16) { - strtok(nullptr, NETD_MESSAGE_DELIMIT); - } - - char* reason = strtok(nullptr, "\0"); - - if (isBroadcastMessage(code)) { - NU_DBG("Receiving broadcast message from netd."); - NU_DBG(" ==> Code: %d Reason: %s", code, reason); - sendBroadcastMessage(code, reason); - - if (code == NETD_COMMAND_INTERFACE_CHANGE) { - if (gWifiTetheringParms) { - char linkdownReason[MAX_COMMAND_SIZE]; - snprintf(linkdownReason, MAX_COMMAND_SIZE - 1, - "Iface linkstate %s down", - NS_ConvertUTF16toUTF8(gWifiTetheringParms->mIfname).get()); - - if (!strcmp(reason, linkdownReason)) { - NU_DBG("Wifi link down, restarting tethering."); - runChain(*gWifiTetheringParms, sWifiRetryChain, wifiTetheringFail); - } - } - } - - nextNetdCommand(); - return; - } - - // Set pending to false before we handle next command. - NU_DBG("Receiving \"%s\" command response from netd.", gCurrentCommand.command); - NU_DBG(" ==> Code: %d Reason: %s", code, reason); - - gReason.AppendElement(nsCString(reason)); - - // 1xx response code regards as command is proceeding, we need to wait for - // final response code such as 2xx, 4xx and 5xx before sending next command. - if (isProceeding(code)) { - return; - } - - if (isComplete(code)) { - gPending = false; - } - - { - char buf[BUF_SIZE]; - join(gReason, INTERFACE_DELIMIT, BUF_SIZE, buf); - - NetworkResultOptions result; - result.mResultCode = code; - result.mResultReason = NS_ConvertUTF8toUTF16(buf); - (gCurrentCommand.callback)(gCurrentCommand.chain, isError(code), result); - gReason.Clear(); - } - - // Handling pending commands if any. - if (isComplete(code)) { - nextNetdCommand(); - } -} - -/** - * Start/Stop DHCP server. - */ -CommandResult NetworkUtils::setDhcpServer(NetworkParams& aOptions) -{ - if (aOptions.mEnabled) { - aOptions.mWifiStartIp = aOptions.mStartIp; - aOptions.mWifiEndIp = aOptions.mEndIp; - aOptions.mIp = aOptions.mServerIp; - aOptions.mPrefix = aOptions.mMaskLength; - aOptions.mLink = NS_ConvertUTF8toUTF16("up"); - - runChain(aOptions, sStartDhcpServerChain, setDhcpServerFail); - } else { - runChain(aOptions, sStopDhcpServerChain, setDhcpServerFail); - } - return CommandResult::Pending(); -} - -/** - * Set DNS servers for given network interface. - */ -CommandResult NetworkUtils::setDNS(NetworkParams& aOptions) -{ - uint32_t length = aOptions.mDnses.Length(); - - if (length > 0) { - for (uint32_t i = 0; i < length; i++) { - NS_ConvertUTF16toUTF8 autoDns(aOptions.mDnses[i]); - - char dns_prop_key[Property::VALUE_MAX_LENGTH]; - SprintfLiteral(dns_prop_key, "net.dns%d", i+1); - Property::Set(dns_prop_key, autoDns.get()); - } - } else { - // Set dnses from system properties. - IFProperties interfaceProperties; - getIFProperties(GET_CHAR(mIfname), interfaceProperties); - - Property::Set("net.dns1", interfaceProperties.dns1); - Property::Set("net.dns2", interfaceProperties.dns2); - } - - // Bump the DNS change property. - char dnschange[Property::VALUE_MAX_LENGTH]; - Property::Get("net.dnschange", dnschange, "0"); - - char num[Property::VALUE_MAX_LENGTH]; - snprintf(num, Property::VALUE_MAX_LENGTH - 1, "%d", atoi(dnschange) + 1); - Property::Set("net.dnschange", num); - - // DNS needs to be set through netd since JellyBean (4.3). - if (SDK_VERSION >= 20) { - // Lollipop. - static CommandFunc COMMAND_CHAIN[] = { - setInterfaceDns, - addDefaultRouteToNetwork, - defaultAsyncSuccessHandler - }; - NetIdManager::NetIdInfo netIdInfo; - if (!mNetIdManager.lookup(aOptions.mIfname, &netIdInfo)) { - return -1; - } - aOptions.mNetId = netIdInfo.mNetId; - runChain(aOptions, COMMAND_CHAIN, setDnsFail); - return CommandResult::Pending(); - } - if (SDK_VERSION >= 18) { - // JB, KK. - static CommandFunc COMMAND_CHAIN[] = { - #if ANDROID_VERSION == 18 - // Since we don't use per-interface DNS lookup feature on JB, - // we need to set the default DNS interface whenever setting the - // DNS name server. - setDefaultInterface, - #endif - setInterfaceDns, - defaultAsyncSuccessHandler - }; - runChain(aOptions, COMMAND_CHAIN, setDnsFail); - return CommandResult::Pending(); - } - - return SUCCESS; -} - -CommandResult NetworkUtils::configureInterface(NetworkParams& aOptions) -{ - NS_ConvertUTF16toUTF8 autoIfname(aOptions.mIfname); - return mNetUtils->do_ifc_configure( - autoIfname.get(), - aOptions.mIpaddr, - aOptions.mMask, - aOptions.mGateway_long, - aOptions.mDns1_long, - aOptions.mDns2_long - ); -} - -CommandResult NetworkUtils::stopDhcp(NetworkParams& aOptions) -{ - return mNetUtils->do_dhcp_stop(GET_CHAR(mIfname)); -} - -CommandResult NetworkUtils::dhcpRequest(NetworkParams& aOptions) { - mozilla::dom::NetworkResultOptions result; - - NS_ConvertUTF16toUTF8 autoIfname(aOptions.mIfname); - char ipaddr[Property::VALUE_MAX_LENGTH]; - char gateway[Property::VALUE_MAX_LENGTH]; - uint32_t prefixLength; - char dns1[Property::VALUE_MAX_LENGTH]; - char dns2[Property::VALUE_MAX_LENGTH]; - char server[Property::VALUE_MAX_LENGTH]; - uint32_t lease; - char vendorinfo[Property::VALUE_MAX_LENGTH]; - int32_t ret = mNetUtils->do_dhcp_do_request(autoIfname.get(), - ipaddr, - gateway, - &prefixLength, - dns1, - dns2, - server, - &lease, - vendorinfo); - - RETURN_IF_FAILED(ret); - - result.mIpaddr_str = NS_ConvertUTF8toUTF16(ipaddr); - result.mGateway_str = NS_ConvertUTF8toUTF16(gateway); - result.mDns1_str = NS_ConvertUTF8toUTF16(dns1); - result.mDns2_str = NS_ConvertUTF8toUTF16(dns2); - result.mServer_str = NS_ConvertUTF8toUTF16(server); - result.mVendor_str = NS_ConvertUTF8toUTF16(vendorinfo); - result.mLease = lease; - result.mPrefixLength = prefixLength; - result.mMask = makeMask(prefixLength); - - uint32_t inet4; // only support IPv4 for now. - -#define INET_PTON(var, field) \ - PR_BEGIN_MACRO \ - inet_pton(AF_INET, var, &inet4); \ - result.field = inet4; \ - PR_END_MACRO - - INET_PTON(ipaddr, mIpaddr); - INET_PTON(gateway, mGateway); - - if (dns1[0] != '\0') { - INET_PTON(dns1, mDns1); - } - - if (dns2[0] != '\0') { - INET_PTON(dns2, mDns2); - } - - INET_PTON(server, mServer); - - char inet_str[64]; - if (inet_ntop(AF_INET, &result.mMask, inet_str, sizeof(inet_str))) { - result.mMask_str = NS_ConvertUTF8toUTF16(inet_str); - } - - return result; -} - -CommandResult NetworkUtils::enableInterface(NetworkParams& aOptions) { - return mNetUtils->do_ifc_enable( - NS_ConvertUTF16toUTF8(aOptions.mIfname).get()); -} - -CommandResult NetworkUtils::disableInterface(NetworkParams& aOptions) { - return mNetUtils->do_ifc_disable( - NS_ConvertUTF16toUTF8(aOptions.mIfname).get()); -} - -CommandResult NetworkUtils::resetConnections(NetworkParams& aOptions) { - NS_ConvertUTF16toUTF8 autoIfname(aOptions.mIfname); - return mNetUtils->do_ifc_reset_connections( - NS_ConvertUTF16toUTF8(aOptions.mIfname).get(), - RESET_ALL_ADDRESSES); -} - -/** - * Set default route and DNS servers for given network interface. - */ -CommandResult NetworkUtils::setDefaultRoute(NetworkParams& aOptions) -{ - if (SDK_VERSION < 20) { - return setDefaultRouteLegacy(aOptions); - } - - static CommandFunc COMMAND_CHAIN[] = { - addDefaultRouteToNetwork, - setDefaultNetwork, - defaultAsyncSuccessHandler, - }; - - NetIdManager::NetIdInfo netIdInfo; - if (!mNetIdManager.lookup(GET_FIELD(mIfname), &netIdInfo)) { - ERROR("No such interface"); - return -1; - } - - aOptions.mNetId = netIdInfo.mNetId; - aOptions.mLoopIndex = 0; - runChain(aOptions, COMMAND_CHAIN, defaultAsyncFailureHandler); - - return CommandResult::Pending(); -} - -/** - * Set default route and DNS servers for given network interface by obsoleted libnetutils. - */ -CommandResult NetworkUtils::setDefaultRouteLegacy(NetworkParams& aOptions) -{ - NS_ConvertUTF16toUTF8 autoIfname(aOptions.mIfname); - - uint32_t length = aOptions.mGateways.Length(); - if (length > 0) { - for (uint32_t i = 0; i < length; i++) { - NS_ConvertUTF16toUTF8 autoGateway(aOptions.mGateways[i]); - - int type = getIpType(autoGateway.get()); - if (type != AF_INET && type != AF_INET6) { - continue; - } - - if (type == AF_INET6) { - RETURN_IF_FAILED(mNetUtils->do_ifc_add_route(autoIfname.get(), "::", 0, autoGateway.get())); - } else { /* type == AF_INET */ - RETURN_IF_FAILED(mNetUtils->do_ifc_set_default_route(autoIfname.get(), inet_addr(autoGateway.get()))); - } - } - } else { - // Set default froute from system properties. - char key[Property::KEY_MAX_LENGTH]; - char gateway[Property::KEY_MAX_LENGTH]; - - snprintf(key, sizeof key - 1, "net.%s.gw", autoIfname.get()); - Property::Get(key, gateway, ""); - - int type = getIpType(gateway); - if (type != AF_INET && type != AF_INET6) { - return EAFNOSUPPORT; - } - - if (type == AF_INET6) { - RETURN_IF_FAILED(mNetUtils->do_ifc_add_route(autoIfname.get(), "::", 0, gateway)); - } else { /* type == AF_INET */ - RETURN_IF_FAILED(mNetUtils->do_ifc_set_default_route(autoIfname.get(), inet_addr(gateway))); - } - } - - // Set the default DNS interface. - if (SDK_VERSION >= 18) { - // For JB, KK only. - static CommandFunc COMMAND_CHAIN[] = { - setDefaultInterface, - defaultAsyncSuccessHandler - }; - runChain(aOptions, COMMAND_CHAIN, setDnsFail); - return CommandResult::Pending(); - } - - return SUCCESS; -} - -/** - * Remove default route for given network interface. - */ -CommandResult NetworkUtils::removeDefaultRoute(NetworkParams& aOptions) -{ - NU_DBG("Calling NetworkUtils::removeDefaultRoute"); - - if (SDK_VERSION < 20) { - return removeDefaultRouteLegacy(aOptions); - } - - static CommandFunc COMMAND_CHAIN[] = { - removeDefaultRoute, - defaultAsyncSuccessHandler, - }; - - NetIdManager::NetIdInfo netIdInfo; - if (!mNetIdManager.lookup(GET_FIELD(mIfname), &netIdInfo)) { - ERROR("No such interface: %s", GET_CHAR(mIfname)); - return -1; - } - - NU_DBG("Obtained netid %d for interface %s", netIdInfo.mNetId, GET_CHAR(mIfname)); - - aOptions.mNetId = netIdInfo.mNetId; - aOptions.mLoopIndex = 0; - runChain(aOptions, COMMAND_CHAIN, defaultAsyncFailureHandler); - - return CommandResult::Pending(); -} - -/** - * Remove default route for given network interface by obsoleted libnetutils. - */ -CommandResult NetworkUtils::removeDefaultRouteLegacy(NetworkParams& aOptions) -{ - // Legacy libnetutils calls before Lollipop. - uint32_t length = aOptions.mGateways.Length(); - for (uint32_t i = 0; i < length; i++) { - NS_ConvertUTF16toUTF8 autoGateway(aOptions.mGateways[i]); - - int type = getIpType(autoGateway.get()); - if (type != AF_INET && type != AF_INET6) { - return EAFNOSUPPORT; - } - - WARN_IF_FAILED(mNetUtils->do_ifc_remove_route(GET_CHAR(mIfname), - type == AF_INET ? "0.0.0.0" : "::", - 0, autoGateway.get())); - } - - return SUCCESS; -} - -/** - * Add host route for given network interface. - */ -CommandResult NetworkUtils::addHostRoute(NetworkParams& aOptions) -{ - if (SDK_VERSION < 20) { - return addHostRouteLegacy(aOptions); - } - - static CommandFunc COMMAND_CHAIN[] = { - addRouteToInterface, - defaultAsyncSuccessHandler, - }; - - NetIdManager::NetIdInfo netIdInfo; - if (!mNetIdManager.lookup(GET_FIELD(mIfname), &netIdInfo)) { - ERROR("No such interface: %s", GET_CHAR(mIfname)); - return -1; - } - - NU_DBG("Obtained netid %d for interface %s", netIdInfo.mNetId, GET_CHAR(mIfname)); - - aOptions.mNetId = netIdInfo.mNetId; - runChain(aOptions, COMMAND_CHAIN, defaultAsyncFailureHandler); - - return CommandResult::Pending(); -} - -/** - * Add host route for given network interface. - */ -CommandResult NetworkUtils::addHostRouteLegacy(NetworkParams& aOptions) -{ - if (aOptions.mGateway.IsEmpty()) { - ERROR("addHostRouteLegacy does not support empty gateway."); - return EINVAL; - } - - NS_ConvertUTF16toUTF8 autoIfname(aOptions.mIfname); - NS_ConvertUTF16toUTF8 autoHostname(aOptions.mIp); - NS_ConvertUTF16toUTF8 autoGateway(aOptions.mGateway); - int type, prefix; - - type = getIpType(autoHostname.get()); - if (type != AF_INET && type != AF_INET6) { - return EAFNOSUPPORT; - } - - if (type != getIpType(autoGateway.get())) { - return EINVAL; - } - - prefix = type == AF_INET ? 32 : 128; - return mNetUtils->do_ifc_add_route(autoIfname.get(), autoHostname.get(), - prefix, autoGateway.get()); -} - -/** - * Remove host route for given network interface. - */ -CommandResult NetworkUtils::removeHostRoute(NetworkParams& aOptions) -{ - if (SDK_VERSION < 20) { - return removeHostRouteLegacy(aOptions); - } - - static CommandFunc COMMAND_CHAIN[] = { - removeRouteFromInterface, - defaultAsyncSuccessHandler, - }; - - NetIdManager::NetIdInfo netIdInfo; - if (!mNetIdManager.lookup(GET_FIELD(mIfname), &netIdInfo)) { - ERROR("No such interface: %s", GET_CHAR(mIfname)); - return -1; - } - - NU_DBG("Obtained netid %d for interface %s", netIdInfo.mNetId, GET_CHAR(mIfname)); - - aOptions.mNetId = netIdInfo.mNetId; - runChain(aOptions, COMMAND_CHAIN, defaultAsyncFailureHandler); - - return CommandResult::Pending(); -} - -/** - * Remove host route for given network interface. - */ -CommandResult NetworkUtils::removeHostRouteLegacy(NetworkParams& aOptions) -{ - NS_ConvertUTF16toUTF8 autoIfname(aOptions.mIfname); - NS_ConvertUTF16toUTF8 autoHostname(aOptions.mIp); - NS_ConvertUTF16toUTF8 autoGateway(aOptions.mGateway); - int type, prefix; - - type = getIpType(autoHostname.get()); - if (type != AF_INET && type != AF_INET6) { - return EAFNOSUPPORT; - } - - if (type != getIpType(autoGateway.get())) { - return EINVAL; - } - - prefix = type == AF_INET ? 32 : 128; - return mNetUtils->do_ifc_remove_route(autoIfname.get(), autoHostname.get(), - prefix, autoGateway.get()); -} - -CommandResult NetworkUtils::removeNetworkRoute(NetworkParams& aOptions) -{ - if (SDK_VERSION < 20) { - return removeNetworkRouteLegacy(aOptions); - } - - static CommandFunc COMMAND_CHAIN[] = { - clearAddrForInterface, - defaultAsyncSuccessHandler, - }; - - NetIdManager::NetIdInfo netIdInfo; - if (!mNetIdManager.lookup(GET_FIELD(mIfname), &netIdInfo)) { - ERROR("interface %s is not present in any network", GET_CHAR(mIfname)); - return -1; - } - - NU_DBG("Obtained netid %d for interface %s", netIdInfo.mNetId, GET_CHAR(mIfname)); - - aOptions.mNetId = netIdInfo.mNetId; - runChain(aOptions, COMMAND_CHAIN, defaultAsyncFailureHandler); - - return CommandResult::Pending(); -} - -nsCString NetworkUtils::getSubnetIp(const nsCString& aIp, int aPrefixLength) -{ - int type = getIpType(aIp.get()); - - if (AF_INET6 == type) { - struct in6_addr in6; - if (inet_pton(AF_INET6, aIp.get(), &in6) != 1) { - return nsCString(); - } - - uint32_t p, i, p1, mask; - p = aPrefixLength; - i = 0; - while (i < 4) { - p1 = p > 32 ? 32 : p; - p -= p1; - mask = p1 ? ~0x0 << (32 - p1) : 0; - in6.s6_addr32[i++] &= htonl(mask); - } - - char subnetStr[INET6_ADDRSTRLEN]; - if (!inet_ntop(AF_INET6, &in6, subnetStr, sizeof subnetStr)) { - return nsCString(); - } - - return nsCString(subnetStr); - } - - if (AF_INET == type) { - uint32_t ip = inet_addr(aIp.get()); - uint32_t netmask = makeMask(aPrefixLength); - uint32_t subnet = ip & netmask; - struct in_addr addr; - addr.s_addr = subnet; - return nsCString(inet_ntoa(addr)); - } - - return nsCString(); -} - -CommandResult NetworkUtils::removeNetworkRouteLegacy(NetworkParams& aOptions) -{ - NS_ConvertUTF16toUTF8 autoIfname(aOptions.mIfname); - NS_ConvertUTF16toUTF8 autoIp(aOptions.mIp); - - int type = getIpType(autoIp.get()); - if (type != AF_INET && type != AF_INET6) { - return EAFNOSUPPORT; - } - - uint32_t prefixLength = GET_FIELD(mPrefixLength); - - if (type == AF_INET6) { - // Calculate subnet. - struct in6_addr in6; - if (inet_pton(AF_INET6, autoIp.get(), &in6) != 1) { - return EINVAL; - } - - uint32_t p, i, p1, mask; - p = prefixLength; - i = 0; - while (i < 4) { - p1 = p > 32 ? 32 : p; - p -= p1; - mask = p1 ? ~0x0 << (32 - p1) : 0; - in6.s6_addr32[i++] &= htonl(mask); - } - - char subnetStr[INET6_ADDRSTRLEN]; - if (!inet_ntop(AF_INET6, &in6, subnetStr, sizeof subnetStr)) { - return EINVAL; - } - - // Remove default route. - WARN_IF_FAILED(mNetUtils->do_ifc_remove_route(autoIfname.get(), "::", 0, NULL)); - - // Remove subnet route. - RETURN_IF_FAILED(mNetUtils->do_ifc_remove_route(autoIfname.get(), subnetStr, prefixLength, NULL)); - return SUCCESS; - } - - /* type == AF_INET */ - uint32_t ip = inet_addr(autoIp.get()); - uint32_t netmask = makeMask(prefixLength); - uint32_t subnet = ip & netmask; - const char* gateway = "0.0.0.0"; - struct in_addr addr; - addr.s_addr = subnet; - const char* dst = inet_ntoa(addr); - - RETURN_IF_FAILED(mNetUtils->do_ifc_remove_default_route(autoIfname.get())); - RETURN_IF_FAILED(mNetUtils->do_ifc_remove_route(autoIfname.get(), dst, prefixLength, gateway)); - return SUCCESS; -} - -CommandResult NetworkUtils::addSecondaryRoute(NetworkParams& aOptions) -{ - static CommandFunc COMMAND_CHAIN[] = { - addRouteToSecondaryTable, - defaultAsyncSuccessHandler - }; - - if (SDK_VERSION >= 20) { - NetIdManager::NetIdInfo netIdInfo; - if (!mNetIdManager.lookup(aOptions.mIfname, &netIdInfo)) { - return -1; - } - aOptions.mNetId = netIdInfo.mNetId; - } - - runChain(aOptions, COMMAND_CHAIN, defaultAsyncFailureHandler); - return CommandResult::Pending(); -} - -CommandResult NetworkUtils::removeSecondaryRoute(NetworkParams& aOptions) -{ - static CommandFunc COMMAND_CHAIN[] = { - removeRouteFromSecondaryTable, - defaultAsyncSuccessHandler - }; - - if (SDK_VERSION >= 20) { - NetIdManager::NetIdInfo netIdInfo; - if (!mNetIdManager.lookup(aOptions.mIfname, &netIdInfo)) { - return -1; - } - aOptions.mNetId = netIdInfo.mNetId; - } - - runChain(aOptions, COMMAND_CHAIN, defaultAsyncFailureHandler); - return CommandResult::Pending(); -} - -CommandResult NetworkUtils::setNetworkInterfaceAlarm(NetworkParams& aOptions) -{ - NU_DBG("setNetworkInterfaceAlarms: %s", GET_CHAR(mIfname)); - runChain(aOptions, sNetworkInterfaceSetAlarmChain, networkInterfaceAlarmFail); - return CommandResult::Pending(); -} - -CommandResult NetworkUtils::enableNetworkInterfaceAlarm(NetworkParams& aOptions) -{ - NU_DBG("enableNetworkInterfaceAlarm: %s", GET_CHAR(mIfname)); - runChain(aOptions, sNetworkInterfaceEnableAlarmChain, networkInterfaceAlarmFail); - return CommandResult::Pending(); -} - -CommandResult NetworkUtils::disableNetworkInterfaceAlarm(NetworkParams& aOptions) -{ - NU_DBG("disableNetworkInterfaceAlarms: %s", GET_CHAR(mIfname)); - runChain(aOptions, sNetworkInterfaceDisableAlarmChain, networkInterfaceAlarmFail); - return CommandResult::Pending(); -} - -CommandResult NetworkUtils::setTetheringAlarm(NetworkParams& aOptions) -{ - NU_DBG("setTetheringAlarm"); - runChain(aOptions, sTetheringInterfaceSetAlarmChain, networkInterfaceAlarmFail); - return CommandResult::Pending(); -} - -CommandResult NetworkUtils::removeTetheringAlarm(NetworkParams& aOptions) -{ - NU_DBG("removeTetheringAlarm"); - runChain(aOptions, sTetheringInterfaceRemoveAlarmChain, networkInterfaceAlarmFail); - return CommandResult::Pending(); -} - -CommandResult NetworkUtils::getTetheringStatus(NetworkParams& aOptions) -{ - NU_DBG("getTetheringStatus"); - runChain(aOptions, sTetheringGetStatusChain, networkInterfaceAlarmFail); - return CommandResult::Pending(); -} - -/** - * handling main thread's reload Wifi firmware request - */ -CommandResult NetworkUtils::setWifiOperationMode(NetworkParams& aOptions) -{ - NU_DBG("setWifiOperationMode: %s %s", GET_CHAR(mIfname), GET_CHAR(mMode)); - runChain(aOptions, sWifiOperationModeChain, wifiOperationModeFail); - return CommandResult::Pending(); -} - -/** - * handling main thread's enable/disable WiFi Tethering request - */ -CommandResult NetworkUtils::setWifiTethering(NetworkParams& aOptions) -{ - bool enable = aOptions.mEnable; - IFProperties interfaceProperties; - getIFProperties(GET_CHAR(mExternalIfname), interfaceProperties); - - if (strcmp(interfaceProperties.dns1, "")) { - int type = getIpType(interfaceProperties.dns1); - if (type != AF_INET6) { - aOptions.mDns1 = NS_ConvertUTF8toUTF16(interfaceProperties.dns1); - } - } - if (strcmp(interfaceProperties.dns2, "")) { - int type = getIpType(interfaceProperties.dns2); - if (type != AF_INET6) { - aOptions.mDns2 = NS_ConvertUTF8toUTF16(interfaceProperties.dns2); - } - } - dumpParams(aOptions, "WIFI"); - - if (SDK_VERSION >= 20) { - NetIdManager::NetIdInfo netIdInfo; - if (!mNetIdManager.lookup(aOptions.mExternalIfname, &netIdInfo)) { - ERROR("No such interface: %s", GET_CHAR(mExternalIfname)); - return -1; - } - aOptions.mNetId = netIdInfo.mNetId; - } - - if (enable) { - NU_DBG("Starting Wifi Tethering on %s <-> %s", - GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname)); - runChain(aOptions, sWifiEnableChain, wifiTetheringFail); - } else { - NU_DBG("Stopping Wifi Tethering on %s <-> %s", - GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname)); - runChain(aOptions, sWifiDisableChain, wifiTetheringFail); - } - return CommandResult::Pending(); -} - -CommandResult NetworkUtils::setUSBTethering(NetworkParams& aOptions) -{ - bool enable = aOptions.mEnable; - IFProperties interfaceProperties; - getIFProperties(GET_CHAR(mExternalIfname), interfaceProperties); - - if (strcmp(interfaceProperties.dns1, "")) { - int type = getIpType(interfaceProperties.dns1); - if (type != AF_INET6) { - aOptions.mDns1 = NS_ConvertUTF8toUTF16(interfaceProperties.dns1); - } - } - if (strcmp(interfaceProperties.dns2, "")) { - int type = getIpType(interfaceProperties.dns2); - if (type != AF_INET6) { - aOptions.mDns2 = NS_ConvertUTF8toUTF16(interfaceProperties.dns2); - } - } - dumpParams(aOptions, "USB"); - - if (SDK_VERSION >= 20) { - NetIdManager::NetIdInfo netIdInfo; - if (!mNetIdManager.lookup(aOptions.mExternalIfname, &netIdInfo)) { - ERROR("No such interface: %s", GET_CHAR(mExternalIfname)); - return -1; - } - aOptions.mNetId = netIdInfo.mNetId; - } - - if (enable) { - NU_DBG("Starting USB Tethering on %s <-> %s", - GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname)); - runChain(aOptions, sUSBEnableChain, usbTetheringFail); - } else { - NU_DBG("Stopping USB Tethering on %s <-> %s", - GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname)); - runChain(aOptions, sUSBDisableChain, usbTetheringFail); - } - return CommandResult::Pending(); -} - -void NetworkUtils::escapeQuote(nsCString& aString) -{ - aString.ReplaceSubstring("\\", "\\\\"); - aString.ReplaceSubstring("\"", "\\\""); -} - -CommandResult NetworkUtils::checkUsbRndisState(NetworkParams& aOptions) -{ - static uint32_t retry = 0; - - char currentState[Property::VALUE_MAX_LENGTH]; - Property::Get(SYS_USB_STATE_PROPERTY, currentState, nullptr); - - nsTArray<nsCString> stateFuncs; - split(currentState, USB_CONFIG_DELIMIT, stateFuncs); - bool rndisPresent = stateFuncs.Contains(nsCString(USB_FUNCTION_RNDIS)); - - if (aOptions.mEnable == rndisPresent) { - NetworkResultOptions result; - result.mEnable = aOptions.mEnable; - result.mResult = true; - retry = 0; - return result; - } - if (retry < USB_FUNCTION_RETRY_TIMES) { - retry++; - usleep(USB_FUNCTION_RETRY_INTERVAL * 1000); - return checkUsbRndisState(aOptions); - } - - NetworkResultOptions result; - result.mResult = false; - retry = 0; - return result; -} - -/** - * Modify usb function's property to turn on USB RNDIS function - */ -CommandResult NetworkUtils::enableUsbRndis(NetworkParams& aOptions) -{ - bool report = aOptions.mReport; - - // For some reason, rndis doesn't play well with diag,modem,nmea. - // So when turning rndis on, we set sys.usb.config to either "rndis" - // or "rndis,adb". When turning rndis off, we go back to - // persist.sys.usb.config. - // - // On the otoro/unagi, persist.sys.usb.config should be one of: - // - // diag,modem,nmea,mass_storage - // diag,modem,nmea,mass_storage,adb - // - // When rndis is enabled, sys.usb.config should be one of: - // - // rdnis - // rndis,adb - // - // and when rndis is disabled, it should revert to persist.sys.usb.config - - char currentConfig[Property::VALUE_MAX_LENGTH]; - Property::Get(SYS_USB_CONFIG_PROPERTY, currentConfig, nullptr); - - nsTArray<nsCString> configFuncs; - split(currentConfig, USB_CONFIG_DELIMIT, configFuncs); - - char persistConfig[Property::VALUE_MAX_LENGTH]; - Property::Get(PERSIST_SYS_USB_CONFIG_PROPERTY, persistConfig, nullptr); - - nsTArray<nsCString> persistFuncs; - split(persistConfig, USB_CONFIG_DELIMIT, persistFuncs); - - if (aOptions.mEnable) { - configFuncs.Clear(); - configFuncs.AppendElement(nsCString(USB_FUNCTION_RNDIS)); - if (persistFuncs.Contains(nsCString(USB_FUNCTION_ADB))) { - configFuncs.AppendElement(nsCString(USB_FUNCTION_ADB)); - } - } else { - // We're turning rndis off, revert back to the persist setting. - // adb will already be correct there, so we don't need to do any - // further adjustments. - configFuncs = persistFuncs; - } - - char newConfig[Property::VALUE_MAX_LENGTH] = ""; - Property::Get(SYS_USB_CONFIG_PROPERTY, currentConfig, nullptr); - join(configFuncs, USB_CONFIG_DELIMIT, Property::VALUE_MAX_LENGTH, newConfig); - if (strcmp(currentConfig, newConfig)) { - Property::Set(SYS_USB_CONFIG_PROPERTY, newConfig); - } - - // Trigger the timer to check usb state and report the result to NetworkManager. - if (report) { - usleep(USB_FUNCTION_RETRY_INTERVAL * 1000); - return checkUsbRndisState(aOptions); - } - return SUCCESS; -} - -/** - * handling upstream interface change event. - */ -CommandResult NetworkUtils::updateUpStream(NetworkParams& aOptions) -{ - runChain(aOptions, sUpdateUpStreamChain, updateUpStreamFail); - return CommandResult::Pending(); -} - -/** - * handling upstream interface change event. - */ -CommandResult NetworkUtils::createNetwork(NetworkParams& aOptions) -{ - if (SDK_VERSION < 20) { - return SUCCESS; - } - - static CommandFunc COMMAND_CHAIN[] = { - createNetwork, - enableIpv6, - addInterfaceToNetwork, - defaultAsyncSuccessHandler, - }; - - NetIdManager::NetIdInfo netIdInfo; - mNetIdManager.acquire(GET_FIELD(mIfname), &netIdInfo); - if (netIdInfo.mRefCnt > 1) { - // Already created. Just return. - NU_DBG("Interface %s (%d) has been created.", GET_CHAR(mIfname), - netIdInfo.mNetId); - return SUCCESS; - } - - NU_DBG("Request netd to create a network with netid %d", netIdInfo.mNetId); - // Newly created netid. Ask netd to create network. - aOptions.mNetId = netIdInfo.mNetId; - runChain(aOptions, COMMAND_CHAIN, defaultAsyncFailureHandler); - - return CommandResult::Pending(); -} - -/** - * handling upstream interface change event. - */ -CommandResult NetworkUtils::destroyNetwork(NetworkParams& aOptions) -{ - if (SDK_VERSION < 20) { - return SUCCESS; - } - - static CommandFunc COMMAND_CHAIN[] = { - disableIpv6, - destroyNetwork, - defaultAsyncSuccessHandler, - }; - - NetIdManager::NetIdInfo netIdInfo; - if (!mNetIdManager.release(GET_FIELD(mIfname), &netIdInfo)) { - ERROR("No existing netid for %s", GET_CHAR(mIfname)); - return -1; - } - - if (netIdInfo.mRefCnt > 0) { - // Still be referenced. Just return. - NU_DBG("Someone is still using this interface."); - return SUCCESS; - } - - NU_DBG("Interface %s (%d) is no longer used. Tell netd to destroy.", - GET_CHAR(mIfname), netIdInfo.mNetId); - - aOptions.mNetId = netIdInfo.mNetId; - runChain(aOptions, COMMAND_CHAIN, defaultAsyncFailureHandler); - return CommandResult::Pending(); -} - -/** - * Query the netId associated with the given network interface name. - */ -CommandResult NetworkUtils::getNetId(NetworkParams& aOptions) -{ - NetworkResultOptions result; - - if (SDK_VERSION < 20) { - // For pre-Lollipop, use the interface name as the fallback. - result.mNetId = GET_FIELD(mIfname); - return result; - } - - NetIdManager::NetIdInfo netIdInfo; - if (-1 == mNetIdManager.lookup(GET_FIELD(mIfname), &netIdInfo)) { - return ESRCH; - } - result.mNetId.AppendInt(netIdInfo.mNetId, 10); - return result; -} - -/** - * Get existing network interfaces. - */ -CommandResult NetworkUtils::getInterfaces(NetworkParams& aOptions) -{ - runChain(aOptions, sGetInterfacesChain, getInterfacesFail); - return CommandResult::Pending(); -} - -/** - * Get network config of a specified interface. - */ -CommandResult NetworkUtils::getInterfaceConfig(NetworkParams& aOptions) -{ - runChain(aOptions, sGetInterfaceConfigChain, getInterfaceConfigFail); - return CommandResult::Pending(); -} - -/** - * Set network config for a specified interface. - */ -CommandResult NetworkUtils::setInterfaceConfig(NetworkParams& aOptions) -{ - runChain(aOptions, sSetInterfaceConfigChain, setInterfaceConfigFail); - return CommandResult::Pending(); -} - -CommandResult NetworkUtils::setMtu(NetworkParams& aOptions) -{ - // Setting/getting mtu is supported since Kitkat. - if (SDK_VERSION < 19) { - ERROR("setMtu is not supported in current SDK_VERSION."); - return -1; - } - - static CommandFunc COMMAND_CHAIN[] = { - setMtu, - defaultAsyncSuccessHandler, - }; - - runChain(aOptions, COMMAND_CHAIN, defaultAsyncFailureHandler); - return CommandResult::Pending(); -} - -void NetworkUtils::sendBroadcastMessage(uint32_t code, char* reason) -{ - NetworkResultOptions result; - switch(code) { - case NETD_COMMAND_INTERFACE_CHANGE: - result.mTopic = NS_ConvertUTF8toUTF16("netd-interface-change"); - break; - case NETD_COMMAND_BANDWIDTH_CONTROLLER: - result.mTopic = NS_ConvertUTF8toUTF16("netd-bandwidth-control"); - break; - default: - return; - } - - result.mBroadcast = true; - result.mReason = NS_ConvertUTF8toUTF16(reason); - postMessage(result); -} - -inline uint32_t NetworkUtils::netdResponseType(uint32_t code) -{ - return (code / 100) * 100; -} - -inline bool NetworkUtils::isBroadcastMessage(uint32_t code) -{ - uint32_t type = netdResponseType(code); - return type == NETD_COMMAND_UNSOLICITED; -} - -inline bool NetworkUtils::isError(uint32_t code) -{ - uint32_t type = netdResponseType(code); - return type != NETD_COMMAND_PROCEEDING && type != NETD_COMMAND_OKAY; -} - -inline bool NetworkUtils::isComplete(uint32_t code) -{ - uint32_t type = netdResponseType(code); - return type != NETD_COMMAND_PROCEEDING; -} - -inline bool NetworkUtils::isProceeding(uint32_t code) -{ - uint32_t type = netdResponseType(code); - return type == NETD_COMMAND_PROCEEDING; -} - -void NetworkUtils::dumpParams(NetworkParams& aOptions, const char* aType) -{ -#ifdef _DEBUG - NU_DBG("Dump params:"); - NU_DBG(" ifname: %s", GET_CHAR(mIfname)); - NU_DBG(" ip: %s", GET_CHAR(mIp)); - NU_DBG(" link: %s", GET_CHAR(mLink)); - NU_DBG(" prefix: %s", GET_CHAR(mPrefix)); - NU_DBG(" wifiStartIp: %s", GET_CHAR(mWifiStartIp)); - NU_DBG(" wifiEndIp: %s", GET_CHAR(mWifiEndIp)); - NU_DBG(" usbStartIp: %s", GET_CHAR(mUsbStartIp)); - NU_DBG(" usbEndIp: %s", GET_CHAR(mUsbEndIp)); - NU_DBG(" dnsserver1: %s", GET_CHAR(mDns1)); - NU_DBG(" dnsserver2: %s", GET_CHAR(mDns2)); - NU_DBG(" internalIfname: %s", GET_CHAR(mInternalIfname)); - NU_DBG(" externalIfname: %s", GET_CHAR(mExternalIfname)); - if (!strcmp(aType, "WIFI")) { - NU_DBG(" wifictrlinterfacename: %s", GET_CHAR(mWifictrlinterfacename)); - NU_DBG(" ssid: %s", GET_CHAR(mSsid)); - NU_DBG(" security: %s", GET_CHAR(mSecurity)); - NU_DBG(" key: %s", GET_CHAR(mKey)); - } -#endif -} - -#undef GET_CHAR -#undef GET_FIELD |