cli->sendMsg(ResponseCode::CommandOkay, "MTU changed", false);
} else {
cli->sendMsg(ResponseCode::OperationFailed,
- "Failed to get MTU", true);
+ "Failed to set MTU", true);
}
return 0;
} else {
NetdCommand("ipfwd") {
}
-int CommandListener::IpFwdCmd::runCommand(SocketClient *cli,
- int argc, char **argv) {
- int rc = 0;
-
- if (argc < 2) {
- cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
- return 0;
- }
+int CommandListener::IpFwdCmd::runCommand(SocketClient *cli, int argc, char **argv) {
+ bool matched = false;
+ bool success;
- if (!strcmp(argv[1], "status")) {
- char *tmp = NULL;
+ if (argc == 2) {
+ // 0 1
+ // ipfwd status
+ if (!strcmp(argv[1], "status")) {
+ char *tmp = NULL;
- asprintf(&tmp, "Forwarding %s", (sTetherCtrl->getIpFwdEnabled() ? "enabled" : "disabled"));
- cli->sendMsg(ResponseCode::IpFwdStatusResult, tmp, false);
- free(tmp);
- return 0;
- } else if (!strcmp(argv[1], "enable")) {
- rc = sTetherCtrl->setIpFwdEnabled(true);
- } else if (!strcmp(argv[1], "disable")) {
- rc = sTetherCtrl->setIpFwdEnabled(false);
- } else {
+ asprintf(&tmp, "Forwarding %s",
+ ((sTetherCtrl->forwardingRequestCount() > 0) ? "enabled" : "disabled"));
+ cli->sendMsg(ResponseCode::IpFwdStatusResult, tmp, false);
+ free(tmp);
+ return 0;
+ }
+ } else if (argc == 3) {
+ // 0 1 2
+ // ipfwd enable <requester>
+ // ipfwd disable <requester>
+ if (!strcmp(argv[1], "enable")) {
+ matched = true;
+ success = sTetherCtrl->enableForwarding(argv[2]);
+ } else if (!strcmp(argv[1], "disable")) {
+ matched = true;
+ success = sTetherCtrl->disableForwarding(argv[2]);
+ }
+ } else if (argc == 4) {
+ // 0 1 2 3
+ // ipfwd add wlan0 dummy0
+ // ipfwd remove wlan0 dummy0
+ int ret = 0;
+ if (!strcmp(argv[1], "add")) {
+ matched = true;
+ ret = RouteController::enableTethering(argv[2], argv[3]);
+ } else if (!strcmp(argv[1], "remove")) {
+ matched = true;
+ ret = RouteController::disableTethering(argv[2], argv[3]);
+ }
+ success = (ret == 0);
+ errno = -ret;
+ }
+
+ if (!matched) {
cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown ipfwd cmd", false);
return 0;
}
- if (!rc) {
+ if (success) {
cli->sendMsg(ResponseCode::CommandOkay, "ipfwd operation succeeded", false);
} else {
cli->sendMsg(ResponseCode::OperationFailed, "ipfwd operation failed", true);
}
-
return 0;
}
return 0;
}
- int num_addrs = argc - 2;
- int arg_index = 2;
- int array_index = 0;
- in_addr *addrs = (in_addr *)malloc(sizeof(in_addr) * num_addrs);
- while (array_index < num_addrs) {
- if (!inet_aton(argv[arg_index++], &(addrs[array_index++]))) {
+ const int num_addrs = argc - 2;
+ // TODO: consider moving this validation into TetherController.
+ struct in_addr tmp_addr;
+ for (int arg_index = 2; arg_index < argc; arg_index++) {
+ if (!inet_aton(argv[arg_index], &tmp_addr)) {
cli->sendMsg(ResponseCode::CommandParameterError, "Invalid address", false);
- free(addrs);
return 0;
}
}
- rc = sTetherCtrl->startTethering(num_addrs, addrs);
- free(addrs);
+
+ rc = sTetherCtrl->startTethering(num_addrs, &(argv[2]));
} else if (!strcmp(argv[1], "interface")) {
if (!strcmp(argv[2], "add")) {
rc = sTetherCtrl->tetherInterface(argv[3]);
FirewallRule CommandListener::FirewallCmd::parseRule(const char* arg) {
if (!strcmp(arg, "allow")) {
return ALLOW;
- } else {
+ } else if (!strcmp(arg, "deny")) {
return DENY;
+ } else {
+ ALOGE("failed to parse uid rule (%s)", arg);
+ return ALLOW;
+ }
+}
+
+FirewallType CommandListener::FirewallCmd::parseFirewallType(const char* arg) {
+ if (!strcmp(arg, "whitelist")) {
+ return WHITELIST;
+ } else if (!strcmp(arg, "blacklist")) {
+ return BLACKLIST;
+ } else {
+ ALOGE("failed to parse firewall type (%s)", arg);
+ return BLACKLIST;
+ }
+}
+
+ChildChain CommandListener::FirewallCmd::parseChildChain(const char* arg) {
+ if (!strcmp(arg, "dozable")) {
+ return DOZABLE;
+ } else if (!strcmp(arg, "standby")) {
+ return STANDBY;
+ } else if (!strcmp(arg, "none")) {
+ return NONE;
+ } else {
+ ALOGE("failed to parse child firewall chain (%s)", arg);
+ return INVALID_CHAIN;
}
}
}
if (!strcmp(argv[1], "enable")) {
- int res = sFirewallCtrl->enableFirewall();
+ if (argc != 3) {
+ cli->sendMsg(ResponseCode::CommandSyntaxError,
+ "Usage: firewall enable <whitelist|blacklist>", false);
+ return 0;
+ }
+ FirewallType firewallType = parseFirewallType(argv[2]);
+
+ int res = sFirewallCtrl->enableFirewall(firewallType);
return sendGenericOkFail(cli, res);
}
if (!strcmp(argv[1], "disable")) {
}
if (!strcmp(argv[1], "set_uid_rule")) {
- if (argc != 4) {
+ if (argc != 5) {
cli->sendMsg(ResponseCode::CommandSyntaxError,
- "Usage: firewall set_uid_rule <1000> <allow|deny>",
+ "Usage: firewall set_uid_rule <dozable|standby|none> <1000> <allow|deny>",
false);
return 0;
}
- int uid = atoi(argv[2]);
- FirewallRule rule = parseRule(argv[3]);
+ ChildChain childChain = parseChildChain(argv[2]);
+ if (childChain == INVALID_CHAIN) {
+ cli->sendMsg(ResponseCode::CommandSyntaxError,
+ "Invalid chain name. Valid names are: <dozable|standby|none>",
+ false);
+ return 0;
+ }
+ int uid = atoi(argv[3]);
+ FirewallRule rule = parseRule(argv[4]);
+ int res = sFirewallCtrl->setUidRule(childChain, uid, rule);
+ return sendGenericOkFail(cli, res);
+ }
+
+ if (!strcmp(argv[1], "enable_chain")) {
+ if (argc != 3) {
+ cli->sendMsg(ResponseCode::CommandSyntaxError,
+ "Usage: firewall enable_chain <dozable|standby>",
+ false);
+ return 0;
+ }
+
+ ChildChain childChain = parseChildChain(argv[2]);
+ int res = sFirewallCtrl->enableChildChains(childChain, true);
+ return sendGenericOkFail(cli, res);
+ }
+
+ if (!strcmp(argv[1], "disable_chain")) {
+ if (argc != 3) {
+ cli->sendMsg(ResponseCode::CommandSyntaxError,
+ "Usage: firewall disable_chain <dozable|standby>",
+ false);
+ return 0;
+ }
- int res = sFirewallCtrl->setUidRule(uid, rule);
+ ChildChain childChain = parseChildChain(argv[2]);
+ int res = sFirewallCtrl->enableChildChains(childChain, false);
return sendGenericOkFail(cli, res);
}