Beispiel #1
0
void runCmd(struct Node* node, const char *fPath) {
	//Run the commands for each node in parallel
	pthread_t pt;

	if (node->child != NULL)
		runCmd(node->child, fPath);

	if (node->command != NULL) {
		char buf[2048];
		memset(buf, 0, sizeof(buf));
		if (node->statusFlag == 0) {
			if (treeSearchDups(node, node->nodeName, node->statusFlag,
					node->command))
				return 0;
		}
		if (node->statusFlag == 0) {

			char *sourceExt = strchr(node->nodeName, '.');
			if (sourceExt != NULL) {

				if ((strcmp(sourceExt, ".cpp") == 0)
						|| (strcmp(sourceExt, ".o") == 0))
					resetCommand(node, fPath);
			} else {

				//Need to fix other string and remove ""
				const char *src = strrchr(node->command, 'g');
				int endl = 0;
				if (src != NULL) {
					//src--;
					const char *dsc = strrchr(src, '"');
					endl = dsc - src;
					char* iptr = (char*) malloc(endl + 1);
					memset(iptr, 0, endl);
					memcpy(iptr, src, endl);
					iptr[endl] = 0;
					node->command = iptr;
				}
			}

			sprintf(buf, "%s", node->command);

			if (createThread(buf, &pt))
				return NULL;
			node->statusFlag = 1;

			if (node->next != NULL)
				runCmd(node->next, fPath);
		}
	}

}
int SecondaryTableController::modifyRoute(SocketClient *cli, const char *action, char *iface,
        char *dest, int prefix, char *gateway, unsigned netId) {
    char dest_str[44]; // enough to store an IPv6 address + 3 character bitmask
    char tableIndex_str[11];
    int ret;

    //  IP tool doesn't like "::" - the equiv of 0.0.0.0 that it accepts for ipv4
    snprintf(dest_str, sizeof(dest_str), "%s/%d", dest, prefix);
    snprintf(tableIndex_str, sizeof(tableIndex_str), "%u", netId + BASE_TABLE_NUMBER);

    if (strcmp("::", gateway) == 0) {
        const char *cmd[] = {
                IP_PATH,
                "route",
                action,
                dest_str,
                "dev",
                iface,
                "table",
                tableIndex_str
        };
        ret = runCmd(ARRAY_SIZE(cmd), cmd);
    } else {
        const char *cmd[] = {
                IP_PATH,
                "route",
                action,
                dest_str,
                "via",
                gateway,
                "dev",
                iface,
                "table",
                tableIndex_str
        };
        ret = runCmd(ARRAY_SIZE(cmd), cmd);
    }

    if (ret) {
        ALOGE("ip route %s failed: %s route %s %s/%d via %s dev %s table %u", action,
                IP_PATH, action, dest, prefix, gateway, iface, netId + BASE_TABLE_NUMBER);
        errno = ENODEV;
        cli->sendMsg(ResponseCode::OperationFailed, "ip route modification failed", true);
        return -1;
    }

    modifyRuleCount(netId, action);
    cli->sendMsg(ResponseCode::CommandOkay, "Route modified", false);
    return 0;
}
Beispiel #3
0
// ATSn=X – set radio parameter number ‘n’ to ‘X’
void MavlinkModem::ats(int number, int p_value) {
  long regValue;
  if (startCmdMode()) {
    if (number == 8 || number == 9) {
      regValue = long(p_value) *1000;
    } else {
      regValue = p_value;
    }
    String cmd = "ATS" + String(number) + "=" + String(regValue) + "\r";
    runCmd(cmd, ATI_DELAY, false);
    runCmd("AT&W\r", ATI_DELAY, false);
    stopCmdMode();
  }
}
int SecondaryTableController::setHostExemption(const char *host, bool add) {
    IptablesTarget target = !strcmp(getVersion(host), "-4") ? V4 : V6;
    char protect_mark_str[11];
    snprintf(protect_mark_str, sizeof(protect_mark_str), "%d", PROTECT_MARK);
    int ret = execIptables(target,
            "-t",
            "mangle",
            add ? "-A" : "-D",
            LOCAL_MANGLE_EXEMPT,
            "-d",
            host,
            "-j",
            "MARK",
            "--set-mark",
            protect_mark_str,
            NULL);
    const char *cmd[] = {
        IP_PATH,
        getVersion(host),
        "rule",
        add ? "add" : "del",
        "prio",
        EXEMPT_PRIO,
        "to",
        host,
        "table",
        "main"
    };
    ret |= runCmd(ARRAY_SIZE(cmd), cmd);
    return ret;
}
int NatController::setDefaults() {
    /*
     * The following only works because:
     *  - the defaultsCommands[].cmd array is padded with NULL, and
     *  - the 1st argc of runCmd() will just be the max for the CommandsAndArgs[].cmd, and
     *  - internally it will be memcopied to an array and terminated with a NULL.
     */
    struct CommandsAndArgs defaultCommands[] = {
        {{IPTABLES_PATH, "-F", LOCAL_FORWARD,}, 1},
        {{IPTABLES_PATH, "-A", LOCAL_FORWARD, "-j", "DROP"}, 1},
        {{IPTABLES_PATH, "-t", "nat", "-F", LOCAL_NAT_POSTROUTING}, 1},
        {{IP_PATH, "rule", "flush"}, 0},
        {{IP_PATH, "-6", "rule", "flush"}, 0},
        {{IP_PATH, "rule", "add", "from", "all", "lookup", "default", "prio", "32767"}, 0},
        {{IP_PATH, "rule", "add", "from", "all", "lookup", "main", "prio", "32766"}, 0},
        {{IP_PATH, "-6", "rule", "add", "from", "all", "lookup", "default", "prio", "32767"}, 0},
        {{IP_PATH, "-6", "rule", "add", "from", "all", "lookup", "main", "prio", "32766"}, 0},
        {{IP_PATH, "route", "flush", "cache"}, 0},
    };
    for (unsigned int cmdNum = 0; cmdNum < ARRAY_SIZE(defaultCommands); cmdNum++) {
        if (runCmd(ARRAY_SIZE(defaultCommands[cmdNum].cmd), defaultCommands[cmdNum].cmd) &&
            defaultCommands[cmdNum].checkRes) {
                return -1;
        }
    }

    natCount = 0;

    return 0;
}
Beispiel #6
0
// get a "universal" path -- friendly to cygwin and non-cygwin
// no-op outside of cygwin
static std::string unipath(const std::string path)
{
  if(!isCygwin())
    return path;

  std::vector<std::string> args;
  std::string result;

  args.push_back("cygpath");
  args.push_back("-at");
  args.push_back("mixed");
  args.push_back(path);
  runCmd(&result, args);

  size_t len = result.length();
  const char *rdata = result.data() + len - 1;

  while(len && *rdata == '\n')
  {
    len--;
    rdata--;
  }
  result.resize(len);
  return result;
}
int NatController::setupIptablesHooks() {
    int res;
    res = setDefaults();
    if (res < 0) {
        return res;
    }

    struct CommandsAndArgs defaultCommands[] = {
        /*
         * Chain for tethering counters.
         * This chain is reached via --goto, and then RETURNS.
         */
        {{IPTABLES_PATH, "-F", LOCAL_TETHER_COUNTERS_CHAIN,}, 0},
        {{IPTABLES_PATH, "-X", LOCAL_TETHER_COUNTERS_CHAIN,}, 0},
        {{IPTABLES_PATH, "-N", LOCAL_TETHER_COUNTERS_CHAIN,}, 1},
    };
    for (unsigned int cmdNum = 0; cmdNum < ARRAY_SIZE(defaultCommands); cmdNum++) {
        if (runCmd(ARRAY_SIZE(defaultCommands[cmdNum].cmd), defaultCommands[cmdNum].cmd) &&
            defaultCommands[cmdNum].checkRes) {
                return -1;
        }
    }

    return 0;
}
Beispiel #8
0
bool QMplayer::installYoutubeDl()
{
#ifdef QTOPIA
    return runCmd("apt-get update", 300) &&
        runCmd("apt-get -y install python", 200) &&
        runCmd("wget -O /usr/bin/youtube-dl http://dl.linuxphone.ru/openmoko/qtmoko/packages/youtube-dl", 100) &&
        QFile::setPermissions("/usr/bin/youtube-dl", QFile::ReadOwner |
                          QFile::WriteOwner | QFile::ExeOwner |
                          QFile::ReadUser | QFile::ExeUser |
                          QFile::ReadGroup | QFile::ExeGroup |
                          QFile::ReadOther | QFile::ExeOther);
#else
    QMessageBox::critical(this, tr("qmplayer"), tr("You must install youtube-dl"));
    return false;
#endif
}
Beispiel #9
0
int main(int argc, char **argv) {
    char *cmd;
    char **args;

    printf("------Welcome to Shelldon------\n");
    printf("use \"help\" to see list of available features\n");

    while(1) {
        printf("%s=> ",getlogin());
        cmd = readCmd();
        args = splitCmd(cmd);

        if(args[0]!=NULL&&!runCmd(args)) //need to skip if blank command
            break;

        //printf("%s\n%s\n%s\n",args[0],args[1],args[2]);
        free(cmd);
        free(args);
    }

    free(cmd);
    free(args);

    return 0;
}
Beispiel #10
0
std::string CPage::getErrorExtraInfo(const std::string& host)
{
	Trace("CPage::getErrorExtraInfo()","Entry",0);

	std::string s;

	std::string cmd;
	cmd = "/bin/traceroute -I -w2 ";
	cmd.append(host);
	Trace("CPage::addExtraInfo()", s.c_str(), 1);
	s.append("<traceroute>");
	Trace("CPage::addExtraInfo()", s.c_str(), 2);
	s.append(runCmd(cmd));
	Trace("CPage::addExtraInfo()", s.c_str(), 3);
	s.append("</traceroute>");
	Trace("CPage::addExtraInfo()", s.c_str(), 4);

	cmd = "/usr/bin/host ";
	cmd.append(host);
	s.append("<host>");
	Trace("CPage::addExtraInfo()", s.c_str(), 5);
	s.append(runCmd(cmd));
	Trace("CPage::addExtraInfo()", s.c_str(), 6);
	s.append("</host>");
	Trace("CPage::addExtraInfo()", s.c_str(), 7);

	cmd = "/usr/bin/host -v ";
	cmd.append(host);
	s.append("<host-v>");
	Trace("CPage::addExtraInfo()", s.c_str(), 8);
	s.append(runCmd(cmd));
	Trace("CPage::addExtraInfo()", s.c_str(), 9);
	s.append("</host-v>");
	Trace("CPage::addExtraInfo()", s.c_str(), 10);

	cmd = "/usr/bin/dig ";
	cmd.append(host);
	s.append("<dig>");
	Trace("CPage::addExtraInfo()", s.c_str(), 11);
	s.append(runCmd(cmd));
	Trace("CPage::addExtraInfo()", s.c_str(), 12);
	s.append("</dig>");
	Trace("CPage::addExtraInfo()", s.c_str(), 13);

	Trace("CPage::getErrorExtraInfo() - Exit",s.c_str(),0);
	return s;
}
Beispiel #11
0
void QMplayer::removeMplayer()
{
#ifdef QTOPIA
    if(QMessageBox::question(this, tr("qmplayer"),
            tr("You are about to remove mplayer. Are you sure?"),
            QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
    {
        bool res = runCmd("rm /usr/bin/mplayer", 10) && runCmd("rm /home/root/.mplayer/config", 10);
        runCmd("apt-get remove mplayer");
        showScreen(QMplayer::ScreenInit);
        if (res)
            QMessageBox::information(this, tr("qmplayer"), tr("mplayer has been removed"));
        else
            QMessageBox::critical(this, tr("qmplayer"), tr("Can't remove mplayer"));
    }
#endif
}
Beispiel #12
0
void MavlinkModem::writeAtsAll(int rows[]) {
  if (startCmdMode()) {
    String cmd;
    long value;
    for (int i = 1; i < 16; i++) {
      if (i == 8 || i == 9) {
        value = long(rows[i-1]) * 1000;
      } else {
        value = long(rows[i-1]);
      }
      cmd = "ATS" + String(i) + "=" + value + "\r";
      runCmd(cmd, ATI_DELAY, false);
    }
    runCmd("AT&W\r", ATI_DELAY, false);
    stopCmdMode();
  }
}
Beispiel #13
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;
}
Beispiel #14
0
// display RSSI signal report
String MavlinkModem::ati7(void) {
  String response = "";
  if (startCmdMode()) {
    response = runCmd("ATI7\r", ATI_DELAY, false);
    response.replace("ATI7\r\n", "");
    stopCmdMode();
  }
  return response;
}
void mxpanelorientation::whichPanel()
{
    // take the first panel we see as default
    QString panel_content;
    QStringList panelIDs;
    panel_content = runCmd("xfconf-query -c xfce4-panel -p /panels | grep -v Value | grep -v ^$").output;
    panelIDs = panel_content.split("\n");
    panel = panelIDs.value(0);
    qDebug() << "panel to use: " << panel;
}
Beispiel #16
0
// show radio version
String MavlinkModem::ati(void) {
  //  String response = runCmd("+++", 1200, true);
  //  runCmd("ATO\r", ATI_DELAY, false);
  String response = "";
  if (startCmdMode()) {
    response = runCmd("ATI\r", ATI_DELAY, false);
    response.replace("ATI\r\n", "");
    stopCmdMode();
  }
  return response;
}
Beispiel #17
0
   INT32 _omaTask::initJsEnv()
   {
      INT32 rc     = SDB_OK ;
      INT32 tmpRc  = SDB_OK ;
      INT32 errNum = 0 ;
      const CHAR *pDetail = NULL ;
      BSONObj obj ;
      BSONObj retObj ;
      _omaInitEnv runCmd( _taskID, obj ) ;

      rc = runCmd.init( NULL ) ;
      if ( SDB_OK != rc )
      {
         PD_LOG( PDWARNING, "Failed to init for running js script, "
                 "rc = %d", rc ) ;
         goto error ;
      }
      rc = runCmd.doit( retObj ) ;
      if ( SDB_OK != rc )
      {
         PD_LOG( PDWARNING, "Failed to init for running js script, "
                 "rc = %d", rc ) ;
         goto error ;
      }
      rc = omaGetIntElement ( retObj, OMA_FIELD_ERRNO, errNum ) ;
      if ( rc )
      {
         PD_LOG( PDERROR, "Failed to get errno from js after initializing "
                 "environment for execting js script, rc = %d", rc ) ;
         goto error ;
      }
      if ( SDB_OK != errNum )
      {
         rc = errNum ;
         tmpRc = omaGetStringElement ( retObj, OMA_FIELD_DETAIL, &pDetail ) ;
         if ( SDB_OK != tmpRc )
         {
            PD_LOG( PDERROR, "Failed to get error detail from js after "
                    "environment for execting js script, rc = %d", rc ) ;
         }
         else
         {
            PD_LOG( PDERROR, "Failed to init environment for execting js"
                    "script, rc = %d, detail = %s", rc, pDetail ) ;
         }
         goto error ;
      }

   done:
      return rc ;
   error:
      goto done ;
   }
Beispiel #18
0
int NatController::setDefaults() {
    if (runCmd(IPTABLES_PATH, "-F natctrl_FORWARD"))
        return -1;
    if (runCmd(IPTABLES_PATH, "-t nat -F natctrl_nat_POSTROUTING"))
        return -1;

    runCmd(IP_PATH, "rule flush");
    runCmd(IP_PATH, "-6 rule flush");
    runCmd(IP_PATH, "rule add from all lookup default prio 32767");
    runCmd(IP_PATH, "rule add from all lookup main prio 32766");
    runCmd(IP_PATH, "-6 rule add from all lookup default prio 32767");
    runCmd(IP_PATH, "-6 rule add from all lookup main prio 32766");
    runCmd(IP_PATH, "route flush cache");

    natCount = 0;

    return 0;
}
Beispiel #19
0
void VMsgLog::doRun()
{
    _running = TRUE;
    if( isIconic() ) {
        show( WWinStateShowNormal );
    } else {
        show();
    }
    setFocus();
    _batcher->setFocus();
    if( _cwd.size() > 0 ) {
        WString c( "cd " );
        c.concat( _cwd );
        lastCD = "";
        if( !_batserv ) {
            runCmd( c );
        } else {
            addLine( c );
            BatchChdir( _cwd );
        }
    }

    int icount = _command.size();
    for( int i=0; i<icount; ) {
        WString cbuff;
        for( ;i<icount; ) {
            char ch = _command[i++];
            if( ch == '\n' ) break;
            cbuff.concat( ch );
        }
        if( cbuff.size() > 0 ) {
            runCmd( cbuff );
        }
    }
    addLine( "Execution complete" );
    _running = FALSE;
    _parent->quickRefresh();
}
// Apply button clicked
void mxpanelorientation::on_buttonApply_clicked()
{
    ui->buttonApply->setEnabled(false);
    //read in plugin ID's
    if (ui->radioHorizontalPanel->isChecked()) {
        flipToHorizontal();
        runCmd("sleep .5");
    }

    if (ui->radioVerticalPanel->isChecked()) {
        flipToVertical();
        runCmd("sleep .5");
    }

    if (ui->radioDefaultPanel->isChecked()) {
        restoreDefaultPanel();
        runCmd("sleep .5");
        whichPanel();
    }

    if (ui->radioRestoreBackup->isChecked()) {
        restoreBackup();
        runCmd("sleep .5");
        whichPanel();
    }

    if (ui->radioBackupPanel->isChecked()) {
        backupPanel();
        message();
    }

    // reset gui

    setupUiSelections();

}
int SecondaryTableController::setHostExemption(const char *host, bool add) {
    const char *cmd[] = {
        IP_PATH,
        getVersion(host),
        "rule",
        add ? "add" : "del",
        "prio",
        EXEMPT_PRIO,
        "to",
        host,
        "table",
        "main"
    };
    return runCmd(ARRAY_SIZE(cmd), cmd);
}
Beispiel #22
0
void QMplayer::removeYoutubeDl()
{
#ifdef QTOPIA
    if(QMessageBox::question(this, tr("qmplayer"),
            tr("You are about to remove youtube-dl. Are you sure?"),
            QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
    {
        bool res = runCmd("rm /usr/bin/youtube-dl", 10);
        showScreen(QMplayer::ScreenInit);
        if (res)
            QMessageBox::information(this, tr("qmplayer"), tr("youtube-dl has been removed"));
        else
            QMessageBox::critical(this, tr("qmplayer"), tr("Can't remove youtube-dl"));
    }
#endif
}
Beispiel #23
0
int DebugConsole::exec()
{
    MyDevice mydev;

    if (!devUsbOpen(mydev))
		return 1;


    MyDeviceProto mydevproto(mydev);

	printHelp();
	bool go = true;
	while (go)
	{
		QStringList params;
		CmdType ct = readCmd(params);
		if (ct == ctUnknown)
		{
			qout << "ERROR: Unknown command" << endl;
		}
		else if (ct == ctHelp)
		{
			printHelp();
		}
		else if (ct == ctExit)
		{
			go = false;
		}
		else
		{
            CmdError ce = runCmd(mydevproto, ct, params);
			if (ce == ceParams)
			{
				qout << "ERROR: Incorrect parameters" << endl;
			}
			else if (ce == ceRun)
			{
				qout << "ERROR: Can't run the command! The device may be unplugged..." << endl;
			}
		}
	}


    devUsbClose(mydev);

	return 0;
}
int SecondaryTableController::modifyLocalRoute(unsigned netId, const char *action,
        const char *iface, const char *addr) {
    char tableIndex_str[11];

    modifyRuleCount(netId, action); // some del's will fail as the iface is already gone.
    snprintf(tableIndex_str, sizeof(tableIndex_str), "%u", netId + BASE_TABLE_NUMBER);
    const char *cmd[] = {
            IP_PATH,
            "route",
            action,
            addr,
            "dev",
            iface,
            "table",
            tableIndex_str
    };

    return runCmd(ARRAY_SIZE(cmd), cmd);
}
Beispiel #25
0
// ATSn? – display radio parameter number ‘n’
int MavlinkModem::ats(int number) {
  int result;
  if (startCmdMode()) {
    String cmd = "ATS" + String(number) + "?\r";
    String value = runCmd(cmd, ATI_DELAY, false);
    value.replace(cmd, "");
    value.replace("\r\n", "");

    if (number == 8 || number == 9) {
    char tarray[10];
      value.toCharArray(tarray, sizeof(tarray));
      long lValue = atol(tarray);
      result = lValue / 1000;
    } else {
      result = value.toInt();
    }
    stopCmdMode();
  }
  return result;
}
Beispiel #26
0
int main(int argc, char **argv) {
    mainTestFn testFunction = NULL;
    char *dbPath = NULL;
    char **testArgv = NULL;
    int testArgc = 0;
    int rv = 0;

    rv = getTestArguments(argc, argv, &testFunction, &dbPath,
                          &testArgc, &testArgv);
    if (rv != SECSuccess) {
        printUsage(argv[0]);
        return 1;
    }
    
    rv = runCmd(testFunction, testArgc, testArgv, dbPath);

    PORT_Free(testArgv);

    return rv;
}
Beispiel #27
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;
}
Beispiel #28
0
void MavlinkModem::readAtsAll(int rows[]) {
  if (startCmdMode()) {
    String cmd;
    String value;
    for (int i = 1; i < 16; i++) {
      cmd = "ATS" + String(i) + "?\r";
      value = runCmd(cmd, ATI_DELAY, false);
      value.replace(cmd, "");
      value.replace("\r\n", "");

      if (i == 8 || i == 9) {
      char tarray[10];
        value.toCharArray(tarray, sizeof(tarray));
        long lValue = atol(tarray);
        rows[i-1] = lValue / 1000;
      } else {
        rows[i-1] = value.toInt();
      }
    }
    stopCmdMode();
  }
}
int NatController::routesOp(bool add, const char *intIface, const char *extIface, char **argv, int addrCount) {
    unsigned netId = mNetCtrl->getNetworkId(extIface);
    int ret = 0;

    for (int i = 0; i < addrCount; i++) {
        if (add) {
            ret |= mSecondaryTableCtrl->modifyFromRule(netId, ADD, argv[5+i]);
            ret |= mSecondaryTableCtrl->modifyLocalRoute(netId, ADD, intIface, argv[5+i]);
        } else {
            ret |= mSecondaryTableCtrl->modifyLocalRoute(netId, DEL, intIface, argv[5+i]);
            ret |= mSecondaryTableCtrl->modifyFromRule(netId, DEL, argv[5+i]);
        }
    }
    const char *cmd[] = {
            IP_PATH,
            "route",
            "flush",
            "cache"
    };
    runCmd(ARRAY_SIZE(cmd), cmd);
    return ret;
}
int SecondaryTableController::modifyFromRule(unsigned netId, const char *action,
        const char *addr) {
    char tableIndex_str[11];

    snprintf(tableIndex_str, sizeof(tableIndex_str), "%u", netId + BASE_TABLE_NUMBER);
    const char *cmd[] = {
            IP_PATH,
            getVersion(addr),
            "rule",
            action,
            "from",
            addr,
            "table",
            tableIndex_str
    };
    if (runCmd(ARRAY_SIZE(cmd), cmd)) {
        return -1;
    }

    modifyRuleCount(netId, action);
    return 0;
}