• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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