1d18304287dbabc7835be771400b85d4ae8b63de6San Mehat/*
2d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * Copyright (C) 2008 The Android Open Source Project
3d18304287dbabc7835be771400b85d4ae8b63de6San Mehat *
4d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * Licensed under the Apache License, Version 2.0 (the "License");
5d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * you may not use this file except in compliance with the License.
6d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * You may obtain a copy of the License at
7d18304287dbabc7835be771400b85d4ae8b63de6San Mehat *
8d18304287dbabc7835be771400b85d4ae8b63de6San Mehat *      http://www.apache.org/licenses/LICENSE-2.0
9d18304287dbabc7835be771400b85d4ae8b63de6San Mehat *
10d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * Unless required by applicable law or agreed to in writing, software
11d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * distributed under the License is distributed on an "AS IS" BASIS,
12d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * See the License for the specific language governing permissions and
14d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * limitations under the License.
15d18304287dbabc7835be771400b85d4ae8b63de6San Mehat */
16d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
171fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall// #define LOG_NDEBUG 0
18db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
19d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <stdlib.h>
20d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <sys/socket.h>
21d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <sys/types.h>
22d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <netinet/in.h>
23d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <arpa/inet.h>
24d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <dirent.h>
25d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <errno.h>
26ff2c0d8c13457e43f0d4bf06d3177271aac104c1Olivier Bailly#include <string.h>
275c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat#include <linux/if.h>
285c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
29d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#define LOG_TAG "CommandListener"
30d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
311ed47c4a016e420a855ee46922e512150245ff61Lorenzo Colitti#include <cutils/log.h>
321ed47c4a016e420a855ee46922e512150245ff61Lorenzo Colitti#include <netutils/ifc.h>
33d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <sysutils/SocketClient.h>
34d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
35d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include "CommandListener.h"
36d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include "ResponseCode.h"
374a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall#include "BandwidthController.h"
380031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall#include "IdletimerController.h"
39fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt#include "SecondaryTableController.h"
400031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall#include "oem_iptables_hook.h"
418e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey#include "NetdConstants.h"
42d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey#include "FirewallController.h"
435c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
449d10b341a0ba46f108cb96e46691197d778cbc06San MehatTetherController *CommandListener::sTetherCtrl = NULL;
459ff78fb7da7158f5bd7c86d89a842691820259cfSan MehatNatController *CommandListener::sNatCtrl = NULL;
46d5573d34c8fac49e16b20cf144486125bf940086San MehatPppController *CommandListener::sPppCtrl = NULL;
475af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry ShmidtSoftapController *CommandListener::sSoftapCtrl = NULL;
484a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP AbgrallBandwidthController * CommandListener::sBandwidthCtrl = NULL;
490031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP AbgrallIdletimerController * CommandListener::sIdletimerCtrl = NULL;
502eab1f762badb7ba46b95716e62ea4548a979903Dmitry ShmidtInterfaceController *CommandListener::sInterfaceCtrl = NULL;
5189c1e975f0c03997808d35c7be10b244c5309f9fMattias FalkResolverController *CommandListener::sResolverCtrl = NULL;
52fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert GreenwaltSecondaryTableController *CommandListener::sSecondaryTableCtrl = NULL;
53d8c64026aaae5a9987151b719bd840ec7d68747aJeff SharkeyFirewallController *CommandListener::sFirewallCtrl = NULL;
540da73fcecc30140439f856118056df8908609627Daniel DrownClatdController *CommandListener::sClatdCtrl = NULL;
559d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
568e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey/**
578e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey * List of module chains to be created, along with explicit ordering. ORDERING
588e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey * IS CRITICAL, AND SHOULD BE TRIPLE-CHECKED WITH EACH CHANGE.
598e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey */
608e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkeystatic const char* FILTER_INPUT[] = {
61d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        // Bandwidth should always be early in input chain, to make sure we
62d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        // correctly count incoming traffic against data plan.
638e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        BandwidthController::LOCAL_INPUT,
64d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        FirewallController::LOCAL_INPUT,
658e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        NULL,
668e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey};
678e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey
688e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkeystatic const char* FILTER_FORWARD[] = {
698e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        OEM_IPTABLES_FILTER_FORWARD,
70d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        FirewallController::LOCAL_FORWARD,
718e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        BandwidthController::LOCAL_FORWARD,
728e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        NatController::LOCAL_FORWARD,
738e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        NULL,
748e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey};
758e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey
768e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkeystatic const char* FILTER_OUTPUT[] = {
778e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        OEM_IPTABLES_FILTER_OUTPUT,
78d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        FirewallController::LOCAL_OUTPUT,
798e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        BandwidthController::LOCAL_OUTPUT,
808e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        NULL,
818e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey};
828e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey
838e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkeystatic const char* RAW_PREROUTING[] = {
848e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        BandwidthController::LOCAL_RAW_PREROUTING,
855c4faf7602de0268aa09a3a525b427f83d617b5cHaoyu Bai        IdletimerController::LOCAL_RAW_PREROUTING,
868e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        NULL,
878e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey};
888e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey
898e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkeystatic const char* MANGLE_POSTROUTING[] = {
908e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        BandwidthController::LOCAL_MANGLE_POSTROUTING,
915c4faf7602de0268aa09a3a525b427f83d617b5cHaoyu Bai        IdletimerController::LOCAL_MANGLE_POSTROUTING,
928e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        NULL,
938e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey};
948e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey
958e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkeystatic const char* NAT_PREROUTING[] = {
968e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        OEM_IPTABLES_NAT_PREROUTING,
978e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        NULL,
988e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey};
998e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey
1008e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkeystatic const char* NAT_POSTROUTING[] = {
1018e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        NatController::LOCAL_NAT_POSTROUTING,
1028e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        NULL,
1038e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey};
1048e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey
1058e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkeystatic void createChildChains(IptablesTarget target, const char* table, const char* parentChain,
1068e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        const char** childChains) {
1078e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey    const char** childChain = childChains;
1088e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey    do {
1098e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        // Order is important:
1108e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        // -D to delete any pre-existing jump rule (removes references
1118e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        //    that would prevent -X from working)
1128e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        // -F to flush any existing chain
1138e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        // -X to delete any existing chain
1148e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        // -N to create the chain
1158e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        // -A to append the chain to parent
1168e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey
1178e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        execIptablesSilently(target, "-t", table, "-D", parentChain, "-j", *childChain, NULL);
1188e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        execIptablesSilently(target, "-t", table, "-F", *childChain, NULL);
1198e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        execIptablesSilently(target, "-t", table, "-X", *childChain, NULL);
1208e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        execIptables(target, "-t", table, "-N", *childChain, NULL);
1218e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey        execIptables(target, "-t", table, "-A", parentChain, "-j", *childChain, NULL);
1228e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey    } while (*(++childChain) != NULL);
1238e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey}
1248e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey
125d18304287dbabc7835be771400b85d4ae8b63de6San MehatCommandListener::CommandListener() :
126a8e59f8c50aed3f91dead377b8ae21646978506cRobert Greenwalt                 FrameworkListener("netd", true) {
1275c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat    registerCmd(new InterfaceCmd());
128d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    registerCmd(new IpFwdCmd());
129d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    registerCmd(new TetherCmd());
130d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    registerCmd(new NatCmd());
131d5573d34c8fac49e16b20cf144486125bf940086San Mehat    registerCmd(new ListTtysCmd());
132d5573d34c8fac49e16b20cf144486125bf940086San Mehat    registerCmd(new PppdCmd());
1335af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    registerCmd(new SoftapCmd());
1344a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall    registerCmd(new BandwidthControlCmd());
1350031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    registerCmd(new IdletimerControlCmd());
13689c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    registerCmd(new ResolverCmd());
137d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    registerCmd(new FirewallCmd());
1380da73fcecc30140439f856118056df8908609627Daniel Drown    registerCmd(new ClatdCmd());
1399d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
140fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt    if (!sSecondaryTableCtrl)
141fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt        sSecondaryTableCtrl = new SecondaryTableController();
1429d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (!sTetherCtrl)
1439d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        sTetherCtrl = new TetherController();
1449ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat    if (!sNatCtrl)
145fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt        sNatCtrl = new NatController(sSecondaryTableCtrl);
146d5573d34c8fac49e16b20cf144486125bf940086San Mehat    if (!sPppCtrl)
147d5573d34c8fac49e16b20cf144486125bf940086San Mehat        sPppCtrl = new PppController();
1485af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    if (!sSoftapCtrl)
1495af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        sSoftapCtrl = new SoftapController();
1504a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall    if (!sBandwidthCtrl)
1514a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall        sBandwidthCtrl = new BandwidthController();
1520031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    if (!sIdletimerCtrl)
1530031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall        sIdletimerCtrl = new IdletimerController();
15489c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    if (!sResolverCtrl)
15589c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        sResolverCtrl = new ResolverController();
156d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    if (!sFirewallCtrl)
157d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        sFirewallCtrl = new FirewallController();
1582eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    if (!sInterfaceCtrl)
1592eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt        sInterfaceCtrl = new InterfaceController();
1600da73fcecc30140439f856118056df8908609627Daniel Drown    if (!sClatdCtrl)
1610da73fcecc30140439f856118056df8908609627Daniel Drown        sClatdCtrl = new ClatdController();
1620031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall
1630031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    /*
1648e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey     * This is the only time we touch top-level chains in iptables; controllers
1658e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey     * should only mutate rules inside of their children chains, as created by
1668e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey     * the constants above.
1678e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey     *
1688e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey     * Modules should never ACCEPT packets (except in well-justified cases);
1698e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey     * they should instead defer to any remaining modules using RETURN, or
1708e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey     * otherwise DROP/REJECT.
1710031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall     */
1728e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey
1738e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey    // Create chains for children modules
1748e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey    createChildChains(V4V6, "filter", "INPUT", FILTER_INPUT);
1758e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey    createChildChains(V4V6, "filter", "FORWARD", FILTER_FORWARD);
1768e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey    createChildChains(V4V6, "filter", "OUTPUT", FILTER_OUTPUT);
1778e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey    createChildChains(V4V6, "raw", "PREROUTING", RAW_PREROUTING);
1788e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey    createChildChains(V4V6, "mangle", "POSTROUTING", MANGLE_POSTROUTING);
1798e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey    createChildChains(V4, "nat", "PREROUTING", NAT_PREROUTING);
1808e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey    createChildChains(V4, "nat", "POSTROUTING", NAT_POSTROUTING);
1818e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey
1828e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey    // Let each module setup their child chains
1830031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    setupOemIptablesHook();
1848e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey
185d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    /* When enabled, DROPs all packets except those matching rules. */
186d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    sFirewallCtrl->setupIptablesHooks();
187d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey
1880031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    /* Does DROPs in FORWARD by default */
1890031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    sNatCtrl->setupIptablesHooks();
1900031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    /*
1910031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall     * Does REJECT in INPUT, OUTPUT. Does counting also.
1920031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall     * No DROP/REJECT allowed later in netfilter-flow hook order.
1930031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall     */
1940031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    sBandwidthCtrl->setupIptablesHooks();
1950031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    /*
1960031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall     * Counts in nat: PREROUTING, POSTROUTING.
1970031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall     * No DROP/REJECT allowed later in netfilter-flow hook order.
1980031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall     */
1990031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    sIdletimerCtrl->setupIptablesHooks();
2000031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall
2010031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    sBandwidthCtrl->enableBandwidthControl(false);
202d18304287dbabc7835be771400b85d4ae8b63de6San Mehat}
203d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
2045c1b8af16dbbc20c89aaca2f93e725e12b16d055San MehatCommandListener::InterfaceCmd::InterfaceCmd() :
2055c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                 NetdCommand("interface") {
206d18304287dbabc7835be771400b85d4ae8b63de6San Mehat}
207d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
2085c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehatint CommandListener::InterfaceCmd::runCommand(SocketClient *cli,
209d18304287dbabc7835be771400b85d4ae8b63de6San Mehat                                                      int argc, char **argv) {
2105c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat    if (argc < 2) {
2115c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
2125c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        return 0;
2135c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat    }
2145c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
2155c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat    if (!strcmp(argv[1], "list")) {
2165c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        DIR *d;
2175c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        struct dirent *de;
2185c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
2195c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        if (!(d = opendir("/sys/class/net"))) {
2205c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            cli->sendMsg(ResponseCode::OperationFailed, "Failed to open sysfs dir", true);
2215c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            return 0;
2225c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        }
2235c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
2245c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        while((de = readdir(d))) {
2255c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            if (de->d_name[0] == '.')
2265c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                continue;
2275c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            cli->sendMsg(ResponseCode::InterfaceListResult, de->d_name, false);
2285c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        }
2295c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        closedir(d);
2305c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        cli->sendMsg(ResponseCode::CommandOkay, "Interface list completed", false);
2315c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        return 0;
2322eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    } else if (!strcmp(argv[1], "driver")) {
2332eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt        int rc;
2342eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt        char *rbuf;
2352eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt
2362eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt        if (argc < 4) {
2372eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt            cli->sendMsg(ResponseCode::CommandSyntaxError,
2382eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt                    "Usage: interface driver <interface> <cmd> <args>", false);
2392eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt            return 0;
2402eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt        }
2412eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt        rc = sInterfaceCtrl->interfaceCommand(argc, argv, &rbuf);
2422eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt        if (rc) {
2432eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt            cli->sendMsg(ResponseCode::OperationFailed, "Failed to execute command", true);
2442eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt        } else {
2452eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt            cli->sendMsg(ResponseCode::CommandOkay, rbuf, false);
2462eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt        }
2472eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt        return 0;
2485c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat    } else {
2495c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        /*
2505c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat         * These commands take a minimum of 3 arguments
2515c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat         */
2525c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        if (argc < 3) {
2535c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
2545c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            return 0;
2555c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        }
256e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt
257fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt        //     0       1       2        3          4           5     6      7
258fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt        // interface route add/remove iface default/secondary dest prefix gateway
259e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt        if (!strcmp(argv[1], "route")) {
260e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt            int prefix_length = 0;
261fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt            if (argc < 8) {
262e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt                cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
263e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt                return 0;
264e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt            }
265fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt            if (sscanf(argv[6], "%d", &prefix_length) != 1) {
266e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt                cli->sendMsg(ResponseCode::CommandParameterError, "Invalid route prefix", false);
267e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt                return 0;
268e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt            }
269e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt            if (!strcmp(argv[2], "add")) {
270fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt                if (!strcmp(argv[4], "default")) {
271fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt                    if (ifc_add_route(argv[3], argv[5], prefix_length, argv[7])) {
272fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt                        cli->sendMsg(ResponseCode::OperationFailed,
273fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt                                "Failed to add route to default table", true);
274fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt                    } else {
275fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt                        cli->sendMsg(ResponseCode::CommandOkay,
276fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt                                "Route added to default table", false);
277fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt                    }
278fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt                } else if (!strcmp(argv[4], "secondary")) {
279fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt                    return sSecondaryTableCtrl->addRoute(cli, argv[3], argv[5],
280fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt                            prefix_length, argv[7]);
281e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt                } else {
282fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt                    cli->sendMsg(ResponseCode::CommandParameterError,
283fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt                            "Invalid route type, expecting 'default' or 'secondary'", false);
284fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt                    return 0;
285e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt                }
286e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt            } else if (!strcmp(argv[2], "remove")) {
287fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt                if (!strcmp(argv[4], "default")) {
288fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt                    if (ifc_remove_route(argv[3], argv[5], prefix_length, argv[7])) {
289fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt                        cli->sendMsg(ResponseCode::OperationFailed,
290fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt                                "Failed to remove route from default table", true);
291fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt                    } else {
292fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt                        cli->sendMsg(ResponseCode::CommandOkay,
293fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt                                "Route removed from default table", false);
294fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt                    }
295fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt                } else if (!strcmp(argv[4], "secondary")) {
296fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt                    return sSecondaryTableCtrl->removeRoute(cli, argv[3], argv[5],
297fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt                            prefix_length, argv[7]);
298e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt                } else {
299fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt                    cli->sendMsg(ResponseCode::CommandParameterError,
300fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt                            "Invalid route type, expecting 'default' or 'secondary'", false);
301fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt                    return 0;
302e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt                }
303e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt            } else {
304e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt                cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown interface cmd", false);
305e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt            }
306e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt            return 0;
307e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt        }
308e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt
3095c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        if (!strcmp(argv[1], "getcfg")) {
3101d93e170f13b221362ee268fdc94b25db06c21c9Robert Greenwalt            struct in_addr addr;
3111d93e170f13b221362ee268fdc94b25db06c21c9Robert Greenwalt            int prefixLength;
3125c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            unsigned char hwaddr[6];
3135c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            unsigned flags = 0;
3145c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
3155c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            ifc_init();
3165c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            memset(hwaddr, 0, sizeof(hwaddr));
3175c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
3181d93e170f13b221362ee268fdc94b25db06c21c9Robert Greenwalt            if (ifc_get_info(argv[2], &addr.s_addr, &prefixLength, &flags)) {
3195c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                cli->sendMsg(ResponseCode::OperationFailed, "Interface not found", true);
320e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff                ifc_close();
3215c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                return 0;
3225c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            }
3235c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
3245c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            if (ifc_get_hwaddr(argv[2], (void *) hwaddr)) {
3250e76b761a1514d5182675dd7b7d33725f62d6bc5Steve Block                ALOGW("Failed to retrieve HW addr for %s (%s)", argv[2], strerror(errno));
3265c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            }
3275c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
3285c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            char *addr_s = strdup(inet_ntoa(addr));
3295c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            const char *updown, *brdcst, *loopbk, *ppp, *running, *multi;
3305c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
3315c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            updown =  (flags & IFF_UP)           ? "up" : "down";
3325c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            brdcst =  (flags & IFF_BROADCAST)    ? " broadcast" : "";
3335c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            loopbk =  (flags & IFF_LOOPBACK)     ? " loopback" : "";
3345c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            ppp =     (flags & IFF_POINTOPOINT)  ? " point-to-point" : "";
3355c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            running = (flags & IFF_RUNNING)      ? " running" : "";
3365c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            multi =   (flags & IFF_MULTICAST)    ? " multicast" : "";
3375c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
3385c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            char *flag_s;
3395c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
34031ea0b03afeedd17f703b7a6d1e5c9feb2d6000dJeff Sharkey            asprintf(&flag_s, "%s%s%s%s%s%s", updown, brdcst, loopbk, ppp, running, multi);
3415c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
3425c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            char *msg = NULL;
3431d93e170f13b221362ee268fdc94b25db06c21c9Robert Greenwalt            asprintf(&msg, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x %s %d %s",
3445c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                     hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5],
3451d93e170f13b221362ee268fdc94b25db06c21c9Robert Greenwalt                     addr_s, prefixLength, flag_s);
3465c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
34701fed783828b592cda3b774deea4099a9e690e3dSan Mehat            cli->sendMsg(ResponseCode::InterfaceGetCfgResult, msg, false);
3485c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
3495c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            free(addr_s);
3505c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            free(flag_s);
3515c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            free(msg);
352e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff
353e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff            ifc_close();
3545c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            return 0;
3555c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        } else if (!strcmp(argv[1], "setcfg")) {
356778ffe4d3dcab5453b57a0d960ea7f066374b953Dmitry Shmidt            // arglist: iface [addr prefixLength] flags
357778ffe4d3dcab5453b57a0d960ea7f066374b953Dmitry Shmidt            if (argc < 4) {
3585c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
3595c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                return 0;
3605c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            }
3617b984e3f7e724f8a3547a707210319f3d479f261Steve Block            ALOGD("Setting iface cfg");
3625c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
3631d93e170f13b221362ee268fdc94b25db06c21c9Robert Greenwalt            struct in_addr addr;
3645c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            unsigned flags = 0;
365778ffe4d3dcab5453b57a0d960ea7f066374b953Dmitry Shmidt            int index = 5;
3665c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
3675c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            ifc_init();
3685c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
369778ffe4d3dcab5453b57a0d960ea7f066374b953Dmitry Shmidt            if (!inet_aton(argv[3], &addr)) {
370778ffe4d3dcab5453b57a0d960ea7f066374b953Dmitry Shmidt                // Handle flags only case
371778ffe4d3dcab5453b57a0d960ea7f066374b953Dmitry Shmidt                index = 3;
372778ffe4d3dcab5453b57a0d960ea7f066374b953Dmitry Shmidt            } else {
373778ffe4d3dcab5453b57a0d960ea7f066374b953Dmitry Shmidt                if (ifc_set_addr(argv[2], addr.s_addr)) {
374778ffe4d3dcab5453b57a0d960ea7f066374b953Dmitry Shmidt                    cli->sendMsg(ResponseCode::OperationFailed, "Failed to set address", true);
375778ffe4d3dcab5453b57a0d960ea7f066374b953Dmitry Shmidt                    ifc_close();
376778ffe4d3dcab5453b57a0d960ea7f066374b953Dmitry Shmidt                    return 0;
377778ffe4d3dcab5453b57a0d960ea7f066374b953Dmitry Shmidt                }
378778ffe4d3dcab5453b57a0d960ea7f066374b953Dmitry Shmidt
379778ffe4d3dcab5453b57a0d960ea7f066374b953Dmitry Shmidt                // Set prefix length on a non zero address
380778ffe4d3dcab5453b57a0d960ea7f066374b953Dmitry Shmidt                if (addr.s_addr != 0 && ifc_set_prefixLength(argv[2], atoi(argv[4]))) {
381778ffe4d3dcab5453b57a0d960ea7f066374b953Dmitry Shmidt                   cli->sendMsg(ResponseCode::OperationFailed, "Failed to set prefixLength", true);
382778ffe4d3dcab5453b57a0d960ea7f066374b953Dmitry Shmidt                   ifc_close();
383778ffe4d3dcab5453b57a0d960ea7f066374b953Dmitry Shmidt                   return 0;
384778ffe4d3dcab5453b57a0d960ea7f066374b953Dmitry Shmidt               }
3855c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            }
3865c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
3875c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            /* Process flags */
388778ffe4d3dcab5453b57a0d960ea7f066374b953Dmitry Shmidt            for (int i = index; i < argc; i++) {
389e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt                char *flag = argv[i];
390e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt                if (!strcmp(flag, "up")) {
3917b984e3f7e724f8a3547a707210319f3d479f261Steve Block                    ALOGD("Trying to bring up %s", argv[2]);
3925c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                    if (ifc_up(argv[2])) {
3935ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block                        ALOGE("Error upping interface");
3945c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                        cli->sendMsg(ResponseCode::OperationFailed, "Failed to up interface", true);
395e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff                        ifc_close();
3965c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                        return 0;
3975c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                    }
398e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt                } else if (!strcmp(flag, "down")) {
3997b984e3f7e724f8a3547a707210319f3d479f261Steve Block                    ALOGD("Trying to bring down %s", argv[2]);
4005c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                    if (ifc_down(argv[2])) {
4015ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block                        ALOGE("Error downing interface");
4025c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                        cli->sendMsg(ResponseCode::OperationFailed, "Failed to down interface", true);
403e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff                        ifc_close();
4045c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                        return 0;
4055c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                    }
406e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt                } else if (!strcmp(flag, "broadcast")) {
4077c2ddd84ec501aaedb806a3ecec5de00d618a036Jeff Sharkey                    // currently ignored
408e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt                } else if (!strcmp(flag, "multicast")) {
4097c2ddd84ec501aaedb806a3ecec5de00d618a036Jeff Sharkey                    // currently ignored
4107c2ddd84ec501aaedb806a3ecec5de00d618a036Jeff Sharkey                } else if (!strcmp(flag, "running")) {
4117c2ddd84ec501aaedb806a3ecec5de00d618a036Jeff Sharkey                    // currently ignored
4127c2ddd84ec501aaedb806a3ecec5de00d618a036Jeff Sharkey                } else if (!strcmp(flag, "loopback")) {
4137c2ddd84ec501aaedb806a3ecec5de00d618a036Jeff Sharkey                    // currently ignored
4147c2ddd84ec501aaedb806a3ecec5de00d618a036Jeff Sharkey                } else if (!strcmp(flag, "point-to-point")) {
4157c2ddd84ec501aaedb806a3ecec5de00d618a036Jeff Sharkey                    // currently ignored
4165c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                } else {
4175c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                    cli->sendMsg(ResponseCode::CommandParameterError, "Flag unsupported", false);
418e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff                    ifc_close();
4195c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                    return 0;
4205c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                }
4215c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            }
422e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff
4235c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            cli->sendMsg(ResponseCode::CommandOkay, "Interface configuration set", false);
424e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff            ifc_close();
425e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff            return 0;
426e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff        } else if (!strcmp(argv[1], "clearaddrs")) {
427e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff            // arglist: iface
4287b984e3f7e724f8a3547a707210319f3d479f261Steve Block            ALOGD("Clearing all IP addresses on %s", argv[2]);
429e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff
4301ed47c4a016e420a855ee46922e512150245ff61Lorenzo Colitti            ifc_clear_addresses(argv[2]);
4311ed47c4a016e420a855ee46922e512150245ff61Lorenzo Colitti
432e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff            cli->sendMsg(ResponseCode::CommandOkay, "Interface IP addresses cleared", false);
4335c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            return 0;
43432a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff        } else if (!strcmp(argv[1], "ipv6privacyextensions")) {
43532a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff            if (argc != 4) {
43632a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff                cli->sendMsg(ResponseCode::CommandSyntaxError,
43732a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff                        "Usage: interface ipv6privacyextensions <interface> <enable|disable>",
43832a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff                        false);
43932a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff                return 0;
44032a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff            }
44170afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti            int enable = !strncmp(argv[3], "enable", 7);
44270afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti            if (sInterfaceCtrl->setIPv6PrivacyExtensions(argv[2], enable) == 0) {
44370afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti                cli->sendMsg(ResponseCode::CommandOkay, "IPv6 privacy extensions changed", false);
44470afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti            } else {
44532a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff                cli->sendMsg(ResponseCode::OperationFailed,
44632a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff                        "Failed to set ipv6 privacy extensions", true);
44732a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff            }
448c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync            return 0;
449c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync        } else if (!strcmp(argv[1], "ipv6")) {
450c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync            if (argc != 4) {
451c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync                cli->sendMsg(ResponseCode::CommandSyntaxError,
452c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync                        "Usage: interface ipv6 <interface> <enable|disable>",
453c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync                        false);
454c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync                return 0;
455c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync            }
456c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync
45770afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti            int enable = !strncmp(argv[3], "enable", 7);
45870afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti            if (sInterfaceCtrl->setEnableIPv6(argv[2], enable) == 0) {
45970afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti                cli->sendMsg(ResponseCode::CommandOkay, "IPv6 state changed", false);
46070afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti            } else {
46132a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff                cli->sendMsg(ResponseCode::OperationFailed,
462c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync                        "Failed to change IPv6 state", true);
46332a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff            }
46432a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff            return 0;
4655c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        } else {
4665c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown interface cmd", false);
4675c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            return 0;
4685c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        }
4695c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat    }
470d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    return 0;
471d18304287dbabc7835be771400b85d4ae8b63de6San Mehat}
472d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
4734a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall
474d5573d34c8fac49e16b20cf144486125bf940086San MehatCommandListener::ListTtysCmd::ListTtysCmd() :
475d5573d34c8fac49e16b20cf144486125bf940086San Mehat                 NetdCommand("list_ttys") {
476d5573d34c8fac49e16b20cf144486125bf940086San Mehat}
477d5573d34c8fac49e16b20cf144486125bf940086San Mehat
478d5573d34c8fac49e16b20cf144486125bf940086San Mehatint CommandListener::ListTtysCmd::runCommand(SocketClient *cli,
479d5573d34c8fac49e16b20cf144486125bf940086San Mehat                                             int argc, char **argv) {
480d5573d34c8fac49e16b20cf144486125bf940086San Mehat    TtyCollection *tlist = sPppCtrl->getTtyList();
481d5573d34c8fac49e16b20cf144486125bf940086San Mehat    TtyCollection::iterator it;
482d5573d34c8fac49e16b20cf144486125bf940086San Mehat
483d5573d34c8fac49e16b20cf144486125bf940086San Mehat    for (it = tlist->begin(); it != tlist->end(); ++it) {
484d5573d34c8fac49e16b20cf144486125bf940086San Mehat        cli->sendMsg(ResponseCode::TtyListResult, *it, false);
485d5573d34c8fac49e16b20cf144486125bf940086San Mehat    }
486d5573d34c8fac49e16b20cf144486125bf940086San Mehat
487d5573d34c8fac49e16b20cf144486125bf940086San Mehat    cli->sendMsg(ResponseCode::CommandOkay, "Ttys listed.", false);
488d5573d34c8fac49e16b20cf144486125bf940086San Mehat    return 0;
489d5573d34c8fac49e16b20cf144486125bf940086San Mehat}
490d5573d34c8fac49e16b20cf144486125bf940086San Mehat
491d18304287dbabc7835be771400b85d4ae8b63de6San MehatCommandListener::IpFwdCmd::IpFwdCmd() :
492d18304287dbabc7835be771400b85d4ae8b63de6San Mehat                 NetdCommand("ipfwd") {
493d18304287dbabc7835be771400b85d4ae8b63de6San Mehat}
494d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
495d18304287dbabc7835be771400b85d4ae8b63de6San Mehatint CommandListener::IpFwdCmd::runCommand(SocketClient *cli,
496d18304287dbabc7835be771400b85d4ae8b63de6San Mehat                                                      int argc, char **argv) {
4979d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    int rc = 0;
4989d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
4999d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (argc < 2) {
5009d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
5019d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return 0;
5029d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
5039d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
5049d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (!strcmp(argv[1], "status")) {
5059d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        char *tmp = NULL;
5069d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
5079d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        asprintf(&tmp, "Forwarding %s", (sTetherCtrl->getIpFwdEnabled() ? "enabled" : "disabled"));
5089d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::IpFwdStatusResult, tmp, false);
5099d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        free(tmp);
5109d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return 0;
5119d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    } else if (!strcmp(argv[1], "enable")) {
5129d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        rc = sTetherCtrl->setIpFwdEnabled(true);
5139d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    } else if (!strcmp(argv[1], "disable")) {
5149d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        rc = sTetherCtrl->setIpFwdEnabled(false);
5159d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    } else {
5169d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown ipfwd cmd", false);
5179d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return 0;
5189d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
5199d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
5209d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (!rc) {
5219d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::CommandOkay, "ipfwd operation succeeded", false);
5229d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    } else {
5239d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::OperationFailed, "ipfwd operation failed", true);
5249d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
525d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
526d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    return 0;
527d18304287dbabc7835be771400b85d4ae8b63de6San Mehat}
528d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
529d18304287dbabc7835be771400b85d4ae8b63de6San MehatCommandListener::TetherCmd::TetherCmd() :
530d18304287dbabc7835be771400b85d4ae8b63de6San Mehat                 NetdCommand("tether") {
531d18304287dbabc7835be771400b85d4ae8b63de6San Mehat}
532d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
533d18304287dbabc7835be771400b85d4ae8b63de6San Mehatint CommandListener::TetherCmd::runCommand(SocketClient *cli,
534d18304287dbabc7835be771400b85d4ae8b63de6San Mehat                                                      int argc, char **argv) {
5359d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    int rc = 0;
5369d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
537d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    if (argc < 2) {
538d18304287dbabc7835be771400b85d4ae8b63de6San Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
539d18304287dbabc7835be771400b85d4ae8b63de6San Mehat        return 0;
540d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    }
541d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
5429d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (!strcmp(argv[1], "stop")) {
5439d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        rc = sTetherCtrl->stopTethering();
544d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    } else if (!strcmp(argv[1], "status")) {
5459d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        char *tmp = NULL;
5469d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
5479d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        asprintf(&tmp, "Tethering services %s",
5489d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                 (sTetherCtrl->isTetheringStarted() ? "started" : "stopped"));
5499d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::TetherStatusResult, tmp, false);
5509d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        free(tmp);
551d18304287dbabc7835be771400b85d4ae8b63de6San Mehat        return 0;
55236971a687bf3a6edc2bf5af8a8b2a3176e7d4691JP Abgrall    } else if (argc == 3) {
55336971a687bf3a6edc2bf5af8a8b2a3176e7d4691JP Abgrall        if (!strcmp(argv[1], "interface") && !strcmp(argv[2], "list")) {
55436971a687bf3a6edc2bf5af8a8b2a3176e7d4691JP Abgrall            InterfaceCollection *ilist = sTetherCtrl->getTetheredInterfaceList();
55536971a687bf3a6edc2bf5af8a8b2a3176e7d4691JP Abgrall            InterfaceCollection::iterator it;
55636971a687bf3a6edc2bf5af8a8b2a3176e7d4691JP Abgrall            for (it = ilist->begin(); it != ilist->end(); ++it) {
55736971a687bf3a6edc2bf5af8a8b2a3176e7d4691JP Abgrall                cli->sendMsg(ResponseCode::TetherInterfaceListResult, *it, false);
55836971a687bf3a6edc2bf5af8a8b2a3176e7d4691JP Abgrall            }
55936971a687bf3a6edc2bf5af8a8b2a3176e7d4691JP Abgrall        } else if (!strcmp(argv[1], "dns") && !strcmp(argv[2], "list")) {
56036971a687bf3a6edc2bf5af8a8b2a3176e7d4691JP Abgrall            NetAddressCollection *dlist = sTetherCtrl->getDnsForwarders();
56136971a687bf3a6edc2bf5af8a8b2a3176e7d4691JP Abgrall            NetAddressCollection::iterator it;
56236971a687bf3a6edc2bf5af8a8b2a3176e7d4691JP Abgrall
56336971a687bf3a6edc2bf5af8a8b2a3176e7d4691JP Abgrall            for (it = dlist->begin(); it != dlist->end(); ++it) {
56436971a687bf3a6edc2bf5af8a8b2a3176e7d4691JP Abgrall                cli->sendMsg(ResponseCode::TetherDnsFwdTgtListResult, inet_ntoa(*it), false);
56536971a687bf3a6edc2bf5af8a8b2a3176e7d4691JP Abgrall            }
56620f95ed9db048261c18bbeb152d3204d9cbb58f1JP Abgrall        }
5679d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    } else {
5689d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        /*
5699d10b341a0ba46f108cb96e46691197d778cbc06San Mehat         * These commands take a minimum of 4 arguments
5709d10b341a0ba46f108cb96e46691197d778cbc06San Mehat         */
5719d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        if (argc < 4) {
5729d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
5739d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            return 0;
5749d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        }
5759d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
5769d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        if (!strcmp(argv[1], "start")) {
5773208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt            if (argc % 2 == 1) {
5783208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt                cli->sendMsg(ResponseCode::CommandSyntaxError, "Bad number of arguments", false);
5799d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                return 0;
5809d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            }
5813208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt
5823208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt            int num_addrs = argc - 2;
5833208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt            int arg_index = 2;
5843208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt            int array_index = 0;
5853208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt            in_addr *addrs = (in_addr *)malloc(sizeof(in_addr) * num_addrs);
5863208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt            while (array_index < num_addrs) {
5873208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt                if (!inet_aton(argv[arg_index++], &(addrs[array_index++]))) {
5883208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt                    cli->sendMsg(ResponseCode::CommandParameterError, "Invalid address", false);
5893208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt                    free(addrs);
5903208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt                    return 0;
5913208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt                }
5929d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            }
5933208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt            rc = sTetherCtrl->startTethering(num_addrs, addrs);
5943208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt            free(addrs);
5959d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        } else if (!strcmp(argv[1], "interface")) {
5969d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            if (!strcmp(argv[2], "add")) {
5979d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                rc = sTetherCtrl->tetherInterface(argv[3]);
5989d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            } else if (!strcmp(argv[2], "remove")) {
5999d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                rc = sTetherCtrl->untetherInterface(argv[3]);
60020f95ed9db048261c18bbeb152d3204d9cbb58f1JP Abgrall            /* else if (!strcmp(argv[2], "list")) handled above */
6019d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            } else {
6029d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                cli->sendMsg(ResponseCode::CommandParameterError,
6039d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                             "Unknown tether interface operation", false);
6049d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                return 0;
6059d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            }
6069d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        } else if (!strcmp(argv[1], "dns")) {
6079d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            if (!strcmp(argv[2], "set")) {
6089d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                rc = sTetherCtrl->setDnsForwarders(&argv[3], argc - 3);
60936971a687bf3a6edc2bf5af8a8b2a3176e7d4691JP Abgrall            /* else if (!strcmp(argv[2], "list")) handled above */
6109d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            } else {
6119d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                cli->sendMsg(ResponseCode::CommandParameterError,
6129d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                             "Unknown tether interface operation", false);
6139d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                return 0;
6149d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            }
6159d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        } else {
6169d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown tether cmd", false);
6179d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            return 0;
6189d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        }
6199d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
6209d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
6219d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (!rc) {
6229d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::CommandOkay, "Tether operation succeeded", false);
6239d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    } else {
6249d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::OperationFailed, "Tether operation failed", true);
625d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    }
626d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
627d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    return 0;
628d18304287dbabc7835be771400b85d4ae8b63de6San Mehat}
629d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
630d18304287dbabc7835be771400b85d4ae8b63de6San MehatCommandListener::NatCmd::NatCmd() :
631d18304287dbabc7835be771400b85d4ae8b63de6San Mehat                 NetdCommand("nat") {
632d18304287dbabc7835be771400b85d4ae8b63de6San Mehat}
633d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
634d18304287dbabc7835be771400b85d4ae8b63de6San Mehatint CommandListener::NatCmd::runCommand(SocketClient *cli,
635d18304287dbabc7835be771400b85d4ae8b63de6San Mehat                                                      int argc, char **argv) {
6369d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    int rc = 0;
6379d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
638fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt    if (argc < 5) {
6399d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
6409d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return 0;
6419d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
6429d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
6439ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat    if (!strcmp(argv[1], "enable")) {
644fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt        rc = sNatCtrl->enableNat(argc, argv);
645c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        if(!rc) {
646c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall            /* Ignore ifaces for now. */
647c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall            rc = sBandwidthCtrl->setGlobalAlertInForwardChain();
648c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        }
6499ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat    } else if (!strcmp(argv[1], "disable")) {
650f7bf29c8a37d65e132a4dceb7c5a4200ed5c3d79Robert Greenwalt        /* Ignore ifaces for now. */
651fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt        rc = sBandwidthCtrl->removeGlobalAlertInForwardChain();
652fc97b82e02979f246d56a4bfd60e4aab8686d3f6Robert Greenwalt        rc |= sNatCtrl->disableNat(argc, argv);
6539d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    } else {
6549d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown nat cmd", false);
6559d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return 0;
6569d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
6579d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
6589d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (!rc) {
6599d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::CommandOkay, "Nat operation succeeded", false);
6609d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    } else {
6619d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::OperationFailed, "Nat operation failed", true);
6629d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
663d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
664d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    return 0;
665d18304287dbabc7835be771400b85d4ae8b63de6San Mehat}
666d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
667d5573d34c8fac49e16b20cf144486125bf940086San MehatCommandListener::PppdCmd::PppdCmd() :
668d5573d34c8fac49e16b20cf144486125bf940086San Mehat                 NetdCommand("pppd") {
669d5573d34c8fac49e16b20cf144486125bf940086San Mehat}
670d5573d34c8fac49e16b20cf144486125bf940086San Mehat
671d5573d34c8fac49e16b20cf144486125bf940086San Mehatint CommandListener::PppdCmd::runCommand(SocketClient *cli,
672d5573d34c8fac49e16b20cf144486125bf940086San Mehat                                                      int argc, char **argv) {
673d5573d34c8fac49e16b20cf144486125bf940086San Mehat    int rc = 0;
674d5573d34c8fac49e16b20cf144486125bf940086San Mehat
675d5573d34c8fac49e16b20cf144486125bf940086San Mehat    if (argc < 3) {
676d5573d34c8fac49e16b20cf144486125bf940086San Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
677d5573d34c8fac49e16b20cf144486125bf940086San Mehat        return 0;
678d5573d34c8fac49e16b20cf144486125bf940086San Mehat    }
679d5573d34c8fac49e16b20cf144486125bf940086San Mehat
680d5573d34c8fac49e16b20cf144486125bf940086San Mehat    if (!strcmp(argv[1], "attach")) {
68174d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt        struct in_addr l, r, dns1, dns2;
68274d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt
68374d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt        memset(&dns1, sizeof(struct in_addr), 0);
68474d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt        memset(&dns2, sizeof(struct in_addr), 0);
685d5573d34c8fac49e16b20cf144486125bf940086San Mehat
686d5573d34c8fac49e16b20cf144486125bf940086San Mehat        if (!inet_aton(argv[3], &l)) {
687d5573d34c8fac49e16b20cf144486125bf940086San Mehat            cli->sendMsg(ResponseCode::CommandParameterError, "Invalid local address", false);
688d5573d34c8fac49e16b20cf144486125bf940086San Mehat            return 0;
689d5573d34c8fac49e16b20cf144486125bf940086San Mehat        }
690d5573d34c8fac49e16b20cf144486125bf940086San Mehat        if (!inet_aton(argv[4], &r)) {
691d5573d34c8fac49e16b20cf144486125bf940086San Mehat            cli->sendMsg(ResponseCode::CommandParameterError, "Invalid remote address", false);
692d5573d34c8fac49e16b20cf144486125bf940086San Mehat            return 0;
693d5573d34c8fac49e16b20cf144486125bf940086San Mehat        }
69474d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt        if ((argc > 3) && (!inet_aton(argv[5], &dns1))) {
69574d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt            cli->sendMsg(ResponseCode::CommandParameterError, "Invalid dns1 address", false);
69674d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt            return 0;
69774d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt        }
69874d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt        if ((argc > 4) && (!inet_aton(argv[6], &dns2))) {
69974d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt            cli->sendMsg(ResponseCode::CommandParameterError, "Invalid dns2 address", false);
70074d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt            return 0;
70174d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt        }
70274d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt        rc = sPppCtrl->attachPppd(argv[2], l, r, dns1, dns2);
703d5573d34c8fac49e16b20cf144486125bf940086San Mehat    } else if (!strcmp(argv[1], "detach")) {
704d5573d34c8fac49e16b20cf144486125bf940086San Mehat        rc = sPppCtrl->detachPppd(argv[2]);
705d5573d34c8fac49e16b20cf144486125bf940086San Mehat    } else {
706d5573d34c8fac49e16b20cf144486125bf940086San Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown pppd cmd", false);
707d5573d34c8fac49e16b20cf144486125bf940086San Mehat        return 0;
708d5573d34c8fac49e16b20cf144486125bf940086San Mehat    }
709d5573d34c8fac49e16b20cf144486125bf940086San Mehat
710d5573d34c8fac49e16b20cf144486125bf940086San Mehat    if (!rc) {
711d5573d34c8fac49e16b20cf144486125bf940086San Mehat        cli->sendMsg(ResponseCode::CommandOkay, "Pppd operation succeeded", false);
712d5573d34c8fac49e16b20cf144486125bf940086San Mehat    } else {
713d5573d34c8fac49e16b20cf144486125bf940086San Mehat        cli->sendMsg(ResponseCode::OperationFailed, "Pppd operation failed", true);
714d5573d34c8fac49e16b20cf144486125bf940086San Mehat    }
715d5573d34c8fac49e16b20cf144486125bf940086San Mehat
716d5573d34c8fac49e16b20cf144486125bf940086San Mehat    return 0;
717d5573d34c8fac49e16b20cf144486125bf940086San Mehat}
7181bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat
7195af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry ShmidtCommandListener::SoftapCmd::SoftapCmd() :
7205af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt                 NetdCommand("softap") {
7215af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt}
7225af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
7235af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidtint CommandListener::SoftapCmd::runCommand(SocketClient *cli,
7245af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt                                        int argc, char **argv) {
72525753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy    int rc = ResponseCode::SoftapStatusResult;
72625753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy    int flag = 0;
727666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt    char *retbuf = NULL;
7285af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
72925753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy    if (sSoftapCtrl == NULL) {
73025753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy      cli->sendMsg(ResponseCode::ServiceStartFailed, "SoftAP is not available", false);
73125753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy      return -1;
73225753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy    }
7335af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    if (argc < 2) {
73425753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy        cli->sendMsg(ResponseCode::CommandSyntaxError,
73525753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy                     "Missing argument in a SoftAP command", false);
7365af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        return 0;
7375af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    }
7385af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
7397e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff    if (!strcmp(argv[1], "startap")) {
740c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt        rc = sSoftapCtrl->startSoftap();
741c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt    } else if (!strcmp(argv[1], "stopap")) {
7425af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        rc = sSoftapCtrl->stopSoftap();
74331fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    } else if (!strcmp(argv[1], "fwreload")) {
74431fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt        rc = sSoftapCtrl->fwReloadSoftap(argc, argv);
7455af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    } else if (!strcmp(argv[1], "status")) {
74625753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy        asprintf(&retbuf, "Softap service %s running",
74725753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy                 (sSoftapCtrl->isSoftapStarted() ? "is" : "is not"));
74825753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy        cli->sendMsg(rc, retbuf, false);
749666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt        free(retbuf);
7505af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        return 0;
7515af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    } else if (!strcmp(argv[1], "set")) {
7525af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        rc = sSoftapCtrl->setSoftap(argc, argv);
7535af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    } else {
75425753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unrecognized SoftAP command", false);
7555af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        return 0;
7565af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    }
7575af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
75825753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy    if (rc >= 400 && rc < 600)
75925753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy      cli->sendMsg(rc, "SoftAP command has failed", false);
76025753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy    else
76125753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy      cli->sendMsg(rc, "Ok", false);
7625af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
7635af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    return 0;
7645af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt}
7653e6ba3ce1abda6071d5b01f53ca6039bb7b5e2d3Robert Greenwalt
76689c1e975f0c03997808d35c7be10b244c5309f9fMattias FalkCommandListener::ResolverCmd::ResolverCmd() :
76789c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        NetdCommand("resolver") {
76889c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk}
76989c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk
77089c1e975f0c03997808d35c7be10b244c5309f9fMattias Falkint CommandListener::ResolverCmd::runCommand(SocketClient *cli, int argc, char **argv) {
77189c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    int rc = 0;
77289c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    struct in_addr addr;
77389c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk
77489c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    if (argc < 2) {
77589c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        cli->sendMsg(ResponseCode::CommandSyntaxError, "Resolver missing arguments", false);
77689c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        return 0;
77789c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    }
77889c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk
77989c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    if (!strcmp(argv[1], "setdefaultif")) { // "resolver setdefaultif <iface>"
78089c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        if (argc == 3) {
78189c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            rc = sResolverCtrl->setDefaultInterface(argv[2]);
78289c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        } else {
78389c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            cli->sendMsg(ResponseCode::CommandSyntaxError,
78489c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk                    "Wrong number of arguments to resolver setdefaultif", false);
78589c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            return 0;
78689c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        }
787dd3e46758b500d5e8c61ed30f7402e8538df7e06Robert Greenwalt    } else if (!strcmp(argv[1], "setifdns")) {
788dd3e46758b500d5e8c61ed30f7402e8538df7e06Robert Greenwalt        // "resolver setifdns <iface> <domains> <dns1> <dns2> ..."
789dd3e46758b500d5e8c61ed30f7402e8538df7e06Robert Greenwalt        if (argc >= 5) {
790dd3e46758b500d5e8c61ed30f7402e8538df7e06Robert Greenwalt            rc = sResolverCtrl->setInterfaceDnsServers(argv[2], argv[3], &argv[4], argc - 4);
79189c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        } else {
79289c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            cli->sendMsg(ResponseCode::CommandSyntaxError,
79389c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk                    "Wrong number of arguments to resolver setifdns", false);
79489c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            return 0;
79589c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        }
79689c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk
79789c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        // set the address of the interface to which the name servers
79889c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        // are bound. Required in order to bind to right interface when
79989c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        // doing the dns query.
80089c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        if (!rc) {
80189c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            ifc_init();
80289c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            ifc_get_info(argv[2], &addr.s_addr, NULL, 0);
80389c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk
80489c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            rc = sResolverCtrl->setInterfaceAddress(argv[2], &addr);
80589c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        }
80689c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    } else if (!strcmp(argv[1], "flushdefaultif")) { // "resolver flushdefaultif"
80789c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        if (argc == 2) {
80889c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            rc = sResolverCtrl->flushDefaultDnsCache();
80989c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        } else {
81089c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            cli->sendMsg(ResponseCode::CommandSyntaxError,
81189c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk                    "Wrong number of arguments to resolver flushdefaultif", false);
81289c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            return 0;
81389c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        }
81489c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    } else if (!strcmp(argv[1], "flushif")) { // "resolver flushif <iface>"
81589c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        if (argc == 3) {
81689c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            rc = sResolverCtrl->flushInterfaceDnsCache(argv[2]);
81789c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        } else {
81889c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            cli->sendMsg(ResponseCode::CommandSyntaxError,
81989c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk                    "Wrong number of arguments to resolver setdefaultif", false);
82089c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            return 0;
82189c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        }
8222d4610ec34cc78799a3353638fa05ee53276892aMattias Falk    } else if (!strcmp(argv[1], "setifaceforpid")) { // resolver setifaceforpid <iface> <pid>
8232d4610ec34cc78799a3353638fa05ee53276892aMattias Falk        if (argc == 4) {
8242d4610ec34cc78799a3353638fa05ee53276892aMattias Falk            rc = sResolverCtrl->setDnsInterfaceForPid(argv[2], atoi(argv[3]));
8252d4610ec34cc78799a3353638fa05ee53276892aMattias Falk        } else {
8262d4610ec34cc78799a3353638fa05ee53276892aMattias Falk            cli->sendMsg(ResponseCode::CommandSyntaxError,
8272d4610ec34cc78799a3353638fa05ee53276892aMattias Falk                    "Wrong number of arguments to resolver setifaceforpid", false);
8282d4610ec34cc78799a3353638fa05ee53276892aMattias Falk            return 0;
8292d4610ec34cc78799a3353638fa05ee53276892aMattias Falk        }
8302d4610ec34cc78799a3353638fa05ee53276892aMattias Falk    } else if (!strcmp(argv[1], "clearifaceforpid")) { // resolver clearifaceforpid <pid>
8312d4610ec34cc78799a3353638fa05ee53276892aMattias Falk        if (argc == 3) {
8322d4610ec34cc78799a3353638fa05ee53276892aMattias Falk            rc = sResolverCtrl->clearDnsInterfaceForPid(atoi(argv[2]));
8332d4610ec34cc78799a3353638fa05ee53276892aMattias Falk        } else {
8342d4610ec34cc78799a3353638fa05ee53276892aMattias Falk            cli->sendMsg(ResponseCode::CommandSyntaxError,
8352d4610ec34cc78799a3353638fa05ee53276892aMattias Falk                    "Wrong number of arguments to resolver clearifaceforpid", false);
8362d4610ec34cc78799a3353638fa05ee53276892aMattias Falk            return 0;
8372d4610ec34cc78799a3353638fa05ee53276892aMattias Falk        }
83889c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    } else {
83989c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        cli->sendMsg(ResponseCode::CommandSyntaxError,"Resolver unknown command", false);
84089c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        return 0;
84189c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    }
84289c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk
84389c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    if (!rc) {
84489c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        cli->sendMsg(ResponseCode::CommandOkay, "Resolver command succeeded", false);
84589c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    } else {
84689c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        cli->sendMsg(ResponseCode::OperationFailed, "Resolver command failed", true);
84789c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    }
84889c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk
84989c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    return 0;
85089c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk}
85189c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk
8524a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP AbgrallCommandListener::BandwidthControlCmd::BandwidthControlCmd() :
8530dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall    NetdCommand("bandwidth") {
8544a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall}
8554a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall
856db7da58e8d2aa021060098057f944ef754be06e3JP Abgrallvoid CommandListener::BandwidthControlCmd::sendGenericSyntaxError(SocketClient *cli, const char *usageMsg) {
857db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    char *msg;
858db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    asprintf(&msg, "Usage: bandwidth %s", usageMsg);
859db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    cli->sendMsg(ResponseCode::CommandSyntaxError, msg, false);
860db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    free(msg);
861db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall}
862db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
863db7da58e8d2aa021060098057f944ef754be06e3JP Abgrallvoid CommandListener::BandwidthControlCmd::sendGenericOkFail(SocketClient *cli, int cond) {
864db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!cond) {
865db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        cli->sendMsg(ResponseCode::CommandOkay, "Bandwidth command succeeeded", false);
866db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    } else {
867db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        cli->sendMsg(ResponseCode::OperationFailed, "Bandwidth command failed", false);
868db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
869db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall}
870db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
871db7da58e8d2aa021060098057f944ef754be06e3JP Abgrallvoid CommandListener::BandwidthControlCmd::sendGenericOpFailed(SocketClient *cli, const char *errMsg) {
872db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    cli->sendMsg(ResponseCode::OperationFailed, errMsg, false);
873db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall}
874db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
875fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrallint CommandListener::BandwidthControlCmd::runCommand(SocketClient *cli, int argc, char **argv) {
8764a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall    if (argc < 2) {
877db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericSyntaxError(cli, "<cmds> <args...>");
8784a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall        return 0;
8794a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall    }
8804a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall
8813fb42e026ffebab2c8f282e42501040121e32d83Steve Block    ALOGV("bwctrlcmd: argc=%d %s %s ...", argc, argv[0], argv[1]);
882db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
8834a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall    if (!strcmp(argv[1], "enable")) {
8840031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall        int rc = sBandwidthCtrl->enableBandwidthControl(true);
885db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
886db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
887db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
888db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
889db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "disable")) {
890db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->disableBandwidthControl();
891db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
892db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
8930dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall
894db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
895db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "removequota") || !strcmp(argv[1], "rq")) {
896fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall        if (argc != 3) {
897db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "removequota <interface>");
898fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall            return 0;
899fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall        }
900db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->removeInterfaceSharedQuota(argv[2]);
901db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
902db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
903fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall
904db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
905db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "getquota") || !strcmp(argv[1], "gq")) {
9068a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        int64_t bytes;
9078a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        if (argc != 2) {
908db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "getquota");
9098a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall            return 0;
9108a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        }
911db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->getInterfaceSharedQuota(&bytes);
9128a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        if (rc) {
913db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericOpFailed(cli, "Failed to get quota");
9148a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall            return 0;
9158a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        }
916db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
9178a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        char *msg;
9188a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        asprintf(&msg, "%lld", bytes);
9198a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        cli->sendMsg(ResponseCode::QuotaCounterResult, msg, false);
9208a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        free(msg);
921db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
9228a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
923db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
924db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "getiquota") || !strcmp(argv[1], "giq")) {
9258a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        int64_t bytes;
9268a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        if (argc != 3) {
927db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "getiquota <iface>");
9288a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall            return 0;
9298a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        }
930db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
931db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->getInterfaceQuota(argv[2], &bytes);
9328a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        if (rc) {
933db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericOpFailed(cli, "Failed to get quota");
9348a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall            return 0;
9358a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        }
9368a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        char *msg;
9378a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        asprintf(&msg, "%lld", bytes);
9388a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        cli->sendMsg(ResponseCode::QuotaCounterResult, msg, false);
9398a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        free(msg);
940db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
9418a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
942db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
943db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "setquota") || !strcmp(argv[1], "sq")) {
944fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall        if (argc != 4) {
945db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "setquota <interface> <bytes>");
946fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall            return 0;
947fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall        }
948db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->setInterfaceSharedQuota(argv[2], atoll(argv[3]));
949db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
950db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
951db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
952db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "setquotas") || !strcmp(argv[1], "sqs")) {
953db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc;
954fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall        if (argc < 4) {
955db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "setquotas <bytes> <interface> ...");
956fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall            return 0;
957fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall        }
958db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
9598a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        for (int q = 3; argc >= 4; q++, argc--) {
9600dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall            rc = sBandwidthCtrl->setInterfaceSharedQuota(argv[q], atoll(argv[2]));
9610dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall            if (rc) {
9620dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall                char *msg;
9630dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall                asprintf(&msg, "bandwidth setquotas %s %s failed", argv[2], argv[q]);
9640dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall                cli->sendMsg(ResponseCode::OperationFailed,
9650dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall                             msg, false);
9660dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall                free(msg);
967db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall                return 0;
9680dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall            }
9690dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall        }
970db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
971db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
9720dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall
973db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
974db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "removequotas") || !strcmp(argv[1], "rqs")) {
975db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc;
9760dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall        if (argc < 3) {
977db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "removequotas <interface> ...");
9780dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall            return 0;
9790dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall        }
980db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
9818a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        for (int q = 2; argc >= 3; q++, argc--) {
9820dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall            rc = sBandwidthCtrl->removeInterfaceSharedQuota(argv[q]);
9830dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall            if (rc) {
9840dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall                char *msg;
9850dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall                asprintf(&msg, "bandwidth removequotas %s failed", argv[q]);
9860dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall                cli->sendMsg(ResponseCode::OperationFailed,
9870dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall                             msg, false);
9880dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall                free(msg);
989db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall                return 0;
9900dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall            }
9910dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall        }
992db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
993db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
9940dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall
995db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
996db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "removeiquota") || !strcmp(argv[1], "riq")) {
9970dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall        if (argc != 3) {
998db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "removeiquota <interface>");
9990dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall            return 0;
10000dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall        }
1001db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->removeInterfaceQuota(argv[2]);
1002db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
1003db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
10040dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall
1005db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
1006db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "setiquota") || !strcmp(argv[1], "siq")) {
10070dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall        if (argc != 4) {
1008db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "setiquota <interface> <bytes>");
10090dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall            return 0;
10100dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall        }
1011db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->setInterfaceQuota(argv[2], atoll(argv[3]));
1012db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
1013db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
1014fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall
1015db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
1016db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "addnaughtyapps") || !strcmp(argv[1], "ana")) {
1017fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall        if (argc < 3) {
1018db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "addnaughtyapps <appUid> ...");
10194a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall            return 0;
1020fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall        }
1021db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->addNaughtyApps(argc - 2, argv + 2);
1022db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
1023db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
1024db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
1025fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall
1026db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
1027db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "removenaughtyapps") || !strcmp(argv[1], "rna")) {
1028fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall        if (argc < 3) {
1029db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "removenaughtyapps <appUid> ...");
1030fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall            return 0;
1031fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall        }
1032db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->removeNaughtyApps(argc - 2, argv + 2);
1033db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
1034db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
1035fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall
1036db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
1037db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "setglobalalert") || !strcmp(argv[1], "sga")) {
10388a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        if (argc != 3) {
1039db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "setglobalalert <bytes>");
10408a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall            return 0;
10418a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        }
1042db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->setGlobalAlert(atoll(argv[2]));
1043db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
1044db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
10458a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
1046db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
1047c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall    if (!strcmp(argv[1], "debugsettetherglobalalert") || !strcmp(argv[1], "dstga")) {
1048c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        if (argc != 4) {
1049c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall            sendGenericSyntaxError(cli, "debugsettetherglobalalert <interface0> <interface1>");
1050c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall            return 0;
1051c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        }
1052c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        /* We ignore the interfaces for now. */
1053c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        int rc = sBandwidthCtrl->setGlobalAlertInForwardChain();
1054c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        sendGenericOkFail(cli, rc);
1055c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        return 0;
1056c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall
1057c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall    }
1058db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "removeglobalalert") || !strcmp(argv[1], "rga")) {
10598a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        if (argc != 2) {
1060db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "removeglobalalert");
10618a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall            return 0;
10628a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        }
1063db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->removeGlobalAlert();
1064db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
1065db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
10668a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
1067db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
1068c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall    if (!strcmp(argv[1], "debugremovetetherglobalalert") || !strcmp(argv[1], "drtga")) {
1069c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        if (argc != 4) {
1070c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall            sendGenericSyntaxError(cli, "debugremovetetherglobalalert <interface0> <interface1>");
1071c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall            return 0;
1072c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        }
1073c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        /* We ignore the interfaces for now. */
1074c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        int rc = sBandwidthCtrl->removeGlobalAlertInForwardChain();
1075c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        sendGenericOkFail(cli, rc);
1076c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        return 0;
1077c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall
1078c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall    }
1079db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "setsharedalert") || !strcmp(argv[1], "ssa")) {
10808a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        if (argc != 3) {
1081db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "setsharedalert <bytes>");
10828a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall            return 0;
10838a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        }
1084db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->setSharedAlert(atoll(argv[2]));
1085db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
1086db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
10878a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
1088db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
1089db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "removesharedalert") || !strcmp(argv[1], "rsa")) {
10908a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        if (argc != 2) {
1091db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "removesharedalert");
10928a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall            return 0;
10938a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        }
1094db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->removeSharedAlert();
1095db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
1096db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
10978a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
1098db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
1099db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "setinterfacealert") || !strcmp(argv[1], "sia")) {
11008a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        if (argc != 4) {
1101db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "setinterfacealert <interface> <bytes>");
11028a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall            return 0;
11038a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        }
1104db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->setInterfaceAlert(argv[2], atoll(argv[3]));
1105db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
1106db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
11078a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
1108db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
1109db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "removeinterfacealert") || !strcmp(argv[1], "ria")) {
11108a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        if (argc != 3) {
1111db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "removeinterfacealert <interface>");
11128a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall            return 0;
11138a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        }
1114db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->removeInterfaceAlert(argv[2]);
1115db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
1116fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall        return 0;
1117db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
11184a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall    }
1119db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "gettetherstats") || !strcmp(argv[1], "gts")) {
1120db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        BandwidthController::TetherStats tetherStats;
1121a2a64f004f1677daf16b0b03d589d6572ec547c2JP Abgrall        std::string extraProcessingInfo = "";
1122db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        if (argc != 4) {
1123db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "gettetherstats <interface0> <interface1>");
1124db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            return 0;
1125db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        }
1126db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
1127db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        tetherStats.ifaceIn = argv[2];
1128db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        tetherStats.ifaceOut = argv[3];
1129a2a64f004f1677daf16b0b03d589d6572ec547c2JP Abgrall        int rc = sBandwidthCtrl->getTetherStats(tetherStats, extraProcessingInfo);
1130db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        if (rc) {
1131a2a64f004f1677daf16b0b03d589d6572ec547c2JP Abgrall                extraProcessingInfo.insert(0, "Failed to get tethering stats.\n");
1132a2a64f004f1677daf16b0b03d589d6572ec547c2JP Abgrall                sendGenericOpFailed(cli, extraProcessingInfo.c_str());
1133db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            return 0;
1134db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        }
1135db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
1136db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        char *msg = tetherStats.getStatsLine();
1137db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        cli->sendMsg(ResponseCode::TetheringStatsResult, msg, false);
1138db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        free(msg);
1139db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
11404a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall
11414a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall    }
1142db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
1143db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown bandwidth cmd", false);
11444a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall    return 0;
11454a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall}
11460031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall
11470031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP AbgrallCommandListener::IdletimerControlCmd::IdletimerControlCmd() :
11480031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    NetdCommand("idletimer") {
11490031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall}
11500031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall
11510031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrallint CommandListener::IdletimerControlCmd::runCommand(SocketClient *cli, int argc, char **argv) {
11520031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall  // TODO(ashish): Change the error statements
11530031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    if (argc < 2) {
11540031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
11550031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall        return 0;
11560031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    }
11570031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall
11580031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    ALOGV("idletimerctrlcmd: argc=%d %s %s ...", argc, argv[0], argv[1]);
11590031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall
11600031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    if (!strcmp(argv[1], "enable")) {
11610031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall      if (0 != sIdletimerCtrl->enableIdletimerControl()) {
11620031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
11630031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall      } else {
11640031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall        cli->sendMsg(ResponseCode::CommandOkay, "Enable success", false);
11650031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall      }
11660031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall      return 0;
11670031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall
11680031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    }
11690031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    if (!strcmp(argv[1], "disable")) {
11700031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall      if (0 != sIdletimerCtrl->disableIdletimerControl()) {
11710031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
11720031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall      } else {
11730031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall        cli->sendMsg(ResponseCode::CommandOkay, "Disable success", false);
11740031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall      }
11750031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall      return 0;
11760031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    }
11770031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    if (!strcmp(argv[1], "add")) {
117898f65d32b1530b4da6050e38d52f955710577efbHaoyu Bai        if (argc != 5) {
11790031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall            cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
11800031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall            return 0;
11810031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall        }
118298f65d32b1530b4da6050e38d52f955710577efbHaoyu Bai        if(0 != sIdletimerCtrl->addInterfaceIdletimer(
118398f65d32b1530b4da6050e38d52f955710577efbHaoyu Bai                                        argv[2], atoi(argv[3]), argv[4])) {
11840031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall          cli->sendMsg(ResponseCode::OperationFailed, "Failed to add interface", false);
11850031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall        } else {
11860031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall          cli->sendMsg(ResponseCode::CommandOkay,  "Add success", false);
11870031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall        }
11880031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall        return 0;
11890031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    }
11900031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    if (!strcmp(argv[1], "remove")) {
119198f65d32b1530b4da6050e38d52f955710577efbHaoyu Bai        if (argc != 5) {
11920031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall            cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
11930031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall            return 0;
11940031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall        }
11950031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall        // ashish: fixme timeout
119698f65d32b1530b4da6050e38d52f955710577efbHaoyu Bai        if (0 != sIdletimerCtrl->removeInterfaceIdletimer(
119798f65d32b1530b4da6050e38d52f955710577efbHaoyu Bai                                        argv[2], atoi(argv[3]), argv[4])) {
11980031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall          cli->sendMsg(ResponseCode::OperationFailed, "Failed to remove interface", false);
11990031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall        } else {
12000031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall          cli->sendMsg(ResponseCode::CommandOkay, "Remove success", false);
12010031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall        }
12020031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall        return 0;
12030031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    }
12040031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall
12050031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown idletimer cmd", false);
12060031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    return 0;
12070031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall}
1208d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey
1209d8c64026aaae5a9987151b719bd840ec7d68747aJeff SharkeyCommandListener::FirewallCmd::FirewallCmd() :
1210d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    NetdCommand("firewall") {
1211d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey}
1212d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey
1213d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkeyint CommandListener::FirewallCmd::sendGenericOkFail(SocketClient *cli, int cond) {
1214d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    if (!cond) {
1215d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        cli->sendMsg(ResponseCode::CommandOkay, "Firewall command succeeded", false);
1216d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    } else {
1217d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        cli->sendMsg(ResponseCode::OperationFailed, "Firewall command failed", false);
1218d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    }
1219d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    return 0;
1220d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey}
1221d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey
1222d8c64026aaae5a9987151b719bd840ec7d68747aJeff SharkeyFirewallRule CommandListener::FirewallCmd::parseRule(const char* arg) {
1223d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    if (!strcmp(arg, "allow")) {
1224d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        return ALLOW;
1225d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    } else {
1226d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        return DENY;
1227d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    }
1228d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey}
1229d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey
1230d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkeyint CommandListener::FirewallCmd::runCommand(SocketClient *cli, int argc,
1231d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        char **argv) {
1232d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    if (argc < 2) {
1233d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing command", false);
1234d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        return 0;
1235d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    }
1236d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey
1237d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    if (!strcmp(argv[1], "enable")) {
1238d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        int res = sFirewallCtrl->enableFirewall();
1239d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        return sendGenericOkFail(cli, res);
1240d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    }
1241d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    if (!strcmp(argv[1], "disable")) {
1242d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        int res = sFirewallCtrl->disableFirewall();
1243d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        return sendGenericOkFail(cli, res);
1244d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    }
1245d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    if (!strcmp(argv[1], "is_enabled")) {
1246d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        int res = sFirewallCtrl->isFirewallEnabled();
1247d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        return sendGenericOkFail(cli, res);
1248d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    }
1249d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey
1250d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    if (!strcmp(argv[1], "set_interface_rule")) {
1251d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        if (argc != 4) {
1252d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey            cli->sendMsg(ResponseCode::CommandSyntaxError,
1253d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey                         "Usage: firewall set_interface_rule <rmnet0> <allow|deny>", false);
1254d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey            return 0;
1255d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        }
1256d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey
1257d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        const char* iface = argv[2];
1258d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        FirewallRule rule = parseRule(argv[3]);
1259d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey
1260d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        int res = sFirewallCtrl->setInterfaceRule(iface, rule);
1261d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        return sendGenericOkFail(cli, res);
1262d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    }
1263d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey
1264d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    if (!strcmp(argv[1], "set_egress_source_rule")) {
1265d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        if (argc != 4) {
1266d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey            cli->sendMsg(ResponseCode::CommandSyntaxError,
1267d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey                         "Usage: firewall set_egress_source_rule <192.168.0.1> <allow|deny>",
1268d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey                         false);
1269d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey            return 0;
1270d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        }
1271d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey
1272d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        const char* addr = argv[2];
1273d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        FirewallRule rule = parseRule(argv[3]);
1274d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey
1275d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        int res = sFirewallCtrl->setEgressSourceRule(addr, rule);
1276d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        return sendGenericOkFail(cli, res);
1277d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    }
1278d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey
1279d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    if (!strcmp(argv[1], "set_egress_dest_rule")) {
1280d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        if (argc != 5) {
1281d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey            cli->sendMsg(ResponseCode::CommandSyntaxError,
1282d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey                         "Usage: firewall set_egress_dest_rule <192.168.0.1> <80> <allow|deny>",
1283d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey                         false);
1284d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey            return 0;
1285d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        }
1286d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey
1287d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        const char* addr = argv[2];
1288d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        int port = atoi(argv[3]);
1289d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        FirewallRule rule = parseRule(argv[4]);
1290d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey
1291d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        int res = 0;
1292d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        res |= sFirewallCtrl->setEgressDestRule(addr, PROTOCOL_TCP, port, rule);
1293d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        res |= sFirewallCtrl->setEgressDestRule(addr, PROTOCOL_UDP, port, rule);
1294d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        return sendGenericOkFail(cli, res);
1295d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    }
1296d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey
1297d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    if (!strcmp(argv[1], "set_uid_rule")) {
1298d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        if (argc != 4) {
1299d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey            cli->sendMsg(ResponseCode::CommandSyntaxError,
1300d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey                         "Usage: firewall set_uid_rule <1000> <allow|deny>",
1301d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey                         false);
1302d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey            return 0;
1303d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        }
1304d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey
1305d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        int uid = atoi(argv[2]);
1306d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        FirewallRule rule = parseRule(argv[3]);
1307d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey
1308d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        int res = sFirewallCtrl->setUidRule(uid, rule);
1309d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey        return sendGenericOkFail(cli, res);
1310d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    }
1311d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey
1312d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown command", false);
1313d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey    return 0;
1314d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey}
13150da73fcecc30140439f856118056df8908609627Daniel Drown
13160da73fcecc30140439f856118056df8908609627Daniel DrownCommandListener::ClatdCmd::ClatdCmd() : NetdCommand("clatd") {
13170da73fcecc30140439f856118056df8908609627Daniel Drown}
13180da73fcecc30140439f856118056df8908609627Daniel Drown
13190da73fcecc30140439f856118056df8908609627Daniel Drownint CommandListener::ClatdCmd::runCommand(SocketClient *cli, int argc,
13200da73fcecc30140439f856118056df8908609627Daniel Drown                                                            char **argv) {
13210da73fcecc30140439f856118056df8908609627Daniel Drown    int rc = 0;
13220da73fcecc30140439f856118056df8908609627Daniel Drown    if (argc < 2) {
13230da73fcecc30140439f856118056df8908609627Daniel Drown        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
13240da73fcecc30140439f856118056df8908609627Daniel Drown        return 0;
13250da73fcecc30140439f856118056df8908609627Daniel Drown    }
13260da73fcecc30140439f856118056df8908609627Daniel Drown
13270da73fcecc30140439f856118056df8908609627Daniel Drown    if(!strcmp(argv[1], "stop")) {
13280da73fcecc30140439f856118056df8908609627Daniel Drown        rc = sClatdCtrl->stopClatd();
13290da73fcecc30140439f856118056df8908609627Daniel Drown    } else if (!strcmp(argv[1], "status")) {
13300da73fcecc30140439f856118056df8908609627Daniel Drown        char *tmp = NULL;
13310da73fcecc30140439f856118056df8908609627Daniel Drown
13320da73fcecc30140439f856118056df8908609627Daniel Drown        asprintf(&tmp, "Clatd status: %s", (sClatdCtrl->isClatdStarted() ?
13330da73fcecc30140439f856118056df8908609627Daniel Drown                                                        "started" : "stopped"));
13340da73fcecc30140439f856118056df8908609627Daniel Drown        cli->sendMsg(ResponseCode::ClatdStatusResult, tmp, false);
13350da73fcecc30140439f856118056df8908609627Daniel Drown        free(tmp);
13360da73fcecc30140439f856118056df8908609627Daniel Drown        return 0;
13370da73fcecc30140439f856118056df8908609627Daniel Drown    } else if(!strcmp(argv[1], "start")) {
13380da73fcecc30140439f856118056df8908609627Daniel Drown        if (argc < 3) {
13390da73fcecc30140439f856118056df8908609627Daniel Drown            cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
13400da73fcecc30140439f856118056df8908609627Daniel Drown            return 0;
13410da73fcecc30140439f856118056df8908609627Daniel Drown        }
13420da73fcecc30140439f856118056df8908609627Daniel Drown        rc = sClatdCtrl->startClatd(argv[2]);
13430da73fcecc30140439f856118056df8908609627Daniel Drown    } else {
13440da73fcecc30140439f856118056df8908609627Daniel Drown        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown clatd cmd", false);
13450da73fcecc30140439f856118056df8908609627Daniel Drown        return 0;
13460da73fcecc30140439f856118056df8908609627Daniel Drown    }
13470da73fcecc30140439f856118056df8908609627Daniel Drown
13480da73fcecc30140439f856118056df8908609627Daniel Drown    if (!rc) {
13490da73fcecc30140439f856118056df8908609627Daniel Drown        cli->sendMsg(ResponseCode::CommandOkay, "Clatd operation succeeded", false);
13500da73fcecc30140439f856118056df8908609627Daniel Drown    } else {
13510da73fcecc30140439f856118056df8908609627Daniel Drown        cli->sendMsg(ResponseCode::OperationFailed, "Clatd operation failed", false);
13520da73fcecc30140439f856118056df8908609627Daniel Drown    }
13530da73fcecc30140439f856118056df8908609627Daniel Drown
13540da73fcecc30140439f856118056df8908609627Daniel Drown    return 0;
13550da73fcecc30140439f856118056df8908609627Daniel Drown}
1356