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;
}
Ejemplo n.º 4
0
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);
}