NatController.cpp revision 6e4d5db1b11f808bb4bdcc8dd45a7158c6c88515
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> 184309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville#include <sys/wait.h> 199ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <errno.h> 209ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <sys/socket.h> 219ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <sys/stat.h> 229ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <fcntl.h> 239ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <netinet/in.h> 249ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <arpa/inet.h> 259ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 269ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#define LOG_TAG "NatController" 279ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <cutils/log.h> 289ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 299ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include "NatController.h" 309ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 319ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehatextern "C" int logwrap(int argc, const char **argv, int background); 329ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 339ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehatstatic char IPTABLES_PATH[] = "/system/bin/iptables"; 344309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Savillestatic char OEM_SCRIPT_PATH[] = "/system/bin/oem-iptables-init.sh"; 359ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 364309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink SavilleNatController::NatController() : mOemChainsExist(false) { 371caafe66a6b927fa5d8eb4c59ec9eb48b0b1b075Robert Greenwalt natCount = 0; 384309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville 394309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville setDefaults(); 404309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville 414309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville if (0 == access(OEM_SCRIPT_PATH, R_OK | X_OK)) { 424309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville // The call to oemCleanupHooks() is superfluous when done on bootup, 434309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville // but is needed for the case where netd has crashed/stopped and is 444309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville // restarted. 454309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville if (!oemCleanupHooks() && !oemSetupHooks() && !oemInitChains()) { 464309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville mOemChainsExist = true; 474309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville } 484309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville } 499ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 509ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 519ff78fb7da7158f5bd7c86d89a842691820259cfSan MehatNatController::~NatController() { 529ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 539ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 549ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehatint NatController::runIptablesCmd(const char *cmd) { 559ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat char buffer[255]; 569ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 579ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat strncpy(buffer, cmd, sizeof(buffer)-1); 589ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 599ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat const char *args[16]; 609ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat char *next = buffer; 619ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat char *tmp; 629ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 639ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat args[0] = IPTABLES_PATH; 649ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat args[1] = "--verbose"; 659ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat int i = 2; 669ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 679ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat while ((tmp = strsep(&next, " "))) { 689ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat args[i++] = tmp; 699ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat if (i == 16) { 709ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat LOGE("iptables argument overflow"); 719ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat errno = E2BIG; 729ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 739ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 749ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 759ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat args[i] = NULL; 769ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 779ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return logwrap(i, args, 0); 789ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 799ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 809ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehatint NatController::setDefaults() { 819ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 829ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat if (runIptablesCmd("-P INPUT ACCEPT")) 839ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 849ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat if (runIptablesCmd("-P OUTPUT ACCEPT")) 859ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 869ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat if (runIptablesCmd("-P FORWARD DROP")) 879ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 889ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat if (runIptablesCmd("-F FORWARD")) 899ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 904309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville 914309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville if (runIptablesCmd("-t nat -F PREROUTING")) 924309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville return -1; 934309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville if (runIptablesCmd("-t nat -F OUTPUT")) 949ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 954309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville if (runIptablesCmd("-t nat -F POSTROUTING")) 964309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville return -1; 974309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville 984309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville return 0; 994309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville} 1004309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville 1014309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Savilleint NatController::oemSetupHooks() { 1024309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville // Order is important! 1034309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville // -N to create the chain (no-op if already exist). 1044309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville // -D to delete any pre-existing jump rule, to prevent dupes (no-op if doesn't exist) 1054309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville // -I to insert our jump rule into the default chain 1064309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville 1074309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville runIptablesCmd("-N oem_out"); 1084309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville runIptablesCmd("-D OUTPUT -j oem_out"); 1094309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville if (runIptablesCmd("-I OUTPUT -j oem_out")) 1104309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville return -1; 1114309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville 1124309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville runIptablesCmd("-N oem_fwd"); 1134309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville runIptablesCmd("-D FORWARD -j oem_fwd"); 1144309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville if (runIptablesCmd("-I FORWARD -j oem_fwd")) 1154309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville return -1; 1164309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville 1174309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville runIptablesCmd("-t nat -N oem_nat_pre"); 1184309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville runIptablesCmd("-t nat -D PREROUTING -j oem_nat_pre"); 1194309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville if (runIptablesCmd("-t nat -I PREROUTING -j oem_nat_pre")) 1204309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville return -1; 1214309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville 1224309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville return 0; 1234309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville} 1244309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville 1254309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Savilleint NatController::oemCleanupHooks() { 1264309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville // Order is important! 1274309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville // -D to remove ref to the chain 1284309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville // -F to empty the chain 1294309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville // -X to delete the chain 1304309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville 1314309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville runIptablesCmd("-D OUTPUT -j oem_out"); 1324309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville runIptablesCmd("-F oem_out"); 1334309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville runIptablesCmd("-X oem_out"); 1344309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville 1354309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville runIptablesCmd("-D FORWARD -j oem_fwd"); 1364309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville runIptablesCmd("-F oem_fwd"); 1374309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville runIptablesCmd("-X oem_fwd"); 1384309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville 1394309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville runIptablesCmd("-t nat -D PREROUTING -j oem_nat_pre"); 1404309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville runIptablesCmd("-t nat -F oem_nat_pre"); 1414309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville runIptablesCmd("-t nat -X oem_nat_pre"); 1424309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville 1434309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville return 0; 1444309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville} 1454309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville 1464309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville// This method should only be called when netd starts up. The OEM chains are 1474309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville// intended to be static, so there's no need to flush and recreate them every 1484309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville// time setDefaults() is called. 1494309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Savilleint NatController::oemInitChains() { 1504309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville int ret = system(OEM_SCRIPT_PATH); 1514309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville if ((-1 == ret) || (0 != WEXITSTATUS(ret))) { 1524309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville LOGE("%s failed: %s", OEM_SCRIPT_PATH, strerror(errno)); 1534309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville return -1; 1544309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville } 1559ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return 0; 1569ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 1579ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 1589ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehatbool NatController::interfaceExists(const char *iface) { 159b5ff9b277f256df84caf3d798ccc83b4740a1d31Paul Eastham // XXX: Implement this 1609ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return true; 1619ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 1629ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 1631caafe66a6b927fa5d8eb4c59ec9eb48b0b1b075Robert Greenwaltint NatController::doNatCommands(const char *intIface, const char *extIface, bool add) { 1649ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat char cmd[255]; 1659ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 1664309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville // handle decrement to 0 case (do reset to defaults) and erroneous dec below 0 1674309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville if (add == false) { 1684309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville if (natCount <= 1) { 1694309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville int ret = setDefaults(); 1704309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville if (ret == 0) { 1714309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville natCount=0; 172210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt } 1734309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville if (mOemChainsExist) 1744309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville oemSetupHooks(); 1754309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville return ret; 176210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt } 177210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt } 178210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt 1799ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat if (!interfaceExists(intIface) || !interfaceExists (extIface)) { 1809ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat LOGE("Invalid interface specified"); 1819ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat errno = ENODEV; 1829ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 1839ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 1849ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 1859ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat snprintf(cmd, sizeof(cmd), 1861caafe66a6b927fa5d8eb4c59ec9eb48b0b1b075Robert Greenwalt "-%s FORWARD -i %s -o %s -m state --state ESTABLISHED,RELATED -j ACCEPT", 1871caafe66a6b927fa5d8eb4c59ec9eb48b0b1b075Robert Greenwalt (add ? "A" : "D"), 1889ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat extIface, intIface); 1899ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat if (runIptablesCmd(cmd)) { 1909ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 1919ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 1929ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 193ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt snprintf(cmd, sizeof(cmd), 194ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt "-%s FORWARD -i %s -o %s -m state --state INVALID -j DROP", 195ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt (add ? "A" : "D"), 196ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt intIface, extIface); 197ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt if (runIptablesCmd(cmd)) { 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); 2026e4d5db1b11f808bb4bdcc8dd45a7158c6c88515Robert Greenwalt runIptablesCmd(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); 2089ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat if (runIptablesCmd(cmd)) { 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); 214ddb9f6eb8d8c35f46c1e3da68f375b85903e85c9Robert Greenwalt runIptablesCmd(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); 2206e4d5db1b11f808bb4bdcc8dd45a7158c6c88515Robert Greenwalt runIptablesCmd(cmd); 2219ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 2229ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 2239ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 224210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt // add this if we are the first added nat 2251caafe66a6b927fa5d8eb4c59ec9eb48b0b1b075Robert Greenwalt if (add && natCount == 0) { 2261caafe66a6b927fa5d8eb4c59ec9eb48b0b1b075Robert Greenwalt snprintf(cmd, sizeof(cmd), "-t nat -A POSTROUTING -o %s -j MASQUERADE", extIface); 2271caafe66a6b927fa5d8eb4c59ec9eb48b0b1b075Robert Greenwalt if (runIptablesCmd(cmd)) { 2284309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville // unwind what's been done, but don't care about success - what more could we do? 2294309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville setDefaults();; 2304309f87d5baa54a2741f35e0cb09959c55ff1ab6Wink Saville oemSetupHooks(); 2311caafe66a6b927fa5d8eb4c59ec9eb48b0b1b075Robert Greenwalt return -1; 2321caafe66a6b927fa5d8eb4c59ec9eb48b0b1b075Robert Greenwalt } 2339ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 2349ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 235210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt if (add) { 236210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt natCount++; 237210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt } else { 238210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt natCount--; 239210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt } 2409ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return 0; 2419ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 2429ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 2431caafe66a6b927fa5d8eb4c59ec9eb48b0b1b075Robert Greenwaltint NatController::enableNat(const char *intIface, const char *extIface) { 2441caafe66a6b927fa5d8eb4c59ec9eb48b0b1b075Robert Greenwalt return doNatCommands(intIface, extIface, true); 2451caafe66a6b927fa5d8eb4c59ec9eb48b0b1b075Robert Greenwalt} 2461caafe66a6b927fa5d8eb4c59ec9eb48b0b1b075Robert Greenwalt 2479ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehatint NatController::disableNat(const char *intIface, const char *extIface) { 248210b97745e14830cdb1f29ee1109e6e516f4e6f6Robert Greenwalt return doNatCommands(intIface, extIface, false); 2499ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 250