From 4ab468577647d1ee73810b89d2287eaa5546fecb Mon Sep 17 00:00:00 2001 From: Kazuhiro Ondo Date: Thu, 12 Jan 2012 16:15:06 -0600 Subject: [PATCH] Add back hook for inserting OEM specific iptables rules. The functionality was lost during merge in ICS branch. This patch is adding back OEM iptables hook in netd. Bug:5862460 Change-Id: I9444b8c53e8b84fea2002c2c1d9ba42e45ae5f0c --- Android.mk | 1 + BandwidthController.cpp | 4 ++ NatController.cpp | 12 +++-- oem_iptables_hook.cpp | 114 ++++++++++++++++++++++++++++++++++++++++++++++++ oem_iptables_hook.h | 22 ++++++++++ 5 files changed, 146 insertions(+), 7 deletions(-) create mode 100644 oem_iptables_hook.cpp create mode 100644 oem_iptables_hook.h diff --git a/Android.mk b/Android.mk index dbf9b7d..c20898b 100644 --- a/Android.mk +++ b/Android.mk @@ -17,6 +17,7 @@ LOCAL_SRC_FILES:= \ SoftapController.cpp \ TetherController.cpp \ ThrottleController.cpp \ + oem_iptables_hook.cpp \ logwrapper.c \ main.cpp \ diff --git a/BandwidthController.cpp b/BandwidthController.cpp index be3cb28..4c15394 100644 --- a/BandwidthController.cpp +++ b/BandwidthController.cpp @@ -45,6 +45,7 @@ extern "C" int logwrap(int argc, const char **argv, int background); extern "C" int system_nosh(const char *command); #include "BandwidthController.h" +#include "oem_iptables_hook.h" /* Alphabetical */ const char BandwidthController::ALERT_IPT_TEMPLATE[] = "%s %s %s -m quota2 ! --quota %lld --name %s"; @@ -231,6 +232,8 @@ int BandwidthController::enableBandwidthControl(void) { res = runCommands(sizeof(IPT_BASIC_ACCOUNTING_COMMANDS) / sizeof(char*), IPT_BASIC_ACCOUNTING_COMMANDS, RunCmdFailureBad); + setupOemIptablesHook(); + return res; } @@ -239,6 +242,7 @@ int BandwidthController::disableBandwidthControl(void) { /* The IPT_CLEANUP_COMMANDS are allowed to fail. */ runCommands(sizeof(IPT_CLEANUP_COMMANDS) / sizeof(char*), IPT_CLEANUP_COMMANDS, RunCmdFailureOk); + setupOemIptablesHook(); return 0; } diff --git a/NatController.cpp b/NatController.cpp index ed1b095..7f1bc60 100644 --- a/NatController.cpp +++ b/NatController.cpp @@ -29,6 +29,7 @@ #include "NatController.h" #include "SecondaryTableController.h" +#include "oem_iptables_hook.h" extern "C" int system_nosh(const char *command); @@ -82,6 +83,8 @@ int NatController::setDefaults() { runCmd(IP_PATH, "route flush cache"); natCount = 0; + + setupOemIptablesHook(); return 0; } @@ -263,13 +266,8 @@ int NatController::disableNat(const int argc, char **argv) { } if (--natCount <= 0) { - char bootmode[PROPERTY_VALUE_MAX] = {0}; - property_get("ro.bootmode", bootmode, "unknown"); - if (0 != strcmp("bp-tools", bootmode)) { - // handle decrement to 0 case (do reset to defaults) and erroneous dec below 0 - setDefaults(); - } - natCount = 0; + // handle decrement to 0 case (do reset to defaults) and erroneous dec below 0 + setDefaults(); } return 0; } diff --git a/oem_iptables_hook.cpp b/oem_iptables_hook.cpp new file mode 100644 index 0000000..e50ea6a --- /dev/null +++ b/oem_iptables_hook.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define LOG_TAG "OemIptablesHook" +#include + +extern "C" int system_nosh(const char *command); + +static char IPTABLES_PATH[] = "/system/bin/iptables"; +static char OEM_SCRIPT_PATH[] = "/system/bin/oem-iptables-init.sh"; + +static int runIptablesCmd(const char *cmd) { + char *buffer; + size_t len = strnlen(cmd, 255); + int res; + + if (len == 255) { + LOGE("command too long"); + return -1; + } + + asprintf(&buffer, "%s %s", IPTABLES_PATH, cmd); + res = system_nosh(buffer); + free(buffer); + return res; +} + +static bool oemSetupHooks() { + // Order is important! + // -N to create the chain (no-op if already exist). + // -D to delete any pre-existing jump rule, to prevent dupes (no-op if doesn't exist) + // -I to insert our jump rule into the default chain + + runIptablesCmd("-N oem_out"); + runIptablesCmd("-D OUTPUT -j oem_out"); + if (runIptablesCmd("-I OUTPUT -j oem_out")) + return false; + + runIptablesCmd("-N oem_fwd"); + runIptablesCmd("-D FORWARD -j oem_fwd"); + if (runIptablesCmd("-I FORWARD -j oem_fwd")) + return false; + + runIptablesCmd("-t nat -N oem_nat_pre"); + runIptablesCmd("-t nat -D PREROUTING -j oem_nat_pre"); + if (runIptablesCmd("-t nat -I PREROUTING -j oem_nat_pre")) + return false; + + return true; +} + +static bool oemCleanupHooks() { + // Order is important! + // -D to remove ref to the chain + // -F to empty the chain + // -X to delete the chain + + runIptablesCmd("-D OUTPUT -j oem_out"); + runIptablesCmd("-F oem_out"); + runIptablesCmd("-X oem_out"); + + runIptablesCmd("-D FORWARD -j oem_fwd"); + runIptablesCmd("-F oem_fwd"); + runIptablesCmd("-X oem_fwd"); + + runIptablesCmd("-t nat -D PREROUTING -j oem_nat_pre"); + runIptablesCmd("-t nat -F oem_nat_pre"); + runIptablesCmd("-t nat -X oem_nat_pre"); + + return true; +} + +static bool oemInitChains() { + int ret = system(OEM_SCRIPT_PATH); + if ((-1 == ret) || (0 != WEXITSTATUS(ret))) { + LOGE("%s failed: %s", OEM_SCRIPT_PATH, strerror(errno)); + oemCleanupHooks(); + return false; + } + return true; +} + + +void setupOemIptablesHook() { + if (0 == access(OEM_SCRIPT_PATH, R_OK | X_OK)) { + // The call to oemCleanupHooks() is superfluous when done on bootup, + // but is needed for the case where netd has crashed/stopped and is + // restarted. + if (oemCleanupHooks() && oemSetupHooks() && oemInitChains()) { + LOGI("OEM iptable hook installed."); + } + } +} diff --git a/oem_iptables_hook.h b/oem_iptables_hook.h new file mode 100644 index 0000000..f5696ba --- /dev/null +++ b/oem_iptables_hook.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _OEM_IPTABLES_HOOK_H +#define _OEM_IPTABLES_HOOK_H + +void setupOemIptablesHook(); + +#endif -- 2.11.0