CommandListener.cpp revision f7bf29c8a37d65e132a4dceb7c5a4200ed5c3d79
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
17db7da58e8d2aa021060098057f944ef754be06e3JP 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>
2732a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff#include <fcntl.h>
285c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat#include <linux/if.h>
295c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
30d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#define LOG_TAG "CommandListener"
31d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
321ed47c4a016e420a855ee46922e512150245ff61Lorenzo Colitti#include <cutils/log.h>
331ed47c4a016e420a855ee46922e512150245ff61Lorenzo Colitti#include <netutils/ifc.h>
34d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <sysutils/SocketClient.h>
35d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
36d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include "CommandListener.h"
37d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include "ResponseCode.h"
38a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat#include "ThrottleController.h"
394a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall#include "BandwidthController.h"
40a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat
41d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
425c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
439d10b341a0ba46f108cb96e46691197d778cbc06San MehatTetherController *CommandListener::sTetherCtrl = NULL;
449ff78fb7da7158f5bd7c86d89a842691820259cfSan MehatNatController *CommandListener::sNatCtrl = NULL;
45d5573d34c8fac49e16b20cf144486125bf940086San MehatPppController *CommandListener::sPppCtrl = NULL;
461bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San MehatPanController *CommandListener::sPanCtrl = NULL;
475af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry ShmidtSoftapController *CommandListener::sSoftapCtrl = NULL;
484a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP AbgrallBandwidthController * CommandListener::sBandwidthCtrl = NULL;
4989c1e975f0c03997808d35c7be10b244c5309f9fMattias FalkResolverController *CommandListener::sResolverCtrl = NULL;
509d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
51d18304287dbabc7835be771400b85d4ae8b63de6San MehatCommandListener::CommandListener() :
52d18304287dbabc7835be771400b85d4ae8b63de6San Mehat                 FrameworkListener("netd") {
535c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat    registerCmd(new InterfaceCmd());
54d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    registerCmd(new IpFwdCmd());
55d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    registerCmd(new TetherCmd());
56d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    registerCmd(new NatCmd());
57d5573d34c8fac49e16b20cf144486125bf940086San Mehat    registerCmd(new ListTtysCmd());
58d5573d34c8fac49e16b20cf144486125bf940086San Mehat    registerCmd(new PppdCmd());
591bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat    registerCmd(new PanCmd());
605af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    registerCmd(new SoftapCmd());
614a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall    registerCmd(new BandwidthControlCmd());
6289c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    registerCmd(new ResolverCmd());
639d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
649d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (!sTetherCtrl)
659d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        sTetherCtrl = new TetherController();
669ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat    if (!sNatCtrl)
679ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat        sNatCtrl = new NatController();
68d5573d34c8fac49e16b20cf144486125bf940086San Mehat    if (!sPppCtrl)
69d5573d34c8fac49e16b20cf144486125bf940086San Mehat        sPppCtrl = new PppController();
701bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat    if (!sPanCtrl)
711bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat        sPanCtrl = new PanController();
725af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    if (!sSoftapCtrl)
735af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        sSoftapCtrl = new SoftapController();
744a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall    if (!sBandwidthCtrl)
754a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall        sBandwidthCtrl = new BandwidthController();
7689c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    if (!sResolverCtrl)
7789c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        sResolverCtrl = new ResolverController();
78d18304287dbabc7835be771400b85d4ae8b63de6San Mehat}
79d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
805c1b8af16dbbc20c89aaca2f93e725e12b16d055San MehatCommandListener::InterfaceCmd::InterfaceCmd() :
815c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                 NetdCommand("interface") {
82d18304287dbabc7835be771400b85d4ae8b63de6San Mehat}
83d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
84c1b3870147acd0dd42e2e767df08b4d64d5d2423repo syncint CommandListener::writeFile(const char *path, const char *value, int size) {
85c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync    int fd = open(path, O_WRONLY);
86c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync    if (fd < 0) {
87c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync        LOGE("Failed to open %s: %s", path, strerror(errno));
88c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync        return -1;
89c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync    }
90c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync
91c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync    if (write(fd, value, size) != size) {
92c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync        LOGE("Failed to write %s: %s", path, strerror(errno));
93c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync        close(fd);
94c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync        return -1;
95c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync    }
96c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync    close(fd);
97c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync    return 0;
98c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync}
99c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync
1005c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehatint CommandListener::InterfaceCmd::runCommand(SocketClient *cli,
101d18304287dbabc7835be771400b85d4ae8b63de6San Mehat                                                      int argc, char **argv) {
1025c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat    if (argc < 2) {
1035c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
1045c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        return 0;
1055c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat    }
1065c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
1075c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat    if (!strcmp(argv[1], "list")) {
1085c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        DIR *d;
1095c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        struct dirent *de;
1105c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
1115c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        if (!(d = opendir("/sys/class/net"))) {
1125c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            cli->sendMsg(ResponseCode::OperationFailed, "Failed to open sysfs dir", true);
1135c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            return 0;
1145c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        }
1155c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
1165c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        while((de = readdir(d))) {
1175c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            if (de->d_name[0] == '.')
1185c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                continue;
1195c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            cli->sendMsg(ResponseCode::InterfaceListResult, de->d_name, false);
1205c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        }
1215c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        closedir(d);
1225c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        cli->sendMsg(ResponseCode::CommandOkay, "Interface list completed", false);
1235c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        return 0;
1248e46896b4c4be5deaef651a12b17314f63ae9070San Mehat    } else if (!strcmp(argv[1], "readrxcounter")) {
1258e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        if (argc != 3) {
1268e46896b4c4be5deaef651a12b17314f63ae9070San Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError,
1278e46896b4c4be5deaef651a12b17314f63ae9070San Mehat                    "Usage: interface readrxcounter <interface>", false);
1288e46896b4c4be5deaef651a12b17314f63ae9070San Mehat            return 0;
1298e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        }
1308e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        unsigned long rx = 0, tx = 0;
1318e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        if (readInterfaceCounters(argv[2], &rx, &tx)) {
1328e46896b4c4be5deaef651a12b17314f63ae9070San Mehat            cli->sendMsg(ResponseCode::OperationFailed, "Failed to read counters", true);
1338e46896b4c4be5deaef651a12b17314f63ae9070San Mehat            return 0;
1348e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        }
1358e46896b4c4be5deaef651a12b17314f63ae9070San Mehat
1368e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        char *msg;
1378e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        asprintf(&msg, "%lu", rx);
1388e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        cli->sendMsg(ResponseCode::InterfaceRxCounterResult, msg, false);
1398e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        free(msg);
1408e46896b4c4be5deaef651a12b17314f63ae9070San Mehat
1418e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        return 0;
1428e46896b4c4be5deaef651a12b17314f63ae9070San Mehat    } else if (!strcmp(argv[1], "readtxcounter")) {
1438e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        if (argc != 3) {
1448e46896b4c4be5deaef651a12b17314f63ae9070San Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError,
1458e46896b4c4be5deaef651a12b17314f63ae9070San Mehat                    "Usage: interface readtxcounter <interface>", false);
1468e46896b4c4be5deaef651a12b17314f63ae9070San Mehat            return 0;
1478e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        }
1488e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        unsigned long rx = 0, tx = 0;
1498e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        if (readInterfaceCounters(argv[2], &rx, &tx)) {
1508e46896b4c4be5deaef651a12b17314f63ae9070San Mehat            cli->sendMsg(ResponseCode::OperationFailed, "Failed to read counters", true);
1518e46896b4c4be5deaef651a12b17314f63ae9070San Mehat            return 0;
1528e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        }
1538e46896b4c4be5deaef651a12b17314f63ae9070San Mehat
1548e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        char *msg = NULL;
1558e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        asprintf(&msg, "%lu", tx);
1568e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        cli->sendMsg(ResponseCode::InterfaceTxCounterResult, msg, false);
1578e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        free(msg);
1588e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        return 0;
1598e46896b4c4be5deaef651a12b17314f63ae9070San Mehat    } else if (!strcmp(argv[1], "getthrottle")) {
160a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat        if (argc != 4 || (argc == 4 && (strcmp(argv[3], "rx") && (strcmp(argv[3], "tx"))))) {
1618e46896b4c4be5deaef651a12b17314f63ae9070San Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError,
1628e46896b4c4be5deaef651a12b17314f63ae9070San Mehat                    "Usage: interface getthrottle <interface> <rx|tx>", false);
1638e46896b4c4be5deaef651a12b17314f63ae9070San Mehat            return 0;
1648e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        }
165a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat        int val = 0;
166a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat        int rc = 0;
167a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat        int voldRc = ResponseCode::InterfaceRxThrottleResult;
168a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat
169a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat        if (!strcmp(argv[3], "rx")) {
170a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat            rc = ThrottleController::getInterfaceRxThrottle(argv[2], &val);
171a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat        } else {
172a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat            rc = ThrottleController::getInterfaceTxThrottle(argv[2], &val);
173a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat            voldRc = ResponseCode::InterfaceTxThrottleResult;
174a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat        }
175a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat        if (rc) {
176a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat            cli->sendMsg(ResponseCode::OperationFailed, "Failed to get throttle", true);
177a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat        } else {
178a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat            char *msg = NULL;
179a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat            asprintf(&msg, "%u", val);
180a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat            cli->sendMsg(voldRc, msg, false);
181a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat            free(msg);
182a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat            return 0;
183a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat        }
1848e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        return 0;
1858e46896b4c4be5deaef651a12b17314f63ae9070San Mehat    } else if (!strcmp(argv[1], "setthrottle")) {
1868e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        if (argc != 5) {
1878e46896b4c4be5deaef651a12b17314f63ae9070San Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError,
188a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat                    "Usage: interface setthrottle <interface> <rx_kbps> <tx_kbps>", false);
1898e46896b4c4be5deaef651a12b17314f63ae9070San Mehat            return 0;
1908e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        }
191a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat        if (ThrottleController::setInterfaceThrottle(argv[2], atoi(argv[3]), atoi(argv[4]))) {
192a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat            cli->sendMsg(ResponseCode::OperationFailed, "Failed to set throttle", true);
193a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat        } else {
194a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat            cli->sendMsg(ResponseCode::CommandOkay, "Interface throttling set", false);
195a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat        }
1968e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        return 0;
1975c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat    } else {
1985c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        /*
1995c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat         * These commands take a minimum of 3 arguments
2005c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat         */
2015c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        if (argc < 3) {
2025c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
2035c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            return 0;
2045c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        }
205e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt
206e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt        if (!strcmp(argv[1], "route")) {
207e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt            int prefix_length = 0;
208e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt            if (argc < 7) {
209e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt                cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
210e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt                return 0;
211e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt            }
212e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt            if (sscanf(argv[5], "%d", &prefix_length) != 1) {
213e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt                cli->sendMsg(ResponseCode::CommandParameterError, "Invalid route prefix", false);
214e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt                return 0;
215e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt            }
216e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt            if (!strcmp(argv[2], "add")) {
217e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt                if (ifc_add_route(argv[3], argv[4], prefix_length, argv[6])) {
218e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt                    cli->sendMsg(ResponseCode::OperationFailed, "Failed to add route", true);
219e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt                } else {
220e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt                    cli->sendMsg(ResponseCode::CommandOkay, "Route added", false);
221e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt                }
222e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt            } else if (!strcmp(argv[2], "remove")) {
223e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt                if (ifc_remove_route(argv[3], argv[4], prefix_length, argv[6])) {
224e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt                    cli->sendMsg(ResponseCode::OperationFailed, "Failed to remove route", true);
225e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt                } else {
226e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt                    cli->sendMsg(ResponseCode::CommandOkay, "Route removed", false);
227e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt                }
228e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt            } else {
229e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt                cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown interface cmd", false);
230e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt            }
231e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt            return 0;
232e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt        }
233e019b65925217bcc3ad9b662aa3125f0593057afRobert Greenwalt
2345c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        if (!strcmp(argv[1], "getcfg")) {
2351d93e170f13b221362ee268fdc94b25db06c21c9Robert Greenwalt            struct in_addr addr;
2361d93e170f13b221362ee268fdc94b25db06c21c9Robert Greenwalt            int prefixLength;
2375c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            unsigned char hwaddr[6];
2385c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            unsigned flags = 0;
2395c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
2405c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            ifc_init();
2415c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            memset(hwaddr, 0, sizeof(hwaddr));
2425c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
2431d93e170f13b221362ee268fdc94b25db06c21c9Robert Greenwalt            if (ifc_get_info(argv[2], &addr.s_addr, &prefixLength, &flags)) {
2445c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                cli->sendMsg(ResponseCode::OperationFailed, "Interface not found", true);
245e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff                ifc_close();
2465c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                return 0;
2475c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            }
2485c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
2495c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            if (ifc_get_hwaddr(argv[2], (void *) hwaddr)) {
2505c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                LOGW("Failed to retrieve HW addr for %s (%s)", argv[2], strerror(errno));
2515c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            }
2525c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
2535c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            char *addr_s = strdup(inet_ntoa(addr));
2545c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            const char *updown, *brdcst, *loopbk, *ppp, *running, *multi;
2555c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
2565c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            updown =  (flags & IFF_UP)           ? "up" : "down";
2575c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            brdcst =  (flags & IFF_BROADCAST)    ? " broadcast" : "";
2585c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            loopbk =  (flags & IFF_LOOPBACK)     ? " loopback" : "";
2595c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            ppp =     (flags & IFF_POINTOPOINT)  ? " point-to-point" : "";
2605c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            running = (flags & IFF_RUNNING)      ? " running" : "";
2615c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            multi =   (flags & IFF_MULTICAST)    ? " multicast" : "";
2625c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
2635c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            char *flag_s;
2645c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
265e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt            asprintf(&flag_s, "[%s%s%s%s%s%s]", updown, brdcst, loopbk, ppp, running, multi);
2665c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
2675c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            char *msg = NULL;
2681d93e170f13b221362ee268fdc94b25db06c21c9Robert Greenwalt            asprintf(&msg, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x %s %d %s",
2695c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                     hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5],
2701d93e170f13b221362ee268fdc94b25db06c21c9Robert Greenwalt                     addr_s, prefixLength, flag_s);
2715c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
27201fed783828b592cda3b774deea4099a9e690e3dSan Mehat            cli->sendMsg(ResponseCode::InterfaceGetCfgResult, msg, false);
2735c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
2745c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            free(addr_s);
2755c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            free(flag_s);
2765c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            free(msg);
277e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff
278e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff            ifc_close();
2795c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            return 0;
2805c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        } else if (!strcmp(argv[1], "setcfg")) {
2811d93e170f13b221362ee268fdc94b25db06c21c9Robert Greenwalt            // arglist: iface addr prefixLength [flags]
2825c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            if (argc < 5) {
2835c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
2845c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                return 0;
2855c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            }
286e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt            LOGD("Setting iface cfg");
2875c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
2881d93e170f13b221362ee268fdc94b25db06c21c9Robert Greenwalt            struct in_addr addr;
2895c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            unsigned flags = 0;
2905c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
2915c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            if (!inet_aton(argv[3], &addr)) {
2925c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                cli->sendMsg(ResponseCode::CommandParameterError, "Invalid address", false);
2935c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                return 0;
2945c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            }
2955c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
2965c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            ifc_init();
2975c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            if (ifc_set_addr(argv[2], addr.s_addr)) {
2985c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                cli->sendMsg(ResponseCode::OperationFailed, "Failed to set address", true);
299e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff                ifc_close();
3005c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                return 0;
3015c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            }
3025c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
303ab374f426a0d1d8598f3eb4b0339440dcb313a1aIrfan Sheriff            //Set prefix length on a non zero address
304ab374f426a0d1d8598f3eb4b0339440dcb313a1aIrfan Sheriff            if (addr.s_addr != 0 && ifc_set_prefixLength(argv[2], atoi(argv[4]))) {
3051d93e170f13b221362ee268fdc94b25db06c21c9Robert Greenwalt                cli->sendMsg(ResponseCode::OperationFailed, "Failed to set prefixLength", true);
306e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff                ifc_close();
3075c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                return 0;
3085c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            }
3095c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat
3105c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            /* Process flags */
311e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt            /* read from "[XX" arg to "YY]" arg */
312e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt            bool bStarted = false;
3135c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            for (int i = 5; i < argc; i++) {
314e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt                char *flag = argv[i];
315e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt                if (!bStarted) {
316e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt                    if (*flag == '[') {
317e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt                        flag++;
318e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt                        bStarted = true;
319e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt                    } else {
320e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt                        continue;
321e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt                    }
322e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt                }
323e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt                int len = strlen(flag);
324e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt                if (flag[len-1] == ']') {
325e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt                    i = argc;  // stop after this loop
326e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt                    flag[len-1] = 0;
327e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt                }
328e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt                if (!strcmp(flag, "up")) {
329e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt                    LOGD("Trying to bring up %s", argv[2]);
3305c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                    if (ifc_up(argv[2])) {
3315c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                        LOGE("Error upping interface");
3325c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                        cli->sendMsg(ResponseCode::OperationFailed, "Failed to up interface", true);
333e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff                        ifc_close();
3345c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                        return 0;
3355c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                    }
336e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt                } else if (!strcmp(flag, "down")) {
337e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt                    LOGD("Trying to bring down %s", argv[2]);
3385c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                    if (ifc_down(argv[2])) {
3395c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                        LOGE("Error downing interface");
3405c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                        cli->sendMsg(ResponseCode::OperationFailed, "Failed to down interface", true);
341e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff                        ifc_close();
3425c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                        return 0;
3435c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                    }
344e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt                } else if (!strcmp(flag, "broadcast")) {
345e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt                    LOGD("broadcast flag ignored");
346e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt                } else if (!strcmp(flag, "multicast")) {
347e7b9422f0dc7a18041536c63efe74c7095496258Robert Greenwalt                    LOGD("multicast flag ignored");
3485c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                } else {
3495c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                    cli->sendMsg(ResponseCode::CommandParameterError, "Flag unsupported", false);
350e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff                    ifc_close();
3515c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                    return 0;
3525c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat                }
3535c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            }
354e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff
3555c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            cli->sendMsg(ResponseCode::CommandOkay, "Interface configuration set", false);
356e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff            ifc_close();
357e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff            return 0;
358e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff        } else if (!strcmp(argv[1], "clearaddrs")) {
359e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff            // arglist: iface
360e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff            LOGD("Clearing all IP addresses on %s", argv[2]);
361e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff
3621ed47c4a016e420a855ee46922e512150245ff61Lorenzo Colitti            ifc_clear_addresses(argv[2]);
3631ed47c4a016e420a855ee46922e512150245ff61Lorenzo Colitti
364e734edd35d8d02da96330d77420650c044a12527Irfan Sheriff            cli->sendMsg(ResponseCode::CommandOkay, "Interface IP addresses cleared", false);
3655c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            return 0;
36632a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff        } else if (!strcmp(argv[1], "ipv6privacyextensions")) {
36732a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff            if (argc != 4) {
36832a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff                cli->sendMsg(ResponseCode::CommandSyntaxError,
36932a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff                        "Usage: interface ipv6privacyextensions <interface> <enable|disable>",
37032a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff                        false);
37132a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff                return 0;
37232a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff            }
37332a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff
374c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync            char *tmp;
37532a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff            asprintf(&tmp, "/proc/sys/net/ipv6/conf/%s/use_tempaddr", argv[2]);
376c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync
377c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync            if (writeFile(tmp, !strncmp(argv[3], "enable", 7) ? "2" : "0", 1) < 0) {
37832a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff                free(tmp);
37932a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff                cli->sendMsg(ResponseCode::OperationFailed,
38032a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff                        "Failed to set ipv6 privacy extensions", true);
38132a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff                return 0;
38232a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff            }
38332a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff
384c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync            free(tmp);
385c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync            cli->sendMsg(ResponseCode::CommandOkay, "IPv6 privacy extensions changed", false);
386c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync            return 0;
387c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync        } else if (!strcmp(argv[1], "ipv6")) {
388c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync            if (argc != 4) {
389c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync                cli->sendMsg(ResponseCode::CommandSyntaxError,
390c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync                        "Usage: interface ipv6 <interface> <enable|disable>",
391c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync                        false);
392c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync                return 0;
393c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync            }
394c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync
395c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync            char *tmp;
396c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync            asprintf(&tmp, "/proc/sys/net/ipv6/conf/%s/disable_ipv6", argv[2]);
397c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync
398c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync            if (writeFile(tmp, !strncmp(argv[3], "enable", 7) ? "0" : "1", 1) < 0) {
39932a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff                free(tmp);
40032a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff                cli->sendMsg(ResponseCode::OperationFailed,
401c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync                        "Failed to change IPv6 state", true);
40232a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff                return 0;
40332a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff            }
404c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync
40532a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff            free(tmp);
406c1b3870147acd0dd42e2e767df08b4d64d5d2423repo sync            cli->sendMsg(ResponseCode::CommandOkay, "IPv6 state changed", false);
40732a9dc6f484deb3462d11084caca21e3f1f662b2Irfan Sheriff            return 0;
4085c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        } else {
4095c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown interface cmd", false);
4105c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat            return 0;
4115c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat        }
4125c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat    }
413d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    return 0;
414d18304287dbabc7835be771400b85d4ae8b63de6San Mehat}
415d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
4164a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall
417d5573d34c8fac49e16b20cf144486125bf940086San MehatCommandListener::ListTtysCmd::ListTtysCmd() :
418d5573d34c8fac49e16b20cf144486125bf940086San Mehat                 NetdCommand("list_ttys") {
419d5573d34c8fac49e16b20cf144486125bf940086San Mehat}
420d5573d34c8fac49e16b20cf144486125bf940086San Mehat
421d5573d34c8fac49e16b20cf144486125bf940086San Mehatint CommandListener::ListTtysCmd::runCommand(SocketClient *cli,
422d5573d34c8fac49e16b20cf144486125bf940086San Mehat                                             int argc, char **argv) {
423d5573d34c8fac49e16b20cf144486125bf940086San Mehat    TtyCollection *tlist = sPppCtrl->getTtyList();
424d5573d34c8fac49e16b20cf144486125bf940086San Mehat    TtyCollection::iterator it;
425d5573d34c8fac49e16b20cf144486125bf940086San Mehat
426d5573d34c8fac49e16b20cf144486125bf940086San Mehat    for (it = tlist->begin(); it != tlist->end(); ++it) {
427d5573d34c8fac49e16b20cf144486125bf940086San Mehat        cli->sendMsg(ResponseCode::TtyListResult, *it, false);
428d5573d34c8fac49e16b20cf144486125bf940086San Mehat    }
429d5573d34c8fac49e16b20cf144486125bf940086San Mehat
430d5573d34c8fac49e16b20cf144486125bf940086San Mehat    cli->sendMsg(ResponseCode::CommandOkay, "Ttys listed.", false);
431d5573d34c8fac49e16b20cf144486125bf940086San Mehat    return 0;
432d5573d34c8fac49e16b20cf144486125bf940086San Mehat}
433d5573d34c8fac49e16b20cf144486125bf940086San Mehat
434d18304287dbabc7835be771400b85d4ae8b63de6San MehatCommandListener::IpFwdCmd::IpFwdCmd() :
435d18304287dbabc7835be771400b85d4ae8b63de6San Mehat                 NetdCommand("ipfwd") {
436d18304287dbabc7835be771400b85d4ae8b63de6San Mehat}
437d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
438d18304287dbabc7835be771400b85d4ae8b63de6San Mehatint CommandListener::IpFwdCmd::runCommand(SocketClient *cli,
439d18304287dbabc7835be771400b85d4ae8b63de6San Mehat                                                      int argc, char **argv) {
4409d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    int rc = 0;
4419d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
4429d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (argc < 2) {
4439d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
4449d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return 0;
4459d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
4469d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
4479d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (!strcmp(argv[1], "status")) {
4489d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        char *tmp = NULL;
4499d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
4509d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        asprintf(&tmp, "Forwarding %s", (sTetherCtrl->getIpFwdEnabled() ? "enabled" : "disabled"));
4519d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::IpFwdStatusResult, tmp, false);
4529d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        free(tmp);
4539d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return 0;
4549d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    } else if (!strcmp(argv[1], "enable")) {
4559d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        rc = sTetherCtrl->setIpFwdEnabled(true);
4569d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    } else if (!strcmp(argv[1], "disable")) {
4579d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        rc = sTetherCtrl->setIpFwdEnabled(false);
4589d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    } else {
4599d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown ipfwd cmd", false);
4609d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return 0;
4619d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
4629d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
4639d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (!rc) {
4649d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::CommandOkay, "ipfwd operation succeeded", false);
4659d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    } else {
4669d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::OperationFailed, "ipfwd operation failed", true);
4679d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
468d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
469d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    return 0;
470d18304287dbabc7835be771400b85d4ae8b63de6San Mehat}
471d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
472d18304287dbabc7835be771400b85d4ae8b63de6San MehatCommandListener::TetherCmd::TetherCmd() :
473d18304287dbabc7835be771400b85d4ae8b63de6San Mehat                 NetdCommand("tether") {
474d18304287dbabc7835be771400b85d4ae8b63de6San Mehat}
475d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
476d18304287dbabc7835be771400b85d4ae8b63de6San Mehatint CommandListener::TetherCmd::runCommand(SocketClient *cli,
477d18304287dbabc7835be771400b85d4ae8b63de6San Mehat                                                      int argc, char **argv) {
4789d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    int rc = 0;
4799d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
480d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    if (argc < 2) {
481d18304287dbabc7835be771400b85d4ae8b63de6San Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
482d18304287dbabc7835be771400b85d4ae8b63de6San Mehat        return 0;
483d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    }
484d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
4859d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (!strcmp(argv[1], "stop")) {
4869d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        rc = sTetherCtrl->stopTethering();
487d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    } else if (!strcmp(argv[1], "status")) {
4889d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        char *tmp = NULL;
4899d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
4909d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        asprintf(&tmp, "Tethering services %s",
4919d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                 (sTetherCtrl->isTetheringStarted() ? "started" : "stopped"));
4929d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::TetherStatusResult, tmp, false);
4939d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        free(tmp);
494d18304287dbabc7835be771400b85d4ae8b63de6San Mehat        return 0;
4959d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    } else {
4969d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        /*
4979d10b341a0ba46f108cb96e46691197d778cbc06San Mehat         * These commands take a minimum of 4 arguments
4989d10b341a0ba46f108cb96e46691197d778cbc06San Mehat         */
4999d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        if (argc < 4) {
5009d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
5019d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            return 0;
5029d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        }
5039d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
5049d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        if (!strcmp(argv[1], "start")) {
5053208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt            if (argc % 2 == 1) {
5063208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt                cli->sendMsg(ResponseCode::CommandSyntaxError, "Bad number of arguments", false);
5079d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                return 0;
5089d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            }
5093208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt
5103208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt            int num_addrs = argc - 2;
5113208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt            int arg_index = 2;
5123208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt            int array_index = 0;
5133208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt            in_addr *addrs = (in_addr *)malloc(sizeof(in_addr) * num_addrs);
5143208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt            while (array_index < num_addrs) {
5153208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt                if (!inet_aton(argv[arg_index++], &(addrs[array_index++]))) {
5163208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt                    cli->sendMsg(ResponseCode::CommandParameterError, "Invalid address", false);
5173208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt                    free(addrs);
5183208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt                    return 0;
5193208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt                }
5209d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            }
5213208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt            rc = sTetherCtrl->startTethering(num_addrs, addrs);
5223208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt            free(addrs);
5239d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        } else if (!strcmp(argv[1], "interface")) {
5249d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            if (!strcmp(argv[2], "add")) {
5259d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                rc = sTetherCtrl->tetherInterface(argv[3]);
5269d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            } else if (!strcmp(argv[2], "remove")) {
5279d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                rc = sTetherCtrl->untetherInterface(argv[3]);
5289d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            } else if (!strcmp(argv[2], "list")) {
5299d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                InterfaceCollection *ilist = sTetherCtrl->getTetheredInterfaceList();
5309d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                InterfaceCollection::iterator it;
5319d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
5329d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                for (it = ilist->begin(); it != ilist->end(); ++it) {
5339d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                    cli->sendMsg(ResponseCode::TetherInterfaceListResult, *it, false);
5349d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                }
5359d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            } else {
5369d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                cli->sendMsg(ResponseCode::CommandParameterError,
5379d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                             "Unknown tether interface operation", false);
5389d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                return 0;
5399d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            }
5409d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        } else if (!strcmp(argv[1], "dns")) {
5419d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            if (!strcmp(argv[2], "set")) {
5429d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                rc = sTetherCtrl->setDnsForwarders(&argv[3], argc - 3);
5439d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            } else if (!strcmp(argv[2], "list")) {
5449d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                NetAddressCollection *dlist = sTetherCtrl->getDnsForwarders();
5459d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                NetAddressCollection::iterator it;
5469d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
5479d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                for (it = dlist->begin(); it != dlist->end(); ++it) {
5489d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                    cli->sendMsg(ResponseCode::TetherDnsFwdTgtListResult, inet_ntoa(*it), false);
5499d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                }
5509d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            } else {
5519d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                cli->sendMsg(ResponseCode::CommandParameterError,
5529d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                             "Unknown tether interface operation", false);
5539d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                return 0;
5549d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            }
5559d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        } else {
5569d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown tether cmd", false);
5579d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            return 0;
5589d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        }
5599d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
5609d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
5619d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (!rc) {
5629d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::CommandOkay, "Tether operation succeeded", false);
5639d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    } else {
5649d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::OperationFailed, "Tether operation failed", true);
565d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    }
566d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
567d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    return 0;
568d18304287dbabc7835be771400b85d4ae8b63de6San Mehat}
569d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
570d18304287dbabc7835be771400b85d4ae8b63de6San MehatCommandListener::NatCmd::NatCmd() :
571d18304287dbabc7835be771400b85d4ae8b63de6San Mehat                 NetdCommand("nat") {
572d18304287dbabc7835be771400b85d4ae8b63de6San Mehat}
573d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
574d18304287dbabc7835be771400b85d4ae8b63de6San Mehatint CommandListener::NatCmd::runCommand(SocketClient *cli,
575d18304287dbabc7835be771400b85d4ae8b63de6San Mehat                                                      int argc, char **argv) {
5769d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    int rc = 0;
5779d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
5789d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (argc < 3) {
5799d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
5809d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return 0;
5819d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
5829d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
5839ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat    if (!strcmp(argv[1], "enable")) {
5849ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat        rc = sNatCtrl->enableNat(argv[2], argv[3]);
585c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        if(!rc) {
586c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall            /* Ignore ifaces for now. */
587c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall            rc = sBandwidthCtrl->setGlobalAlertInForwardChain();
588c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        }
5899ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat    } else if (!strcmp(argv[1], "disable")) {
5909ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat        rc = sNatCtrl->disableNat(argv[2], argv[3]);
591f7bf29c8a37d65e132a4dceb7c5a4200ed5c3d79Robert Greenwalt        /* Ignore ifaces for now. */
592f7bf29c8a37d65e132a4dceb7c5a4200ed5c3d79Robert Greenwalt        rc |= sBandwidthCtrl->removeGlobalAlertInForwardChain();
5939d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    } else {
5949d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown nat cmd", false);
5959d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return 0;
5969d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
5979d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
5989d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (!rc) {
5999d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::CommandOkay, "Nat operation succeeded", false);
6009d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    } else {
6019d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::OperationFailed, "Nat operation failed", true);
6029d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
603d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
604d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    return 0;
605d18304287dbabc7835be771400b85d4ae8b63de6San Mehat}
606d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
607d5573d34c8fac49e16b20cf144486125bf940086San MehatCommandListener::PppdCmd::PppdCmd() :
608d5573d34c8fac49e16b20cf144486125bf940086San Mehat                 NetdCommand("pppd") {
609d5573d34c8fac49e16b20cf144486125bf940086San Mehat}
610d5573d34c8fac49e16b20cf144486125bf940086San Mehat
611d5573d34c8fac49e16b20cf144486125bf940086San Mehatint CommandListener::PppdCmd::runCommand(SocketClient *cli,
612d5573d34c8fac49e16b20cf144486125bf940086San Mehat                                                      int argc, char **argv) {
613d5573d34c8fac49e16b20cf144486125bf940086San Mehat    int rc = 0;
614d5573d34c8fac49e16b20cf144486125bf940086San Mehat
615d5573d34c8fac49e16b20cf144486125bf940086San Mehat    if (argc < 3) {
616d5573d34c8fac49e16b20cf144486125bf940086San Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
617d5573d34c8fac49e16b20cf144486125bf940086San Mehat        return 0;
618d5573d34c8fac49e16b20cf144486125bf940086San Mehat    }
619d5573d34c8fac49e16b20cf144486125bf940086San Mehat
620d5573d34c8fac49e16b20cf144486125bf940086San Mehat    if (!strcmp(argv[1], "attach")) {
62174d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt        struct in_addr l, r, dns1, dns2;
62274d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt
62374d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt        memset(&dns1, sizeof(struct in_addr), 0);
62474d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt        memset(&dns2, sizeof(struct in_addr), 0);
625d5573d34c8fac49e16b20cf144486125bf940086San Mehat
626d5573d34c8fac49e16b20cf144486125bf940086San Mehat        if (!inet_aton(argv[3], &l)) {
627d5573d34c8fac49e16b20cf144486125bf940086San Mehat            cli->sendMsg(ResponseCode::CommandParameterError, "Invalid local address", false);
628d5573d34c8fac49e16b20cf144486125bf940086San Mehat            return 0;
629d5573d34c8fac49e16b20cf144486125bf940086San Mehat        }
630d5573d34c8fac49e16b20cf144486125bf940086San Mehat        if (!inet_aton(argv[4], &r)) {
631d5573d34c8fac49e16b20cf144486125bf940086San Mehat            cli->sendMsg(ResponseCode::CommandParameterError, "Invalid remote address", false);
632d5573d34c8fac49e16b20cf144486125bf940086San Mehat            return 0;
633d5573d34c8fac49e16b20cf144486125bf940086San Mehat        }
63474d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt        if ((argc > 3) && (!inet_aton(argv[5], &dns1))) {
63574d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt            cli->sendMsg(ResponseCode::CommandParameterError, "Invalid dns1 address", false);
63674d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt            return 0;
63774d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt        }
63874d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt        if ((argc > 4) && (!inet_aton(argv[6], &dns2))) {
63974d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt            cli->sendMsg(ResponseCode::CommandParameterError, "Invalid dns2 address", false);
64074d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt            return 0;
64174d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt        }
64274d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt        rc = sPppCtrl->attachPppd(argv[2], l, r, dns1, dns2);
643d5573d34c8fac49e16b20cf144486125bf940086San Mehat    } else if (!strcmp(argv[1], "detach")) {
644d5573d34c8fac49e16b20cf144486125bf940086San Mehat        rc = sPppCtrl->detachPppd(argv[2]);
645d5573d34c8fac49e16b20cf144486125bf940086San Mehat    } else {
646d5573d34c8fac49e16b20cf144486125bf940086San Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown pppd cmd", false);
647d5573d34c8fac49e16b20cf144486125bf940086San Mehat        return 0;
648d5573d34c8fac49e16b20cf144486125bf940086San Mehat    }
649d5573d34c8fac49e16b20cf144486125bf940086San Mehat
650d5573d34c8fac49e16b20cf144486125bf940086San Mehat    if (!rc) {
651d5573d34c8fac49e16b20cf144486125bf940086San Mehat        cli->sendMsg(ResponseCode::CommandOkay, "Pppd operation succeeded", false);
652d5573d34c8fac49e16b20cf144486125bf940086San Mehat    } else {
653d5573d34c8fac49e16b20cf144486125bf940086San Mehat        cli->sendMsg(ResponseCode::OperationFailed, "Pppd operation failed", true);
654d5573d34c8fac49e16b20cf144486125bf940086San Mehat    }
655d5573d34c8fac49e16b20cf144486125bf940086San Mehat
656d5573d34c8fac49e16b20cf144486125bf940086San Mehat    return 0;
657d5573d34c8fac49e16b20cf144486125bf940086San Mehat}
6581bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat
6591bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San MehatCommandListener::PanCmd::PanCmd() :
6601bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat                 NetdCommand("pan") {
6611bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat}
6621bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat
6631bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehatint CommandListener::PanCmd::runCommand(SocketClient *cli,
6641bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat                                        int argc, char **argv) {
6651bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat    int rc = 0;
6661bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat
6671bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat    if (argc < 2) {
6681bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
6691bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat        return 0;
6701bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat    }
6711bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat
6721bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat    if (!strcmp(argv[1], "start")) {
6731bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat        rc = sPanCtrl->startPan();
6741bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat    } else if (!strcmp(argv[1], "stop")) {
6751bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat        rc = sPanCtrl->stopPan();
6761bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat    } else if (!strcmp(argv[1], "status")) {
6771bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat        char *tmp = NULL;
6781bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat
6791bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat        asprintf(&tmp, "Pan services %s",
6801bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat                 (sPanCtrl->isPanStarted() ? "started" : "stopped"));
6811bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat        cli->sendMsg(ResponseCode::PanStatusResult, tmp, false);
6821bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat        free(tmp);
6831bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat        return 0;
6841bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat    } else {
6851bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown pan cmd", false);
6861bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat        return 0;
6871bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat    }
6881bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat
6891bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat    if (!rc) {
6901bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat        cli->sendMsg(ResponseCode::CommandOkay, "Pan operation succeeded", false);
6911bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat    } else {
6921bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat        cli->sendMsg(ResponseCode::OperationFailed, "Pan operation failed", true);
6931bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat    }
6941bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat
6951bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat    return 0;
6961bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15San Mehat}
6975af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
6985af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry ShmidtCommandListener::SoftapCmd::SoftapCmd() :
6995af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt                 NetdCommand("softap") {
7005af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt}
7015af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
7025af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidtint CommandListener::SoftapCmd::runCommand(SocketClient *cli,
7035af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt                                        int argc, char **argv) {
70431fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    int rc = 0, flag = 0;
705666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt    char *retbuf = NULL;
7065af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
7075af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    if (argc < 2) {
7085af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        cli->sendMsg(ResponseCode::CommandSyntaxError, "Softap Missing argument", false);
7095af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        return 0;
7105af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    }
7115af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
7125af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    if (!strcmp(argv[1], "start")) {
713c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt        rc = sSoftapCtrl->startDriver(argv[2]);
7145af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    } else if (!strcmp(argv[1], "stop")) {
715c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt        rc = sSoftapCtrl->stopDriver(argv[2]);
716c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt    } else if (!strcmp(argv[1], "startap")) {
717c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt        rc = sSoftapCtrl->startSoftap();
718c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt    } else if (!strcmp(argv[1], "stopap")) {
7195af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        rc = sSoftapCtrl->stopSoftap();
72031fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    } else if (!strcmp(argv[1], "fwreload")) {
72131fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt        rc = sSoftapCtrl->fwReloadSoftap(argc, argv);
722666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt    } else if (!strcmp(argv[1], "clients")) {
723666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt        rc = sSoftapCtrl->clientsSoftap(&retbuf);
724666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt        if (!rc) {
725666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt            cli->sendMsg(ResponseCode::CommandOkay, retbuf, false);
726666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt            free(retbuf);
727666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt            return 0;
728666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt        }
7295af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    } else if (!strcmp(argv[1], "status")) {
730666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt        asprintf(&retbuf, "Softap service %s",
7315af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt                 (sSoftapCtrl->isSoftapStarted() ? "started" : "stopped"));
732666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt        cli->sendMsg(ResponseCode::SoftapStatusResult, retbuf, false);
733666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt        free(retbuf);
7345af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        return 0;
7355af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    } else if (!strcmp(argv[1], "set")) {
7365af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        rc = sSoftapCtrl->setSoftap(argc, argv);
7375af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    } else {
7385af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        cli->sendMsg(ResponseCode::CommandSyntaxError, "Softap Unknown cmd", false);
7395af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        return 0;
7405af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    }
7415af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
7425af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    if (!rc) {
7435af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        cli->sendMsg(ResponseCode::CommandOkay, "Softap operation succeeded", false);
7445af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    } else {
7455af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        cli->sendMsg(ResponseCode::OperationFailed, "Softap operation failed", true);
7465af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    }
7475af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
7485af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    return 0;
7495af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt}
7503e6ba3ce1abda6071d5b01f53ca6039bb7b5e2d3Robert Greenwalt
75189c1e975f0c03997808d35c7be10b244c5309f9fMattias FalkCommandListener::ResolverCmd::ResolverCmd() :
75289c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        NetdCommand("resolver") {
75389c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk}
75489c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk
75589c1e975f0c03997808d35c7be10b244c5309f9fMattias Falkint CommandListener::ResolverCmd::runCommand(SocketClient *cli, int argc, char **argv) {
75689c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    int rc = 0;
75789c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    struct in_addr addr;
75889c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk
75989c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    if (argc < 2) {
76089c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        cli->sendMsg(ResponseCode::CommandSyntaxError, "Resolver missing arguments", false);
76189c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        return 0;
76289c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    }
76389c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk
76489c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    if (!strcmp(argv[1], "setdefaultif")) { // "resolver setdefaultif <iface>"
76589c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        if (argc == 3) {
76689c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            rc = sResolverCtrl->setDefaultInterface(argv[2]);
76789c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        } else {
76889c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            cli->sendMsg(ResponseCode::CommandSyntaxError,
76989c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk                    "Wrong number of arguments to resolver setdefaultif", false);
77089c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            return 0;
77189c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        }
77289c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    } else if (!strcmp(argv[1], "setifdns")) { // "resolver setifdns <iface> <dns1> <dns2> ..."
77389c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        if (argc >= 4) {
77489c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            rc = sResolverCtrl->setInterfaceDnsServers(argv[2], &argv[3], argc - 3);
77589c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        } else {
77689c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            cli->sendMsg(ResponseCode::CommandSyntaxError,
77789c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk                    "Wrong number of arguments to resolver setifdns", false);
77889c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            return 0;
77989c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        }
78089c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk
78189c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        // set the address of the interface to which the name servers
78289c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        // are bound. Required in order to bind to right interface when
78389c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        // doing the dns query.
78489c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        if (!rc) {
78589c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            ifc_init();
78689c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            ifc_get_info(argv[2], &addr.s_addr, NULL, 0);
78789c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk
78889c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            rc = sResolverCtrl->setInterfaceAddress(argv[2], &addr);
78989c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        }
79089c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    } else if (!strcmp(argv[1], "flushdefaultif")) { // "resolver flushdefaultif"
79189c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        if (argc == 2) {
79289c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            rc = sResolverCtrl->flushDefaultDnsCache();
79389c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        } else {
79489c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            cli->sendMsg(ResponseCode::CommandSyntaxError,
79589c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk                    "Wrong number of arguments to resolver flushdefaultif", false);
79689c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            return 0;
79789c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        }
79889c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    } else if (!strcmp(argv[1], "flushif")) { // "resolver flushif <iface>"
79989c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        if (argc == 3) {
80089c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            rc = sResolverCtrl->flushInterfaceDnsCache(argv[2]);
80189c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        } else {
80289c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            cli->sendMsg(ResponseCode::CommandSyntaxError,
80389c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk                    "Wrong number of arguments to resolver setdefaultif", false);
80489c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk            return 0;
80589c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        }
80689c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    } else {
80789c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        cli->sendMsg(ResponseCode::CommandSyntaxError,"Resolver unknown command", false);
80889c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        return 0;
80989c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    }
81089c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk
81189c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    if (!rc) {
81289c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        cli->sendMsg(ResponseCode::CommandOkay, "Resolver command succeeded", false);
81389c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    } else {
81489c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk        cli->sendMsg(ResponseCode::OperationFailed, "Resolver command failed", true);
81589c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    }
81689c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk
81789c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk    return 0;
81889c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk}
81989c1e975f0c03997808d35c7be10b244c5309f9fMattias Falk
8208e46896b4c4be5deaef651a12b17314f63ae9070San Mehatint CommandListener::readInterfaceCounters(const char *iface, unsigned long *rx, unsigned long *tx) {
8218e46896b4c4be5deaef651a12b17314f63ae9070San Mehat    FILE *fp = fopen("/proc/net/dev", "r");
8228e46896b4c4be5deaef651a12b17314f63ae9070San Mehat    if (!fp) {
8238e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        LOGE("Failed to open /proc/net/dev (%s)", strerror(errno));
8248e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        return -1;
8258e46896b4c4be5deaef651a12b17314f63ae9070San Mehat    }
8268e46896b4c4be5deaef651a12b17314f63ae9070San Mehat
8278e46896b4c4be5deaef651a12b17314f63ae9070San Mehat    char buffer[512];
8288e46896b4c4be5deaef651a12b17314f63ae9070San Mehat
8298e46896b4c4be5deaef651a12b17314f63ae9070San Mehat    fgets(buffer, sizeof(buffer), fp); // Header 1
8308e46896b4c4be5deaef651a12b17314f63ae9070San Mehat    fgets(buffer, sizeof(buffer), fp); // Header 2
8318e46896b4c4be5deaef651a12b17314f63ae9070San Mehat    while(fgets(buffer, sizeof(buffer), fp)) {
8328e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        buffer[strlen(buffer)-1] = '\0';
8338e46896b4c4be5deaef651a12b17314f63ae9070San Mehat
834651417c7c8662572de761c3b9260b1241ff21a79Robert Greenwalt        char name[31];
8358e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        unsigned long d;
836651417c7c8662572de761c3b9260b1241ff21a79Robert Greenwalt        sscanf(buffer, "%30s %lu %lu %lu %lu %lu %lu %lu %lu %lu",
8378e46896b4c4be5deaef651a12b17314f63ae9070San Mehat                name, rx, &d, &d, &d, &d, &d, &d, &d, tx);
838651417c7c8662572de761c3b9260b1241ff21a79Robert Greenwalt        char *rxString = strchr(name, ':');
839651417c7c8662572de761c3b9260b1241ff21a79Robert Greenwalt        *rxString = '\0';
840651417c7c8662572de761c3b9260b1241ff21a79Robert Greenwalt        rxString++;
841651417c7c8662572de761c3b9260b1241ff21a79Robert Greenwalt        // when the rx count gets too big it changes from "name: 999" to "name:1000"
842651417c7c8662572de761c3b9260b1241ff21a79Robert Greenwalt        // and the sscanf munge the two together.  Detect that and fix
843651417c7c8662572de761c3b9260b1241ff21a79Robert Greenwalt        // note that all the %lu will be off by one and the real tx value will be in d
844651417c7c8662572de761c3b9260b1241ff21a79Robert Greenwalt        if (*rxString != '\0') {
845651417c7c8662572de761c3b9260b1241ff21a79Robert Greenwalt            *tx = d;
846651417c7c8662572de761c3b9260b1241ff21a79Robert Greenwalt            sscanf(rxString, "%20lu", rx);
847651417c7c8662572de761c3b9260b1241ff21a79Robert Greenwalt        }
8488e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        if (strcmp(name, iface)) {
8498e46896b4c4be5deaef651a12b17314f63ae9070San Mehat            continue;
8508e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        }
8518e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        fclose(fp);
8528e46896b4c4be5deaef651a12b17314f63ae9070San Mehat        return 0;
8538e46896b4c4be5deaef651a12b17314f63ae9070San Mehat    }
8548e46896b4c4be5deaef651a12b17314f63ae9070San Mehat
8558e46896b4c4be5deaef651a12b17314f63ae9070San Mehat    fclose(fp);
85631c61c80a013bd1a050f0f4103e13fba62bf1717Robert Greenwalt    *rx = 0;
85731c61c80a013bd1a050f0f4103e13fba62bf1717Robert Greenwalt    *tx = 0;
85831c61c80a013bd1a050f0f4103e13fba62bf1717Robert Greenwalt    return 0;
8598e46896b4c4be5deaef651a12b17314f63ae9070San Mehat}
8604a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall
8614a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP AbgrallCommandListener::BandwidthControlCmd::BandwidthControlCmd() :
8620dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall    NetdCommand("bandwidth") {
8634a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall}
8644a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall
865db7da58e8d2aa021060098057f944ef754be06e3JP Abgrallvoid CommandListener::BandwidthControlCmd::sendGenericSyntaxError(SocketClient *cli, const char *usageMsg) {
866db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    char *msg;
867db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    asprintf(&msg, "Usage: bandwidth %s", usageMsg);
868db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    cli->sendMsg(ResponseCode::CommandSyntaxError, msg, false);
869db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    free(msg);
870db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall}
871db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
872db7da58e8d2aa021060098057f944ef754be06e3JP Abgrallvoid CommandListener::BandwidthControlCmd::sendGenericOkFail(SocketClient *cli, int cond) {
873db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!cond) {
874db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        cli->sendMsg(ResponseCode::CommandOkay, "Bandwidth command succeeeded", false);
875db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    } else {
876db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        cli->sendMsg(ResponseCode::OperationFailed, "Bandwidth command failed", false);
877db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
878db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall}
879db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
880db7da58e8d2aa021060098057f944ef754be06e3JP Abgrallvoid CommandListener::BandwidthControlCmd::sendGenericOpFailed(SocketClient *cli, const char *errMsg) {
881db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    cli->sendMsg(ResponseCode::OperationFailed, errMsg, false);
882db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall}
883db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
884fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrallint CommandListener::BandwidthControlCmd::runCommand(SocketClient *cli, int argc, char **argv) {
8854a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall    if (argc < 2) {
886db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericSyntaxError(cli, "<cmds> <args...>");
8874a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall        return 0;
8884a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall    }
8894a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall
890db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    LOGV("bwctrlcmd: argc=%d %s %s ...", argc, argv[0], argv[1]);
891db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
8924a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall    if (!strcmp(argv[1], "enable")) {
893db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->enableBandwidthControl();
894db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
895db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
896db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
897db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
898db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "disable")) {
899db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->disableBandwidthControl();
900db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
901db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
9020dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall
903db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
904db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "removequota") || !strcmp(argv[1], "rq")) {
905fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall        if (argc != 3) {
906db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "removequota <interface>");
907fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall            return 0;
908fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall        }
909db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->removeInterfaceSharedQuota(argv[2]);
910db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
911db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
912fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall
913db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
914db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "getquota") || !strcmp(argv[1], "gq")) {
9158a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        int64_t bytes;
9168a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        if (argc != 2) {
917db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "getquota");
9188a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall            return 0;
9198a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        }
920db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->getInterfaceSharedQuota(&bytes);
9218a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        if (rc) {
922db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericOpFailed(cli, "Failed to get quota");
9238a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall            return 0;
9248a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        }
925db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
9268a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        char *msg;
9278a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        asprintf(&msg, "%lld", bytes);
9288a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        cli->sendMsg(ResponseCode::QuotaCounterResult, msg, false);
9298a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        free(msg);
930db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
9318a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
932db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
933db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "getiquota") || !strcmp(argv[1], "giq")) {
9348a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        int64_t bytes;
9358a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        if (argc != 3) {
936db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "getiquota <iface>");
9378a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall            return 0;
9388a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        }
939db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
940db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->getInterfaceQuota(argv[2], &bytes);
9418a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        if (rc) {
942db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericOpFailed(cli, "Failed to get quota");
9438a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall            return 0;
9448a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        }
9458a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        char *msg;
9468a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        asprintf(&msg, "%lld", bytes);
9478a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        cli->sendMsg(ResponseCode::QuotaCounterResult, msg, false);
9488a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        free(msg);
949db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
9508a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
951db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
952db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "setquota") || !strcmp(argv[1], "sq")) {
953fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall        if (argc != 4) {
954db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "setquota <interface> <bytes>");
955fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall            return 0;
956fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall        }
957db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->setInterfaceSharedQuota(argv[2], atoll(argv[3]));
958db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
959db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
960db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
961db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "setquotas") || !strcmp(argv[1], "sqs")) {
962db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc;
963fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall        if (argc < 4) {
964db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "setquotas <bytes> <interface> ...");
965fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall            return 0;
966fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall        }
967db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
9688a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        for (int q = 3; argc >= 4; q++, argc--) {
9690dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall            rc = sBandwidthCtrl->setInterfaceSharedQuota(argv[q], atoll(argv[2]));
9700dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall            if (rc) {
9710dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall                char *msg;
9720dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall                asprintf(&msg, "bandwidth setquotas %s %s failed", argv[2], argv[q]);
9730dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall                cli->sendMsg(ResponseCode::OperationFailed,
9740dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall                             msg, false);
9750dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall                free(msg);
976db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall                return 0;
9770dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall            }
9780dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall        }
979db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
980db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
9810dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall
982db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
983db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "removequotas") || !strcmp(argv[1], "rqs")) {
984db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc;
9850dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall        if (argc < 3) {
986db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "removequotas <interface> ...");
9870dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall            return 0;
9880dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall        }
989db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
9908a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        for (int q = 2; argc >= 3; q++, argc--) {
9910dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall            rc = sBandwidthCtrl->removeInterfaceSharedQuota(argv[q]);
9920dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall            if (rc) {
9930dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall                char *msg;
9940dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall                asprintf(&msg, "bandwidth removequotas %s failed", argv[q]);
9950dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall                cli->sendMsg(ResponseCode::OperationFailed,
9960dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall                             msg, false);
9970dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall                free(msg);
998db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall                return 0;
9990dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall            }
10000dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall        }
1001db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
1002db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
10030dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall
1004db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
1005db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "removeiquota") || !strcmp(argv[1], "riq")) {
10060dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall        if (argc != 3) {
1007db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "removeiquota <interface>");
10080dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall            return 0;
10090dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall        }
1010db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->removeInterfaceQuota(argv[2]);
1011db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
1012db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
10130dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall
1014db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
1015db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "setiquota") || !strcmp(argv[1], "siq")) {
10160dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall        if (argc != 4) {
1017db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "setiquota <interface> <bytes>");
10180dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall            return 0;
10190dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall        }
1020db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->setInterfaceQuota(argv[2], atoll(argv[3]));
1021db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
1022db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
1023fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall
1024db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
1025db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "addnaughtyapps") || !strcmp(argv[1], "ana")) {
1026fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall        if (argc < 3) {
1027db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "addnaughtyapps <appUid> ...");
10284a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall            return 0;
1029fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall        }
1030db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->addNaughtyApps(argc - 2, argv + 2);
1031db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
1032db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
1033db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
1034fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall
1035db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
1036db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "removenaughtyapps") || !strcmp(argv[1], "rna")) {
1037fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall        if (argc < 3) {
1038db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "removenaughtyapps <appUid> ...");
1039fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall            return 0;
1040fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall        }
1041db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->removeNaughtyApps(argc - 2, argv + 2);
1042db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
1043db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
1044fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall
1045db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
1046db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "setglobalalert") || !strcmp(argv[1], "sga")) {
10478a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        if (argc != 3) {
1048db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "setglobalalert <bytes>");
10498a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall            return 0;
10508a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        }
1051db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->setGlobalAlert(atoll(argv[2]));
1052db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
1053db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
10548a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
1055db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
1056c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall    if (!strcmp(argv[1], "debugsettetherglobalalert") || !strcmp(argv[1], "dstga")) {
1057c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        if (argc != 4) {
1058c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall            sendGenericSyntaxError(cli, "debugsettetherglobalalert <interface0> <interface1>");
1059c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall            return 0;
1060c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        }
1061c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        /* We ignore the interfaces for now. */
1062c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        int rc = sBandwidthCtrl->setGlobalAlertInForwardChain();
1063c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        sendGenericOkFail(cli, rc);
1064c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        return 0;
1065c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall
1066c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall    }
1067db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "removeglobalalert") || !strcmp(argv[1], "rga")) {
10688a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        if (argc != 2) {
1069db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "removeglobalalert");
10708a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall            return 0;
10718a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        }
1072db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->removeGlobalAlert();
1073db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
1074db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
10758a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
1076db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
1077c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall    if (!strcmp(argv[1], "debugremovetetherglobalalert") || !strcmp(argv[1], "drtga")) {
1078c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        if (argc != 4) {
1079c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall            sendGenericSyntaxError(cli, "debugremovetetherglobalalert <interface0> <interface1>");
1080c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall            return 0;
1081c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        }
1082c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        /* We ignore the interfaces for now. */
1083c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        int rc = sBandwidthCtrl->removeGlobalAlertInForwardChain();
1084c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        sendGenericOkFail(cli, rc);
1085c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        return 0;
1086c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall
1087c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall    }
1088db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "setsharedalert") || !strcmp(argv[1], "ssa")) {
10898a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        if (argc != 3) {
1090db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "setsharedalert <bytes>");
10918a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall            return 0;
10928a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        }
1093db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->setSharedAlert(atoll(argv[2]));
1094db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
1095db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
10968a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
1097db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
1098db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "removesharedalert") || !strcmp(argv[1], "rsa")) {
10998a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        if (argc != 2) {
1100db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "removesharedalert");
11018a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall            return 0;
11028a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        }
1103db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->removeSharedAlert();
1104db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
1105db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
11068a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
1107db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
1108db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "setinterfacealert") || !strcmp(argv[1], "sia")) {
11098a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        if (argc != 4) {
1110db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "setinterfacealert <interface> <bytes>");
11118a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall            return 0;
11128a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        }
1113db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->setInterfaceAlert(argv[2], atoll(argv[3]));
1114db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
1115db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
11168a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
1117db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    }
1118db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "removeinterfacealert") || !strcmp(argv[1], "ria")) {
11198a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        if (argc != 3) {
1120db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "removeinterfacealert <interface>");
11218a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall            return 0;
11228a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        }
1123db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->removeInterfaceAlert(argv[2]);
1124db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        sendGenericOkFail(cli, rc);
1125fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall        return 0;
1126db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
11274a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall    }
1128db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    if (!strcmp(argv[1], "gettetherstats") || !strcmp(argv[1], "gts")) {
1129db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        BandwidthController::TetherStats tetherStats;
1130db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        if (argc != 4) {
1131db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericSyntaxError(cli, "gettetherstats <interface0> <interface1>");
1132db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            return 0;
1133db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        }
1134db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
1135db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        tetherStats.ifaceIn = argv[2];
1136db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        tetherStats.ifaceOut = argv[3];
1137db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int rc = sBandwidthCtrl->getTetherStats(tetherStats);
1138db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        if (rc) {
1139db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            sendGenericOpFailed(cli, "Failed to get tethering stats");
1140db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall            return 0;
1141db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        }
1142db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
1143db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        char *msg = tetherStats.getStatsLine();
1144db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        cli->sendMsg(ResponseCode::TetheringStatsResult, msg, false);
1145db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        free(msg);
1146db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        return 0;
11474a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall
11484a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall    }
1149db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
1150db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown bandwidth cmd", false);
11514a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall    return 0;
11524a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall}
1153