NatController.cpp revision 5ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13
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 179ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <stdlib.h> 189ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <errno.h> 199ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <sys/socket.h> 209ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <sys/stat.h> 219ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <fcntl.h> 229ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <netinet/in.h> 239ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <arpa/inet.h> 24ff2c0d8c13457e43f0d4bf06d3177271aac104c1Olivier Bailly#include <string.h> 25ac208608c9e10ef199fdd11c38a31675ee9290c0John Michelau#include <cutils/properties.h> 269ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 279ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#define LOG_TAG "NatController" 289ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <cutils/log.h> 299ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 309ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include "NatController.h" 31fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt#include "SecondaryTableController.h" 329ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 339e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrallextern "C" int system_nosh(const char *command); 349ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 359ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehatstatic char IPTABLES_PATH[] = "/system/bin/iptables"; 36fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwaltstatic char IP_PATH[] = "/system/bin/ip"; 379ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 38fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert GreenwaltNatController::NatController(SecondaryTableController *ctrl) { 39fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt secondaryTableCtrl = ctrl; 40fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt setDefaults(); 419ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 429ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 439ff78fb7da7158f5bd7c86d89a842691820259cfSan MehatNatController::~NatController() { 449ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 459ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 46fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwaltint NatController::runCmd(const char *path, const char *cmd) { 4711b4e9b26fe7b878992162afb39f5a8acfd143edJP Abgrall char *buffer; 4811b4e9b26fe7b878992162afb39f5a8acfd143edJP Abgrall size_t len = strnlen(cmd, 255); 4911b4e9b26fe7b878992162afb39f5a8acfd143edJP Abgrall int res; 509ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 5111b4e9b26fe7b878992162afb39f5a8acfd143edJP Abgrall if (len == 255) { 525ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block ALOGE("command too long"); 5311b4e9b26fe7b878992162afb39f5a8acfd143edJP Abgrall errno = E2BIG; 5411b4e9b26fe7b878992162afb39f5a8acfd143edJP Abgrall return -1; 559ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 569ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 57fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt asprintf(&buffer, "%s %s", path, cmd); 589e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall res = system_nosh(buffer); 5911b4e9b26fe7b878992162afb39f5a8acfd143edJP Abgrall free(buffer); 6011b4e9b26fe7b878992162afb39f5a8acfd143edJP Abgrall return res; 619ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 629ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 639ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehatint NatController::setDefaults() { 649ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 65fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (runCmd(IPTABLES_PATH, "-P INPUT ACCEPT")) 669ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 67fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (runCmd(IPTABLES_PATH, "-P OUTPUT ACCEPT")) 689ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 69fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (runCmd(IPTABLES_PATH, "-P FORWARD DROP")) 709ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 71fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (runCmd(IPTABLES_PATH, "-F FORWARD")) 729ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 73fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (runCmd(IPTABLES_PATH, "-t nat -F")) 749ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 75fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 76fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt runCmd(IP_PATH, "rule flush"); 77063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt runCmd(IP_PATH, "-6 rule flush"); 78fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt runCmd(IP_PATH, "rule add from all lookup default prio 32767"); 79fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt runCmd(IP_PATH, "rule add from all lookup main prio 32766"); 80063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt runCmd(IP_PATH, "-6 rule add from all lookup default prio 32767"); 81063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt runCmd(IP_PATH, "-6 rule add from all lookup main prio 32766"); 82063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt runCmd(IP_PATH, "route flush cache"); 83fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 84fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt natCount = 0; 859ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return 0; 869ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 879ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 88fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwaltbool NatController::checkInterface(const char *iface) { 89fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (strlen(iface) > MAX_IFACE_LENGTH) return false; 909ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return true; 919ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 929ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 93063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwaltconst char *NatController::getVersion(const char *addr) { 94063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt if (strchr(addr, ':') != NULL) { 95063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt return "-6"; 96063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt } else { 97063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt return "-4"; 98063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt } 99063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt} 100063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt 101fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt// 0 1 2 3 4 5 102fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt// nat enable intface extface addrcnt nated-ipaddr/prelength 103fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwaltint NatController::enableNat(const int argc, char **argv) { 1049ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat char cmd[255]; 105fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt int i; 106fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt int addrCount = atoi(argv[4]); 107fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt int ret = 0; 108fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt const char *intIface = argv[2]; 109fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt const char *extIface = argv[3]; 110fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt int tableNumber; 111fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 112fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (!checkInterface(intIface) || !checkInterface(extIface)) { 1135ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block ALOGE("Invalid interface specified"); 114fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt errno = ENODEV; 115fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return -1; 116fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 1179ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 118fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (argc < 5 + addrCount) { 1195ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block ALOGE("Missing Argument"); 120fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt errno = EINVAL; 121fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return -1; 122fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 123fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 124fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt tableNumber = secondaryTableCtrl->findTableNumber(extIface); 125fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (tableNumber != -1) { 126fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt for(i = 0; i < addrCount && ret == 0; i++) { 127063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt snprintf(cmd, sizeof(cmd), "%s rule add from %s table %d", getVersion(argv[5+i]), 128063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt argv[5+i], tableNumber + BASE_TABLE_NUMBER); 129fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt ret |= runCmd(IP_PATH, cmd); 1305ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block if (ret) ALOGE("IP rule %s got %d", cmd, ret); 131fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 132fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt snprintf(cmd, sizeof(cmd), "route add %s dev %s table %d", argv[5+i], intIface, 133fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt tableNumber + BASE_TABLE_NUMBER); 134fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt ret |= runCmd(IP_PATH, cmd); 1355ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block if (ret) ALOGE("IP route %s got %d", cmd, ret); 136210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt } 137063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt runCmd(IP_PATH, "route flush cache"); 138210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt } 139210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt 140fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (ret != 0 || setForwardRules(true, intIface, extIface) != 0) { 141fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (tableNumber != -1) { 142fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt for (i = 0; i < addrCount; i++) { 143fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt snprintf(cmd, sizeof(cmd), "route del %s dev %s table %d", argv[5+i], intIface, 144fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt tableNumber + BASE_TABLE_NUMBER); 145fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt runCmd(IP_PATH, cmd); 146fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 147063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt snprintf(cmd, sizeof(cmd), "%s rule del from %s table %d", getVersion(argv[5+i]), 148063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt argv[5+i], tableNumber + BASE_TABLE_NUMBER); 149fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt runCmd(IP_PATH, cmd); 150fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 151063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt runCmd(IP_PATH, "route flush cache"); 152fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 1535ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block ALOGE("Error setting forward rules"); 1549ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat errno = ENODEV; 1559ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 1569ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 1579ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 158fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt natCount++; 159fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt // add this if we are the first added nat 160fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (natCount == 1) { 161fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt snprintf(cmd, sizeof(cmd), "-t nat -A POSTROUTING -o %s -j MASQUERADE", extIface); 162fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (runCmd(IPTABLES_PATH, cmd)) { 1635ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block ALOGE("Error seting postroute rule: %s", cmd); 164fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt // unwind what's been done, but don't care about success - what more could we do? 165fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt for (i = 0; i < addrCount; i++) { 166fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt snprintf(cmd, sizeof(cmd), "route del %s dev %s table %d", argv[5+i], intIface, 167fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt tableNumber + BASE_TABLE_NUMBER); 168fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt runCmd(IP_PATH, cmd); 169fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 170fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt setDefaults(); 171fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return -1; 172fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 173fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 174fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 175fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return 0; 176fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt} 177fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 178fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwaltint NatController::setForwardRules(bool add, const char *intIface, const char * extIface) { 179fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt char cmd[255]; 180fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 1819ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat snprintf(cmd, sizeof(cmd), 1821caafe66a6b927fa5d8eb4c59ec9eb48b0b1b075Robert Greenwalt "-%s FORWARD -i %s -o %s -m state --state ESTABLISHED,RELATED -j ACCEPT", 1831caafe66a6b927fa5d8eb4c59ec9eb48b0b1b075Robert Greenwalt (add ? "A" : "D"), 1849ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat extIface, intIface); 185fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (runCmd(IPTABLES_PATH, cmd) && add) { 1869ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 1879ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 1889ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 189ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt snprintf(cmd, sizeof(cmd), 190ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt "-%s FORWARD -i %s -o %s -m state --state INVALID -j DROP", 191ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt (add ? "A" : "D"), 192ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt intIface, extIface); 193fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (runCmd(IPTABLES_PATH, cmd) && add) { 194f7bf29c8a37d65e132a4dceb7c5a4200ed5c3d79Robert Greenwalt // bail on error, but only if adding 195ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt snprintf(cmd, sizeof(cmd), 196ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt "-%s FORWARD -i %s -o %s -m state --state ESTABLISHED,RELATED -j ACCEPT", 197ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt (!add ? "A" : "D"), 198ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt extIface, intIface); 199fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt runCmd(IPTABLES_PATH, cmd); 200ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt return -1; 201ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt } 202ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt 2031caafe66a6b927fa5d8eb4c59ec9eb48b0b1b075Robert Greenwalt snprintf(cmd, sizeof(cmd), "-%s FORWARD -i %s -o %s -j ACCEPT", (add ? "A" : "D"), 2041caafe66a6b927fa5d8eb4c59ec9eb48b0b1b075Robert Greenwalt intIface, extIface); 205fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (runCmd(IPTABLES_PATH, cmd) && add) { 206210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt // unwind what's been done, but don't care about success - what more could we do? 207210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt snprintf(cmd, sizeof(cmd), 208ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt "-%s FORWARD -i %s -o %s -m state --state INVALID -j DROP", 209ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt (!add ? "A" : "D"), 210ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt intIface, extIface); 211fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt runCmd(IPTABLES_PATH, cmd); 212ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt 213ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt snprintf(cmd, sizeof(cmd), 214210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt "-%s FORWARD -i %s -o %s -m state --state ESTABLISHED,RELATED -j ACCEPT", 215210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt (!add ? "A" : "D"), 216210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt extIface, intIface); 217fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt runCmd(IPTABLES_PATH, cmd); 2189ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 2199ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 220fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return 0; 221fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt} 2229ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 223fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt// nat disable intface extface 224fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt// 0 1 2 3 4 5 225fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt// nat enable intface extface addrcnt nated-ipaddr/prelength 226fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwaltint NatController::disableNat(const int argc, char **argv) { 227fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt char cmd[255]; 228fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt int i; 229fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt int addrCount = atoi(argv[4]); 230fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt const char *intIface = argv[2]; 231fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt const char *extIface = argv[3]; 232fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt int tableNumber; 233fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 234fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (!checkInterface(intIface) || !checkInterface(extIface)) { 2355ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block ALOGE("Invalid interface specified"); 236fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt errno = ENODEV; 237fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return -1; 2389ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 2399ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 240fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (argc < 5 + addrCount) { 2415ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block ALOGE("Missing Argument"); 242fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt errno = EINVAL; 243fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return -1; 244210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt } 2459ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 246fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt setForwardRules(false, intIface, extIface); 2471caafe66a6b927fa5d8eb4c59ec9eb48b0b1b075Robert Greenwalt 248fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt tableNumber = secondaryTableCtrl->findTableNumber(extIface); 249fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (tableNumber != -1) { 250fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt for (i = 0; i < addrCount; i++) { 251fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt snprintf(cmd, sizeof(cmd), "route del %s dev %s table %d", argv[5+i], intIface, 252fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt tableNumber + BASE_TABLE_NUMBER); 253fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt // if the interface has gone down these will be gone already and give errors 254fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt // ignore them. 255fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt runCmd(IP_PATH, cmd); 256063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt 257063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt snprintf(cmd, sizeof(cmd), "%s rule del from %s table %d", getVersion(argv[5+i]), 258063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt argv[5+i], tableNumber + BASE_TABLE_NUMBER); 259063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt runCmd(IP_PATH, cmd); 260fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 261063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt 262063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt runCmd(IP_PATH, "route flush cache"); 263fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 264fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 265fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (--natCount <= 0) { 266fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt char bootmode[PROPERTY_VALUE_MAX] = {0}; 267fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt property_get("ro.bootmode", bootmode, "unknown"); 268fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (0 != strcmp("bp-tools", bootmode)) { 269fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt // handle decrement to 0 case (do reset to defaults) and erroneous dec below 0 270fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt setDefaults(); 271fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 272fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt natCount = 0; 273fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 274fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return 0; 2759ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 276