1c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt/* 2c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt * Copyright (C) 2012 The Android Open Source Project 3c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt * 4c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt * Licensed under the Apache License, Version 2.0 (the "License"); 5c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt * you may not use this file except in compliance with the License. 6c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt * You may obtain a copy of the License at 7c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt * 8c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt * http://www.apache.org/licenses/LICENSE-2.0 9c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt * 10c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt * Unless required by applicable law or agreed to in writing, software 11c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt * distributed under the License is distributed on an "AS IS" BASIS, 12c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt * See the License for the specific language governing permissions and 14c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt * limitations under the License. 15c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt */ 16c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt 1770afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti#include <fcntl.h> 188e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey#include <string.h> 19838ef6491794900731760aecc1d4a10bb2fdd2ecRom Lemarchand#include <sys/wait.h> 208e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey 21bec6d04e1a84823b89e5581ea8ebcf9f08915216Jeff Sharkey#define LOG_TAG "Netd" 22bec6d04e1a84823b89e5581ea8ebcf9f08915216Jeff Sharkey 238e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey#include <cutils/log.h> 24838ef6491794900731760aecc1d4a10bb2fdd2ecRom Lemarchand#include <logwrap/logwrap.h> 258e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey 26c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt#include "NetdConstants.h" 27c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwalt 28c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwaltconst char * const OEM_SCRIPT_PATH = "/system/bin/oem-iptables-init.sh"; 29c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwaltconst char * const IPTABLES_PATH = "/system/bin/iptables"; 300031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrallconst char * const IP6TABLES_PATH = "/system/bin/ip6tables"; 31c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwaltconst char * const TC_PATH = "/system/bin/tc"; 32c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwaltconst char * const IP_PATH = "/system/bin/ip"; 33c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwaltconst char * const ADD = "add"; 34c462177bd58e3bf0ac4f618934dae060569e3e0bRobert Greenwaltconst char * const DEL = "del"; 358e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey 36838ef6491794900731760aecc1d4a10bb2fdd2ecRom Lemarchandstatic void logExecError(const char* argv[], int res, int status) { 378e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey const char** argp = argv; 388e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey std::string args = ""; 398e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey while (*argp) { 408e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey args += *argp; 418e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey args += ' '; 428e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey argp++; 438e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey } 44838ef6491794900731760aecc1d4a10bb2fdd2ecRom Lemarchand ALOGE("exec() res=%d, status=%d for %s", res, status, args.c_str()); 45838ef6491794900731760aecc1d4a10bb2fdd2ecRom Lemarchand} 46838ef6491794900731760aecc1d4a10bb2fdd2ecRom Lemarchand 47838ef6491794900731760aecc1d4a10bb2fdd2ecRom Lemarchandstatic int execIptablesCommand(int argc, const char *argv[], bool silent) { 48838ef6491794900731760aecc1d4a10bb2fdd2ecRom Lemarchand int res; 49838ef6491794900731760aecc1d4a10bb2fdd2ecRom Lemarchand int status; 50838ef6491794900731760aecc1d4a10bb2fdd2ecRom Lemarchand 51838ef6491794900731760aecc1d4a10bb2fdd2ecRom Lemarchand res = android_fork_execvp(argc, (char **)argv, &status, false, 52838ef6491794900731760aecc1d4a10bb2fdd2ecRom Lemarchand !silent); 53838ef6491794900731760aecc1d4a10bb2fdd2ecRom Lemarchand if (res || !WIFEXITED(status) || WEXITSTATUS(status)) { 54838ef6491794900731760aecc1d4a10bb2fdd2ecRom Lemarchand if (!silent) { 55838ef6491794900731760aecc1d4a10bb2fdd2ecRom Lemarchand logExecError(argv, res, status); 56838ef6491794900731760aecc1d4a10bb2fdd2ecRom Lemarchand } 57838ef6491794900731760aecc1d4a10bb2fdd2ecRom Lemarchand if (res) 58838ef6491794900731760aecc1d4a10bb2fdd2ecRom Lemarchand return res; 59838ef6491794900731760aecc1d4a10bb2fdd2ecRom Lemarchand if (!WIFEXITED(status)) 60838ef6491794900731760aecc1d4a10bb2fdd2ecRom Lemarchand return ECHILD; 61838ef6491794900731760aecc1d4a10bb2fdd2ecRom Lemarchand } 62838ef6491794900731760aecc1d4a10bb2fdd2ecRom Lemarchand return WEXITSTATUS(status); 638e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey} 648e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey 658e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkeystatic int execIptables(IptablesTarget target, bool silent, va_list args) { 668e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey /* Read arguments from incoming va_list; we expect the list to be NULL terminated. */ 678e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey std::list<const char*> argsList; 688e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey argsList.push_back(NULL); 698e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey const char* arg; 708e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey do { 718e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey arg = va_arg(args, const char *); 728e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey argsList.push_back(arg); 738e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey } while (arg); 748e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey 758e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey int i = 0; 768e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey const char* argv[argsList.size()]; 778e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey std::list<const char*>::iterator it; 788e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey for (it = argsList.begin(); it != argsList.end(); it++, i++) { 798e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey argv[i] = *it; 808e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey } 818e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey 828e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey int res = 0; 838e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey if (target == V4 || target == V4V6) { 848e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey argv[0] = IPTABLES_PATH; 85838ef6491794900731760aecc1d4a10bb2fdd2ecRom Lemarchand res |= execIptablesCommand(argsList.size(), argv, silent); 868e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey } 878e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey if (target == V6 || target == V4V6) { 888e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey argv[0] = IP6TABLES_PATH; 89838ef6491794900731760aecc1d4a10bb2fdd2ecRom Lemarchand res |= execIptablesCommand(argsList.size(), argv, silent); 908e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey } 918e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey return res; 928e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey} 938e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey 948e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkeyint execIptables(IptablesTarget target, ...) { 958e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey va_list args; 968e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey va_start(args, target); 978e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey int res = execIptables(target, false, args); 988e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey va_end(args); 998e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey return res; 1008e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey} 1018e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey 1028e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkeyint execIptablesSilently(IptablesTarget target, ...) { 1038e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey va_list args; 1048e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey va_start(args, target); 1058e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey int res = execIptables(target, true, args); 1068e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey va_end(args); 1078e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey return res; 1088e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey} 10970afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti 11070afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colittiint writeFile(const char *path, const char *value, int size) { 11170afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti int fd = open(path, O_WRONLY); 11270afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti if (fd < 0) { 11370afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti ALOGE("Failed to open %s: %s", path, strerror(errno)); 11470afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti return -1; 11570afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti } 11670afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti 11770afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti if (write(fd, value, size) != size) { 11870afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti ALOGE("Failed to write %s: %s", path, strerror(errno)); 11970afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti close(fd); 12070afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti return -1; 12170afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti } 12270afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti close(fd); 12370afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti return 0; 12470afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti} 1256d6c0e6f1164e3182538cb48c2b95d90a2eb780cDmitry Shmidt 1266d6c0e6f1164e3182538cb48c2b95d90a2eb780cDmitry Shmidtint readFile(const char *path, char *buf, int *sizep) 1276d6c0e6f1164e3182538cb48c2b95d90a2eb780cDmitry Shmidt{ 1286d6c0e6f1164e3182538cb48c2b95d90a2eb780cDmitry Shmidt int fd = open(path, O_RDONLY); 1296d6c0e6f1164e3182538cb48c2b95d90a2eb780cDmitry Shmidt int size; 1306d6c0e6f1164e3182538cb48c2b95d90a2eb780cDmitry Shmidt 1316d6c0e6f1164e3182538cb48c2b95d90a2eb780cDmitry Shmidt if (fd < 0) { 1326d6c0e6f1164e3182538cb48c2b95d90a2eb780cDmitry Shmidt ALOGE("Failed to open %s: %s", path, strerror(errno)); 1336d6c0e6f1164e3182538cb48c2b95d90a2eb780cDmitry Shmidt return -1; 1346d6c0e6f1164e3182538cb48c2b95d90a2eb780cDmitry Shmidt } 1356d6c0e6f1164e3182538cb48c2b95d90a2eb780cDmitry Shmidt 1366d6c0e6f1164e3182538cb48c2b95d90a2eb780cDmitry Shmidt size = read(fd, buf, *sizep); 1376d6c0e6f1164e3182538cb48c2b95d90a2eb780cDmitry Shmidt if (size < 0) { 1386d6c0e6f1164e3182538cb48c2b95d90a2eb780cDmitry Shmidt ALOGE("Failed to write %s: %s", path, strerror(errno)); 1396d6c0e6f1164e3182538cb48c2b95d90a2eb780cDmitry Shmidt close(fd); 1406d6c0e6f1164e3182538cb48c2b95d90a2eb780cDmitry Shmidt return -1; 1416d6c0e6f1164e3182538cb48c2b95d90a2eb780cDmitry Shmidt } 1426d6c0e6f1164e3182538cb48c2b95d90a2eb780cDmitry Shmidt *sizep = size; 1436d6c0e6f1164e3182538cb48c2b95d90a2eb780cDmitry Shmidt close(fd); 1446d6c0e6f1164e3182538cb48c2b95d90a2eb780cDmitry Shmidt return 0; 1456d6c0e6f1164e3182538cb48c2b95d90a2eb780cDmitry Shmidt} 146