1 /*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 // #define LOG_NDEBUG 0
18
19 #include <stdlib.h>
20 #include <sys/socket.h>
21 #include <sys/types.h>
22 #include <netinet/in.h>
23 #include <arpa/inet.h>
24 #include <dirent.h>
25 #include <errno.h>
26 #include <string.h>
27 #include <linux/if.h>
28
29 #define LOG_TAG "CommandListener"
30
31 #include <cutils/log.h>
32 #include <netutils/ifc.h>
33 #include <sysutils/SocketClient.h>
34
35 #include "CommandListener.h"
36 #include "ResponseCode.h"
37 #include "BandwidthController.h"
38 #include "IdletimerController.h"
39 #include "SecondaryTableController.h"
40 #include "oem_iptables_hook.h"
41 #include "NetdConstants.h"
42 #include "FirewallController.h"
43
44 TetherController *CommandListener::sTetherCtrl = NULL;
45 NatController *CommandListener::sNatCtrl = NULL;
46 PppController *CommandListener::sPppCtrl = NULL;
47 SoftapController *CommandListener::sSoftapCtrl = NULL;
48 BandwidthController * CommandListener::sBandwidthCtrl = NULL;
49 IdletimerController * CommandListener::sIdletimerCtrl = NULL;
50 InterfaceController *CommandListener::sInterfaceCtrl = NULL;
51 ResolverController *CommandListener::sResolverCtrl = NULL;
52 SecondaryTableController *CommandListener::sSecondaryTableCtrl = NULL;
53 FirewallController *CommandListener::sFirewallCtrl = NULL;
54 ClatdController *CommandListener::sClatdCtrl = NULL;
55
56 /**
57 * List of module chains to be created, along with explicit ordering. ORDERING
58 * IS CRITICAL, AND SHOULD BE TRIPLE-CHECKED WITH EACH CHANGE.
59 */
60 static const char* FILTER_INPUT[] = {
61 // Bandwidth should always be early in input chain, to make sure we
62 // correctly count incoming traffic against data plan.
63 BandwidthController::LOCAL_INPUT,
64 FirewallController::LOCAL_INPUT,
65 NULL,
66 };
67
68 static const char* FILTER_FORWARD[] = {
69 OEM_IPTABLES_FILTER_FORWARD,
70 FirewallController::LOCAL_FORWARD,
71 BandwidthController::LOCAL_FORWARD,
72 NatController::LOCAL_FORWARD,
73 NULL,
74 };
75
76 static const char* FILTER_OUTPUT[] = {
77 OEM_IPTABLES_FILTER_OUTPUT,
78 FirewallController::LOCAL_OUTPUT,
79 BandwidthController::LOCAL_OUTPUT,
80 NULL,
81 };
82
83 static const char* RAW_PREROUTING[] = {
84 BandwidthController::LOCAL_RAW_PREROUTING,
85 IdletimerController::LOCAL_RAW_PREROUTING,
86 NULL,
87 };
88
89 static const char* MANGLE_POSTROUTING[] = {
90 BandwidthController::LOCAL_MANGLE_POSTROUTING,
91 IdletimerController::LOCAL_MANGLE_POSTROUTING,
92 NULL,
93 };
94
95 static const char* NAT_PREROUTING[] = {
96 OEM_IPTABLES_NAT_PREROUTING,
97 NULL,
98 };
99
100 static const char* NAT_POSTROUTING[] = {
101 NatController::LOCAL_NAT_POSTROUTING,
102 NULL,
103 };
104
createChildChains(IptablesTarget target,const char * table,const char * parentChain,const char ** childChains)105 static void createChildChains(IptablesTarget target, const char* table, const char* parentChain,
106 const char** childChains) {
107 const char** childChain = childChains;
108 do {
109 // Order is important:
110 // -D to delete any pre-existing jump rule (removes references
111 // that would prevent -X from working)
112 // -F to flush any existing chain
113 // -X to delete any existing chain
114 // -N to create the chain
115 // -A to append the chain to parent
116
117 execIptablesSilently(target, "-t", table, "-D", parentChain, "-j", *childChain, NULL);
118 execIptablesSilently(target, "-t", table, "-F", *childChain, NULL);
119 execIptablesSilently(target, "-t", table, "-X", *childChain, NULL);
120 execIptables(target, "-t", table, "-N", *childChain, NULL);
121 execIptables(target, "-t", table, "-A", parentChain, "-j", *childChain, NULL);
122 } while (*(++childChain) != NULL);
123 }
124
CommandListener()125 CommandListener::CommandListener() :
126 FrameworkListener("netd", true) {
127 registerCmd(new InterfaceCmd());
128 registerCmd(new IpFwdCmd());
129 registerCmd(new TetherCmd());
130 registerCmd(new NatCmd());
131 registerCmd(new ListTtysCmd());
132 registerCmd(new PppdCmd());
133 registerCmd(new SoftapCmd());
134 registerCmd(new BandwidthControlCmd());
135 registerCmd(new IdletimerControlCmd());
136 registerCmd(new ResolverCmd());
137 registerCmd(new FirewallCmd());
138 registerCmd(new ClatdCmd());
139
140 if (!sSecondaryTableCtrl)
141 sSecondaryTableCtrl = new SecondaryTableController();
142 if (!sTetherCtrl)
143 sTetherCtrl = new TetherController();
144 if (!sNatCtrl)
145 sNatCtrl = new NatController(sSecondaryTableCtrl);
146 if (!sPppCtrl)
147 sPppCtrl = new PppController();
148 if (!sSoftapCtrl)
149 sSoftapCtrl = new SoftapController();
150 if (!sBandwidthCtrl)
151 sBandwidthCtrl = new BandwidthController();
152 if (!sIdletimerCtrl)
153 sIdletimerCtrl = new IdletimerController();
154 if (!sResolverCtrl)
155 sResolverCtrl = new ResolverController();
156 if (!sFirewallCtrl)
157 sFirewallCtrl = new FirewallController();
158 if (!sInterfaceCtrl)
159 sInterfaceCtrl = new InterfaceController();
160 if (!sClatdCtrl)
161 sClatdCtrl = new ClatdController();
162
163 /*
164 * This is the only time we touch top-level chains in iptables; controllers
165 * should only mutate rules inside of their children chains, as created by
166 * the constants above.
167 *
168 * Modules should never ACCEPT packets (except in well-justified cases);
169 * they should instead defer to any remaining modules using RETURN, or
170 * otherwise DROP/REJECT.
171 */
172
173 // Create chains for children modules
174 createChildChains(V4V6, "filter", "INPUT", FILTER_INPUT);
175 createChildChains(V4V6, "filter", "FORWARD", FILTER_FORWARD);
176 createChildChains(V4V6, "filter", "OUTPUT", FILTER_OUTPUT);
177 createChildChains(V4V6, "raw", "PREROUTING", RAW_PREROUTING);
178 createChildChains(V4V6, "mangle", "POSTROUTING", MANGLE_POSTROUTING);
179 createChildChains(V4, "nat", "PREROUTING", NAT_PREROUTING);
180 createChildChains(V4, "nat", "POSTROUTING", NAT_POSTROUTING);
181
182 // Let each module setup their child chains
183 setupOemIptablesHook();
184
185 /* When enabled, DROPs all packets except those matching rules. */
186 sFirewallCtrl->setupIptablesHooks();
187
188 /* Does DROPs in FORWARD by default */
189 sNatCtrl->setupIptablesHooks();
190 /*
191 * Does REJECT in INPUT, OUTPUT. Does counting also.
192 * No DROP/REJECT allowed later in netfilter-flow hook order.
193 */
194 sBandwidthCtrl->setupIptablesHooks();
195 /*
196 * Counts in nat: PREROUTING, POSTROUTING.
197 * No DROP/REJECT allowed later in netfilter-flow hook order.
198 */
199 sIdletimerCtrl->setupIptablesHooks();
200
201 sBandwidthCtrl->enableBandwidthControl(false);
202 }
203
InterfaceCmd()204 CommandListener::InterfaceCmd::InterfaceCmd() :
205 NetdCommand("interface") {
206 }
207
runCommand(SocketClient * cli,int argc,char ** argv)208 int CommandListener::InterfaceCmd::runCommand(SocketClient *cli,
209 int argc, char **argv) {
210 if (argc < 2) {
211 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
212 return 0;
213 }
214
215 if (!strcmp(argv[1], "list")) {
216 DIR *d;
217 struct dirent *de;
218
219 if (!(d = opendir("/sys/class/net"))) {
220 cli->sendMsg(ResponseCode::OperationFailed, "Failed to open sysfs dir", true);
221 return 0;
222 }
223
224 while((de = readdir(d))) {
225 if (de->d_name[0] == '.')
226 continue;
227 cli->sendMsg(ResponseCode::InterfaceListResult, de->d_name, false);
228 }
229 closedir(d);
230 cli->sendMsg(ResponseCode::CommandOkay, "Interface list completed", false);
231 return 0;
232 } else if (!strcmp(argv[1], "driver")) {
233 int rc;
234 char *rbuf;
235
236 if (argc < 4) {
237 cli->sendMsg(ResponseCode::CommandSyntaxError,
238 "Usage: interface driver <interface> <cmd> <args>", false);
239 return 0;
240 }
241 rc = sInterfaceCtrl->interfaceCommand(argc, argv, &rbuf);
242 if (rc) {
243 cli->sendMsg(ResponseCode::OperationFailed, "Failed to execute command", true);
244 } else {
245 cli->sendMsg(ResponseCode::CommandOkay, rbuf, false);
246 }
247 return 0;
248 } else {
249 /*
250 * These commands take a minimum of 3 arguments
251 */
252 if (argc < 3) {
253 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
254 return 0;
255 }
256
257 // 0 1 2 3 4 5 6 7
258 // interface route add/remove iface default/secondary dest prefix gateway
259 if (!strcmp(argv[1], "route")) {
260 int prefix_length = 0;
261 if (argc < 8) {
262 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
263 return 0;
264 }
265 if (sscanf(argv[6], "%d", &prefix_length) != 1) {
266 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid route prefix", false);
267 return 0;
268 }
269 if (!strcmp(argv[2], "add")) {
270 if (!strcmp(argv[4], "default")) {
271 if (ifc_add_route(argv[3], argv[5], prefix_length, argv[7])) {
272 cli->sendMsg(ResponseCode::OperationFailed,
273 "Failed to add route to default table", true);
274 } else {
275 cli->sendMsg(ResponseCode::CommandOkay,
276 "Route added to default table", false);
277 }
278 } else if (!strcmp(argv[4], "secondary")) {
279 return sSecondaryTableCtrl->addRoute(cli, argv[3], argv[5],
280 prefix_length, argv[7]);
281 } else {
282 cli->sendMsg(ResponseCode::CommandParameterError,
283 "Invalid route type, expecting 'default' or 'secondary'", false);
284 return 0;
285 }
286 } else if (!strcmp(argv[2], "remove")) {
287 if (!strcmp(argv[4], "default")) {
288 if (ifc_remove_route(argv[3], argv[5], prefix_length, argv[7])) {
289 cli->sendMsg(ResponseCode::OperationFailed,
290 "Failed to remove route from default table", true);
291 } else {
292 cli->sendMsg(ResponseCode::CommandOkay,
293 "Route removed from default table", false);
294 }
295 } else if (!strcmp(argv[4], "secondary")) {
296 return sSecondaryTableCtrl->removeRoute(cli, argv[3], argv[5],
297 prefix_length, argv[7]);
298 } else {
299 cli->sendMsg(ResponseCode::CommandParameterError,
300 "Invalid route type, expecting 'default' or 'secondary'", false);
301 return 0;
302 }
303 } else {
304 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown interface cmd", false);
305 }
306 return 0;
307 }
308
309 if (!strcmp(argv[1], "getcfg")) {
310 struct in_addr addr;
311 int prefixLength;
312 unsigned char hwaddr[6];
313 unsigned flags = 0;
314
315 ifc_init();
316 memset(hwaddr, 0, sizeof(hwaddr));
317
318 if (ifc_get_info(argv[2], &addr.s_addr, &prefixLength, &flags)) {
319 cli->sendMsg(ResponseCode::OperationFailed, "Interface not found", true);
320 ifc_close();
321 return 0;
322 }
323
324 if (ifc_get_hwaddr(argv[2], (void *) hwaddr)) {
325 ALOGW("Failed to retrieve HW addr for %s (%s)", argv[2], strerror(errno));
326 }
327
328 char *addr_s = strdup(inet_ntoa(addr));
329 const char *updown, *brdcst, *loopbk, *ppp, *running, *multi;
330
331 updown = (flags & IFF_UP) ? "up" : "down";
332 brdcst = (flags & IFF_BROADCAST) ? " broadcast" : "";
333 loopbk = (flags & IFF_LOOPBACK) ? " loopback" : "";
334 ppp = (flags & IFF_POINTOPOINT) ? " point-to-point" : "";
335 running = (flags & IFF_RUNNING) ? " running" : "";
336 multi = (flags & IFF_MULTICAST) ? " multicast" : "";
337
338 char *flag_s;
339
340 asprintf(&flag_s, "%s%s%s%s%s%s", updown, brdcst, loopbk, ppp, running, multi);
341
342 char *msg = NULL;
343 asprintf(&msg, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x %s %d %s",
344 hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5],
345 addr_s, prefixLength, flag_s);
346
347 cli->sendMsg(ResponseCode::InterfaceGetCfgResult, msg, false);
348
349 free(addr_s);
350 free(flag_s);
351 free(msg);
352
353 ifc_close();
354 return 0;
355 } else if (!strcmp(argv[1], "setcfg")) {
356 // arglist: iface [addr prefixLength] flags
357 if (argc < 4) {
358 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
359 return 0;
360 }
361 ALOGD("Setting iface cfg");
362
363 struct in_addr addr;
364 unsigned flags = 0;
365 int index = 5;
366
367 ifc_init();
368
369 if (!inet_aton(argv[3], &addr)) {
370 // Handle flags only case
371 index = 3;
372 } else {
373 if (ifc_set_addr(argv[2], addr.s_addr)) {
374 cli->sendMsg(ResponseCode::OperationFailed, "Failed to set address", true);
375 ifc_close();
376 return 0;
377 }
378
379 // Set prefix length on a non zero address
380 if (addr.s_addr != 0 && ifc_set_prefixLength(argv[2], atoi(argv[4]))) {
381 cli->sendMsg(ResponseCode::OperationFailed, "Failed to set prefixLength", true);
382 ifc_close();
383 return 0;
384 }
385 }
386
387 /* Process flags */
388 for (int i = index; i < argc; i++) {
389 char *flag = argv[i];
390 if (!strcmp(flag, "up")) {
391 ALOGD("Trying to bring up %s", argv[2]);
392 if (ifc_up(argv[2])) {
393 ALOGE("Error upping interface");
394 cli->sendMsg(ResponseCode::OperationFailed, "Failed to up interface", true);
395 ifc_close();
396 return 0;
397 }
398 } else if (!strcmp(flag, "down")) {
399 ALOGD("Trying to bring down %s", argv[2]);
400 if (ifc_down(argv[2])) {
401 ALOGE("Error downing interface");
402 cli->sendMsg(ResponseCode::OperationFailed, "Failed to down interface", true);
403 ifc_close();
404 return 0;
405 }
406 } else if (!strcmp(flag, "broadcast")) {
407 // currently ignored
408 } else if (!strcmp(flag, "multicast")) {
409 // currently ignored
410 } else if (!strcmp(flag, "running")) {
411 // currently ignored
412 } else if (!strcmp(flag, "loopback")) {
413 // currently ignored
414 } else if (!strcmp(flag, "point-to-point")) {
415 // currently ignored
416 } else {
417 cli->sendMsg(ResponseCode::CommandParameterError, "Flag unsupported", false);
418 ifc_close();
419 return 0;
420 }
421 }
422
423 cli->sendMsg(ResponseCode::CommandOkay, "Interface configuration set", false);
424 ifc_close();
425 return 0;
426 } else if (!strcmp(argv[1], "clearaddrs")) {
427 // arglist: iface
428 ALOGD("Clearing all IP addresses on %s", argv[2]);
429
430 ifc_clear_addresses(argv[2]);
431
432 cli->sendMsg(ResponseCode::CommandOkay, "Interface IP addresses cleared", false);
433 return 0;
434 } else if (!strcmp(argv[1], "ipv6privacyextensions")) {
435 if (argc != 4) {
436 cli->sendMsg(ResponseCode::CommandSyntaxError,
437 "Usage: interface ipv6privacyextensions <interface> <enable|disable>",
438 false);
439 return 0;
440 }
441 int enable = !strncmp(argv[3], "enable", 7);
442 if (sInterfaceCtrl->setIPv6PrivacyExtensions(argv[2], enable) == 0) {
443 cli->sendMsg(ResponseCode::CommandOkay, "IPv6 privacy extensions changed", false);
444 } else {
445 cli->sendMsg(ResponseCode::OperationFailed,
446 "Failed to set ipv6 privacy extensions", true);
447 }
448 return 0;
449 } else if (!strcmp(argv[1], "ipv6")) {
450 if (argc != 4) {
451 cli->sendMsg(ResponseCode::CommandSyntaxError,
452 "Usage: interface ipv6 <interface> <enable|disable>",
453 false);
454 return 0;
455 }
456
457 int enable = !strncmp(argv[3], "enable", 7);
458 if (sInterfaceCtrl->setEnableIPv6(argv[2], enable) == 0) {
459 cli->sendMsg(ResponseCode::CommandOkay, "IPv6 state changed", false);
460 } else {
461 cli->sendMsg(ResponseCode::OperationFailed,
462 "Failed to change IPv6 state", true);
463 }
464 return 0;
465 } else {
466 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown interface cmd", false);
467 return 0;
468 }
469 }
470 return 0;
471 }
472
473
ListTtysCmd()474 CommandListener::ListTtysCmd::ListTtysCmd() :
475 NetdCommand("list_ttys") {
476 }
477
runCommand(SocketClient * cli,int argc,char ** argv)478 int CommandListener::ListTtysCmd::runCommand(SocketClient *cli,
479 int argc, char **argv) {
480 TtyCollection *tlist = sPppCtrl->getTtyList();
481 TtyCollection::iterator it;
482
483 for (it = tlist->begin(); it != tlist->end(); ++it) {
484 cli->sendMsg(ResponseCode::TtyListResult, *it, false);
485 }
486
487 cli->sendMsg(ResponseCode::CommandOkay, "Ttys listed.", false);
488 return 0;
489 }
490
IpFwdCmd()491 CommandListener::IpFwdCmd::IpFwdCmd() :
492 NetdCommand("ipfwd") {
493 }
494
runCommand(SocketClient * cli,int argc,char ** argv)495 int CommandListener::IpFwdCmd::runCommand(SocketClient *cli,
496 int argc, char **argv) {
497 int rc = 0;
498
499 if (argc < 2) {
500 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
501 return 0;
502 }
503
504 if (!strcmp(argv[1], "status")) {
505 char *tmp = NULL;
506
507 asprintf(&tmp, "Forwarding %s", (sTetherCtrl->getIpFwdEnabled() ? "enabled" : "disabled"));
508 cli->sendMsg(ResponseCode::IpFwdStatusResult, tmp, false);
509 free(tmp);
510 return 0;
511 } else if (!strcmp(argv[1], "enable")) {
512 rc = sTetherCtrl->setIpFwdEnabled(true);
513 } else if (!strcmp(argv[1], "disable")) {
514 rc = sTetherCtrl->setIpFwdEnabled(false);
515 } else {
516 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown ipfwd cmd", false);
517 return 0;
518 }
519
520 if (!rc) {
521 cli->sendMsg(ResponseCode::CommandOkay, "ipfwd operation succeeded", false);
522 } else {
523 cli->sendMsg(ResponseCode::OperationFailed, "ipfwd operation failed", true);
524 }
525
526 return 0;
527 }
528
TetherCmd()529 CommandListener::TetherCmd::TetherCmd() :
530 NetdCommand("tether") {
531 }
532
runCommand(SocketClient * cli,int argc,char ** argv)533 int CommandListener::TetherCmd::runCommand(SocketClient *cli,
534 int argc, char **argv) {
535 int rc = 0;
536
537 if (argc < 2) {
538 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
539 return 0;
540 }
541
542 if (!strcmp(argv[1], "stop")) {
543 rc = sTetherCtrl->stopTethering();
544 } else if (!strcmp(argv[1], "status")) {
545 char *tmp = NULL;
546
547 asprintf(&tmp, "Tethering services %s",
548 (sTetherCtrl->isTetheringStarted() ? "started" : "stopped"));
549 cli->sendMsg(ResponseCode::TetherStatusResult, tmp, false);
550 free(tmp);
551 return 0;
552 } else if (argc == 3) {
553 if (!strcmp(argv[1], "interface") && !strcmp(argv[2], "list")) {
554 InterfaceCollection *ilist = sTetherCtrl->getTetheredInterfaceList();
555 InterfaceCollection::iterator it;
556 for (it = ilist->begin(); it != ilist->end(); ++it) {
557 cli->sendMsg(ResponseCode::TetherInterfaceListResult, *it, false);
558 }
559 } else if (!strcmp(argv[1], "dns") && !strcmp(argv[2], "list")) {
560 NetAddressCollection *dlist = sTetherCtrl->getDnsForwarders();
561 NetAddressCollection::iterator it;
562
563 for (it = dlist->begin(); it != dlist->end(); ++it) {
564 cli->sendMsg(ResponseCode::TetherDnsFwdTgtListResult, inet_ntoa(*it), false);
565 }
566 }
567 } else {
568 /*
569 * These commands take a minimum of 4 arguments
570 */
571 if (argc < 4) {
572 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
573 return 0;
574 }
575
576 if (!strcmp(argv[1], "start")) {
577 if (argc % 2 == 1) {
578 cli->sendMsg(ResponseCode::CommandSyntaxError, "Bad number of arguments", false);
579 return 0;
580 }
581
582 int num_addrs = argc - 2;
583 int arg_index = 2;
584 int array_index = 0;
585 in_addr *addrs = (in_addr *)malloc(sizeof(in_addr) * num_addrs);
586 while (array_index < num_addrs) {
587 if (!inet_aton(argv[arg_index++], &(addrs[array_index++]))) {
588 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid address", false);
589 free(addrs);
590 return 0;
591 }
592 }
593 rc = sTetherCtrl->startTethering(num_addrs, addrs);
594 free(addrs);
595 } else if (!strcmp(argv[1], "interface")) {
596 if (!strcmp(argv[2], "add")) {
597 rc = sTetherCtrl->tetherInterface(argv[3]);
598 } else if (!strcmp(argv[2], "remove")) {
599 rc = sTetherCtrl->untetherInterface(argv[3]);
600 /* else if (!strcmp(argv[2], "list")) handled above */
601 } else {
602 cli->sendMsg(ResponseCode::CommandParameterError,
603 "Unknown tether interface operation", false);
604 return 0;
605 }
606 } else if (!strcmp(argv[1], "dns")) {
607 if (!strcmp(argv[2], "set")) {
608 rc = sTetherCtrl->setDnsForwarders(&argv[3], argc - 3);
609 /* else if (!strcmp(argv[2], "list")) handled above */
610 } else {
611 cli->sendMsg(ResponseCode::CommandParameterError,
612 "Unknown tether interface operation", false);
613 return 0;
614 }
615 } else {
616 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown tether cmd", false);
617 return 0;
618 }
619 }
620
621 if (!rc) {
622 cli->sendMsg(ResponseCode::CommandOkay, "Tether operation succeeded", false);
623 } else {
624 cli->sendMsg(ResponseCode::OperationFailed, "Tether operation failed", true);
625 }
626
627 return 0;
628 }
629
NatCmd()630 CommandListener::NatCmd::NatCmd() :
631 NetdCommand("nat") {
632 }
633
runCommand(SocketClient * cli,int argc,char ** argv)634 int CommandListener::NatCmd::runCommand(SocketClient *cli,
635 int argc, char **argv) {
636 int rc = 0;
637
638 if (argc < 5) {
639 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
640 return 0;
641 }
642
643 if (!strcmp(argv[1], "enable")) {
644 rc = sNatCtrl->enableNat(argc, argv);
645 if(!rc) {
646 /* Ignore ifaces for now. */
647 rc = sBandwidthCtrl->setGlobalAlertInForwardChain();
648 }
649 } else if (!strcmp(argv[1], "disable")) {
650 /* Ignore ifaces for now. */
651 rc = sBandwidthCtrl->removeGlobalAlertInForwardChain();
652 rc |= sNatCtrl->disableNat(argc, argv);
653 } else {
654 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown nat cmd", false);
655 return 0;
656 }
657
658 if (!rc) {
659 cli->sendMsg(ResponseCode::CommandOkay, "Nat operation succeeded", false);
660 } else {
661 cli->sendMsg(ResponseCode::OperationFailed, "Nat operation failed", true);
662 }
663
664 return 0;
665 }
666
PppdCmd()667 CommandListener::PppdCmd::PppdCmd() :
668 NetdCommand("pppd") {
669 }
670
runCommand(SocketClient * cli,int argc,char ** argv)671 int CommandListener::PppdCmd::runCommand(SocketClient *cli,
672 int argc, char **argv) {
673 int rc = 0;
674
675 if (argc < 3) {
676 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
677 return 0;
678 }
679
680 if (!strcmp(argv[1], "attach")) {
681 struct in_addr l, r, dns1, dns2;
682
683 memset(&dns1, sizeof(struct in_addr), 0);
684 memset(&dns2, sizeof(struct in_addr), 0);
685
686 if (!inet_aton(argv[3], &l)) {
687 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid local address", false);
688 return 0;
689 }
690 if (!inet_aton(argv[4], &r)) {
691 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid remote address", false);
692 return 0;
693 }
694 if ((argc > 3) && (!inet_aton(argv[5], &dns1))) {
695 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid dns1 address", false);
696 return 0;
697 }
698 if ((argc > 4) && (!inet_aton(argv[6], &dns2))) {
699 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid dns2 address", false);
700 return 0;
701 }
702 rc = sPppCtrl->attachPppd(argv[2], l, r, dns1, dns2);
703 } else if (!strcmp(argv[1], "detach")) {
704 rc = sPppCtrl->detachPppd(argv[2]);
705 } else {
706 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown pppd cmd", false);
707 return 0;
708 }
709
710 if (!rc) {
711 cli->sendMsg(ResponseCode::CommandOkay, "Pppd operation succeeded", false);
712 } else {
713 cli->sendMsg(ResponseCode::OperationFailed, "Pppd operation failed", true);
714 }
715
716 return 0;
717 }
718
SoftapCmd()719 CommandListener::SoftapCmd::SoftapCmd() :
720 NetdCommand("softap") {
721 }
722
runCommand(SocketClient * cli,int argc,char ** argv)723 int CommandListener::SoftapCmd::runCommand(SocketClient *cli,
724 int argc, char **argv) {
725 int rc = ResponseCode::SoftapStatusResult;
726 int flag = 0;
727 char *retbuf = NULL;
728
729 if (sSoftapCtrl == NULL) {
730 cli->sendMsg(ResponseCode::ServiceStartFailed, "SoftAP is not available", false);
731 return -1;
732 }
733 if (argc < 2) {
734 cli->sendMsg(ResponseCode::CommandSyntaxError,
735 "Missing argument in a SoftAP command", false);
736 return 0;
737 }
738
739 if (!strcmp(argv[1], "startap")) {
740 rc = sSoftapCtrl->startSoftap();
741 } else if (!strcmp(argv[1], "stopap")) {
742 rc = sSoftapCtrl->stopSoftap();
743 } else if (!strcmp(argv[1], "fwreload")) {
744 rc = sSoftapCtrl->fwReloadSoftap(argc, argv);
745 } else if (!strcmp(argv[1], "status")) {
746 asprintf(&retbuf, "Softap service %s running",
747 (sSoftapCtrl->isSoftapStarted() ? "is" : "is not"));
748 cli->sendMsg(rc, retbuf, false);
749 free(retbuf);
750 return 0;
751 } else if (!strcmp(argv[1], "set")) {
752 rc = sSoftapCtrl->setSoftap(argc, argv);
753 } else {
754 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unrecognized SoftAP command", false);
755 return 0;
756 }
757
758 if (rc >= 400 && rc < 600)
759 cli->sendMsg(rc, "SoftAP command has failed", false);
760 else
761 cli->sendMsg(rc, "Ok", false);
762
763 return 0;
764 }
765
ResolverCmd()766 CommandListener::ResolverCmd::ResolverCmd() :
767 NetdCommand("resolver") {
768 }
769
runCommand(SocketClient * cli,int argc,char ** argv)770 int CommandListener::ResolverCmd::runCommand(SocketClient *cli, int argc, char **argv) {
771 int rc = 0;
772 struct in_addr addr;
773
774 if (argc < 2) {
775 cli->sendMsg(ResponseCode::CommandSyntaxError, "Resolver missing arguments", false);
776 return 0;
777 }
778
779 if (!strcmp(argv[1], "setdefaultif")) { // "resolver setdefaultif <iface>"
780 if (argc == 3) {
781 rc = sResolverCtrl->setDefaultInterface(argv[2]);
782 } else {
783 cli->sendMsg(ResponseCode::CommandSyntaxError,
784 "Wrong number of arguments to resolver setdefaultif", false);
785 return 0;
786 }
787 } else if (!strcmp(argv[1], "setifdns")) {
788 // "resolver setifdns <iface> <domains> <dns1> <dns2> ..."
789 if (argc >= 5) {
790 rc = sResolverCtrl->setInterfaceDnsServers(argv[2], argv[3], &argv[4], argc - 4);
791 } else {
792 cli->sendMsg(ResponseCode::CommandSyntaxError,
793 "Wrong number of arguments to resolver setifdns", false);
794 return 0;
795 }
796
797 // set the address of the interface to which the name servers
798 // are bound. Required in order to bind to right interface when
799 // doing the dns query.
800 if (!rc) {
801 ifc_init();
802 ifc_get_info(argv[2], &addr.s_addr, NULL, 0);
803
804 rc = sResolverCtrl->setInterfaceAddress(argv[2], &addr);
805 }
806 } else if (!strcmp(argv[1], "flushdefaultif")) { // "resolver flushdefaultif"
807 if (argc == 2) {
808 rc = sResolverCtrl->flushDefaultDnsCache();
809 } else {
810 cli->sendMsg(ResponseCode::CommandSyntaxError,
811 "Wrong number of arguments to resolver flushdefaultif", false);
812 return 0;
813 }
814 } else if (!strcmp(argv[1], "flushif")) { // "resolver flushif <iface>"
815 if (argc == 3) {
816 rc = sResolverCtrl->flushInterfaceDnsCache(argv[2]);
817 } else {
818 cli->sendMsg(ResponseCode::CommandSyntaxError,
819 "Wrong number of arguments to resolver setdefaultif", false);
820 return 0;
821 }
822 } else if (!strcmp(argv[1], "setifaceforpid")) { // resolver setifaceforpid <iface> <pid>
823 if (argc == 4) {
824 rc = sResolverCtrl->setDnsInterfaceForPid(argv[2], atoi(argv[3]));
825 } else {
826 cli->sendMsg(ResponseCode::CommandSyntaxError,
827 "Wrong number of arguments to resolver setifaceforpid", false);
828 return 0;
829 }
830 } else if (!strcmp(argv[1], "clearifaceforpid")) { // resolver clearifaceforpid <pid>
831 if (argc == 3) {
832 rc = sResolverCtrl->clearDnsInterfaceForPid(atoi(argv[2]));
833 } else {
834 cli->sendMsg(ResponseCode::CommandSyntaxError,
835 "Wrong number of arguments to resolver clearifaceforpid", false);
836 return 0;
837 }
838 } else {
839 cli->sendMsg(ResponseCode::CommandSyntaxError,"Resolver unknown command", false);
840 return 0;
841 }
842
843 if (!rc) {
844 cli->sendMsg(ResponseCode::CommandOkay, "Resolver command succeeded", false);
845 } else {
846 cli->sendMsg(ResponseCode::OperationFailed, "Resolver command failed", true);
847 }
848
849 return 0;
850 }
851
BandwidthControlCmd()852 CommandListener::BandwidthControlCmd::BandwidthControlCmd() :
853 NetdCommand("bandwidth") {
854 }
855
sendGenericSyntaxError(SocketClient * cli,const char * usageMsg)856 void CommandListener::BandwidthControlCmd::sendGenericSyntaxError(SocketClient *cli, const char *usageMsg) {
857 char *msg;
858 asprintf(&msg, "Usage: bandwidth %s", usageMsg);
859 cli->sendMsg(ResponseCode::CommandSyntaxError, msg, false);
860 free(msg);
861 }
862
sendGenericOkFail(SocketClient * cli,int cond)863 void CommandListener::BandwidthControlCmd::sendGenericOkFail(SocketClient *cli, int cond) {
864 if (!cond) {
865 cli->sendMsg(ResponseCode::CommandOkay, "Bandwidth command succeeeded", false);
866 } else {
867 cli->sendMsg(ResponseCode::OperationFailed, "Bandwidth command failed", false);
868 }
869 }
870
sendGenericOpFailed(SocketClient * cli,const char * errMsg)871 void CommandListener::BandwidthControlCmd::sendGenericOpFailed(SocketClient *cli, const char *errMsg) {
872 cli->sendMsg(ResponseCode::OperationFailed, errMsg, false);
873 }
874
runCommand(SocketClient * cli,int argc,char ** argv)875 int CommandListener::BandwidthControlCmd::runCommand(SocketClient *cli, int argc, char **argv) {
876 if (argc < 2) {
877 sendGenericSyntaxError(cli, "<cmds> <args...>");
878 return 0;
879 }
880
881 ALOGV("bwctrlcmd: argc=%d %s %s ...", argc, argv[0], argv[1]);
882
883 if (!strcmp(argv[1], "enable")) {
884 int rc = sBandwidthCtrl->enableBandwidthControl(true);
885 sendGenericOkFail(cli, rc);
886 return 0;
887
888 }
889 if (!strcmp(argv[1], "disable")) {
890 int rc = sBandwidthCtrl->disableBandwidthControl();
891 sendGenericOkFail(cli, rc);
892 return 0;
893
894 }
895 if (!strcmp(argv[1], "removequota") || !strcmp(argv[1], "rq")) {
896 if (argc != 3) {
897 sendGenericSyntaxError(cli, "removequota <interface>");
898 return 0;
899 }
900 int rc = sBandwidthCtrl->removeInterfaceSharedQuota(argv[2]);
901 sendGenericOkFail(cli, rc);
902 return 0;
903
904 }
905 if (!strcmp(argv[1], "getquota") || !strcmp(argv[1], "gq")) {
906 int64_t bytes;
907 if (argc != 2) {
908 sendGenericSyntaxError(cli, "getquota");
909 return 0;
910 }
911 int rc = sBandwidthCtrl->getInterfaceSharedQuota(&bytes);
912 if (rc) {
913 sendGenericOpFailed(cli, "Failed to get quota");
914 return 0;
915 }
916
917 char *msg;
918 asprintf(&msg, "%lld", bytes);
919 cli->sendMsg(ResponseCode::QuotaCounterResult, msg, false);
920 free(msg);
921 return 0;
922
923 }
924 if (!strcmp(argv[1], "getiquota") || !strcmp(argv[1], "giq")) {
925 int64_t bytes;
926 if (argc != 3) {
927 sendGenericSyntaxError(cli, "getiquota <iface>");
928 return 0;
929 }
930
931 int rc = sBandwidthCtrl->getInterfaceQuota(argv[2], &bytes);
932 if (rc) {
933 sendGenericOpFailed(cli, "Failed to get quota");
934 return 0;
935 }
936 char *msg;
937 asprintf(&msg, "%lld", bytes);
938 cli->sendMsg(ResponseCode::QuotaCounterResult, msg, false);
939 free(msg);
940 return 0;
941
942 }
943 if (!strcmp(argv[1], "setquota") || !strcmp(argv[1], "sq")) {
944 if (argc != 4) {
945 sendGenericSyntaxError(cli, "setquota <interface> <bytes>");
946 return 0;
947 }
948 int rc = sBandwidthCtrl->setInterfaceSharedQuota(argv[2], atoll(argv[3]));
949 sendGenericOkFail(cli, rc);
950 return 0;
951 }
952 if (!strcmp(argv[1], "setquotas") || !strcmp(argv[1], "sqs")) {
953 int rc;
954 if (argc < 4) {
955 sendGenericSyntaxError(cli, "setquotas <bytes> <interface> ...");
956 return 0;
957 }
958
959 for (int q = 3; argc >= 4; q++, argc--) {
960 rc = sBandwidthCtrl->setInterfaceSharedQuota(argv[q], atoll(argv[2]));
961 if (rc) {
962 char *msg;
963 asprintf(&msg, "bandwidth setquotas %s %s failed", argv[2], argv[q]);
964 cli->sendMsg(ResponseCode::OperationFailed,
965 msg, false);
966 free(msg);
967 return 0;
968 }
969 }
970 sendGenericOkFail(cli, rc);
971 return 0;
972
973 }
974 if (!strcmp(argv[1], "removequotas") || !strcmp(argv[1], "rqs")) {
975 int rc;
976 if (argc < 3) {
977 sendGenericSyntaxError(cli, "removequotas <interface> ...");
978 return 0;
979 }
980
981 for (int q = 2; argc >= 3; q++, argc--) {
982 rc = sBandwidthCtrl->removeInterfaceSharedQuota(argv[q]);
983 if (rc) {
984 char *msg;
985 asprintf(&msg, "bandwidth removequotas %s failed", argv[q]);
986 cli->sendMsg(ResponseCode::OperationFailed,
987 msg, false);
988 free(msg);
989 return 0;
990 }
991 }
992 sendGenericOkFail(cli, rc);
993 return 0;
994
995 }
996 if (!strcmp(argv[1], "removeiquota") || !strcmp(argv[1], "riq")) {
997 if (argc != 3) {
998 sendGenericSyntaxError(cli, "removeiquota <interface>");
999 return 0;
1000 }
1001 int rc = sBandwidthCtrl->removeInterfaceQuota(argv[2]);
1002 sendGenericOkFail(cli, rc);
1003 return 0;
1004
1005 }
1006 if (!strcmp(argv[1], "setiquota") || !strcmp(argv[1], "siq")) {
1007 if (argc != 4) {
1008 sendGenericSyntaxError(cli, "setiquota <interface> <bytes>");
1009 return 0;
1010 }
1011 int rc = sBandwidthCtrl->setInterfaceQuota(argv[2], atoll(argv[3]));
1012 sendGenericOkFail(cli, rc);
1013 return 0;
1014
1015 }
1016 if (!strcmp(argv[1], "addnaughtyapps") || !strcmp(argv[1], "ana")) {
1017 if (argc < 3) {
1018 sendGenericSyntaxError(cli, "addnaughtyapps <appUid> ...");
1019 return 0;
1020 }
1021 int rc = sBandwidthCtrl->addNaughtyApps(argc - 2, argv + 2);
1022 sendGenericOkFail(cli, rc);
1023 return 0;
1024
1025
1026 }
1027 if (!strcmp(argv[1], "removenaughtyapps") || !strcmp(argv[1], "rna")) {
1028 if (argc < 3) {
1029 sendGenericSyntaxError(cli, "removenaughtyapps <appUid> ...");
1030 return 0;
1031 }
1032 int rc = sBandwidthCtrl->removeNaughtyApps(argc - 2, argv + 2);
1033 sendGenericOkFail(cli, rc);
1034 return 0;
1035
1036 }
1037 if (!strcmp(argv[1], "setglobalalert") || !strcmp(argv[1], "sga")) {
1038 if (argc != 3) {
1039 sendGenericSyntaxError(cli, "setglobalalert <bytes>");
1040 return 0;
1041 }
1042 int rc = sBandwidthCtrl->setGlobalAlert(atoll(argv[2]));
1043 sendGenericOkFail(cli, rc);
1044 return 0;
1045
1046 }
1047 if (!strcmp(argv[1], "debugsettetherglobalalert") || !strcmp(argv[1], "dstga")) {
1048 if (argc != 4) {
1049 sendGenericSyntaxError(cli, "debugsettetherglobalalert <interface0> <interface1>");
1050 return 0;
1051 }
1052 /* We ignore the interfaces for now. */
1053 int rc = sBandwidthCtrl->setGlobalAlertInForwardChain();
1054 sendGenericOkFail(cli, rc);
1055 return 0;
1056
1057 }
1058 if (!strcmp(argv[1], "removeglobalalert") || !strcmp(argv[1], "rga")) {
1059 if (argc != 2) {
1060 sendGenericSyntaxError(cli, "removeglobalalert");
1061 return 0;
1062 }
1063 int rc = sBandwidthCtrl->removeGlobalAlert();
1064 sendGenericOkFail(cli, rc);
1065 return 0;
1066
1067 }
1068 if (!strcmp(argv[1], "debugremovetetherglobalalert") || !strcmp(argv[1], "drtga")) {
1069 if (argc != 4) {
1070 sendGenericSyntaxError(cli, "debugremovetetherglobalalert <interface0> <interface1>");
1071 return 0;
1072 }
1073 /* We ignore the interfaces for now. */
1074 int rc = sBandwidthCtrl->removeGlobalAlertInForwardChain();
1075 sendGenericOkFail(cli, rc);
1076 return 0;
1077
1078 }
1079 if (!strcmp(argv[1], "setsharedalert") || !strcmp(argv[1], "ssa")) {
1080 if (argc != 3) {
1081 sendGenericSyntaxError(cli, "setsharedalert <bytes>");
1082 return 0;
1083 }
1084 int rc = sBandwidthCtrl->setSharedAlert(atoll(argv[2]));
1085 sendGenericOkFail(cli, rc);
1086 return 0;
1087
1088 }
1089 if (!strcmp(argv[1], "removesharedalert") || !strcmp(argv[1], "rsa")) {
1090 if (argc != 2) {
1091 sendGenericSyntaxError(cli, "removesharedalert");
1092 return 0;
1093 }
1094 int rc = sBandwidthCtrl->removeSharedAlert();
1095 sendGenericOkFail(cli, rc);
1096 return 0;
1097
1098 }
1099 if (!strcmp(argv[1], "setinterfacealert") || !strcmp(argv[1], "sia")) {
1100 if (argc != 4) {
1101 sendGenericSyntaxError(cli, "setinterfacealert <interface> <bytes>");
1102 return 0;
1103 }
1104 int rc = sBandwidthCtrl->setInterfaceAlert(argv[2], atoll(argv[3]));
1105 sendGenericOkFail(cli, rc);
1106 return 0;
1107
1108 }
1109 if (!strcmp(argv[1], "removeinterfacealert") || !strcmp(argv[1], "ria")) {
1110 if (argc != 3) {
1111 sendGenericSyntaxError(cli, "removeinterfacealert <interface>");
1112 return 0;
1113 }
1114 int rc = sBandwidthCtrl->removeInterfaceAlert(argv[2]);
1115 sendGenericOkFail(cli, rc);
1116 return 0;
1117
1118 }
1119 if (!strcmp(argv[1], "gettetherstats") || !strcmp(argv[1], "gts")) {
1120 BandwidthController::TetherStats tetherStats;
1121 std::string extraProcessingInfo = "";
1122 if (argc != 4) {
1123 sendGenericSyntaxError(cli, "gettetherstats <interface0> <interface1>");
1124 return 0;
1125 }
1126
1127 tetherStats.ifaceIn = argv[2];
1128 tetherStats.ifaceOut = argv[3];
1129 int rc = sBandwidthCtrl->getTetherStats(tetherStats, extraProcessingInfo);
1130 if (rc) {
1131 extraProcessingInfo.insert(0, "Failed to get tethering stats.\n");
1132 sendGenericOpFailed(cli, extraProcessingInfo.c_str());
1133 return 0;
1134 }
1135
1136 char *msg = tetherStats.getStatsLine();
1137 cli->sendMsg(ResponseCode::TetheringStatsResult, msg, false);
1138 free(msg);
1139 return 0;
1140
1141 }
1142
1143 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown bandwidth cmd", false);
1144 return 0;
1145 }
1146
IdletimerControlCmd()1147 CommandListener::IdletimerControlCmd::IdletimerControlCmd() :
1148 NetdCommand("idletimer") {
1149 }
1150
runCommand(SocketClient * cli,int argc,char ** argv)1151 int CommandListener::IdletimerControlCmd::runCommand(SocketClient *cli, int argc, char **argv) {
1152 // TODO(ashish): Change the error statements
1153 if (argc < 2) {
1154 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
1155 return 0;
1156 }
1157
1158 ALOGV("idletimerctrlcmd: argc=%d %s %s ...", argc, argv[0], argv[1]);
1159
1160 if (!strcmp(argv[1], "enable")) {
1161 if (0 != sIdletimerCtrl->enableIdletimerControl()) {
1162 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
1163 } else {
1164 cli->sendMsg(ResponseCode::CommandOkay, "Enable success", false);
1165 }
1166 return 0;
1167
1168 }
1169 if (!strcmp(argv[1], "disable")) {
1170 if (0 != sIdletimerCtrl->disableIdletimerControl()) {
1171 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
1172 } else {
1173 cli->sendMsg(ResponseCode::CommandOkay, "Disable success", false);
1174 }
1175 return 0;
1176 }
1177 if (!strcmp(argv[1], "add")) {
1178 if (argc != 5) {
1179 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
1180 return 0;
1181 }
1182 if(0 != sIdletimerCtrl->addInterfaceIdletimer(
1183 argv[2], atoi(argv[3]), argv[4])) {
1184 cli->sendMsg(ResponseCode::OperationFailed, "Failed to add interface", false);
1185 } else {
1186 cli->sendMsg(ResponseCode::CommandOkay, "Add success", false);
1187 }
1188 return 0;
1189 }
1190 if (!strcmp(argv[1], "remove")) {
1191 if (argc != 5) {
1192 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
1193 return 0;
1194 }
1195 // ashish: fixme timeout
1196 if (0 != sIdletimerCtrl->removeInterfaceIdletimer(
1197 argv[2], atoi(argv[3]), argv[4])) {
1198 cli->sendMsg(ResponseCode::OperationFailed, "Failed to remove interface", false);
1199 } else {
1200 cli->sendMsg(ResponseCode::CommandOkay, "Remove success", false);
1201 }
1202 return 0;
1203 }
1204
1205 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown idletimer cmd", false);
1206 return 0;
1207 }
1208
FirewallCmd()1209 CommandListener::FirewallCmd::FirewallCmd() :
1210 NetdCommand("firewall") {
1211 }
1212
sendGenericOkFail(SocketClient * cli,int cond)1213 int CommandListener::FirewallCmd::sendGenericOkFail(SocketClient *cli, int cond) {
1214 if (!cond) {
1215 cli->sendMsg(ResponseCode::CommandOkay, "Firewall command succeeded", false);
1216 } else {
1217 cli->sendMsg(ResponseCode::OperationFailed, "Firewall command failed", false);
1218 }
1219 return 0;
1220 }
1221
parseRule(const char * arg)1222 FirewallRule CommandListener::FirewallCmd::parseRule(const char* arg) {
1223 if (!strcmp(arg, "allow")) {
1224 return ALLOW;
1225 } else {
1226 return DENY;
1227 }
1228 }
1229
runCommand(SocketClient * cli,int argc,char ** argv)1230 int CommandListener::FirewallCmd::runCommand(SocketClient *cli, int argc,
1231 char **argv) {
1232 if (argc < 2) {
1233 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing command", false);
1234 return 0;
1235 }
1236
1237 if (!strcmp(argv[1], "enable")) {
1238 int res = sFirewallCtrl->enableFirewall();
1239 return sendGenericOkFail(cli, res);
1240 }
1241 if (!strcmp(argv[1], "disable")) {
1242 int res = sFirewallCtrl->disableFirewall();
1243 return sendGenericOkFail(cli, res);
1244 }
1245 if (!strcmp(argv[1], "is_enabled")) {
1246 int res = sFirewallCtrl->isFirewallEnabled();
1247 return sendGenericOkFail(cli, res);
1248 }
1249
1250 if (!strcmp(argv[1], "set_interface_rule")) {
1251 if (argc != 4) {
1252 cli->sendMsg(ResponseCode::CommandSyntaxError,
1253 "Usage: firewall set_interface_rule <rmnet0> <allow|deny>", false);
1254 return 0;
1255 }
1256
1257 const char* iface = argv[2];
1258 FirewallRule rule = parseRule(argv[3]);
1259
1260 int res = sFirewallCtrl->setInterfaceRule(iface, rule);
1261 return sendGenericOkFail(cli, res);
1262 }
1263
1264 if (!strcmp(argv[1], "set_egress_source_rule")) {
1265 if (argc != 4) {
1266 cli->sendMsg(ResponseCode::CommandSyntaxError,
1267 "Usage: firewall set_egress_source_rule <192.168.0.1> <allow|deny>",
1268 false);
1269 return 0;
1270 }
1271
1272 const char* addr = argv[2];
1273 FirewallRule rule = parseRule(argv[3]);
1274
1275 int res = sFirewallCtrl->setEgressSourceRule(addr, rule);
1276 return sendGenericOkFail(cli, res);
1277 }
1278
1279 if (!strcmp(argv[1], "set_egress_dest_rule")) {
1280 if (argc != 5) {
1281 cli->sendMsg(ResponseCode::CommandSyntaxError,
1282 "Usage: firewall set_egress_dest_rule <192.168.0.1> <80> <allow|deny>",
1283 false);
1284 return 0;
1285 }
1286
1287 const char* addr = argv[2];
1288 int port = atoi(argv[3]);
1289 FirewallRule rule = parseRule(argv[4]);
1290
1291 int res = 0;
1292 res |= sFirewallCtrl->setEgressDestRule(addr, PROTOCOL_TCP, port, rule);
1293 res |= sFirewallCtrl->setEgressDestRule(addr, PROTOCOL_UDP, port, rule);
1294 return sendGenericOkFail(cli, res);
1295 }
1296
1297 if (!strcmp(argv[1], "set_uid_rule")) {
1298 if (argc != 4) {
1299 cli->sendMsg(ResponseCode::CommandSyntaxError,
1300 "Usage: firewall set_uid_rule <1000> <allow|deny>",
1301 false);
1302 return 0;
1303 }
1304
1305 int uid = atoi(argv[2]);
1306 FirewallRule rule = parseRule(argv[3]);
1307
1308 int res = sFirewallCtrl->setUidRule(uid, rule);
1309 return sendGenericOkFail(cli, res);
1310 }
1311
1312 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown command", false);
1313 return 0;
1314 }
1315
ClatdCmd()1316 CommandListener::ClatdCmd::ClatdCmd() : NetdCommand("clatd") {
1317 }
1318
runCommand(SocketClient * cli,int argc,char ** argv)1319 int CommandListener::ClatdCmd::runCommand(SocketClient *cli, int argc,
1320 char **argv) {
1321 int rc = 0;
1322 if (argc < 2) {
1323 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
1324 return 0;
1325 }
1326
1327 if(!strcmp(argv[1], "stop")) {
1328 rc = sClatdCtrl->stopClatd();
1329 } else if (!strcmp(argv[1], "status")) {
1330 char *tmp = NULL;
1331
1332 asprintf(&tmp, "Clatd status: %s", (sClatdCtrl->isClatdStarted() ?
1333 "started" : "stopped"));
1334 cli->sendMsg(ResponseCode::ClatdStatusResult, tmp, false);
1335 free(tmp);
1336 return 0;
1337 } else if(!strcmp(argv[1], "start")) {
1338 if (argc < 3) {
1339 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
1340 return 0;
1341 }
1342 rc = sClatdCtrl->startClatd(argv[2]);
1343 } else {
1344 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown clatd cmd", false);
1345 return 0;
1346 }
1347
1348 if (!rc) {
1349 cli->sendMsg(ResponseCode::CommandOkay, "Clatd operation succeeded", false);
1350 } else {
1351 cli->sendMsg(ResponseCode::OperationFailed, "Clatd operation failed", false);
1352 }
1353
1354 return 0;
1355 }
1356