1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <fcntl.h> 18 #include <string.h> 19 #include <sys/wait.h> 20 21 #define LOG_TAG "Netd" 22 23 #include <cutils/log.h> 24 #include <logwrap/logwrap.h> 25 26 #include "NetdConstants.h" 27 28 const char * const OEM_SCRIPT_PATH = "/system/bin/oem-iptables-init.sh"; 29 const char * const IPTABLES_PATH = "/system/bin/iptables"; 30 const char * const IP6TABLES_PATH = "/system/bin/ip6tables"; 31 const char * const TC_PATH = "/system/bin/tc"; 32 const char * const IP_PATH = "/system/bin/ip"; 33 const char * const ADD = "add"; 34 const char * const DEL = "del"; 35 36 static void logExecError(const char* argv[], int res, int status) { 37 const char** argp = argv; 38 std::string args = ""; 39 while (*argp) { 40 args += *argp; 41 args += ' '; 42 argp++; 43 } 44 ALOGE("exec() res=%d, status=%d for %s", res, status, args.c_str()); 45 } 46 47 static int execIptablesCommand(int argc, const char *argv[], bool silent) { 48 int res; 49 int status; 50 51 res = android_fork_execvp(argc, (char **)argv, &status, false, 52 !silent); 53 if (res || !WIFEXITED(status) || WEXITSTATUS(status)) { 54 if (!silent) { 55 logExecError(argv, res, status); 56 } 57 if (res) 58 return res; 59 if (!WIFEXITED(status)) 60 return ECHILD; 61 } 62 return WEXITSTATUS(status); 63 } 64 65 static int execIptables(IptablesTarget target, bool silent, va_list args) { 66 /* Read arguments from incoming va_list; we expect the list to be NULL terminated. */ 67 std::list<const char*> argsList; 68 argsList.push_back(NULL); 69 const char* arg; 70 do { 71 arg = va_arg(args, const char *); 72 argsList.push_back(arg); 73 } while (arg); 74 75 int i = 0; 76 const char* argv[argsList.size()]; 77 std::list<const char*>::iterator it; 78 for (it = argsList.begin(); it != argsList.end(); it++, i++) { 79 argv[i] = *it; 80 } 81 82 int res = 0; 83 if (target == V4 || target == V4V6) { 84 argv[0] = IPTABLES_PATH; 85 res |= execIptablesCommand(argsList.size(), argv, silent); 86 } 87 if (target == V6 || target == V4V6) { 88 argv[0] = IP6TABLES_PATH; 89 res |= execIptablesCommand(argsList.size(), argv, silent); 90 } 91 return res; 92 } 93 94 int execIptables(IptablesTarget target, ...) { 95 va_list args; 96 va_start(args, target); 97 int res = execIptables(target, false, args); 98 va_end(args); 99 return res; 100 } 101 102 int execIptablesSilently(IptablesTarget target, ...) { 103 va_list args; 104 va_start(args, target); 105 int res = execIptables(target, true, args); 106 va_end(args); 107 return res; 108 } 109 110 int writeFile(const char *path, const char *value, int size) { 111 int fd = open(path, O_WRONLY); 112 if (fd < 0) { 113 ALOGE("Failed to open %s: %s", path, strerror(errno)); 114 return -1; 115 } 116 117 if (write(fd, value, size) != size) { 118 ALOGE("Failed to write %s: %s", path, strerror(errno)); 119 close(fd); 120 return -1; 121 } 122 close(fd); 123 return 0; 124 } 125 126 int readFile(const char *path, char *buf, int *sizep) 127 { 128 int fd = open(path, O_RDONLY); 129 int size; 130 131 if (fd < 0) { 132 ALOGE("Failed to open %s: %s", path, strerror(errno)); 133 return -1; 134 } 135 136 size = read(fd, buf, *sizep); 137 if (size < 0) { 138 ALOGE("Failed to write %s: %s", path, strerror(errno)); 139 close(fd); 140 return -1; 141 } 142 *sizep = size; 143 close(fd); 144 return 0; 145 } 146