NatController.cpp revision 56afacf838d24cf8e54d2cf0d8ab9182ab704125
19ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat/* 29ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * Copyright (C) 2008 The Android Open Source Project 39ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * 49ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * Licensed under the Apache License, Version 2.0 (the "License"); 59ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * you may not use this file except in compliance with the License. 69ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * You may obtain a copy of the License at 79ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * 89ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * http://www.apache.org/licenses/LICENSE-2.0 99ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * 109ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * Unless required by applicable law or agreed to in writing, software 119ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * distributed under the License is distributed on an "AS IS" BASIS, 129ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * See the License for the specific language governing permissions and 149ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * limitations under the License. 159ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat */ 169ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 17baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall#define LOG_NDEBUG 0 180031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall 199ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <stdlib.h> 209ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <errno.h> 219ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <sys/socket.h> 229ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <sys/stat.h> 23001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand#include <sys/wait.h> 249ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <fcntl.h> 259ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <netinet/in.h> 269ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <arpa/inet.h> 27ff2c0d8c13457e43f0d4bf06d3177271aac104c1Olivier Bailly#include <string.h> 28ac208608c9e10ef199fdd11c38a31675ee9290c0John Michelau#include <cutils/properties.h> 299ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 309ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#define LOG_TAG "NatController" 319ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <cutils/log.h> 32001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand#include <logwrap/logwrap.h> 339ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 349ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include "NatController.h" 35a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak#include "NetworkController.h" 36fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt#include "SecondaryTableController.h" 37c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt#include "NetdConstants.h" 389ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 398e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkeyconst char* NatController::LOCAL_FORWARD = "natctrl_FORWARD"; 408e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkeyconst char* NatController::LOCAL_NAT_POSTROUTING = "natctrl_nat_POSTROUTING"; 41baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrallconst char* NatController::LOCAL_TETHER_COUNTERS_CHAIN = "natctrl_tether_counters"; 428e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey 43a0efaece8c05370f201efe099a537ceb014c6fdfSzymon JakubczakNatController::NatController(SecondaryTableController *table_ctrl, NetworkController* net_ctrl) : 44a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak mSecondaryTableCtrl(table_ctrl), mNetCtrl(net_ctrl) { 459ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 469ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 479ff78fb7da7158f5bd7c86d89a842691820259cfSan MehatNatController::~NatController() { 489ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 499ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 504ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrallstruct CommandsAndArgs { 514ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall /* The array size doesn't really matter as the compiler will barf if too many initializers are specified. */ 524ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall const char *cmd[32]; 534ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall bool checkRes; 544ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall}; 554ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall 56001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchandint NatController::runCmd(int argc, const char **argv) { 5711b4e9b26fe7b878992162afb39f5a8acfd143edJP Abgrall int res; 589ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 59001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand res = android_fork_execvp(argc, (char **)argv, NULL, false, false); 60baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall 61baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall#if !LOG_NDEBUG 62baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall std::string full_cmd = argv[0]; 63baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall argc--; argv++; 64baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall /* 65baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall * HACK: Sometimes runCmd() is called with a ridcously large value (32) 66baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall * and it works because the argv[] contains a NULL after the last 67baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall * true argv. So here we use the NULL argv[] to terminate when the argc 68baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall * is horribly wrong, and argc for the normal cases. 69baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall */ 70baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall for (; argc && argv[0]; argc--, argv++) { 71baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall full_cmd += " "; 72baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall full_cmd += argv[0]; 73baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall } 74baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall ALOGV("runCmd(%s) res=%d", full_cmd.c_str(), res); 75baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall#endif 7611b4e9b26fe7b878992162afb39f5a8acfd143edJP Abgrall return res; 779ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 789ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 790031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrallint NatController::setupIptablesHooks() { 80baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall int res; 81baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall res = setDefaults(); 82baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall if (res < 0) { 83baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall return res; 84baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall } 85baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall 86baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall struct CommandsAndArgs defaultCommands[] = { 87baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall /* 88baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall * Chain for tethering counters. 89baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall * This chain is reached via --goto, and then RETURNS. 90baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall */ 91baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall {{IPTABLES_PATH, "-F", LOCAL_TETHER_COUNTERS_CHAIN,}, 0}, 92baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall {{IPTABLES_PATH, "-X", LOCAL_TETHER_COUNTERS_CHAIN,}, 0}, 93baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall {{IPTABLES_PATH, "-N", LOCAL_TETHER_COUNTERS_CHAIN,}, 1}, 94baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall }; 95baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall for (unsigned int cmdNum = 0; cmdNum < ARRAY_SIZE(defaultCommands); cmdNum++) { 96baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall if (runCmd(ARRAY_SIZE(defaultCommands[cmdNum].cmd), defaultCommands[cmdNum].cmd) && 97baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall defaultCommands[cmdNum].checkRes) { 98baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall return -1; 99baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall } 100baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall } 101f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall ifacePairList.clear(); 102baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall 1030031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall return 0; 1040031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall} 1050031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall 1060031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrallint NatController::setDefaults() { 107baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall /* 108baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall * The following only works because: 109baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall * - the defaultsCommands[].cmd array is padded with NULL, and 110baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall * - the 1st argc of runCmd() will just be the max for the CommandsAndArgs[].cmd, and 111baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall * - internally it will be memcopied to an array and terminated with a NULL. 112baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall */ 1134ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall struct CommandsAndArgs defaultCommands[] = { 114baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall {{IPTABLES_PATH, "-F", LOCAL_FORWARD,}, 1}, 115baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall {{IPTABLES_PATH, "-A", LOCAL_FORWARD, "-j", "DROP"}, 1}, 116baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall {{IPTABLES_PATH, "-t", "nat", "-F", LOCAL_NAT_POSTROUTING}, 1}, 1174ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall {{IP_PATH, "rule", "flush"}, 0}, 1184ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall {{IP_PATH, "-6", "rule", "flush"}, 0}, 1194ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall {{IP_PATH, "rule", "add", "from", "all", "lookup", "default", "prio", "32767"}, 0}, 1204ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall {{IP_PATH, "rule", "add", "from", "all", "lookup", "main", "prio", "32766"}, 0}, 1214ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall {{IP_PATH, "-6", "rule", "add", "from", "all", "lookup", "default", "prio", "32767"}, 0}, 1224ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall {{IP_PATH, "-6", "rule", "add", "from", "all", "lookup", "main", "prio", "32766"}, 0}, 1234ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall {{IP_PATH, "route", "flush", "cache"}, 0}, 124001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand }; 1254ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall for (unsigned int cmdNum = 0; cmdNum < ARRAY_SIZE(defaultCommands); cmdNum++) { 1264ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall if (runCmd(ARRAY_SIZE(defaultCommands[cmdNum].cmd), defaultCommands[cmdNum].cmd) && 1274ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall defaultCommands[cmdNum].checkRes) { 1284ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall return -1; 1294ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall } 1304ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall } 131fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 132fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt natCount = 0; 1334ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo 1349ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return 0; 1359ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 1369ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 137fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwaltbool NatController::checkInterface(const char *iface) { 138d14fd4f83ffeea4ad1cd559a41f775f6814565ccJaime A Lopez-Sollano if (strlen(iface) > IFNAMSIZ) return false; 1399ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return true; 1409ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 1419ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 1424ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrallint NatController::routesOp(bool add, const char *intIface, const char *extIface, char **argv, int addrCount) { 143a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak unsigned netId = mNetCtrl->getNetworkId(extIface); 1444ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall int ret = 0; 1454ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall 146a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak for (int i = 0; i < addrCount; i++) { 147a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak if (add) { 148a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak ret |= mSecondaryTableCtrl->modifyFromRule(netId, ADD, argv[5+i]); 149a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak ret |= mSecondaryTableCtrl->modifyLocalRoute(netId, ADD, intIface, argv[5+i]); 150a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak } else { 151a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak ret |= mSecondaryTableCtrl->modifyLocalRoute(netId, DEL, intIface, argv[5+i]); 152a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak ret |= mSecondaryTableCtrl->modifyFromRule(netId, DEL, argv[5+i]); 1534ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall } 1544ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall } 155a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak const char *cmd[] = { 156a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak IP_PATH, 157a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak "route", 158a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak "flush", 159a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak "cache" 160a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak }; 161a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak runCmd(ARRAY_SIZE(cmd), cmd); 1624ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall return ret; 1634ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall} 1644ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall 165fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt// 0 1 2 3 4 5 166fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt// nat enable intface extface addrcnt nated-ipaddr/prelength 167fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwaltint NatController::enableNat(const int argc, char **argv) { 168fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt int addrCount = atoi(argv[4]); 169fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt const char *intIface = argv[2]; 170fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt const char *extIface = argv[3]; 171fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 172baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall ALOGV("enableNat(intIface=<%s>, extIface=<%s>)",intIface, extIface); 173baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall 174fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (!checkInterface(intIface) || !checkInterface(extIface)) { 1755ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block ALOGE("Invalid interface specified"); 176fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt errno = ENODEV; 177fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return -1; 178fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 1799ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 180baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall /* Bug: b/9565268. "enableNat wlan0 wlan0". For now we fail until java-land is fixed */ 181baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall if (!strcmp(intIface, extIface)) { 182baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall ALOGE("Duplicate interface specified: %s %s", intIface, extIface); 183baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall errno = EINVAL; 184baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall return -1; 185baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall } 186baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall 187fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (argc < 5 + addrCount) { 1885ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block ALOGE("Missing Argument"); 189fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt errno = EINVAL; 190fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return -1; 191fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 192659692a56cca02822a43b792baba2632d39eb739JP Abgrall if (routesOp(true, intIface, extIface, argv, addrCount)) { 193659692a56cca02822a43b792baba2632d39eb739JP Abgrall ALOGE("Error setting route rules"); 1944ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall routesOp(false, intIface, extIface, argv, addrCount); 1959ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat errno = ENODEV; 1969ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 1979ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 1989ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 199fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt // add this if we are the first added nat 200659692a56cca02822a43b792baba2632d39eb739JP Abgrall if (natCount == 0) { 201001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand const char *cmd[] = { 202001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand IPTABLES_PATH, 203001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "-t", 204001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "nat", 205001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "-A", 206baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall LOCAL_NAT_POSTROUTING, 207001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "-o", 208001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand extIface, 209001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "-j", 210001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "MASQUERADE" 211001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand }; 212001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand if (runCmd(ARRAY_SIZE(cmd), cmd)) { 213001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand ALOGE("Error seting postroute rule: iface=%s", extIface); 214fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt // unwind what's been done, but don't care about success - what more could we do? 2154ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall routesOp(false, intIface, extIface, argv, addrCount); 216fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt setDefaults(); 217fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return -1; 218fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 219fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 220fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 221659692a56cca02822a43b792baba2632d39eb739JP Abgrall 222659692a56cca02822a43b792baba2632d39eb739JP Abgrall if (setForwardRules(true, intIface, extIface) != 0) { 223659692a56cca02822a43b792baba2632d39eb739JP Abgrall ALOGE("Error setting forward rules"); 224659692a56cca02822a43b792baba2632d39eb739JP Abgrall routesOp(false, intIface, extIface, argv, addrCount); 225659692a56cca02822a43b792baba2632d39eb739JP Abgrall if (natCount == 0) { 226659692a56cca02822a43b792baba2632d39eb739JP Abgrall setDefaults(); 227659692a56cca02822a43b792baba2632d39eb739JP Abgrall } 228659692a56cca02822a43b792baba2632d39eb739JP Abgrall errno = ENODEV; 229659692a56cca02822a43b792baba2632d39eb739JP Abgrall return -1; 230659692a56cca02822a43b792baba2632d39eb739JP Abgrall } 231659692a56cca02822a43b792baba2632d39eb739JP Abgrall 232659692a56cca02822a43b792baba2632d39eb739JP Abgrall /* Always make sure the drop rule is at the end */ 233659692a56cca02822a43b792baba2632d39eb739JP Abgrall const char *cmd1[] = { 234659692a56cca02822a43b792baba2632d39eb739JP Abgrall IPTABLES_PATH, 235659692a56cca02822a43b792baba2632d39eb739JP Abgrall "-D", 236baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall LOCAL_FORWARD, 237659692a56cca02822a43b792baba2632d39eb739JP Abgrall "-j", 238659692a56cca02822a43b792baba2632d39eb739JP Abgrall "DROP" 239659692a56cca02822a43b792baba2632d39eb739JP Abgrall }; 240659692a56cca02822a43b792baba2632d39eb739JP Abgrall runCmd(ARRAY_SIZE(cmd1), cmd1); 241659692a56cca02822a43b792baba2632d39eb739JP Abgrall const char *cmd2[] = { 242659692a56cca02822a43b792baba2632d39eb739JP Abgrall IPTABLES_PATH, 243659692a56cca02822a43b792baba2632d39eb739JP Abgrall "-A", 244baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall LOCAL_FORWARD, 245659692a56cca02822a43b792baba2632d39eb739JP Abgrall "-j", 246659692a56cca02822a43b792baba2632d39eb739JP Abgrall "DROP" 247659692a56cca02822a43b792baba2632d39eb739JP Abgrall }; 248659692a56cca02822a43b792baba2632d39eb739JP Abgrall runCmd(ARRAY_SIZE(cmd2), cmd2); 249659692a56cca02822a43b792baba2632d39eb739JP Abgrall 250659692a56cca02822a43b792baba2632d39eb739JP Abgrall natCount++; 251fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return 0; 252fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt} 253fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 254f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrallbool NatController::checkTetherCountingRuleExist(const char *pair_name) { 255f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall std::list<std::string>::iterator it; 256f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall 257f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall for (it = ifacePairList.begin(); it != ifacePairList.end(); it++) { 258f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall if (*it == pair_name) { 259f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall /* We already have this counter */ 260f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall return true; 261f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall } 262f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall } 263f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall return false; 264f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall} 265f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall 266baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrallint NatController::setTetherCountingRules(bool add, const char *intIface, const char *extIface) { 267baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall 268baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall /* We only ever add tethering quota rules so that they stick. */ 269baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall if (!add) { 270baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall return 0; 271baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall } 27256afacf838d24cf8e54d2cf0d8ab9182ab704125Sreeram Ramachandran char *pair_name; 273f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall asprintf(&pair_name, "%s_%s", intIface, extIface); 274f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall 275f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall if (checkTetherCountingRuleExist(pair_name)) { 276f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall free(pair_name); 277baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall return 0; 278baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall } 279baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall const char *cmd2b[] = { 280baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall IPTABLES_PATH, 281baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall "-A", 282baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall LOCAL_TETHER_COUNTERS_CHAIN, 283baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall "-i", 284baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall intIface, 285baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall "-o", 286baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall extIface, 287baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall "-j", 288baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall "RETURN" 289baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall }; 290baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall 291baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall if (runCmd(ARRAY_SIZE(cmd2b), cmd2b) && add) { 292f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall free(pair_name); 293baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall return -1; 294baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall } 295f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall ifacePairList.push_front(pair_name); 296f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall free(pair_name); 297f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall 298f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall asprintf(&pair_name, "%s_%s", extIface, intIface); 299f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall if (checkTetherCountingRuleExist(pair_name)) { 300f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall free(pair_name); 301baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall return 0; 302baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall } 303baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall 304baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall const char *cmd3b[] = { 305baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall IPTABLES_PATH, 306baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall "-A", 307baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall LOCAL_TETHER_COUNTERS_CHAIN, 308baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall "-i", 309baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall extIface, 310baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall "-o", 311baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall intIface, 312baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall "-j", 313baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall "RETURN" 314baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall }; 315baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall 316baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall if (runCmd(ARRAY_SIZE(cmd3b), cmd3b) && add) { 317baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall // unwind what's been done, but don't care about success - what more could we do? 318f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall free(pair_name); 319baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall return -1; 320baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall } 321f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall ifacePairList.push_front(pair_name); 322f3cc83fa5b14455589af83b20998885452cdc46dJP Abgrall free(pair_name); 323baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall return 0; 324baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall} 325baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall 326baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrallint NatController::setForwardRules(bool add, const char *intIface, const char *extIface) { 327001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand const char *cmd1[] = { 328001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand IPTABLES_PATH, 329001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand add ? "-A" : "-D", 330baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall LOCAL_FORWARD, 331001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "-i", 332001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand extIface, 333001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "-o", 334001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand intIface, 335001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "-m", 336001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "state", 337001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "--state", 338001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "ESTABLISHED,RELATED", 339baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall "-g", 340baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall LOCAL_TETHER_COUNTERS_CHAIN 341001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand }; 342001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand int rc = 0; 343001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand 344001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand if (runCmd(ARRAY_SIZE(cmd1), cmd1) && add) { 3459ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 3469ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 3479ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 348001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand const char *cmd2[] = { 349001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand IPTABLES_PATH, 350001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand add ? "-A" : "-D", 351baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall LOCAL_FORWARD, 352001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "-i", 353001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand intIface, 354001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "-o", 355001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand extIface, 356001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "-m", 357001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "state", 358001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "--state", 359001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "INVALID", 360001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "-j", 361001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "DROP" 362001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand }; 363001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand 364001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand const char *cmd3[] = { 365001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand IPTABLES_PATH, 366001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand add ? "-A" : "-D", 367baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall LOCAL_FORWARD, 368001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "-i", 369001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand intIface, 370001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand "-o", 371001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand extIface, 372baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall "-g", 373baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall LOCAL_TETHER_COUNTERS_CHAIN 374001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand }; 375001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand 376001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand if (runCmd(ARRAY_SIZE(cmd2), cmd2) && add) { 377f7bf29c8a37d65e132a4dceb7c5a4200ed5c3d79Robert Greenwalt // bail on error, but only if adding 378001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand rc = -1; 379001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand goto err_invalid_drop; 380ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt } 381ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt 382001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand if (runCmd(ARRAY_SIZE(cmd3), cmd3) && add) { 383210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt // unwind what's been done, but don't care about success - what more could we do? 384001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand rc = -1; 385001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand goto err_return; 3869ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 3870031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall 388baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall if (setTetherCountingRules(add, intIface, extIface) && add) { 389baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall rc = -1; 390baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall goto err_return; 391baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall } 392baeccc455b293c2c83dbe6463f56b741177bd612JP Abgrall 393fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return 0; 394001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand 395001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchanderr_return: 396001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand cmd2[1] = "-D"; 397001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand runCmd(ARRAY_SIZE(cmd2), cmd2); 398001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchanderr_invalid_drop: 399001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand cmd1[1] = "-D"; 400001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand runCmd(ARRAY_SIZE(cmd1), cmd1); 401001f0a436e9fe0353dccd98ee34b91095d9ed1a1Rom Lemarchand return rc; 402fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt} 4039ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 404fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt// nat disable intface extface 405fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt// 0 1 2 3 4 5 406fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt// nat enable intface extface addrcnt nated-ipaddr/prelength 407fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwaltint NatController::disableNat(const int argc, char **argv) { 408fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt int addrCount = atoi(argv[4]); 409fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt const char *intIface = argv[2]; 410fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt const char *extIface = argv[3]; 411fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 412fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (!checkInterface(intIface) || !checkInterface(extIface)) { 4135ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block ALOGE("Invalid interface specified"); 414fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt errno = ENODEV; 415fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return -1; 4169ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 4179ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 418fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (argc < 5 + addrCount) { 4195ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block ALOGE("Missing Argument"); 420fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt errno = EINVAL; 421fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return -1; 422210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt } 4239ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 424fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt setForwardRules(false, intIface, extIface); 4254ae80dea9cbf1fe1b33037aeb5feb04daeba8ee0JP Abgrall routesOp(false, intIface, extIface, argv, addrCount); 426fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (--natCount <= 0) { 4274ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo // handle decrement to 0 case (do reset to defaults) and erroneous dec below 0 4284ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo setDefaults(); 429fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 430fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return 0; 4319ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 432