NatController.cpp revision 4ab468577647d1ee73810b89d2287eaa5546fecb
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" 324ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo#include "oem_iptables_hook.h" 339ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 349e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrallextern "C" int system_nosh(const char *command); 359ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 369ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehatstatic char IPTABLES_PATH[] = "/system/bin/iptables"; 37fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwaltstatic char IP_PATH[] = "/system/bin/ip"; 389ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 39fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert GreenwaltNatController::NatController(SecondaryTableController *ctrl) { 40fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt secondaryTableCtrl = ctrl; 41fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt setDefaults(); 429ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 439ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 449ff78fb7da7158f5bd7c86d89a842691820259cfSan MehatNatController::~NatController() { 459ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 469ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 47fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwaltint NatController::runCmd(const char *path, const char *cmd) { 4811b4e9b26fe7b878992162afb39f5a8acfd143edJP Abgrall char *buffer; 4911b4e9b26fe7b878992162afb39f5a8acfd143edJP Abgrall size_t len = strnlen(cmd, 255); 5011b4e9b26fe7b878992162afb39f5a8acfd143edJP Abgrall int res; 519ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 5211b4e9b26fe7b878992162afb39f5a8acfd143edJP Abgrall if (len == 255) { 53fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt LOGE("command too long"); 5411b4e9b26fe7b878992162afb39f5a8acfd143edJP Abgrall errno = E2BIG; 5511b4e9b26fe7b878992162afb39f5a8acfd143edJP Abgrall return -1; 569ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 579ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 58fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt asprintf(&buffer, "%s %s", path, cmd); 599e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall res = system_nosh(buffer); 6011b4e9b26fe7b878992162afb39f5a8acfd143edJP Abgrall free(buffer); 6111b4e9b26fe7b878992162afb39f5a8acfd143edJP Abgrall return res; 629ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 639ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 649ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehatint NatController::setDefaults() { 659ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 66fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (runCmd(IPTABLES_PATH, "-P INPUT ACCEPT")) 679ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 68fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (runCmd(IPTABLES_PATH, "-P OUTPUT ACCEPT")) 699ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 70fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (runCmd(IPTABLES_PATH, "-P FORWARD DROP")) 719ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 72fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (runCmd(IPTABLES_PATH, "-F FORWARD")) 739ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 74fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (runCmd(IPTABLES_PATH, "-t nat -F")) 759ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 76fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 77fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt runCmd(IP_PATH, "rule flush"); 78063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt runCmd(IP_PATH, "-6 rule flush"); 79fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt runCmd(IP_PATH, "rule add from all lookup default prio 32767"); 80fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt runCmd(IP_PATH, "rule add from all lookup main prio 32766"); 81063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt runCmd(IP_PATH, "-6 rule add from all lookup default prio 32767"); 82063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt runCmd(IP_PATH, "-6 rule add from all lookup main prio 32766"); 83063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt runCmd(IP_PATH, "route flush cache"); 84fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 85fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt natCount = 0; 864ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo 874ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo setupOemIptablesHook(); 889ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return 0; 899ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 909ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 91fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwaltbool NatController::checkInterface(const char *iface) { 92fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (strlen(iface) > MAX_IFACE_LENGTH) return false; 939ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return true; 949ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 959ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 96063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwaltconst char *NatController::getVersion(const char *addr) { 97063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt if (strchr(addr, ':') != NULL) { 98063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt return "-6"; 99063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt } else { 100063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt return "-4"; 101063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt } 102063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt} 103063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt 104fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt// 0 1 2 3 4 5 105fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt// nat enable intface extface addrcnt nated-ipaddr/prelength 106fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwaltint NatController::enableNat(const int argc, char **argv) { 1079ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat char cmd[255]; 108fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt int i; 109fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt int addrCount = atoi(argv[4]); 110fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt int ret = 0; 111fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt const char *intIface = argv[2]; 112fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt const char *extIface = argv[3]; 113fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt int tableNumber; 114fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 115fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (!checkInterface(intIface) || !checkInterface(extIface)) { 116fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt LOGE("Invalid interface specified"); 117fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt errno = ENODEV; 118fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return -1; 119fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 1209ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 121fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (argc < 5 + addrCount) { 122fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt LOGE("Missing Argument"); 123fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt errno = EINVAL; 124fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return -1; 125fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 126fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 127fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt tableNumber = secondaryTableCtrl->findTableNumber(extIface); 128fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (tableNumber != -1) { 129fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt for(i = 0; i < addrCount && ret == 0; i++) { 130063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt snprintf(cmd, sizeof(cmd), "%s rule add from %s table %d", getVersion(argv[5+i]), 131063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt argv[5+i], tableNumber + BASE_TABLE_NUMBER); 132fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt ret |= runCmd(IP_PATH, cmd); 133fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (ret) LOGE("IP rule %s got %d", cmd, ret); 134fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 135fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt snprintf(cmd, sizeof(cmd), "route add %s dev %s table %d", argv[5+i], intIface, 136fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt tableNumber + BASE_TABLE_NUMBER); 137fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt ret |= runCmd(IP_PATH, cmd); 138fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (ret) LOGE("IP route %s got %d", cmd, ret); 139210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt } 140063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt runCmd(IP_PATH, "route flush cache"); 141210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt } 142210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt 143fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (ret != 0 || setForwardRules(true, intIface, extIface) != 0) { 144fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (tableNumber != -1) { 145fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt for (i = 0; i < addrCount; i++) { 146fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt snprintf(cmd, sizeof(cmd), "route del %s dev %s table %d", argv[5+i], intIface, 147fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt tableNumber + BASE_TABLE_NUMBER); 148fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt runCmd(IP_PATH, cmd); 149fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 150063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt snprintf(cmd, sizeof(cmd), "%s rule del from %s table %d", getVersion(argv[5+i]), 151063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt argv[5+i], tableNumber + BASE_TABLE_NUMBER); 152fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt runCmd(IP_PATH, cmd); 153fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 154063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt runCmd(IP_PATH, "route flush cache"); 155fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 156fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt LOGE("Error setting forward rules"); 1579ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat errno = ENODEV; 1589ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 1599ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 1609ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 161fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt natCount++; 162fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt // add this if we are the first added nat 163fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (natCount == 1) { 164fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt snprintf(cmd, sizeof(cmd), "-t nat -A POSTROUTING -o %s -j MASQUERADE", extIface); 165fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (runCmd(IPTABLES_PATH, cmd)) { 166fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt LOGE("Error seting postroute rule: %s", cmd); 167fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt // unwind what's been done, but don't care about success - what more could we do? 168fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt for (i = 0; i < addrCount; i++) { 169fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt snprintf(cmd, sizeof(cmd), "route del %s dev %s table %d", argv[5+i], intIface, 170fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt tableNumber + BASE_TABLE_NUMBER); 171fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt runCmd(IP_PATH, cmd); 172fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 173fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt setDefaults(); 174fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return -1; 175fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 176fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 177fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 178fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return 0; 179fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt} 180fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 181fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwaltint NatController::setForwardRules(bool add, const char *intIface, const char * extIface) { 182fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt char cmd[255]; 183fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 1849ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat snprintf(cmd, sizeof(cmd), 1851caafe66a6b927fa5d8eb4c59ec9eb48b0b1b075Robert Greenwalt "-%s FORWARD -i %s -o %s -m state --state ESTABLISHED,RELATED -j ACCEPT", 1861caafe66a6b927fa5d8eb4c59ec9eb48b0b1b075Robert Greenwalt (add ? "A" : "D"), 1879ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat extIface, intIface); 188fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (runCmd(IPTABLES_PATH, cmd) && add) { 1899ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 1909ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 1919ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 192ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt snprintf(cmd, sizeof(cmd), 193ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt "-%s FORWARD -i %s -o %s -m state --state INVALID -j DROP", 194ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt (add ? "A" : "D"), 195ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt intIface, extIface); 196fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (runCmd(IPTABLES_PATH, cmd) && add) { 197f7bf29c8a37d65e132a4dceb7c5a4200ed5c3d79Robert Greenwalt // bail on error, but only if adding 198ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt snprintf(cmd, sizeof(cmd), 199ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt "-%s FORWARD -i %s -o %s -m state --state ESTABLISHED,RELATED -j ACCEPT", 200ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt (!add ? "A" : "D"), 201ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt extIface, intIface); 202fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt runCmd(IPTABLES_PATH, cmd); 203ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt return -1; 204ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt } 205ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt 2061caafe66a6b927fa5d8eb4c59ec9eb48b0b1b075Robert Greenwalt snprintf(cmd, sizeof(cmd), "-%s FORWARD -i %s -o %s -j ACCEPT", (add ? "A" : "D"), 2071caafe66a6b927fa5d8eb4c59ec9eb48b0b1b075Robert Greenwalt intIface, extIface); 208fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (runCmd(IPTABLES_PATH, cmd) && add) { 209210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt // unwind what's been done, but don't care about success - what more could we do? 210210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt snprintf(cmd, sizeof(cmd), 211ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt "-%s FORWARD -i %s -o %s -m state --state INVALID -j DROP", 212ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt (!add ? "A" : "D"), 213ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt intIface, extIface); 214fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt runCmd(IPTABLES_PATH, cmd); 215ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt 216ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt snprintf(cmd, sizeof(cmd), 217210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt "-%s FORWARD -i %s -o %s -m state --state ESTABLISHED,RELATED -j ACCEPT", 218210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt (!add ? "A" : "D"), 219210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt extIface, intIface); 220fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt runCmd(IPTABLES_PATH, cmd); 2219ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 2229ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 223fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return 0; 224fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt} 2259ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 226fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt// nat disable intface extface 227fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt// 0 1 2 3 4 5 228fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt// nat enable intface extface addrcnt nated-ipaddr/prelength 229fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwaltint NatController::disableNat(const int argc, char **argv) { 230fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt char cmd[255]; 231fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt int i; 232fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt int addrCount = atoi(argv[4]); 233fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt const char *intIface = argv[2]; 234fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt const char *extIface = argv[3]; 235fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt int tableNumber; 236fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 237fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (!checkInterface(intIface) || !checkInterface(extIface)) { 238fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt LOGE("Invalid interface specified"); 239fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt errno = ENODEV; 240fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return -1; 2419ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 2429ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 243fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (argc < 5 + addrCount) { 244fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt LOGE("Missing Argument"); 245fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt errno = EINVAL; 246fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return -1; 247210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt } 2489ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 249fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt setForwardRules(false, intIface, extIface); 2501caafe66a6b927fa5d8eb4c59ec9eb48b0b1b075Robert Greenwalt 251fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt tableNumber = secondaryTableCtrl->findTableNumber(extIface); 252fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (tableNumber != -1) { 253fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt for (i = 0; i < addrCount; i++) { 254fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt snprintf(cmd, sizeof(cmd), "route del %s dev %s table %d", argv[5+i], intIface, 255fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt tableNumber + BASE_TABLE_NUMBER); 256fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt // if the interface has gone down these will be gone already and give errors 257fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt // ignore them. 258fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt runCmd(IP_PATH, cmd); 259063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt 260063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt snprintf(cmd, sizeof(cmd), "%s rule del from %s table %d", getVersion(argv[5+i]), 261063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt argv[5+i], tableNumber + BASE_TABLE_NUMBER); 262063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt runCmd(IP_PATH, cmd); 263fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 264063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt 265063af322b48ab1bb0c3e09eb0b64915ba568275bRobert Greenwalt runCmd(IP_PATH, "route flush cache"); 266fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 267fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt 268fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt if (--natCount <= 0) { 2694ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo // handle decrement to 0 case (do reset to defaults) and erroneous dec below 0 2704ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo setDefaults(); 271fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt } 272fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt return 0; 2739ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 274