oem_iptables_hook.cpp revision c462177bd58e3bf0ac4f618934dae060569e3e0b
14ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo/* 24ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo * Copyright (C) 2012 The Android Open Source Project 34ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo * 44ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo * Licensed under the Apache License, Version 2.0 (the "License"); 54ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo * you may not use this file except in compliance with the License. 64ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo * You may obtain a copy of the License at 74ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo * 84ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo * http://www.apache.org/licenses/LICENSE-2.0 94ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo * 104ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo * Unless required by applicable law or agreed to in writing, software 114ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo * distributed under the License is distributed on an "AS IS" BASIS, 124ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo * See the License for the specific language governing permissions and 144ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo * limitations under the License. 154ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo */ 164ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo 174ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo#include <stdio.h> 184ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo#include <stdlib.h> 194ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo#include <sys/types.h> 204ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo#include <sys/wait.h> 214ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo#include <errno.h> 224ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo#include <string.h> 234ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo#include <unistd.h> 244ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo 254ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo#define LOG_TAG "OemIptablesHook" 264ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo#include <cutils/log.h> 27c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt#include "NetdConstants.h" 284ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo 294ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondoextern "C" int system_nosh(const char *command); 304ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo 314ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo 324ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondostatic int runIptablesCmd(const char *cmd) { 334ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo char *buffer; 344ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo size_t len = strnlen(cmd, 255); 354ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo int res; 364ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo 374ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo if (len == 255) { 387c73e8951d91b5afe9d52f88d7ed3a09d120a725JP Abgrall ALOGE("command too long"); 394ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo return -1; 404ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo } 414ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo 424ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo asprintf(&buffer, "%s %s", IPTABLES_PATH, cmd); 434ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo res = system_nosh(buffer); 444ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo free(buffer); 454ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo return res; 464ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo} 474ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo 484ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondostatic bool oemSetupHooks() { 494ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo // Order is important! 504ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo // -N to create the chain (no-op if already exist). 514ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo // -D to delete any pre-existing jump rule, to prevent dupes (no-op if doesn't exist) 524ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo // -I to insert our jump rule into the default chain 534ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo 544ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo runIptablesCmd("-N oem_out"); 554ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo runIptablesCmd("-D OUTPUT -j oem_out"); 564ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo if (runIptablesCmd("-I OUTPUT -j oem_out")) 574ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo return false; 584ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo 594ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo runIptablesCmd("-N oem_fwd"); 604ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo runIptablesCmd("-D FORWARD -j oem_fwd"); 614ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo if (runIptablesCmd("-I FORWARD -j oem_fwd")) 624ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo return false; 634ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo 644ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo runIptablesCmd("-t nat -N oem_nat_pre"); 654ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo runIptablesCmd("-t nat -D PREROUTING -j oem_nat_pre"); 664ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo if (runIptablesCmd("-t nat -I PREROUTING -j oem_nat_pre")) 674ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo return false; 684ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo 694ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo return true; 704ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo} 714ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo 724ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondostatic bool oemCleanupHooks() { 734ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo // Order is important! 744ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo // -D to remove ref to the chain 754ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo // -F to empty the chain 764ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo // -X to delete the chain 774ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo 784ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo runIptablesCmd("-D OUTPUT -j oem_out"); 794ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo runIptablesCmd("-F oem_out"); 804ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo runIptablesCmd("-X oem_out"); 814ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo 824ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo runIptablesCmd("-D FORWARD -j oem_fwd"); 834ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo runIptablesCmd("-F oem_fwd"); 844ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo runIptablesCmd("-X oem_fwd"); 854ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo 864ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo runIptablesCmd("-t nat -D PREROUTING -j oem_nat_pre"); 874ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo runIptablesCmd("-t nat -F oem_nat_pre"); 884ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo runIptablesCmd("-t nat -X oem_nat_pre"); 894ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo 904ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo return true; 914ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo} 924ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo 934ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondostatic bool oemInitChains() { 944ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo int ret = system(OEM_SCRIPT_PATH); 954ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo if ((-1 == ret) || (0 != WEXITSTATUS(ret))) { 967c73e8951d91b5afe9d52f88d7ed3a09d120a725JP Abgrall ALOGE("%s failed: %s", OEM_SCRIPT_PATH, strerror(errno)); 974ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo oemCleanupHooks(); 984ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo return false; 994ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo } 1004ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo return true; 1014ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo} 1024ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo 1034ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo 1044ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondovoid setupOemIptablesHook() { 1054ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo if (0 == access(OEM_SCRIPT_PATH, R_OK | X_OK)) { 1064ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo // The call to oemCleanupHooks() is superfluous when done on bootup, 1074ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo // but is needed for the case where netd has crashed/stopped and is 1084ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo // restarted. 1094ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo if (oemCleanupHooks() && oemSetupHooks() && oemInitChains()) { 1107c73e8951d91b5afe9d52f88d7ed3a09d120a725JP Abgrall ALOGI("OEM iptable hook installed."); 1114ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo } 1124ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo } 1134ab468577647d1ee73810b89d2287eaa5546fecbKazuhiro Ondo} 114