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