int BandwidthController::runIptablesCmd(const char *cmd, IptRejectOp rejectHandling, IptIpVer iptVer, IptFailureLog failureHandling) { char buffer[MAX_CMD_LEN]; const char *argv[MAX_CMD_ARGS]; int argc = 0; char *next = buffer; char *tmp; int res; std::string fullCmd = cmd; if (rejectHandling == IptRejectAdd) { fullCmd += " --jump REJECT --reject-with"; switch (iptVer) { case IptIpV4: fullCmd += " icmp-net-prohibited"; break; case IptIpV6: fullCmd += " icmp6-adm-prohibited"; break; } } fullCmd.insert(0, " "); fullCmd.insert(0, iptVer == IptIpV4 ? IPTABLES_PATH : IP6TABLES_PATH); if (!useLogwrapCall) { res = system_nosh(fullCmd.c_str()); } else { if (StrncpyAndCheck(buffer, fullCmd.c_str(), sizeof(buffer))) { ALOGE("iptables command too long"); return -1; } argc = 0; while ((tmp = strsep(&next, " "))) { argv[argc++] = tmp; if (argc >= MAX_CMD_ARGS) { ALOGE("iptables argument overflow"); return -1; } } argv[argc] = NULL; res = logwrap(argc, argv); } if (res && failureHandling == IptFailShow) { ALOGE("runIptablesCmd(): failed %s res=%d", fullCmd.c_str(), res); } return res; }
int SecondaryTableController::runAndFree(SocketClient *cli, char *cmd) { int ret = 0; if (strlen(cmd) >= 255) { if (cli != NULL) { ALOGE("ip command (%s) too long", cmd); errno = E2BIG; cli->sendMsg(ResponseCode::CommandSyntaxError, "Too long", true); } free(cmd); return -1; } ret = system_nosh(cmd); free(cmd); return ret; }
int ThrottleController::runTcCmd(const char *cmd) { char *buffer; size_t len = strnlen(cmd, 255); int res; if (len == 255) { ALOGE("tc command too long"); errno = E2BIG; return -1; } asprintf(&buffer, "%s %s", TC_PATH, cmd); res = system_nosh(buffer); free(buffer); return res; }
int NatController::runCmd(const char *path, const char *cmd) { char *buffer; size_t len = strnlen(cmd, 255); int res; if (len == 255) { LOGE("command too long"); errno = E2BIG; return -1; } asprintf(&buffer, "%s %s", path, cmd); res = system_nosh(buffer); free(buffer); return res; }
int SecondaryTableController::addRoute(SocketClient *cli, char *iface, char *dest, int prefix, char *gateway) { char *cmd; int tableIndex = findTableNumber(iface); int fd; struct ifreq ifreqs[20]; struct ifconf ic; unsigned int i; if (tableIndex == -1) { tableIndex = findTableNumber(""); // look for an empty slot if (tableIndex == -1) { ALOGE("Max number of NATed interfaces reached"); errno = ENODEV; cli->sendMsg(ResponseCode::OperationFailed, "Max number NATed", true); return -1; } strncpy(mInterfaceTable[tableIndex], iface, IFNAMSIZ); // Ensure null termination even if truncation happened mInterfaceTable[tableIndex][IFNAMSIZ] = 0; } if ((fd = open("/proc/net/mptcp", O_RDONLY)) != -1) { close(fd); fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { ALOGE("socket error"); return -1; } ic.ifc_len = sizeof(ifreqs); ic.ifc_buf = (char *) ifreqs; if (ioctl(fd, SIOCGIFCONF, &ic) < 0) { ALOGE("ioctl error"); return -1; } for (i = 0; i < ic.ifc_len / sizeof(struct ifreq); i++) { if (!strcmp(ifreqs[i].ifr_name, iface)) { asprintf(&cmd, "%s rule add from %s table %d", IP_PATH, inet_ntoa(((struct sockaddr_in *)&ifreqs[i].ifr_addr)->sin_addr), tableIndex+BASE_TABLE_NUMBER); system_nosh(cmd); } } } return modifyRoute(cli, ADD, iface, dest, prefix, gateway, tableIndex); }
int SecondaryTableController::removeRoute(SocketClient *cli, char *iface, char *dest, int prefix, char *gateway) { char *cmd; int tableIndex = findTableNumber(iface); int fd; struct ifreq ifreqs[20]; struct ifconf ic; unsigned int i; if (tableIndex == -1) { ALOGE("Interface not found"); errno = ENODEV; cli->sendMsg(ResponseCode::OperationFailed, "Interface not found", true); return -1; } if ((fd = open("/proc/net/mptcp", O_RDONLY)) != -1) { close(fd); fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { ALOGE("socket error"); return -1; } ic.ifc_len = sizeof(ifreqs); ic.ifc_buf = (char *) ifreqs; if (ioctl(fd, SIOCGIFCONF, &ic) < 0) { ALOGE("ioctl error"); return -1; } for (i = 0; i < ic.ifc_len / sizeof(struct ifreq); i++) { if (!strcmp(ifreqs[i].ifr_name, iface)) { asprintf(&cmd, "%s rule del from %s table %d", IP_PATH, inet_ntoa(((struct sockaddr_in *)&ifreqs[i].ifr_addr)->sin_addr), tableIndex+BASE_TABLE_NUMBER); system_nosh(cmd); } } } return modifyRoute(cli, DEL, iface, dest, prefix, gateway, tableIndex); }