1 /* 2 * Copyright (C) 2008 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 #define LOG_NDEBUG 0 18 19 #include <string> 20 #include <vector> 21 22 #include <errno.h> 23 #include <fcntl.h> 24 #include <stdlib.h> 25 #include <string.h> 26 #include <arpa/inet.h> 27 #include <linux/in.h> 28 #include <netinet/in.h> 29 #include <sys/socket.h> 30 #include <sys/stat.h> 31 #include <sys/wait.h> 32 33 #define LOG_TAG "NatController" 34 #include <android-base/strings.h> 35 #include <android-base/stringprintf.h> 36 #include <cutils/log.h> 37 #include <cutils/properties.h> 38 #include <logwrap/logwrap.h> 39 40 #include "NatController.h" 41 #include "NetdConstants.h" 42 #include "RouteController.h" 43 44 using android::base::Join; 45 using android::base::StringPrintf; 46 47 const char* NatController::LOCAL_FORWARD = "natctrl_FORWARD"; 48 const char* NatController::LOCAL_MANGLE_FORWARD = "natctrl_mangle_FORWARD"; 49 const char* NatController::LOCAL_NAT_POSTROUTING = "natctrl_nat_POSTROUTING"; 50 const char* NatController::LOCAL_RAW_PREROUTING = "natctrl_raw_PREROUTING"; 51 const char* NatController::LOCAL_TETHER_COUNTERS_CHAIN = "natctrl_tether_counters"; 52 53 auto NatController::execFunction = android_fork_execvp; 54 auto NatController::iptablesRestoreFunction = execIptablesRestore; 55 56 NatController::NatController() { 57 } 58 59 NatController::~NatController() { 60 } 61 62 struct CommandsAndArgs { 63 /* The array size doesn't really matter as the compiler will barf if too many initializers are specified. */ 64 const char *cmd[32]; 65 bool checkRes; 66 }; 67 68 int NatController::setupIptablesHooks() { 69 int res; 70 res = setDefaults(); 71 if (res < 0) { 72 return res; 73 } 74 75 // Used to limit downstream mss to the upstream pmtu so we don't end up fragmenting every large 76 // packet tethered devices send. This is IPv4-only, because in IPv6 we send the MTU in the RA. 77 // This is no longer optional and tethering will fail to start if it fails. 78 std::string mssRewriteCommand = StringPrintf( 79 "*mangle\n" 80 "-A %s -p tcp --tcp-flags SYN SYN -j TCPMSS --clamp-mss-to-pmtu\n" 81 "COMMIT\n", LOCAL_MANGLE_FORWARD); 82 83 // This is for tethering counters. This chain is reached via --goto, and then RETURNS. 84 std::string defaultCommands = StringPrintf( 85 "*filter\n" 86 ":%s -\n" 87 "COMMIT\n", LOCAL_TETHER_COUNTERS_CHAIN); 88 89 res = iptablesRestoreFunction(V4, mssRewriteCommand); 90 if (res < 0) { 91 return res; 92 } 93 94 res = iptablesRestoreFunction(V4V6, defaultCommands); 95 if (res < 0) { 96 return res; 97 } 98 99 ifacePairList.clear(); 100 101 return 0; 102 } 103 104 int NatController::setDefaults() { 105 std::string v4Cmd = StringPrintf( 106 "*filter\n" 107 ":%s -\n" 108 "-A %s -j DROP\n" 109 "COMMIT\n" 110 "*nat\n" 111 ":%s -\n" 112 "COMMIT\n", LOCAL_FORWARD, LOCAL_FORWARD, LOCAL_NAT_POSTROUTING); 113 114 std::string v6Cmd = StringPrintf( 115 "*filter\n" 116 ":%s -\n" 117 "COMMIT\n" 118 "*raw\n" 119 ":%s -\n" 120 "COMMIT\n", LOCAL_FORWARD, LOCAL_RAW_PREROUTING); 121 122 int res = iptablesRestoreFunction(V4, v4Cmd); 123 if (res < 0) { 124 return res; 125 } 126 127 res = iptablesRestoreFunction(V6, v6Cmd); 128 if (res < 0) { 129 return res; 130 } 131 132 natCount = 0; 133 134 return 0; 135 } 136 137 int NatController::enableNat(const char* intIface, const char* extIface) { 138 ALOGV("enableNat(intIface=<%s>, extIface=<%s>)",intIface, extIface); 139 140 if (!isIfaceName(intIface) || !isIfaceName(extIface)) { 141 errno = ENODEV; 142 return -1; 143 } 144 145 /* Bug: b/9565268. "enableNat wlan0 wlan0". For now we fail until java-land is fixed */ 146 if (!strcmp(intIface, extIface)) { 147 ALOGE("Duplicate interface specified: %s %s", intIface, extIface); 148 errno = EINVAL; 149 return -1; 150 } 151 152 // add this if we are the first added nat 153 if (natCount == 0) { 154 std::vector<std::string> v4Cmds = { 155 "*nat", 156 StringPrintf("-A %s -o %s -j MASQUERADE", LOCAL_NAT_POSTROUTING, extIface), 157 "COMMIT\n" 158 }; 159 160 /* 161 * IPv6 tethering doesn't need the state-based conntrack rules, so 162 * it unconditionally jumps to the tether counters chain all the time. 163 */ 164 std::vector<std::string> v6Cmds = { 165 "*filter", 166 StringPrintf("-A %s -g %s", LOCAL_FORWARD, LOCAL_TETHER_COUNTERS_CHAIN), 167 "COMMIT\n" 168 }; 169 170 if (iptablesRestoreFunction(V4, Join(v4Cmds, '\n')) || 171 iptablesRestoreFunction(V6, Join(v6Cmds, '\n'))) { 172 ALOGE("Error setting postroute rule: iface=%s", extIface); 173 // unwind what's been done, but don't care about success - what more could we do? 174 setDefaults(); 175 return -1; 176 } 177 } 178 179 if (setForwardRules(true, intIface, extIface) != 0) { 180 ALOGE("Error setting forward rules"); 181 if (natCount == 0) { 182 setDefaults(); 183 } 184 errno = ENODEV; 185 return -1; 186 } 187 188 natCount++; 189 return 0; 190 } 191 192 bool NatController::checkTetherCountingRuleExist(const std::string& pair_name) { 193 return std::find(ifacePairList.begin(), ifacePairList.end(), pair_name) != ifacePairList.end(); 194 } 195 196 /* static */ 197 std::string NatController::makeTetherCountingRule(const char *if1, const char *if2) { 198 return StringPrintf("-A %s -i %s -o %s -j RETURN", LOCAL_TETHER_COUNTERS_CHAIN, if1, if2); 199 } 200 201 int NatController::setForwardRules(bool add, const char *intIface, const char *extIface) { 202 const char *op = add ? "-A" : "-D"; 203 204 std::string rpfilterCmd = StringPrintf( 205 "*raw\n" 206 "%s %s -i %s -m rpfilter --invert ! -s fe80::/64 -j DROP\n" 207 "COMMIT\n", op, LOCAL_RAW_PREROUTING, intIface); 208 if (iptablesRestoreFunction(V6, rpfilterCmd) == -1 && add) { 209 return -1; 210 } 211 212 std::vector<std::string> v4 = { 213 "*filter", 214 StringPrintf("%s %s -i %s -o %s -m state --state ESTABLISHED,RELATED -g %s", 215 op, LOCAL_FORWARD, extIface, intIface, LOCAL_TETHER_COUNTERS_CHAIN), 216 StringPrintf("%s %s -i %s -o %s -m state --state INVALID -j DROP", 217 op, LOCAL_FORWARD, intIface, extIface), 218 StringPrintf("%s %s -i %s -o %s -g %s", 219 op, LOCAL_FORWARD, intIface, extIface, LOCAL_TETHER_COUNTERS_CHAIN), 220 }; 221 222 std::vector<std::string> v6 = { 223 "*filter", 224 }; 225 226 /* We only ever add tethering quota rules so that they stick. */ 227 std::string pair1 = StringPrintf("%s_%s", intIface, extIface); 228 if (add && !checkTetherCountingRuleExist(pair1)) { 229 v4.push_back(makeTetherCountingRule(intIface, extIface)); 230 v6.push_back(makeTetherCountingRule(intIface, extIface)); 231 } 232 std::string pair2 = StringPrintf("%s_%s", extIface, intIface); 233 if (add && !checkTetherCountingRuleExist(pair2)) { 234 v4.push_back(makeTetherCountingRule(extIface, intIface)); 235 v6.push_back(makeTetherCountingRule(extIface, intIface)); 236 } 237 238 // Always make sure the drop rule is at the end. 239 // TODO: instead of doing this, consider just rebuilding LOCAL_FORWARD completely from scratch 240 // every time, starting with ":natctrl_FORWARD -\n". This method would likely be a bit simpler. 241 if (add) { 242 v4.push_back(StringPrintf("-D %s -j DROP", LOCAL_FORWARD)); 243 v4.push_back(StringPrintf("-A %s -j DROP", LOCAL_FORWARD)); 244 } 245 246 v4.push_back("COMMIT\n"); 247 v6.push_back("COMMIT\n"); 248 249 // We only add IPv6 rules here, never remove them. 250 if (iptablesRestoreFunction(V4, Join(v4, '\n')) == -1 || 251 (add && iptablesRestoreFunction(V6, Join(v6, '\n')) == -1)) { 252 // unwind what's been done, but don't care about success - what more could we do? 253 if (add) { 254 setForwardRules(false, intIface, extIface); 255 } 256 return -1; 257 } 258 259 if (add && !checkTetherCountingRuleExist(pair1)) { 260 ifacePairList.push_front(pair1); 261 } 262 if (add && !checkTetherCountingRuleExist(pair2)) { 263 ifacePairList.push_front(pair2); 264 } 265 266 return 0; 267 } 268 269 int NatController::disableNat(const char* intIface, const char* extIface) { 270 if (!isIfaceName(intIface) || !isIfaceName(extIface)) { 271 errno = ENODEV; 272 return -1; 273 } 274 275 setForwardRules(false, intIface, extIface); 276 if (--natCount <= 0) { 277 // handle decrement to 0 case (do reset to defaults) and erroneous dec below 0 278 setDefaults(); 279 } 280 return 0; 281 } 282