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