// nat disable intface extface // 0 1 2 3 4 5 // nat enable intface extface addrcnt nated-ipaddr/prelength int NatController::disableNat(const int argc, char **argv) { int i; int addrCount = atoi(argv[4]); const char *intIface = argv[2]; const char *extIface = argv[3]; int tableNumber; if (!checkInterface(intIface) || !checkInterface(extIface)) { ALOGE("Invalid interface specified"); errno = ENODEV; return -1; } if (argc < 5 + addrCount) { ALOGE("Missing Argument"); errno = EINVAL; return -1; } setForwardRules(false, intIface, extIface); routesOp(false, intIface, extIface, argv, addrCount); if (--natCount <= 0) { // handle decrement to 0 case (do reset to defaults) and erroneous dec below 0 setDefaults(); } return 0; }
// nat disable intface extface // 0 1 2 3 4 5 // nat enable intface extface addrcnt nated-ipaddr/prelength int NatController::disableNat(const int argc, char **argv) { char cmd[255]; int i; int addrCount = atoi(argv[4]); const char *intIface = argv[2]; const char *extIface = argv[3]; int tableNumber; if (!checkInterface(intIface) || !checkInterface(extIface)) { LOGE("Invalid interface specified"); errno = ENODEV; return -1; } if (argc < 5 + addrCount) { LOGE("Missing Argument"); errno = EINVAL; return -1; } setForwardRules(false, intIface, extIface); tableNumber = secondaryTableCtrl->findTableNumber(extIface); if (tableNumber != -1) { for (i = 0; i < addrCount; i++) { snprintf(cmd, sizeof(cmd), "route del %s dev %s table %d", argv[5+i], intIface, tableNumber + BASE_TABLE_NUMBER); // if the interface has gone down these will be gone already and give errors // ignore them. runCmd(IP_PATH, cmd); snprintf(cmd, sizeof(cmd), "%s rule del from %s table %d", getVersion(argv[5+i]), argv[5+i], tableNumber + BASE_TABLE_NUMBER); runCmd(IP_PATH, cmd); } runCmd(IP_PATH, "route flush cache"); } if (--natCount <= 0) { // handle decrement to 0 case (do reset to defaults) and erroneous dec below 0 setDefaults(); } return 0; }
// nat disable intface extface // 0 1 2 3 4 5 // nat enable intface extface addrcnt nated-ipaddr/prelength int NatController::disableNat(const int argc, char **argv) { char cmd[255]; int i; int addrCount = atoi(argv[4]); const char *intIface = argv[2]; const char *extIface = argv[3]; int tableNumber; if (!checkInterface(intIface) || !checkInterface(extIface)) { ALOGE("Invalid interface specified"); errno = ENODEV; return -1; } if (argc < 5 + addrCount) { ALOGE("Missing Argument"); errno = EINVAL; return -1; } setForwardRules(false, intIface, extIface); tableNumber = secondaryTableCtrl->findTableNumber(extIface); if (tableNumber != -1) { for (i = 0; i < addrCount; i++) { secondaryTableCtrl->modifyLocalRoute(tableNumber, DEL, intIface, argv[5+i]); secondaryTableCtrl->modifyFromRule(tableNumber, DEL, argv[5+i]); } runCmd(IP_PATH, "route flush cache"); } if (--natCount <= 0) { // handle decrement to 0 case (do reset to defaults) and erroneous dec below 0 setDefaults(); } ALOGI("disableNat: natCount = %d", natCount); return 0; }
// 0 1 2 3 4 5 // nat enable intface extface addrcnt nated-ipaddr/prelength int NatController::enableNat(const int argc, char **argv) { int i; int addrCount = atoi(argv[4]); const char *intIface = argv[2]; const char *extIface = argv[3]; int tableNumber; ALOGV("enableNat(intIface=<%s>, extIface=<%s>)",intIface, extIface); if (!checkInterface(intIface) || !checkInterface(extIface)) { ALOGE("Invalid interface specified"); errno = ENODEV; return -1; } /* Bug: b/9565268. "enableNat wlan0 wlan0". For now we fail until java-land is fixed */ if (!strcmp(intIface, extIface)) { ALOGE("Duplicate interface specified: %s %s", intIface, extIface); errno = EINVAL; return -1; } if (argc < 5 + addrCount) { ALOGE("Missing Argument"); errno = EINVAL; return -1; } if (routesOp(true, intIface, extIface, argv, addrCount)) { ALOGE("Error setting route rules"); routesOp(false, intIface, extIface, argv, addrCount); errno = ENODEV; return -1; } // add this if we are the first added nat if (natCount == 0) { const char *cmd[] = { IPTABLES_PATH, "-t", "nat", "-A", LOCAL_NAT_POSTROUTING, "-o", extIface, "-j", "MASQUERADE" }; if (runCmd(ARRAY_SIZE(cmd), cmd)) { ALOGE("Error seting postroute rule: iface=%s", extIface); // unwind what's been done, but don't care about success - what more could we do? routesOp(false, intIface, extIface, argv, addrCount); setDefaults(); return -1; } } if (setForwardRules(true, intIface, extIface) != 0) { ALOGE("Error setting forward rules"); routesOp(false, intIface, extIface, argv, addrCount); if (natCount == 0) { setDefaults(); } errno = ENODEV; return -1; } /* Always make sure the drop rule is at the end */ const char *cmd1[] = { IPTABLES_PATH, "-D", LOCAL_FORWARD, "-j", "DROP" }; runCmd(ARRAY_SIZE(cmd1), cmd1); const char *cmd2[] = { IPTABLES_PATH, "-A", LOCAL_FORWARD, "-j", "DROP" }; runCmd(ARRAY_SIZE(cmd2), cmd2); natCount++; return 0; }
// 0 1 2 3 4 5 // nat enable intface extface addrcnt nated-ipaddr/prelength int NatController::enableNat(const int argc, char **argv) { char cmd[255]; int i; int addrCount = atoi(argv[4]); int ret = 0; const char *intIface = argv[2]; const char *extIface = argv[3]; int tableNumber; if (!checkInterface(intIface) || !checkInterface(extIface)) { LOGE("Invalid interface specified"); errno = ENODEV; return -1; } if (argc < 5 + addrCount) { LOGE("Missing Argument"); errno = EINVAL; return -1; } tableNumber = secondaryTableCtrl->findTableNumber(extIface); if (tableNumber != -1) { for(i = 0; i < addrCount && ret == 0; i++) { snprintf(cmd, sizeof(cmd), "%s rule add from %s table %d", getVersion(argv[5+i]), argv[5+i], tableNumber + BASE_TABLE_NUMBER); ret |= runCmd(IP_PATH, cmd); if (ret) LOGE("IP rule %s got %d", cmd, ret); snprintf(cmd, sizeof(cmd), "route add %s dev %s table %d", argv[5+i], intIface, tableNumber + BASE_TABLE_NUMBER); ret |= runCmd(IP_PATH, cmd); if (ret) LOGE("IP route %s got %d", cmd, ret); } runCmd(IP_PATH, "route flush cache"); } if (ret != 0 || setForwardRules(true, intIface, extIface) != 0) { if (tableNumber != -1) { for (i = 0; i < addrCount; i++) { snprintf(cmd, sizeof(cmd), "route del %s dev %s table %d", argv[5+i], intIface, tableNumber + BASE_TABLE_NUMBER); runCmd(IP_PATH, cmd); snprintf(cmd, sizeof(cmd), "%s rule del from %s table %d", getVersion(argv[5+i]), argv[5+i], tableNumber + BASE_TABLE_NUMBER); runCmd(IP_PATH, cmd); } runCmd(IP_PATH, "route flush cache"); } LOGE("Error setting forward rules"); errno = ENODEV; return -1; } natCount++; // add this if we are the first added nat if (natCount == 1) { snprintf(cmd, sizeof(cmd), "-t nat -A POSTROUTING -o %s -j MASQUERADE", extIface); if (runCmd(IPTABLES_PATH, cmd)) { LOGE("Error seting postroute rule: %s", cmd); // unwind what's been done, but don't care about success - what more could we do? for (i = 0; i < addrCount; i++) { snprintf(cmd, sizeof(cmd), "route del %s dev %s table %d", argv[5+i], intIface, tableNumber + BASE_TABLE_NUMBER); runCmd(IP_PATH, cmd); } setDefaults(); return -1; } if (runCmd(IPTABLES_PATH, "-t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu")) LOGW("Unable to set TCPMSS rule (may not be supported by kernel)."); } return 0; }
// 0 1 2 3 4 5 // nat enable intface extface addrcnt nated-ipaddr/prelength int NatController::enableNat(const int argc, char **argv) { char cmd[255]; int i; int addrCount = atoi(argv[4]); int ret = 0; const char *intIface = argv[2]; const char *extIface = argv[3]; int tableNumber; if (!checkInterface(intIface) || !checkInterface(extIface)) { ALOGE("Invalid interface specified"); errno = ENODEV; return -1; } if (argc < 5 + addrCount) { ALOGE("Missing Argument"); errno = EINVAL; return -1; } tableNumber = secondaryTableCtrl->findTableNumber(extIface); if (tableNumber != -1) { for(i = 0; i < addrCount; i++) { ret |= secondaryTableCtrl->modifyFromRule(tableNumber, ADD, argv[5+i]); //ALPS00338128 //ignore the result to protect the tether class from stoping the tethering secondaryTableCtrl->modifyLocalRoute(tableNumber, ADD, intIface, argv[5+i]); } runCmd(IP_PATH, "route flush cache"); } if (ret != 0 || setForwardRules(true, intIface, extIface) != 0) { if (tableNumber != -1) { for (i = 0; i < addrCount; i++) { secondaryTableCtrl->modifyLocalRoute(tableNumber, DEL, intIface, argv[5+i]); secondaryTableCtrl->modifyFromRule(tableNumber, DEL, argv[5+i]); } runCmd(IP_PATH, "route flush cache"); } ALOGE("Error setting forward rules"); errno = ENODEV; return -1; } /* Always make sure the drop rule is at the end */ snprintf(cmd, sizeof(cmd), "-D natctrl_FORWARD -j DROP"); runCmd(IPTABLES_PATH, cmd); snprintf(cmd, sizeof(cmd), "-A natctrl_FORWARD -j DROP"); runCmd(IPTABLES_PATH, cmd); natCount++; ALOGI("enablenat: natCount = %d", natCount); // add this if we are the first added nat if (natCount == 1) { snprintf(cmd, sizeof(cmd), "-t nat -A natctrl_nat_POSTROUTING -o %s -j MASQUERADE", extIface); if (runCmd(IPTABLES_PATH, cmd)) { ALOGE("Error seting postroute rule: %s", cmd); // unwind what's been done, but don't care about success - what more could we do? for (i = 0; i < addrCount; i++) { secondaryTableCtrl->modifyLocalRoute(tableNumber, DEL, intIface, argv[5+i]); secondaryTableCtrl->modifyFromRule(tableNumber, DEL, argv[5+i]); } setDefaults(); return -1; } } return 0; }