1*8542734aSAndroid Build Coastguard Worker /*
2*8542734aSAndroid Build Coastguard Worker * Copyright (C) 2019 The Android Open Source Project
3*8542734aSAndroid Build Coastguard Worker *
4*8542734aSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*8542734aSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*8542734aSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*8542734aSAndroid Build Coastguard Worker *
8*8542734aSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*8542734aSAndroid Build Coastguard Worker *
10*8542734aSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*8542734aSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*8542734aSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*8542734aSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*8542734aSAndroid Build Coastguard Worker * limitations under the License.
15*8542734aSAndroid Build Coastguard Worker */
16*8542734aSAndroid Build Coastguard Worker
17*8542734aSAndroid Build Coastguard Worker #include "NdcDispatcher.h"
18*8542734aSAndroid Build Coastguard Worker
19*8542734aSAndroid Build Coastguard Worker #include <arpa/inet.h>
20*8542734aSAndroid Build Coastguard Worker #include <dirent.h>
21*8542734aSAndroid Build Coastguard Worker #include <errno.h>
22*8542734aSAndroid Build Coastguard Worker #include <linux/if.h>
23*8542734aSAndroid Build Coastguard Worker #include <netinet/in.h>
24*8542734aSAndroid Build Coastguard Worker #include <stdlib.h>
25*8542734aSAndroid Build Coastguard Worker #include <string.h>
26*8542734aSAndroid Build Coastguard Worker #include <sys/socket.h>
27*8542734aSAndroid Build Coastguard Worker #include <sys/types.h>
28*8542734aSAndroid Build Coastguard Worker
29*8542734aSAndroid Build Coastguard Worker #include <cinttypes>
30*8542734aSAndroid Build Coastguard Worker #include <string>
31*8542734aSAndroid Build Coastguard Worker #include <vector>
32*8542734aSAndroid Build Coastguard Worker
33*8542734aSAndroid Build Coastguard Worker #include <android-base/logging.h>
34*8542734aSAndroid Build Coastguard Worker #include <android-base/parseint.h>
35*8542734aSAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
36*8542734aSAndroid Build Coastguard Worker #include <android-base/strings.h>
37*8542734aSAndroid Build Coastguard Worker #include <android/multinetwork.h>
38*8542734aSAndroid Build Coastguard Worker #include <netdutils/ResponseCode.h>
39*8542734aSAndroid Build Coastguard Worker #include <netdutils/Status.h>
40*8542734aSAndroid Build Coastguard Worker #include <netdutils/StatusOr.h>
41*8542734aSAndroid Build Coastguard Worker #include <netutils/ifc.h>
42*8542734aSAndroid Build Coastguard Worker
43*8542734aSAndroid Build Coastguard Worker #include "NetdConstants.h"
44*8542734aSAndroid Build Coastguard Worker #include "NetworkController.h"
45*8542734aSAndroid Build Coastguard Worker #include "Permission.h"
46*8542734aSAndroid Build Coastguard Worker #include "UidRanges.h"
47*8542734aSAndroid Build Coastguard Worker #include "netid_client.h"
48*8542734aSAndroid Build Coastguard Worker
49*8542734aSAndroid Build Coastguard Worker using android::base::Join;
50*8542734aSAndroid Build Coastguard Worker using android::base::StringPrintf;
51*8542734aSAndroid Build Coastguard Worker using android::binder::Status;
52*8542734aSAndroid Build Coastguard Worker
53*8542734aSAndroid Build Coastguard Worker #define PARSE_INT_RETURN_IF_FAIL(cli, label, intLabel, errMsg, addErrno) \
54*8542734aSAndroid Build Coastguard Worker do { \
55*8542734aSAndroid Build Coastguard Worker if (!android::base::ParseInt((label), &(intLabel))) { \
56*8542734aSAndroid Build Coastguard Worker errno = EINVAL; \
57*8542734aSAndroid Build Coastguard Worker (cli)->sendMsg(ResponseCode::OperationFailed, (errMsg), (addErrno)); \
58*8542734aSAndroid Build Coastguard Worker return 0; \
59*8542734aSAndroid Build Coastguard Worker } \
60*8542734aSAndroid Build Coastguard Worker } while (0)
61*8542734aSAndroid Build Coastguard Worker
62*8542734aSAndroid Build Coastguard Worker #define PARSE_UINT_RETURN_IF_FAIL(cli, label, intLabel, errMsg, addErrno) \
63*8542734aSAndroid Build Coastguard Worker do { \
64*8542734aSAndroid Build Coastguard Worker if (!android::base::ParseUint((label), &(intLabel))) { \
65*8542734aSAndroid Build Coastguard Worker errno = EINVAL; \
66*8542734aSAndroid Build Coastguard Worker (cli)->sendMsg(ResponseCode::OperationFailed, (errMsg), (addErrno)); \
67*8542734aSAndroid Build Coastguard Worker return 0; \
68*8542734aSAndroid Build Coastguard Worker } \
69*8542734aSAndroid Build Coastguard Worker } while (0)
70*8542734aSAndroid Build Coastguard Worker
71*8542734aSAndroid Build Coastguard Worker namespace android {
72*8542734aSAndroid Build Coastguard Worker
73*8542734aSAndroid Build Coastguard Worker using netdutils::ResponseCode;
74*8542734aSAndroid Build Coastguard Worker
75*8542734aSAndroid Build Coastguard Worker namespace net {
76*8542734aSAndroid Build Coastguard Worker namespace {
77*8542734aSAndroid Build Coastguard Worker
78*8542734aSAndroid Build Coastguard Worker const unsigned NUM_OEM_IDS = NetworkController::MAX_OEM_ID - NetworkController::MIN_OEM_ID + 1;
79*8542734aSAndroid Build Coastguard Worker
stringToNetId(const char * arg)80*8542734aSAndroid Build Coastguard Worker unsigned stringToNetId(const char* arg) {
81*8542734aSAndroid Build Coastguard Worker if (!strcmp(arg, "local")) {
82*8542734aSAndroid Build Coastguard Worker return NetworkController::LOCAL_NET_ID;
83*8542734aSAndroid Build Coastguard Worker }
84*8542734aSAndroid Build Coastguard Worker // OEM NetIds are "oem1", "oem2", .., "oem50".
85*8542734aSAndroid Build Coastguard Worker if (!strncmp(arg, "oem", 3)) {
86*8542734aSAndroid Build Coastguard Worker unsigned n = strtoul(arg + 3, nullptr, 0);
87*8542734aSAndroid Build Coastguard Worker if (1 <= n && n <= NUM_OEM_IDS) {
88*8542734aSAndroid Build Coastguard Worker return NetworkController::MIN_OEM_ID + n;
89*8542734aSAndroid Build Coastguard Worker }
90*8542734aSAndroid Build Coastguard Worker return NETID_UNSET;
91*8542734aSAndroid Build Coastguard Worker } else if (!strncmp(arg, "handle", 6)) {
92*8542734aSAndroid Build Coastguard Worker unsigned n = netHandleToNetId((net_handle_t)strtoull(arg + 6, nullptr, 10));
93*8542734aSAndroid Build Coastguard Worker if (NetworkController::MIN_OEM_ID <= n && n <= NetworkController::MAX_OEM_ID) {
94*8542734aSAndroid Build Coastguard Worker return n;
95*8542734aSAndroid Build Coastguard Worker }
96*8542734aSAndroid Build Coastguard Worker return NETID_UNSET;
97*8542734aSAndroid Build Coastguard Worker }
98*8542734aSAndroid Build Coastguard Worker // strtoul() returns 0 on errors, which is fine because 0 is an invalid netId.
99*8542734aSAndroid Build Coastguard Worker return strtoul(arg, nullptr, 0);
100*8542734aSAndroid Build Coastguard Worker }
101*8542734aSAndroid Build Coastguard Worker
toStdString(const String16 & s)102*8542734aSAndroid Build Coastguard Worker std::string toStdString(const String16& s) {
103*8542734aSAndroid Build Coastguard Worker return std::string(String8(s.c_str()));
104*8542734aSAndroid Build Coastguard Worker }
105*8542734aSAndroid Build Coastguard Worker
stringToINetdPermission(const char * arg)106*8542734aSAndroid Build Coastguard Worker int stringToINetdPermission(const char* arg) {
107*8542734aSAndroid Build Coastguard Worker if (!strcmp(arg, "NETWORK")) {
108*8542734aSAndroid Build Coastguard Worker return INetd::PERMISSION_NETWORK;
109*8542734aSAndroid Build Coastguard Worker }
110*8542734aSAndroid Build Coastguard Worker if (!strcmp(arg, "SYSTEM")) {
111*8542734aSAndroid Build Coastguard Worker return INetd::PERMISSION_SYSTEM;
112*8542734aSAndroid Build Coastguard Worker }
113*8542734aSAndroid Build Coastguard Worker return INetd::PERMISSION_NONE;
114*8542734aSAndroid Build Coastguard Worker }
115*8542734aSAndroid Build Coastguard Worker
116*8542734aSAndroid Build Coastguard Worker } // namespace
117*8542734aSAndroid Build Coastguard Worker
118*8542734aSAndroid Build Coastguard Worker sp<INetd> NdcDispatcher::mNetd;
119*8542734aSAndroid Build Coastguard Worker sp<IDnsResolver> NdcDispatcher::mDnsResolver;
120*8542734aSAndroid Build Coastguard Worker
NdcDispatcher()121*8542734aSAndroid Build Coastguard Worker NdcDispatcher::NdcDispatcher() {
122*8542734aSAndroid Build Coastguard Worker sp<IServiceManager> sm = defaultServiceManager();
123*8542734aSAndroid Build Coastguard Worker sp<IBinder> binderNetd = sm->getService(String16("netd"));
124*8542734aSAndroid Build Coastguard Worker sp<IBinder> binderDnsResolver = sm->getService(String16("dnsresolver"));
125*8542734aSAndroid Build Coastguard Worker if ((binderNetd != nullptr) && (binderDnsResolver != nullptr)) {
126*8542734aSAndroid Build Coastguard Worker NdcDispatcher::mNetd = interface_cast<INetd>(binderNetd);
127*8542734aSAndroid Build Coastguard Worker NdcDispatcher::mDnsResolver = interface_cast<IDnsResolver>(binderDnsResolver);
128*8542734aSAndroid Build Coastguard Worker } else {
129*8542734aSAndroid Build Coastguard Worker LOG(LOGLEVEL) << "Unable to get binder service";
130*8542734aSAndroid Build Coastguard Worker exit(1);
131*8542734aSAndroid Build Coastguard Worker }
132*8542734aSAndroid Build Coastguard Worker registerCmd(new InterfaceCmd());
133*8542734aSAndroid Build Coastguard Worker registerCmd(new IpFwdCmd());
134*8542734aSAndroid Build Coastguard Worker registerCmd(new TetherCmd());
135*8542734aSAndroid Build Coastguard Worker registerCmd(new NatCmd());
136*8542734aSAndroid Build Coastguard Worker registerCmd(new BandwidthControlCmd());
137*8542734aSAndroid Build Coastguard Worker registerCmd(new IdletimerControlCmd());
138*8542734aSAndroid Build Coastguard Worker registerCmd(new FirewallCmd());
139*8542734aSAndroid Build Coastguard Worker registerCmd(new NetworkCommand());
140*8542734aSAndroid Build Coastguard Worker registerCmd(new StrictCmd());
141*8542734aSAndroid Build Coastguard Worker }
142*8542734aSAndroid Build Coastguard Worker
registerCmd(NdcNetdCommand * cmd)143*8542734aSAndroid Build Coastguard Worker void NdcDispatcher::registerCmd(NdcNetdCommand* cmd) {
144*8542734aSAndroid Build Coastguard Worker mCommands.push_back(cmd);
145*8542734aSAndroid Build Coastguard Worker }
146*8542734aSAndroid Build Coastguard Worker
dispatchCommand(int argc,char ** argv)147*8542734aSAndroid Build Coastguard Worker int NdcDispatcher::dispatchCommand(int argc, char** argv) {
148*8542734aSAndroid Build Coastguard Worker if (argc >= CMD_ARGS_MAX) {
149*8542734aSAndroid Build Coastguard Worker mNdc.sendMsg(500, "Command too long", false);
150*8542734aSAndroid Build Coastguard Worker }
151*8542734aSAndroid Build Coastguard Worker
152*8542734aSAndroid Build Coastguard Worker for (const auto* c : mCommands) {
153*8542734aSAndroid Build Coastguard Worker if (c->getCommand() == argv[0]) {
154*8542734aSAndroid Build Coastguard Worker if (c->runCommand(&mNdc, argc, argv)) {
155*8542734aSAndroid Build Coastguard Worker mNdc.sendMsg(500, "Handler error", true);
156*8542734aSAndroid Build Coastguard Worker }
157*8542734aSAndroid Build Coastguard Worker return 0;
158*8542734aSAndroid Build Coastguard Worker }
159*8542734aSAndroid Build Coastguard Worker }
160*8542734aSAndroid Build Coastguard Worker mNdc.sendMsg(500, "Command not recognized", false);
161*8542734aSAndroid Build Coastguard Worker return 0;
162*8542734aSAndroid Build Coastguard Worker }
163*8542734aSAndroid Build Coastguard Worker
InterfaceCmd()164*8542734aSAndroid Build Coastguard Worker NdcDispatcher::InterfaceCmd::InterfaceCmd() : NdcNetdCommand("interface") {}
165*8542734aSAndroid Build Coastguard Worker
runCommand(NdcClient * cli,int argc,char ** argv) const166*8542734aSAndroid Build Coastguard Worker int NdcDispatcher::InterfaceCmd::runCommand(NdcClient* cli, int argc, char** argv) const {
167*8542734aSAndroid Build Coastguard Worker if (argc < 2) {
168*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
169*8542734aSAndroid Build Coastguard Worker return 0;
170*8542734aSAndroid Build Coastguard Worker }
171*8542734aSAndroid Build Coastguard Worker
172*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "list")) {
173*8542734aSAndroid Build Coastguard Worker std::vector<std::string> interfaceGetList;
174*8542734aSAndroid Build Coastguard Worker Status status = mNetd->interfaceGetList(&interfaceGetList);
175*8542734aSAndroid Build Coastguard Worker
176*8542734aSAndroid Build Coastguard Worker if (!status.isOk()) {
177*8542734aSAndroid Build Coastguard Worker errno = status.serviceSpecificErrorCode();
178*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::OperationFailed, "Failed to get interface list", true);
179*8542734aSAndroid Build Coastguard Worker return 0;
180*8542734aSAndroid Build Coastguard Worker }
181*8542734aSAndroid Build Coastguard Worker for (const auto& iface : interfaceGetList) {
182*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::InterfaceListResult, iface.c_str(), false);
183*8542734aSAndroid Build Coastguard Worker }
184*8542734aSAndroid Build Coastguard Worker
185*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandOkay, "Interface list completed", false);
186*8542734aSAndroid Build Coastguard Worker return 0;
187*8542734aSAndroid Build Coastguard Worker } else {
188*8542734aSAndroid Build Coastguard Worker /*
189*8542734aSAndroid Build Coastguard Worker * These commands take a minimum of 3 arguments
190*8542734aSAndroid Build Coastguard Worker */
191*8542734aSAndroid Build Coastguard Worker if (argc < 3) {
192*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
193*8542734aSAndroid Build Coastguard Worker return 0;
194*8542734aSAndroid Build Coastguard Worker }
195*8542734aSAndroid Build Coastguard Worker
196*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "getcfg")) {
197*8542734aSAndroid Build Coastguard Worker InterfaceConfigurationParcel interfaceCfgResult;
198*8542734aSAndroid Build Coastguard Worker Status status = mNetd->interfaceGetCfg(std::string(argv[2]), &interfaceCfgResult);
199*8542734aSAndroid Build Coastguard Worker
200*8542734aSAndroid Build Coastguard Worker if (!status.isOk()) {
201*8542734aSAndroid Build Coastguard Worker errno = status.serviceSpecificErrorCode();
202*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::OperationFailed, "Interface not found", true);
203*8542734aSAndroid Build Coastguard Worker return 0;
204*8542734aSAndroid Build Coastguard Worker }
205*8542734aSAndroid Build Coastguard Worker
206*8542734aSAndroid Build Coastguard Worker std::string flags = Join(interfaceCfgResult.flags, " ");
207*8542734aSAndroid Build Coastguard Worker
208*8542734aSAndroid Build Coastguard Worker std::string msg = StringPrintf("%s %s %d %s", interfaceCfgResult.hwAddr.c_str(),
209*8542734aSAndroid Build Coastguard Worker interfaceCfgResult.ipv4Addr.c_str(),
210*8542734aSAndroid Build Coastguard Worker interfaceCfgResult.prefixLength, flags.c_str());
211*8542734aSAndroid Build Coastguard Worker
212*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::InterfaceGetCfgResult, msg.c_str(), false);
213*8542734aSAndroid Build Coastguard Worker
214*8542734aSAndroid Build Coastguard Worker return 0;
215*8542734aSAndroid Build Coastguard Worker } else if (!strcmp(argv[1], "setcfg")) {
216*8542734aSAndroid Build Coastguard Worker // arglist: iface [addr prefixLength] flags
217*8542734aSAndroid Build Coastguard Worker if (argc < 4) {
218*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
219*8542734aSAndroid Build Coastguard Worker return 0;
220*8542734aSAndroid Build Coastguard Worker }
221*8542734aSAndroid Build Coastguard Worker LOG(LOGLEVEL) << "Setting iface cfg";
222*8542734aSAndroid Build Coastguard Worker
223*8542734aSAndroid Build Coastguard Worker struct in_addr addr;
224*8542734aSAndroid Build Coastguard Worker int index = 5;
225*8542734aSAndroid Build Coastguard Worker InterfaceConfigurationParcel interfaceCfg;
226*8542734aSAndroid Build Coastguard Worker interfaceCfg.ifName = argv[2];
227*8542734aSAndroid Build Coastguard Worker interfaceCfg.hwAddr = "";
228*8542734aSAndroid Build Coastguard Worker
229*8542734aSAndroid Build Coastguard Worker if (!inet_aton(argv[3], &addr)) {
230*8542734aSAndroid Build Coastguard Worker // Handle flags only case
231*8542734aSAndroid Build Coastguard Worker index = 3;
232*8542734aSAndroid Build Coastguard Worker interfaceCfg.ipv4Addr = "";
233*8542734aSAndroid Build Coastguard Worker interfaceCfg.prefixLength = 0;
234*8542734aSAndroid Build Coastguard Worker } else {
235*8542734aSAndroid Build Coastguard Worker if (addr.s_addr != 0) {
236*8542734aSAndroid Build Coastguard Worker interfaceCfg.ipv4Addr = argv[3];
237*8542734aSAndroid Build Coastguard Worker PARSE_INT_RETURN_IF_FAIL(cli, argv[4], interfaceCfg.prefixLength,
238*8542734aSAndroid Build Coastguard Worker "Failed to set address", true);
239*8542734aSAndroid Build Coastguard Worker Status status = mNetd->interfaceSetCfg(interfaceCfg);
240*8542734aSAndroid Build Coastguard Worker if (!status.isOk()) {
241*8542734aSAndroid Build Coastguard Worker errno = status.serviceSpecificErrorCode();
242*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::OperationFailed, "Failed to set address", true);
243*8542734aSAndroid Build Coastguard Worker return 0;
244*8542734aSAndroid Build Coastguard Worker }
245*8542734aSAndroid Build Coastguard Worker }
246*8542734aSAndroid Build Coastguard Worker }
247*8542734aSAndroid Build Coastguard Worker
248*8542734aSAndroid Build Coastguard Worker /* Process flags */
249*8542734aSAndroid Build Coastguard Worker for (int i = index; i < argc; i++) {
250*8542734aSAndroid Build Coastguard Worker char* flag = argv[i];
251*8542734aSAndroid Build Coastguard Worker if (!strcmp(flag, "up")) {
252*8542734aSAndroid Build Coastguard Worker LOG(LOGLEVEL) << "Trying to bring up " << argv[2];
253*8542734aSAndroid Build Coastguard Worker interfaceCfg.flags.push_back(toStdString(INetd::IF_STATE_UP()));
254*8542734aSAndroid Build Coastguard Worker Status status = mNetd->interfaceSetCfg(interfaceCfg);
255*8542734aSAndroid Build Coastguard Worker if (!status.isOk()) {
256*8542734aSAndroid Build Coastguard Worker LOG(LOGLEVEL) << "Error upping interface";
257*8542734aSAndroid Build Coastguard Worker errno = status.serviceSpecificErrorCode();
258*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::OperationFailed, "Failed to up interface", true);
259*8542734aSAndroid Build Coastguard Worker ifc_close();
260*8542734aSAndroid Build Coastguard Worker return 0;
261*8542734aSAndroid Build Coastguard Worker }
262*8542734aSAndroid Build Coastguard Worker } else if (!strcmp(flag, "down")) {
263*8542734aSAndroid Build Coastguard Worker LOG(LOGLEVEL) << "Trying to bring down " << argv[2];
264*8542734aSAndroid Build Coastguard Worker interfaceCfg.flags.push_back(toStdString(INetd::IF_STATE_DOWN()));
265*8542734aSAndroid Build Coastguard Worker Status status = mNetd->interfaceSetCfg(interfaceCfg);
266*8542734aSAndroid Build Coastguard Worker if (!status.isOk()) {
267*8542734aSAndroid Build Coastguard Worker LOG(LOGLEVEL) << "Error downing interface";
268*8542734aSAndroid Build Coastguard Worker errno = status.serviceSpecificErrorCode();
269*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::OperationFailed, "Failed to down interface",
270*8542734aSAndroid Build Coastguard Worker true);
271*8542734aSAndroid Build Coastguard Worker return 0;
272*8542734aSAndroid Build Coastguard Worker }
273*8542734aSAndroid Build Coastguard Worker } else if (!strcmp(flag, "broadcast") || !strcmp(flag, "multicast") ||
274*8542734aSAndroid Build Coastguard Worker !strcmp(flag, "running") || !strcmp(flag, "loopback") ||
275*8542734aSAndroid Build Coastguard Worker !strcmp(flag, "point-to-point")) {
276*8542734aSAndroid Build Coastguard Worker // currently ignored
277*8542734aSAndroid Build Coastguard Worker } else {
278*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandParameterError, "Flag unsupported", false);
279*8542734aSAndroid Build Coastguard Worker return 0;
280*8542734aSAndroid Build Coastguard Worker }
281*8542734aSAndroid Build Coastguard Worker }
282*8542734aSAndroid Build Coastguard Worker
283*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandOkay, "Interface configuration set", false);
284*8542734aSAndroid Build Coastguard Worker return 0;
285*8542734aSAndroid Build Coastguard Worker } else if (!strcmp(argv[1], "clearaddrs")) {
286*8542734aSAndroid Build Coastguard Worker // arglist: iface
287*8542734aSAndroid Build Coastguard Worker LOG(LOGLEVEL) << "Clearing all IP addresses on " << argv[2];
288*8542734aSAndroid Build Coastguard Worker
289*8542734aSAndroid Build Coastguard Worker mNetd->interfaceClearAddrs(std::string(argv[2]));
290*8542734aSAndroid Build Coastguard Worker
291*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandOkay, "Interface IP addresses cleared", false);
292*8542734aSAndroid Build Coastguard Worker return 0;
293*8542734aSAndroid Build Coastguard Worker } else if (!strcmp(argv[1], "ipv6privacyextensions")) {
294*8542734aSAndroid Build Coastguard Worker if (argc != 4) {
295*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError,
296*8542734aSAndroid Build Coastguard Worker "Usage: interface ipv6privacyextensions <interface> <enable|disable>",
297*8542734aSAndroid Build Coastguard Worker false);
298*8542734aSAndroid Build Coastguard Worker return 0;
299*8542734aSAndroid Build Coastguard Worker }
300*8542734aSAndroid Build Coastguard Worker int enable = !strcmp(argv[3], "enable");
301*8542734aSAndroid Build Coastguard Worker Status status = mNetd->interfaceSetIPv6PrivacyExtensions(std::string(argv[2]), enable);
302*8542734aSAndroid Build Coastguard Worker if (status.isOk()) {
303*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandOkay, "IPv6 privacy extensions changed", false);
304*8542734aSAndroid Build Coastguard Worker } else {
305*8542734aSAndroid Build Coastguard Worker errno = status.serviceSpecificErrorCode();
306*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::OperationFailed, "Failed to set ipv6 privacy extensions",
307*8542734aSAndroid Build Coastguard Worker true);
308*8542734aSAndroid Build Coastguard Worker }
309*8542734aSAndroid Build Coastguard Worker return 0;
310*8542734aSAndroid Build Coastguard Worker } else if (!strcmp(argv[1], "ipv6")) {
311*8542734aSAndroid Build Coastguard Worker if (argc != 4) {
312*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError,
313*8542734aSAndroid Build Coastguard Worker "Usage: interface ipv6 <interface> <enable|disable>", false);
314*8542734aSAndroid Build Coastguard Worker return 0;
315*8542734aSAndroid Build Coastguard Worker }
316*8542734aSAndroid Build Coastguard Worker
317*8542734aSAndroid Build Coastguard Worker int enable = !strcmp(argv[3], "enable");
318*8542734aSAndroid Build Coastguard Worker Status status = mNetd->interfaceSetEnableIPv6(std::string(argv[2]), enable);
319*8542734aSAndroid Build Coastguard Worker if (status.isOk()) {
320*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandOkay, "IPv6 state changed", false);
321*8542734aSAndroid Build Coastguard Worker } else {
322*8542734aSAndroid Build Coastguard Worker errno = status.serviceSpecificErrorCode();
323*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::OperationFailed, "Failed to change IPv6 state", true);
324*8542734aSAndroid Build Coastguard Worker }
325*8542734aSAndroid Build Coastguard Worker return 0;
326*8542734aSAndroid Build Coastguard Worker } else if (!strcmp(argv[1], "setmtu")) {
327*8542734aSAndroid Build Coastguard Worker if (argc != 4) {
328*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError,
329*8542734aSAndroid Build Coastguard Worker "Usage: interface setmtu <interface> <val>", false);
330*8542734aSAndroid Build Coastguard Worker return 0;
331*8542734aSAndroid Build Coastguard Worker }
332*8542734aSAndroid Build Coastguard Worker
333*8542734aSAndroid Build Coastguard Worker int mtuValue = 0;
334*8542734aSAndroid Build Coastguard Worker PARSE_INT_RETURN_IF_FAIL(cli, argv[3], mtuValue, "Failed to set MTU", true);
335*8542734aSAndroid Build Coastguard Worker Status status = mNetd->interfaceSetMtu(std::string(argv[2]), mtuValue);
336*8542734aSAndroid Build Coastguard Worker if (status.isOk()) {
337*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandOkay, "MTU changed", false);
338*8542734aSAndroid Build Coastguard Worker } else {
339*8542734aSAndroid Build Coastguard Worker errno = status.serviceSpecificErrorCode();
340*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::OperationFailed, "Failed to set MTU", true);
341*8542734aSAndroid Build Coastguard Worker }
342*8542734aSAndroid Build Coastguard Worker return 0;
343*8542734aSAndroid Build Coastguard Worker } else {
344*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown interface cmd", false);
345*8542734aSAndroid Build Coastguard Worker return 0;
346*8542734aSAndroid Build Coastguard Worker }
347*8542734aSAndroid Build Coastguard Worker }
348*8542734aSAndroid Build Coastguard Worker return 0;
349*8542734aSAndroid Build Coastguard Worker }
350*8542734aSAndroid Build Coastguard Worker
IpFwdCmd()351*8542734aSAndroid Build Coastguard Worker NdcDispatcher::IpFwdCmd::IpFwdCmd() : NdcNetdCommand("ipfwd") {}
352*8542734aSAndroid Build Coastguard Worker
runCommand(NdcClient * cli,int argc,char ** argv) const353*8542734aSAndroid Build Coastguard Worker int NdcDispatcher::IpFwdCmd::runCommand(NdcClient* cli, int argc, char** argv) const {
354*8542734aSAndroid Build Coastguard Worker bool matched = false;
355*8542734aSAndroid Build Coastguard Worker Status status;
356*8542734aSAndroid Build Coastguard Worker
357*8542734aSAndroid Build Coastguard Worker if (argc == 2) {
358*8542734aSAndroid Build Coastguard Worker // 0 1
359*8542734aSAndroid Build Coastguard Worker // ipfwd status
360*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "status")) {
361*8542734aSAndroid Build Coastguard Worker bool ipfwdEnabled;
362*8542734aSAndroid Build Coastguard Worker mNetd->ipfwdEnabled(&ipfwdEnabled);
363*8542734aSAndroid Build Coastguard Worker std::string msg = StringPrintf("Forwarding %s", ipfwdEnabled ? "enabled" : "disabled");
364*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::IpFwdStatusResult, msg.c_str(), false);
365*8542734aSAndroid Build Coastguard Worker return 0;
366*8542734aSAndroid Build Coastguard Worker }
367*8542734aSAndroid Build Coastguard Worker } else if (argc == 3) {
368*8542734aSAndroid Build Coastguard Worker // 0 1 2
369*8542734aSAndroid Build Coastguard Worker // ipfwd enable <requester>
370*8542734aSAndroid Build Coastguard Worker // ipfwd disable <requester>
371*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "enable")) {
372*8542734aSAndroid Build Coastguard Worker matched = true;
373*8542734aSAndroid Build Coastguard Worker status = mNetd->ipfwdEnableForwarding(argv[2]);
374*8542734aSAndroid Build Coastguard Worker } else if (!strcmp(argv[1], "disable")) {
375*8542734aSAndroid Build Coastguard Worker matched = true;
376*8542734aSAndroid Build Coastguard Worker status = mNetd->ipfwdDisableForwarding(argv[2]);
377*8542734aSAndroid Build Coastguard Worker }
378*8542734aSAndroid Build Coastguard Worker } else if (argc == 4) {
379*8542734aSAndroid Build Coastguard Worker // 0 1 2 3
380*8542734aSAndroid Build Coastguard Worker // ipfwd add wlan0 dummy0
381*8542734aSAndroid Build Coastguard Worker // ipfwd remove wlan0 dummy0
382*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "add")) {
383*8542734aSAndroid Build Coastguard Worker matched = true;
384*8542734aSAndroid Build Coastguard Worker status = mNetd->ipfwdAddInterfaceForward(argv[2], argv[3]);
385*8542734aSAndroid Build Coastguard Worker } else if (!strcmp(argv[1], "remove")) {
386*8542734aSAndroid Build Coastguard Worker matched = true;
387*8542734aSAndroid Build Coastguard Worker status = mNetd->ipfwdRemoveInterfaceForward(argv[2], argv[3]);
388*8542734aSAndroid Build Coastguard Worker }
389*8542734aSAndroid Build Coastguard Worker }
390*8542734aSAndroid Build Coastguard Worker
391*8542734aSAndroid Build Coastguard Worker if (!matched) {
392*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown ipfwd cmd", false);
393*8542734aSAndroid Build Coastguard Worker return 0;
394*8542734aSAndroid Build Coastguard Worker }
395*8542734aSAndroid Build Coastguard Worker
396*8542734aSAndroid Build Coastguard Worker if (status.isOk()) {
397*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandOkay, "ipfwd operation succeeded", false);
398*8542734aSAndroid Build Coastguard Worker } else {
399*8542734aSAndroid Build Coastguard Worker errno = status.serviceSpecificErrorCode();
400*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::OperationFailed, "ipfwd operation failed", true);
401*8542734aSAndroid Build Coastguard Worker }
402*8542734aSAndroid Build Coastguard Worker return 0;
403*8542734aSAndroid Build Coastguard Worker }
404*8542734aSAndroid Build Coastguard Worker
TetherCmd()405*8542734aSAndroid Build Coastguard Worker NdcDispatcher::TetherCmd::TetherCmd() : NdcNetdCommand("tether") {}
406*8542734aSAndroid Build Coastguard Worker
runCommand(NdcClient * cli,int argc,char ** argv) const407*8542734aSAndroid Build Coastguard Worker int NdcDispatcher::TetherCmd::runCommand(NdcClient* cli, int argc, char** argv) const {
408*8542734aSAndroid Build Coastguard Worker Status status;
409*8542734aSAndroid Build Coastguard Worker
410*8542734aSAndroid Build Coastguard Worker if (argc < 2) {
411*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
412*8542734aSAndroid Build Coastguard Worker return 0;
413*8542734aSAndroid Build Coastguard Worker }
414*8542734aSAndroid Build Coastguard Worker
415*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "stop")) {
416*8542734aSAndroid Build Coastguard Worker status = mNetd->tetherStop();
417*8542734aSAndroid Build Coastguard Worker } else if (!strcmp(argv[1], "status")) {
418*8542734aSAndroid Build Coastguard Worker bool tetherEnabled;
419*8542734aSAndroid Build Coastguard Worker mNetd->tetherIsEnabled(&tetherEnabled);
420*8542734aSAndroid Build Coastguard Worker std::string msg =
421*8542734aSAndroid Build Coastguard Worker StringPrintf("Tethering services %s", tetherEnabled ? "started" : "stopped");
422*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::TetherStatusResult, msg.c_str(), false);
423*8542734aSAndroid Build Coastguard Worker return 0;
424*8542734aSAndroid Build Coastguard Worker } else if (argc == 3) {
425*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "interface") && !strcmp(argv[2], "list")) {
426*8542734aSAndroid Build Coastguard Worker std::vector<std::string> ifList;
427*8542734aSAndroid Build Coastguard Worker mNetd->tetherInterfaceList(&ifList);
428*8542734aSAndroid Build Coastguard Worker for (const auto& ifname : ifList) {
429*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::TetherInterfaceListResult, ifname.c_str(), false);
430*8542734aSAndroid Build Coastguard Worker }
431*8542734aSAndroid Build Coastguard Worker }
432*8542734aSAndroid Build Coastguard Worker } else if (!strcmp(argv[1], "start")) {
433*8542734aSAndroid Build Coastguard Worker if (argc % 2 == 1) {
434*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError, "Bad number of arguments", false);
435*8542734aSAndroid Build Coastguard Worker return 0;
436*8542734aSAndroid Build Coastguard Worker }
437*8542734aSAndroid Build Coastguard Worker
438*8542734aSAndroid Build Coastguard Worker std::vector<std::string> dhcpRanges;
439*8542734aSAndroid Build Coastguard Worker // We do the checking of the pairs & addr invalidation in binderService/tetherController.
440*8542734aSAndroid Build Coastguard Worker for (int arg_index = 2; arg_index < argc; arg_index++) {
441*8542734aSAndroid Build Coastguard Worker dhcpRanges.push_back(argv[arg_index]);
442*8542734aSAndroid Build Coastguard Worker }
443*8542734aSAndroid Build Coastguard Worker
444*8542734aSAndroid Build Coastguard Worker status = mNetd->tetherStart(dhcpRanges);
445*8542734aSAndroid Build Coastguard Worker } else {
446*8542734aSAndroid Build Coastguard Worker /*
447*8542734aSAndroid Build Coastguard Worker * These commands take a minimum of 4 arguments
448*8542734aSAndroid Build Coastguard Worker */
449*8542734aSAndroid Build Coastguard Worker if (argc < 4) {
450*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
451*8542734aSAndroid Build Coastguard Worker return 0;
452*8542734aSAndroid Build Coastguard Worker }
453*8542734aSAndroid Build Coastguard Worker
454*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "interface")) {
455*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[2], "add")) {
456*8542734aSAndroid Build Coastguard Worker status = mNetd->tetherInterfaceAdd(argv[3]);
457*8542734aSAndroid Build Coastguard Worker } else if (!strcmp(argv[2], "remove")) {
458*8542734aSAndroid Build Coastguard Worker status = mNetd->tetherInterfaceRemove(argv[3]);
459*8542734aSAndroid Build Coastguard Worker /* else if (!strcmp(argv[2], "list")) handled above */
460*8542734aSAndroid Build Coastguard Worker } else {
461*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandParameterError,
462*8542734aSAndroid Build Coastguard Worker "Unknown tether interface operation", false);
463*8542734aSAndroid Build Coastguard Worker return 0;
464*8542734aSAndroid Build Coastguard Worker }
465*8542734aSAndroid Build Coastguard Worker } else if (!strcmp(argv[1], "dns")) {
466*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[2], "set")) {
467*8542734aSAndroid Build Coastguard Worker if (argc < 5) {
468*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
469*8542734aSAndroid Build Coastguard Worker return 0;
470*8542734aSAndroid Build Coastguard Worker }
471*8542734aSAndroid Build Coastguard Worker std::vector<std::string> tetherDnsAddrs;
472*8542734aSAndroid Build Coastguard Worker unsigned netId = stringToNetId(argv[3]);
473*8542734aSAndroid Build Coastguard Worker for (int arg_index = 4; arg_index < argc; arg_index++) {
474*8542734aSAndroid Build Coastguard Worker tetherDnsAddrs.push_back(argv[arg_index]);
475*8542734aSAndroid Build Coastguard Worker }
476*8542734aSAndroid Build Coastguard Worker status = mNetd->tetherDnsSet(netId, tetherDnsAddrs);
477*8542734aSAndroid Build Coastguard Worker /* else if (!strcmp(argv[2], "list")) handled above */
478*8542734aSAndroid Build Coastguard Worker } else {
479*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandParameterError,
480*8542734aSAndroid Build Coastguard Worker "Unknown tether interface operation", false);
481*8542734aSAndroid Build Coastguard Worker return 0;
482*8542734aSAndroid Build Coastguard Worker }
483*8542734aSAndroid Build Coastguard Worker } else {
484*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown tether cmd", false);
485*8542734aSAndroid Build Coastguard Worker return 0;
486*8542734aSAndroid Build Coastguard Worker }
487*8542734aSAndroid Build Coastguard Worker }
488*8542734aSAndroid Build Coastguard Worker
489*8542734aSAndroid Build Coastguard Worker if (status.isOk()) {
490*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandOkay, "Tether operation succeeded", false);
491*8542734aSAndroid Build Coastguard Worker } else {
492*8542734aSAndroid Build Coastguard Worker errno = status.serviceSpecificErrorCode();
493*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::OperationFailed, "Tether operation failed", true);
494*8542734aSAndroid Build Coastguard Worker }
495*8542734aSAndroid Build Coastguard Worker
496*8542734aSAndroid Build Coastguard Worker return 0;
497*8542734aSAndroid Build Coastguard Worker }
498*8542734aSAndroid Build Coastguard Worker
NatCmd()499*8542734aSAndroid Build Coastguard Worker NdcDispatcher::NatCmd::NatCmd() : NdcNetdCommand("nat") {}
500*8542734aSAndroid Build Coastguard Worker
runCommand(NdcClient * cli,int argc,char ** argv) const501*8542734aSAndroid Build Coastguard Worker int NdcDispatcher::NatCmd::runCommand(NdcClient* cli, int argc, char** argv) const {
502*8542734aSAndroid Build Coastguard Worker Status status;
503*8542734aSAndroid Build Coastguard Worker
504*8542734aSAndroid Build Coastguard Worker if (argc < 5) {
505*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
506*8542734aSAndroid Build Coastguard Worker return 0;
507*8542734aSAndroid Build Coastguard Worker }
508*8542734aSAndroid Build Coastguard Worker
509*8542734aSAndroid Build Coastguard Worker // 0 1 2 3
510*8542734aSAndroid Build Coastguard Worker // nat enable intiface extiface
511*8542734aSAndroid Build Coastguard Worker // nat disable intiface extiface
512*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "enable") && argc >= 4) {
513*8542734aSAndroid Build Coastguard Worker status = mNetd->tetherAddForward(argv[2], argv[3]);
514*8542734aSAndroid Build Coastguard Worker } else if (!strcmp(argv[1], "disable") && argc >= 4) {
515*8542734aSAndroid Build Coastguard Worker status = mNetd->tetherRemoveForward(argv[2], argv[3]);
516*8542734aSAndroid Build Coastguard Worker } else {
517*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown nat cmd", false);
518*8542734aSAndroid Build Coastguard Worker return 0;
519*8542734aSAndroid Build Coastguard Worker }
520*8542734aSAndroid Build Coastguard Worker
521*8542734aSAndroid Build Coastguard Worker if (status.isOk()) {
522*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandOkay, "Nat operation succeeded", false);
523*8542734aSAndroid Build Coastguard Worker } else {
524*8542734aSAndroid Build Coastguard Worker errno = status.serviceSpecificErrorCode();
525*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::OperationFailed, "Nat operation failed", true);
526*8542734aSAndroid Build Coastguard Worker }
527*8542734aSAndroid Build Coastguard Worker
528*8542734aSAndroid Build Coastguard Worker return 0;
529*8542734aSAndroid Build Coastguard Worker }
530*8542734aSAndroid Build Coastguard Worker
BandwidthControlCmd()531*8542734aSAndroid Build Coastguard Worker NdcDispatcher::BandwidthControlCmd::BandwidthControlCmd() : NdcNetdCommand("bandwidth") {}
532*8542734aSAndroid Build Coastguard Worker
sendGenericSyntaxError(NdcClient * cli,const char * usageMsg) const533*8542734aSAndroid Build Coastguard Worker void NdcDispatcher::BandwidthControlCmd::sendGenericSyntaxError(NdcClient* cli,
534*8542734aSAndroid Build Coastguard Worker const char* usageMsg) const {
535*8542734aSAndroid Build Coastguard Worker char* msg;
536*8542734aSAndroid Build Coastguard Worker asprintf(&msg, "Usage: bandwidth %s", usageMsg);
537*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError, msg, false);
538*8542734aSAndroid Build Coastguard Worker free(msg);
539*8542734aSAndroid Build Coastguard Worker }
540*8542734aSAndroid Build Coastguard Worker
sendGenericOkFail(NdcClient * cli,int cond) const541*8542734aSAndroid Build Coastguard Worker void NdcDispatcher::BandwidthControlCmd::sendGenericOkFail(NdcClient* cli, int cond) const {
542*8542734aSAndroid Build Coastguard Worker if (!cond) {
543*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandOkay, "Bandwidth command succeeeded", false);
544*8542734aSAndroid Build Coastguard Worker } else {
545*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::OperationFailed, "Bandwidth command failed", false);
546*8542734aSAndroid Build Coastguard Worker }
547*8542734aSAndroid Build Coastguard Worker }
548*8542734aSAndroid Build Coastguard Worker
sendGenericOpFailed(NdcClient * cli,const char * errMsg) const549*8542734aSAndroid Build Coastguard Worker void NdcDispatcher::BandwidthControlCmd::sendGenericOpFailed(NdcClient* cli,
550*8542734aSAndroid Build Coastguard Worker const char* errMsg) const {
551*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::OperationFailed, errMsg, false);
552*8542734aSAndroid Build Coastguard Worker }
553*8542734aSAndroid Build Coastguard Worker
runCommand(NdcClient * cli,int argc,char ** argv) const554*8542734aSAndroid Build Coastguard Worker int NdcDispatcher::BandwidthControlCmd::runCommand(NdcClient* cli, int argc, char** argv) const {
555*8542734aSAndroid Build Coastguard Worker if (argc < 2) {
556*8542734aSAndroid Build Coastguard Worker sendGenericSyntaxError(cli, "<cmds> <args...>");
557*8542734aSAndroid Build Coastguard Worker return 0;
558*8542734aSAndroid Build Coastguard Worker }
559*8542734aSAndroid Build Coastguard Worker
560*8542734aSAndroid Build Coastguard Worker LOG(LOGLEVEL) << StringPrintf("bwctrlcmd: argc=%d %s %s ...", argc, argv[0], argv[1]).c_str();
561*8542734aSAndroid Build Coastguard Worker
562*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "removeiquota") || !strcmp(argv[1], "riq")) {
563*8542734aSAndroid Build Coastguard Worker if (argc != 3) {
564*8542734aSAndroid Build Coastguard Worker sendGenericSyntaxError(cli, "removeiquota <interface>");
565*8542734aSAndroid Build Coastguard Worker return 0;
566*8542734aSAndroid Build Coastguard Worker }
567*8542734aSAndroid Build Coastguard Worker int rc = !mNetd->bandwidthRemoveInterfaceQuota(argv[2]).isOk();
568*8542734aSAndroid Build Coastguard Worker sendGenericOkFail(cli, rc);
569*8542734aSAndroid Build Coastguard Worker return 0;
570*8542734aSAndroid Build Coastguard Worker }
571*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "setiquota") || !strcmp(argv[1], "siq")) {
572*8542734aSAndroid Build Coastguard Worker if (argc != 4) {
573*8542734aSAndroid Build Coastguard Worker sendGenericSyntaxError(cli, "setiquota <interface> <bytes>");
574*8542734aSAndroid Build Coastguard Worker return 0;
575*8542734aSAndroid Build Coastguard Worker }
576*8542734aSAndroid Build Coastguard Worker int64_t bytes = 0;
577*8542734aSAndroid Build Coastguard Worker PARSE_INT_RETURN_IF_FAIL(cli, argv[3], bytes, "Bandwidth command failed", false);
578*8542734aSAndroid Build Coastguard Worker int rc = !mNetd->bandwidthSetInterfaceQuota(argv[2], bytes).isOk();
579*8542734aSAndroid Build Coastguard Worker sendGenericOkFail(cli, rc);
580*8542734aSAndroid Build Coastguard Worker return 0;
581*8542734aSAndroid Build Coastguard Worker }
582*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "addnaughtyapps") || !strcmp(argv[1], "ana")) {
583*8542734aSAndroid Build Coastguard Worker if (argc < 3) {
584*8542734aSAndroid Build Coastguard Worker sendGenericSyntaxError(cli, "addnaughtyapps <appUid> ...");
585*8542734aSAndroid Build Coastguard Worker return 0;
586*8542734aSAndroid Build Coastguard Worker }
587*8542734aSAndroid Build Coastguard Worker int rc = 0;
588*8542734aSAndroid Build Coastguard Worker for (int arg_index = 2; arg_index < argc; arg_index++) {
589*8542734aSAndroid Build Coastguard Worker uid_t uid = 0;
590*8542734aSAndroid Build Coastguard Worker PARSE_UINT_RETURN_IF_FAIL(cli, argv[arg_index], uid, "Bandwidth command failed", false);
591*8542734aSAndroid Build Coastguard Worker rc = !mNetd->bandwidthAddNaughtyApp(uid).isOk();
592*8542734aSAndroid Build Coastguard Worker if (rc) break;
593*8542734aSAndroid Build Coastguard Worker }
594*8542734aSAndroid Build Coastguard Worker sendGenericOkFail(cli, rc);
595*8542734aSAndroid Build Coastguard Worker return 0;
596*8542734aSAndroid Build Coastguard Worker }
597*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "removenaughtyapps") || !strcmp(argv[1], "rna")) {
598*8542734aSAndroid Build Coastguard Worker if (argc < 3) {
599*8542734aSAndroid Build Coastguard Worker sendGenericSyntaxError(cli, "removenaughtyapps <appUid> ...");
600*8542734aSAndroid Build Coastguard Worker return 0;
601*8542734aSAndroid Build Coastguard Worker }
602*8542734aSAndroid Build Coastguard Worker int rc = 0;
603*8542734aSAndroid Build Coastguard Worker for (int arg_index = 2; arg_index < argc; arg_index++) {
604*8542734aSAndroid Build Coastguard Worker uid_t uid = 0;
605*8542734aSAndroid Build Coastguard Worker PARSE_UINT_RETURN_IF_FAIL(cli, argv[arg_index], uid, "Bandwidth command failed", false);
606*8542734aSAndroid Build Coastguard Worker rc = !mNetd->bandwidthRemoveNaughtyApp(uid).isOk();
607*8542734aSAndroid Build Coastguard Worker if (rc) break;
608*8542734aSAndroid Build Coastguard Worker }
609*8542734aSAndroid Build Coastguard Worker sendGenericOkFail(cli, rc);
610*8542734aSAndroid Build Coastguard Worker return 0;
611*8542734aSAndroid Build Coastguard Worker }
612*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "addniceapps") || !strcmp(argv[1], "aha")) {
613*8542734aSAndroid Build Coastguard Worker if (argc < 3) {
614*8542734aSAndroid Build Coastguard Worker sendGenericSyntaxError(cli, "addniceapps <appUid> ...");
615*8542734aSAndroid Build Coastguard Worker return 0;
616*8542734aSAndroid Build Coastguard Worker }
617*8542734aSAndroid Build Coastguard Worker int rc = 0;
618*8542734aSAndroid Build Coastguard Worker for (int arg_index = 2; arg_index < argc; arg_index++) {
619*8542734aSAndroid Build Coastguard Worker uid_t uid = 0;
620*8542734aSAndroid Build Coastguard Worker PARSE_UINT_RETURN_IF_FAIL(cli, argv[arg_index], uid, "Bandwidth command failed", false);
621*8542734aSAndroid Build Coastguard Worker rc = !mNetd->bandwidthAddNiceApp(uid).isOk();
622*8542734aSAndroid Build Coastguard Worker if (rc) break;
623*8542734aSAndroid Build Coastguard Worker }
624*8542734aSAndroid Build Coastguard Worker sendGenericOkFail(cli, rc);
625*8542734aSAndroid Build Coastguard Worker return 0;
626*8542734aSAndroid Build Coastguard Worker }
627*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "removeniceapps") || !strcmp(argv[1], "rha")) {
628*8542734aSAndroid Build Coastguard Worker if (argc < 3) {
629*8542734aSAndroid Build Coastguard Worker sendGenericSyntaxError(cli, "removeniceapps <appUid> ...");
630*8542734aSAndroid Build Coastguard Worker return 0;
631*8542734aSAndroid Build Coastguard Worker }
632*8542734aSAndroid Build Coastguard Worker int rc = 0;
633*8542734aSAndroid Build Coastguard Worker for (int arg_index = 2; arg_index < argc; arg_index++) {
634*8542734aSAndroid Build Coastguard Worker uid_t uid = 0;
635*8542734aSAndroid Build Coastguard Worker PARSE_UINT_RETURN_IF_FAIL(cli, argv[arg_index], uid, "Bandwidth command failed", false);
636*8542734aSAndroid Build Coastguard Worker rc = !mNetd->bandwidthRemoveNiceApp(uid).isOk();
637*8542734aSAndroid Build Coastguard Worker if (rc) break;
638*8542734aSAndroid Build Coastguard Worker }
639*8542734aSAndroid Build Coastguard Worker sendGenericOkFail(cli, rc);
640*8542734aSAndroid Build Coastguard Worker return 0;
641*8542734aSAndroid Build Coastguard Worker }
642*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "setglobalalert") || !strcmp(argv[1], "sga")) {
643*8542734aSAndroid Build Coastguard Worker if (argc != 3) {
644*8542734aSAndroid Build Coastguard Worker sendGenericSyntaxError(cli, "setglobalalert <bytes>");
645*8542734aSAndroid Build Coastguard Worker return 0;
646*8542734aSAndroid Build Coastguard Worker }
647*8542734aSAndroid Build Coastguard Worker int64_t bytes = 0;
648*8542734aSAndroid Build Coastguard Worker PARSE_INT_RETURN_IF_FAIL(cli, argv[2], bytes, "Bandwidth command failed", false);
649*8542734aSAndroid Build Coastguard Worker int rc = !mNetd->bandwidthSetGlobalAlert(bytes).isOk();
650*8542734aSAndroid Build Coastguard Worker sendGenericOkFail(cli, rc);
651*8542734aSAndroid Build Coastguard Worker return 0;
652*8542734aSAndroid Build Coastguard Worker }
653*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "setinterfacealert") || !strcmp(argv[1], "sia")) {
654*8542734aSAndroid Build Coastguard Worker if (argc != 4) {
655*8542734aSAndroid Build Coastguard Worker sendGenericSyntaxError(cli, "setinterfacealert <interface> <bytes>");
656*8542734aSAndroid Build Coastguard Worker return 0;
657*8542734aSAndroid Build Coastguard Worker }
658*8542734aSAndroid Build Coastguard Worker int64_t bytes = 0;
659*8542734aSAndroid Build Coastguard Worker PARSE_INT_RETURN_IF_FAIL(cli, argv[3], bytes, "Bandwidth command failed", false);
660*8542734aSAndroid Build Coastguard Worker int rc = !mNetd->bandwidthSetInterfaceAlert(argv[2], bytes).isOk();
661*8542734aSAndroid Build Coastguard Worker sendGenericOkFail(cli, rc);
662*8542734aSAndroid Build Coastguard Worker return 0;
663*8542734aSAndroid Build Coastguard Worker }
664*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "removeinterfacealert") || !strcmp(argv[1], "ria")) {
665*8542734aSAndroid Build Coastguard Worker if (argc != 3) {
666*8542734aSAndroid Build Coastguard Worker sendGenericSyntaxError(cli, "removeinterfacealert <interface>");
667*8542734aSAndroid Build Coastguard Worker return 0;
668*8542734aSAndroid Build Coastguard Worker }
669*8542734aSAndroid Build Coastguard Worker int rc = !mNetd->bandwidthRemoveInterfaceAlert(argv[2]).isOk();
670*8542734aSAndroid Build Coastguard Worker sendGenericOkFail(cli, rc);
671*8542734aSAndroid Build Coastguard Worker return 0;
672*8542734aSAndroid Build Coastguard Worker }
673*8542734aSAndroid Build Coastguard Worker
674*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown bandwidth cmd", false);
675*8542734aSAndroid Build Coastguard Worker return 0;
676*8542734aSAndroid Build Coastguard Worker }
677*8542734aSAndroid Build Coastguard Worker
IdletimerControlCmd()678*8542734aSAndroid Build Coastguard Worker NdcDispatcher::IdletimerControlCmd::IdletimerControlCmd() : NdcNetdCommand("idletimer") {}
679*8542734aSAndroid Build Coastguard Worker
runCommand(NdcClient * cli,int argc,char ** argv) const680*8542734aSAndroid Build Coastguard Worker int NdcDispatcher::IdletimerControlCmd::runCommand(NdcClient* cli, int argc, char** argv) const {
681*8542734aSAndroid Build Coastguard Worker // TODO(ashish): Change the error statements
682*8542734aSAndroid Build Coastguard Worker if (argc < 2) {
683*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
684*8542734aSAndroid Build Coastguard Worker return 0;
685*8542734aSAndroid Build Coastguard Worker }
686*8542734aSAndroid Build Coastguard Worker
687*8542734aSAndroid Build Coastguard Worker LOG(LOGLEVEL)
688*8542734aSAndroid Build Coastguard Worker << StringPrintf("idletimerctrlcmd: argc=%d %s %s ...", argc, argv[0], argv[1]).c_str();
689*8542734aSAndroid Build Coastguard Worker
690*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "add")) {
691*8542734aSAndroid Build Coastguard Worker if (argc != 5) {
692*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
693*8542734aSAndroid Build Coastguard Worker return 0;
694*8542734aSAndroid Build Coastguard Worker }
695*8542734aSAndroid Build Coastguard Worker
696*8542734aSAndroid Build Coastguard Worker int timeout = 0;
697*8542734aSAndroid Build Coastguard Worker PARSE_INT_RETURN_IF_FAIL(cli, argv[3], timeout, "Failed to add interface", false);
698*8542734aSAndroid Build Coastguard Worker Status status = mNetd->idletimerAddInterface(argv[2], timeout, argv[4]);
699*8542734aSAndroid Build Coastguard Worker if (!status.isOk()) {
700*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::OperationFailed, "Failed to add interface", false);
701*8542734aSAndroid Build Coastguard Worker } else {
702*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandOkay, "Add success", false);
703*8542734aSAndroid Build Coastguard Worker }
704*8542734aSAndroid Build Coastguard Worker return 0;
705*8542734aSAndroid Build Coastguard Worker }
706*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "remove")) {
707*8542734aSAndroid Build Coastguard Worker if (argc != 5) {
708*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
709*8542734aSAndroid Build Coastguard Worker return 0;
710*8542734aSAndroid Build Coastguard Worker }
711*8542734aSAndroid Build Coastguard Worker int timeout = 0;
712*8542734aSAndroid Build Coastguard Worker PARSE_INT_RETURN_IF_FAIL(cli, argv[3], timeout, "Failed to remove interface", false);
713*8542734aSAndroid Build Coastguard Worker Status status = mNetd->idletimerRemoveInterface(argv[2], timeout, argv[4]);
714*8542734aSAndroid Build Coastguard Worker if (!status.isOk()) {
715*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::OperationFailed, "Failed to remove interface", false);
716*8542734aSAndroid Build Coastguard Worker } else {
717*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandOkay, "Remove success", false);
718*8542734aSAndroid Build Coastguard Worker }
719*8542734aSAndroid Build Coastguard Worker return 0;
720*8542734aSAndroid Build Coastguard Worker }
721*8542734aSAndroid Build Coastguard Worker
722*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown idletimer cmd", false);
723*8542734aSAndroid Build Coastguard Worker return 0;
724*8542734aSAndroid Build Coastguard Worker }
725*8542734aSAndroid Build Coastguard Worker
FirewallCmd()726*8542734aSAndroid Build Coastguard Worker NdcDispatcher::FirewallCmd::FirewallCmd() : NdcNetdCommand("firewall") {}
727*8542734aSAndroid Build Coastguard Worker
sendGenericOkFail(NdcClient * cli,int cond) const728*8542734aSAndroid Build Coastguard Worker int NdcDispatcher::FirewallCmd::sendGenericOkFail(NdcClient* cli, int cond) const {
729*8542734aSAndroid Build Coastguard Worker if (!cond) {
730*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandOkay, "Firewall command succeeded", false);
731*8542734aSAndroid Build Coastguard Worker } else {
732*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::OperationFailed, "Firewall command failed", false);
733*8542734aSAndroid Build Coastguard Worker }
734*8542734aSAndroid Build Coastguard Worker return 0;
735*8542734aSAndroid Build Coastguard Worker }
736*8542734aSAndroid Build Coastguard Worker
parseRule(const char * arg)737*8542734aSAndroid Build Coastguard Worker int NdcDispatcher::FirewallCmd::parseRule(const char* arg) {
738*8542734aSAndroid Build Coastguard Worker if (!strcmp(arg, "allow")) {
739*8542734aSAndroid Build Coastguard Worker return INetd::FIREWALL_RULE_ALLOW;
740*8542734aSAndroid Build Coastguard Worker } else if (!strcmp(arg, "deny")) {
741*8542734aSAndroid Build Coastguard Worker return INetd::FIREWALL_RULE_DENY;
742*8542734aSAndroid Build Coastguard Worker } else {
743*8542734aSAndroid Build Coastguard Worker LOG(LOGLEVEL) << "failed to parse uid rule " << arg;
744*8542734aSAndroid Build Coastguard Worker return INetd::FIREWALL_RULE_ALLOW;
745*8542734aSAndroid Build Coastguard Worker }
746*8542734aSAndroid Build Coastguard Worker }
747*8542734aSAndroid Build Coastguard Worker
parseFirewallType(const char * arg)748*8542734aSAndroid Build Coastguard Worker int NdcDispatcher::FirewallCmd::parseFirewallType(const char* arg) {
749*8542734aSAndroid Build Coastguard Worker if (!strcmp(arg, "allowlist")) {
750*8542734aSAndroid Build Coastguard Worker return INetd::FIREWALL_ALLOWLIST;
751*8542734aSAndroid Build Coastguard Worker } else if (!strcmp(arg, "denylist")) {
752*8542734aSAndroid Build Coastguard Worker return INetd::FIREWALL_DENYLIST;
753*8542734aSAndroid Build Coastguard Worker } else {
754*8542734aSAndroid Build Coastguard Worker LOG(LOGLEVEL) << "failed to parse firewall type " << arg;
755*8542734aSAndroid Build Coastguard Worker return INetd::FIREWALL_DENYLIST;
756*8542734aSAndroid Build Coastguard Worker }
757*8542734aSAndroid Build Coastguard Worker }
758*8542734aSAndroid Build Coastguard Worker
parseChildChain(const char * arg)759*8542734aSAndroid Build Coastguard Worker int NdcDispatcher::FirewallCmd::parseChildChain(const char* arg) {
760*8542734aSAndroid Build Coastguard Worker if (!strcmp(arg, "dozable")) {
761*8542734aSAndroid Build Coastguard Worker return INetd::FIREWALL_CHAIN_DOZABLE;
762*8542734aSAndroid Build Coastguard Worker } else if (!strcmp(arg, "standby")) {
763*8542734aSAndroid Build Coastguard Worker return INetd::FIREWALL_CHAIN_STANDBY;
764*8542734aSAndroid Build Coastguard Worker } else if (!strcmp(arg, "powersave")) {
765*8542734aSAndroid Build Coastguard Worker return INetd::FIREWALL_CHAIN_POWERSAVE;
766*8542734aSAndroid Build Coastguard Worker } else if (!strcmp(arg, "restricted")) {
767*8542734aSAndroid Build Coastguard Worker return INetd::FIREWALL_CHAIN_RESTRICTED;
768*8542734aSAndroid Build Coastguard Worker } else if (!strcmp(arg, "none")) {
769*8542734aSAndroid Build Coastguard Worker return INetd::FIREWALL_CHAIN_NONE;
770*8542734aSAndroid Build Coastguard Worker } else {
771*8542734aSAndroid Build Coastguard Worker LOG(LOGLEVEL) << "failed to parse child firewall chain " << arg;
772*8542734aSAndroid Build Coastguard Worker return -1;
773*8542734aSAndroid Build Coastguard Worker }
774*8542734aSAndroid Build Coastguard Worker }
775*8542734aSAndroid Build Coastguard Worker
runCommand(NdcClient * cli,int argc,char ** argv) const776*8542734aSAndroid Build Coastguard Worker int NdcDispatcher::FirewallCmd::runCommand(NdcClient* cli, int argc, char** argv) const {
777*8542734aSAndroid Build Coastguard Worker if (argc < 2) {
778*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing command", false);
779*8542734aSAndroid Build Coastguard Worker return 0;
780*8542734aSAndroid Build Coastguard Worker }
781*8542734aSAndroid Build Coastguard Worker
782*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "enable")) {
783*8542734aSAndroid Build Coastguard Worker if (argc != 3) {
784*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError,
785*8542734aSAndroid Build Coastguard Worker "Usage: firewall enable <allowlist|denylist>", false);
786*8542734aSAndroid Build Coastguard Worker return 0;
787*8542734aSAndroid Build Coastguard Worker }
788*8542734aSAndroid Build Coastguard Worker int res = !mNetd->firewallSetFirewallType(parseFirewallType(argv[2])).isOk();
789*8542734aSAndroid Build Coastguard Worker return sendGenericOkFail(cli, res);
790*8542734aSAndroid Build Coastguard Worker }
791*8542734aSAndroid Build Coastguard Worker
792*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "set_interface_rule")) {
793*8542734aSAndroid Build Coastguard Worker if (argc != 4) {
794*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError,
795*8542734aSAndroid Build Coastguard Worker "Usage: firewall set_interface_rule <rmnet0> <allow|deny>", false);
796*8542734aSAndroid Build Coastguard Worker return 0;
797*8542734aSAndroid Build Coastguard Worker }
798*8542734aSAndroid Build Coastguard Worker int res = !mNetd->firewallSetInterfaceRule(argv[2], parseRule(argv[3])).isOk();
799*8542734aSAndroid Build Coastguard Worker return sendGenericOkFail(cli, res);
800*8542734aSAndroid Build Coastguard Worker }
801*8542734aSAndroid Build Coastguard Worker
802*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "set_uid_rule")) {
803*8542734aSAndroid Build Coastguard Worker if (argc != 5) {
804*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError,
805*8542734aSAndroid Build Coastguard Worker "Usage: firewall set_uid_rule <dozable|standby|none> <1000> <allow|deny>",
806*8542734aSAndroid Build Coastguard Worker false);
807*8542734aSAndroid Build Coastguard Worker return 0;
808*8542734aSAndroid Build Coastguard Worker }
809*8542734aSAndroid Build Coastguard Worker
810*8542734aSAndroid Build Coastguard Worker int childChain = parseChildChain(argv[2]);
811*8542734aSAndroid Build Coastguard Worker if (childChain == -1) {
812*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError,
813*8542734aSAndroid Build Coastguard Worker "Invalid chain name. Valid names are: <dozable|standby|none>", false);
814*8542734aSAndroid Build Coastguard Worker return 0;
815*8542734aSAndroid Build Coastguard Worker }
816*8542734aSAndroid Build Coastguard Worker uid_t uid = 0;
817*8542734aSAndroid Build Coastguard Worker PARSE_UINT_RETURN_IF_FAIL(cli, argv[3], uid, "Firewall command failed", false);
818*8542734aSAndroid Build Coastguard Worker int res = !mNetd->firewallSetUidRule(childChain, uid, parseRule(argv[4])).isOk();
819*8542734aSAndroid Build Coastguard Worker return sendGenericOkFail(cli, res);
820*8542734aSAndroid Build Coastguard Worker }
821*8542734aSAndroid Build Coastguard Worker
822*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "enable_chain")) {
823*8542734aSAndroid Build Coastguard Worker if (argc != 3) {
824*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError,
825*8542734aSAndroid Build Coastguard Worker "Usage: firewall enable_chain <dozable|standby>", false);
826*8542734aSAndroid Build Coastguard Worker return 0;
827*8542734aSAndroid Build Coastguard Worker }
828*8542734aSAndroid Build Coastguard Worker int res = !mNetd->firewallEnableChildChain(parseChildChain(argv[2]), true).isOk();
829*8542734aSAndroid Build Coastguard Worker return sendGenericOkFail(cli, res);
830*8542734aSAndroid Build Coastguard Worker }
831*8542734aSAndroid Build Coastguard Worker
832*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "disable_chain")) {
833*8542734aSAndroid Build Coastguard Worker if (argc != 3) {
834*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError,
835*8542734aSAndroid Build Coastguard Worker "Usage: firewall disable_chain <dozable|standby>", false);
836*8542734aSAndroid Build Coastguard Worker return 0;
837*8542734aSAndroid Build Coastguard Worker }
838*8542734aSAndroid Build Coastguard Worker int res = !mNetd->firewallEnableChildChain(parseChildChain(argv[2]), false).isOk();
839*8542734aSAndroid Build Coastguard Worker return sendGenericOkFail(cli, res);
840*8542734aSAndroid Build Coastguard Worker }
841*8542734aSAndroid Build Coastguard Worker
842*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown command", false);
843*8542734aSAndroid Build Coastguard Worker return 0;
844*8542734aSAndroid Build Coastguard Worker }
845*8542734aSAndroid Build Coastguard Worker
StrictCmd()846*8542734aSAndroid Build Coastguard Worker NdcDispatcher::StrictCmd::StrictCmd() : NdcNetdCommand("strict") {}
847*8542734aSAndroid Build Coastguard Worker
sendGenericOkFail(NdcClient * cli,int cond) const848*8542734aSAndroid Build Coastguard Worker int NdcDispatcher::StrictCmd::sendGenericOkFail(NdcClient* cli, int cond) const {
849*8542734aSAndroid Build Coastguard Worker if (!cond) {
850*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandOkay, "Strict command succeeded", false);
851*8542734aSAndroid Build Coastguard Worker } else {
852*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::OperationFailed, "Strict command failed", false);
853*8542734aSAndroid Build Coastguard Worker }
854*8542734aSAndroid Build Coastguard Worker return 0;
855*8542734aSAndroid Build Coastguard Worker }
856*8542734aSAndroid Build Coastguard Worker
parsePenalty(const char * arg)857*8542734aSAndroid Build Coastguard Worker int NdcDispatcher::StrictCmd::parsePenalty(const char* arg) {
858*8542734aSAndroid Build Coastguard Worker if (!strcmp(arg, "reject")) {
859*8542734aSAndroid Build Coastguard Worker return INetd::PENALTY_POLICY_REJECT;
860*8542734aSAndroid Build Coastguard Worker } else if (!strcmp(arg, "log")) {
861*8542734aSAndroid Build Coastguard Worker return INetd::PENALTY_POLICY_LOG;
862*8542734aSAndroid Build Coastguard Worker } else if (!strcmp(arg, "accept")) {
863*8542734aSAndroid Build Coastguard Worker return INetd::PENALTY_POLICY_ACCEPT;
864*8542734aSAndroid Build Coastguard Worker } else {
865*8542734aSAndroid Build Coastguard Worker return -1;
866*8542734aSAndroid Build Coastguard Worker }
867*8542734aSAndroid Build Coastguard Worker }
868*8542734aSAndroid Build Coastguard Worker
runCommand(NdcClient * cli,int argc,char ** argv) const869*8542734aSAndroid Build Coastguard Worker int NdcDispatcher::StrictCmd::runCommand(NdcClient* cli, int argc, char** argv) const {
870*8542734aSAndroid Build Coastguard Worker if (argc < 2) {
871*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing command", false);
872*8542734aSAndroid Build Coastguard Worker return 0;
873*8542734aSAndroid Build Coastguard Worker }
874*8542734aSAndroid Build Coastguard Worker
875*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "set_uid_cleartext_policy")) {
876*8542734aSAndroid Build Coastguard Worker if (argc != 4) {
877*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError,
878*8542734aSAndroid Build Coastguard Worker "Usage: strict set_uid_cleartext_policy <uid> <accept|log|reject>", false);
879*8542734aSAndroid Build Coastguard Worker return 0;
880*8542734aSAndroid Build Coastguard Worker }
881*8542734aSAndroid Build Coastguard Worker
882*8542734aSAndroid Build Coastguard Worker errno = 0;
883*8542734aSAndroid Build Coastguard Worker uid_t uid = 0;
884*8542734aSAndroid Build Coastguard Worker PARSE_UINT_RETURN_IF_FAIL(cli, argv[2], uid, "Invalid UID", false);
885*8542734aSAndroid Build Coastguard Worker if (uid > UID_MAX) {
886*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError, "Invalid UID", false);
887*8542734aSAndroid Build Coastguard Worker return 0;
888*8542734aSAndroid Build Coastguard Worker }
889*8542734aSAndroid Build Coastguard Worker
890*8542734aSAndroid Build Coastguard Worker int penalty = parsePenalty(argv[3]);
891*8542734aSAndroid Build Coastguard Worker if (penalty == -1) {
892*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError, "Invalid penalty argument", false);
893*8542734aSAndroid Build Coastguard Worker return 0;
894*8542734aSAndroid Build Coastguard Worker }
895*8542734aSAndroid Build Coastguard Worker
896*8542734aSAndroid Build Coastguard Worker int res = !mNetd->strictUidCleartextPenalty(uid, penalty).isOk();
897*8542734aSAndroid Build Coastguard Worker return sendGenericOkFail(cli, res);
898*8542734aSAndroid Build Coastguard Worker }
899*8542734aSAndroid Build Coastguard Worker
900*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown command", false);
901*8542734aSAndroid Build Coastguard Worker return 0;
902*8542734aSAndroid Build Coastguard Worker }
903*8542734aSAndroid Build Coastguard Worker
NetworkCommand()904*8542734aSAndroid Build Coastguard Worker NdcDispatcher::NetworkCommand::NetworkCommand() : NdcNetdCommand("network") {}
905*8542734aSAndroid Build Coastguard Worker
syntaxError(NdcClient * cli,const char * message) const906*8542734aSAndroid Build Coastguard Worker int NdcDispatcher::NetworkCommand::syntaxError(NdcClient* cli, const char* message) const {
907*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandSyntaxError, message, false);
908*8542734aSAndroid Build Coastguard Worker return 0;
909*8542734aSAndroid Build Coastguard Worker }
910*8542734aSAndroid Build Coastguard Worker
operationError(NdcClient * cli,const char * message,int ret) const911*8542734aSAndroid Build Coastguard Worker int NdcDispatcher::NetworkCommand::operationError(NdcClient* cli, const char* message,
912*8542734aSAndroid Build Coastguard Worker int ret) const {
913*8542734aSAndroid Build Coastguard Worker errno = ret;
914*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::OperationFailed, message, true);
915*8542734aSAndroid Build Coastguard Worker return 0;
916*8542734aSAndroid Build Coastguard Worker }
917*8542734aSAndroid Build Coastguard Worker
success(NdcClient * cli) const918*8542734aSAndroid Build Coastguard Worker int NdcDispatcher::NetworkCommand::success(NdcClient* cli) const {
919*8542734aSAndroid Build Coastguard Worker cli->sendMsg(ResponseCode::CommandOkay, "success", false);
920*8542734aSAndroid Build Coastguard Worker return 0;
921*8542734aSAndroid Build Coastguard Worker }
922*8542734aSAndroid Build Coastguard Worker
runCommand(NdcClient * cli,int argc,char ** argv) const923*8542734aSAndroid Build Coastguard Worker int NdcDispatcher::NetworkCommand::runCommand(NdcClient* cli, int argc, char** argv) const {
924*8542734aSAndroid Build Coastguard Worker if (argc < 2) {
925*8542734aSAndroid Build Coastguard Worker return syntaxError(cli, "Missing argument");
926*8542734aSAndroid Build Coastguard Worker }
927*8542734aSAndroid Build Coastguard Worker
928*8542734aSAndroid Build Coastguard Worker // 0 1 2 3 4 5 6 7 8
929*8542734aSAndroid Build Coastguard Worker // network route [legacy <uid>] add <netId> <interface> <destination> [nexthop]
930*8542734aSAndroid Build Coastguard Worker // network route [legacy <uid>] remove <netId> <interface> <destination> [nexthop]
931*8542734aSAndroid Build Coastguard Worker //
932*8542734aSAndroid Build Coastguard Worker // nexthop may be either an IPv4/IPv6 address or one of "unreachable" or "throw".
933*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "route")) {
934*8542734aSAndroid Build Coastguard Worker if (argc < 6 || argc > 9) {
935*8542734aSAndroid Build Coastguard Worker return syntaxError(cli, "Incorrect number of arguments");
936*8542734aSAndroid Build Coastguard Worker }
937*8542734aSAndroid Build Coastguard Worker
938*8542734aSAndroid Build Coastguard Worker int nextArg = 2;
939*8542734aSAndroid Build Coastguard Worker bool legacy = false;
940*8542734aSAndroid Build Coastguard Worker uid_t uid = 0;
941*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[nextArg], "legacy")) {
942*8542734aSAndroid Build Coastguard Worker ++nextArg;
943*8542734aSAndroid Build Coastguard Worker legacy = true;
944*8542734aSAndroid Build Coastguard Worker PARSE_UINT_RETURN_IF_FAIL(cli, argv[nextArg++], uid, "Unknown argument", false);
945*8542734aSAndroid Build Coastguard Worker }
946*8542734aSAndroid Build Coastguard Worker
947*8542734aSAndroid Build Coastguard Worker bool add = false;
948*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[nextArg], "add")) {
949*8542734aSAndroid Build Coastguard Worker add = true;
950*8542734aSAndroid Build Coastguard Worker } else if (strcmp(argv[nextArg], "remove") != 0) {
951*8542734aSAndroid Build Coastguard Worker return syntaxError(cli, "Unknown argument");
952*8542734aSAndroid Build Coastguard Worker }
953*8542734aSAndroid Build Coastguard Worker ++nextArg;
954*8542734aSAndroid Build Coastguard Worker
955*8542734aSAndroid Build Coastguard Worker if (argc < nextArg + 3 || argc > nextArg + 4) {
956*8542734aSAndroid Build Coastguard Worker return syntaxError(cli, "Incorrect number of arguments");
957*8542734aSAndroid Build Coastguard Worker }
958*8542734aSAndroid Build Coastguard Worker
959*8542734aSAndroid Build Coastguard Worker unsigned netId = stringToNetId(argv[nextArg++]);
960*8542734aSAndroid Build Coastguard Worker const char* interface = argv[nextArg++];
961*8542734aSAndroid Build Coastguard Worker const char* destination = argv[nextArg++];
962*8542734aSAndroid Build Coastguard Worker const char* nexthop = argc > nextArg ? argv[nextArg] : "";
963*8542734aSAndroid Build Coastguard Worker
964*8542734aSAndroid Build Coastguard Worker Status status;
965*8542734aSAndroid Build Coastguard Worker if (legacy) {
966*8542734aSAndroid Build Coastguard Worker status = add ? mNetd->networkAddLegacyRoute(netId, interface, destination, nexthop, uid)
967*8542734aSAndroid Build Coastguard Worker
968*8542734aSAndroid Build Coastguard Worker : mNetd->networkRemoveLegacyRoute(netId, interface, destination, nexthop,
969*8542734aSAndroid Build Coastguard Worker uid);
970*8542734aSAndroid Build Coastguard Worker } else {
971*8542734aSAndroid Build Coastguard Worker status = add ? mNetd->networkAddRoute(netId, interface, destination, nexthop)
972*8542734aSAndroid Build Coastguard Worker : mNetd->networkRemoveRoute(netId, interface, destination, nexthop);
973*8542734aSAndroid Build Coastguard Worker }
974*8542734aSAndroid Build Coastguard Worker
975*8542734aSAndroid Build Coastguard Worker if (!status.isOk()) {
976*8542734aSAndroid Build Coastguard Worker return operationError(cli, add ? "addRoute() failed" : "removeRoute() failed",
977*8542734aSAndroid Build Coastguard Worker status.serviceSpecificErrorCode());
978*8542734aSAndroid Build Coastguard Worker }
979*8542734aSAndroid Build Coastguard Worker
980*8542734aSAndroid Build Coastguard Worker return success(cli);
981*8542734aSAndroid Build Coastguard Worker }
982*8542734aSAndroid Build Coastguard Worker
983*8542734aSAndroid Build Coastguard Worker // 0 1 2 3 4
984*8542734aSAndroid Build Coastguard Worker // network interface add <netId> <interface>
985*8542734aSAndroid Build Coastguard Worker // network interface remove <netId> <interface>
986*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "interface")) {
987*8542734aSAndroid Build Coastguard Worker if (argc != 5) {
988*8542734aSAndroid Build Coastguard Worker return syntaxError(cli, "Missing argument");
989*8542734aSAndroid Build Coastguard Worker }
990*8542734aSAndroid Build Coastguard Worker unsigned netId = stringToNetId(argv[3]);
991*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[2], "add")) {
992*8542734aSAndroid Build Coastguard Worker if (Status status = mNetd->networkAddInterface(netId, argv[4]); !status.isOk()) {
993*8542734aSAndroid Build Coastguard Worker return operationError(cli, "addInterfaceToNetwork() failed",
994*8542734aSAndroid Build Coastguard Worker status.serviceSpecificErrorCode());
995*8542734aSAndroid Build Coastguard Worker }
996*8542734aSAndroid Build Coastguard Worker } else if (!strcmp(argv[2], "remove")) {
997*8542734aSAndroid Build Coastguard Worker if (Status status = mNetd->networkRemoveInterface(netId, argv[4]); !status.isOk()) {
998*8542734aSAndroid Build Coastguard Worker return operationError(cli, "removeInterfaceFromNetwork() failed",
999*8542734aSAndroid Build Coastguard Worker status.serviceSpecificErrorCode());
1000*8542734aSAndroid Build Coastguard Worker }
1001*8542734aSAndroid Build Coastguard Worker } else {
1002*8542734aSAndroid Build Coastguard Worker return syntaxError(cli, "Unknown argument");
1003*8542734aSAndroid Build Coastguard Worker }
1004*8542734aSAndroid Build Coastguard Worker return success(cli);
1005*8542734aSAndroid Build Coastguard Worker }
1006*8542734aSAndroid Build Coastguard Worker
1007*8542734aSAndroid Build Coastguard Worker // 0 1 2 3
1008*8542734aSAndroid Build Coastguard Worker // network create <netId> [permission]
1009*8542734aSAndroid Build Coastguard Worker //
1010*8542734aSAndroid Build Coastguard Worker // 0 1 2 3 4
1011*8542734aSAndroid Build Coastguard Worker // network create <netId> vpn <secure>
1012*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "create")) {
1013*8542734aSAndroid Build Coastguard Worker if (argc < 3) {
1014*8542734aSAndroid Build Coastguard Worker return syntaxError(cli, "Missing argument");
1015*8542734aSAndroid Build Coastguard Worker }
1016*8542734aSAndroid Build Coastguard Worker unsigned netId = stringToNetId(argv[2]);
1017*8542734aSAndroid Build Coastguard Worker if (argc == 5 && !strcmp(argv[3], "vpn")) {
1018*8542734aSAndroid Build Coastguard Worker bool secure = strtol(argv[4], nullptr, 2);
1019*8542734aSAndroid Build Coastguard Worker #pragma clang diagnostic push
1020*8542734aSAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Wdeprecated-declarations"
1021*8542734aSAndroid Build Coastguard Worker if (Status status = mNetd->networkCreateVpn(netId, secure); !status.isOk()) {
1022*8542734aSAndroid Build Coastguard Worker #pragma clang diagnostic pop
1023*8542734aSAndroid Build Coastguard Worker return operationError(cli, "createVirtualNetwork() failed",
1024*8542734aSAndroid Build Coastguard Worker status.serviceSpecificErrorCode());
1025*8542734aSAndroid Build Coastguard Worker }
1026*8542734aSAndroid Build Coastguard Worker } else if (argc > 4) {
1027*8542734aSAndroid Build Coastguard Worker return syntaxError(cli, "Unknown trailing argument(s)");
1028*8542734aSAndroid Build Coastguard Worker } else {
1029*8542734aSAndroid Build Coastguard Worker int permission = INetd::PERMISSION_NONE;
1030*8542734aSAndroid Build Coastguard Worker if (argc == 4) {
1031*8542734aSAndroid Build Coastguard Worker permission = stringToINetdPermission(argv[3]);
1032*8542734aSAndroid Build Coastguard Worker if (permission == INetd::PERMISSION_NONE) {
1033*8542734aSAndroid Build Coastguard Worker return syntaxError(cli, "Unknown permission");
1034*8542734aSAndroid Build Coastguard Worker }
1035*8542734aSAndroid Build Coastguard Worker }
1036*8542734aSAndroid Build Coastguard Worker #pragma clang diagnostic push
1037*8542734aSAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Wdeprecated-declarations"
1038*8542734aSAndroid Build Coastguard Worker if (Status status = mNetd->networkCreatePhysical(netId, permission); !status.isOk()) {
1039*8542734aSAndroid Build Coastguard Worker #pragma clang diagnostic pop
1040*8542734aSAndroid Build Coastguard Worker return operationError(cli, "createPhysicalNetwork() failed",
1041*8542734aSAndroid Build Coastguard Worker status.serviceSpecificErrorCode());
1042*8542734aSAndroid Build Coastguard Worker }
1043*8542734aSAndroid Build Coastguard Worker }
1044*8542734aSAndroid Build Coastguard Worker return success(cli);
1045*8542734aSAndroid Build Coastguard Worker }
1046*8542734aSAndroid Build Coastguard Worker
1047*8542734aSAndroid Build Coastguard Worker // 0 1 2
1048*8542734aSAndroid Build Coastguard Worker // network destroy <netId>
1049*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "destroy")) {
1050*8542734aSAndroid Build Coastguard Worker if (argc != 3) {
1051*8542734aSAndroid Build Coastguard Worker return syntaxError(cli, "Incorrect number of arguments");
1052*8542734aSAndroid Build Coastguard Worker }
1053*8542734aSAndroid Build Coastguard Worker unsigned netId = stringToNetId(argv[2]);
1054*8542734aSAndroid Build Coastguard Worker // Both of these functions manage their own locking internally.
1055*8542734aSAndroid Build Coastguard Worker if (Status status = mNetd->networkDestroy(netId); !status.isOk()) {
1056*8542734aSAndroid Build Coastguard Worker return operationError(cli, "destroyNetwork() failed",
1057*8542734aSAndroid Build Coastguard Worker status.serviceSpecificErrorCode());
1058*8542734aSAndroid Build Coastguard Worker }
1059*8542734aSAndroid Build Coastguard Worker mDnsResolver->destroyNetworkCache(netId);
1060*8542734aSAndroid Build Coastguard Worker return success(cli);
1061*8542734aSAndroid Build Coastguard Worker }
1062*8542734aSAndroid Build Coastguard Worker
1063*8542734aSAndroid Build Coastguard Worker // 0 1 2 3
1064*8542734aSAndroid Build Coastguard Worker // network default set <netId>
1065*8542734aSAndroid Build Coastguard Worker // network default clear
1066*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "default")) {
1067*8542734aSAndroid Build Coastguard Worker if (argc < 3) {
1068*8542734aSAndroid Build Coastguard Worker return syntaxError(cli, "Missing argument");
1069*8542734aSAndroid Build Coastguard Worker }
1070*8542734aSAndroid Build Coastguard Worker unsigned netId = NETID_UNSET;
1071*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[2], "set")) {
1072*8542734aSAndroid Build Coastguard Worker if (argc < 4) {
1073*8542734aSAndroid Build Coastguard Worker return syntaxError(cli, "Missing netId");
1074*8542734aSAndroid Build Coastguard Worker }
1075*8542734aSAndroid Build Coastguard Worker netId = stringToNetId(argv[3]);
1076*8542734aSAndroid Build Coastguard Worker } else if (strcmp(argv[2], "clear") != 0) {
1077*8542734aSAndroid Build Coastguard Worker return syntaxError(cli, "Unknown argument");
1078*8542734aSAndroid Build Coastguard Worker }
1079*8542734aSAndroid Build Coastguard Worker if (Status status = mNetd->networkSetDefault(netId); !status.isOk()) {
1080*8542734aSAndroid Build Coastguard Worker return operationError(cli, "setDefaultNetwork() failed",
1081*8542734aSAndroid Build Coastguard Worker status.serviceSpecificErrorCode());
1082*8542734aSAndroid Build Coastguard Worker }
1083*8542734aSAndroid Build Coastguard Worker return success(cli);
1084*8542734aSAndroid Build Coastguard Worker }
1085*8542734aSAndroid Build Coastguard Worker
1086*8542734aSAndroid Build Coastguard Worker // 0 1 2 3 4 5
1087*8542734aSAndroid Build Coastguard Worker // network permission user set <permission> <uid> ...
1088*8542734aSAndroid Build Coastguard Worker // network permission user clear <uid> ...
1089*8542734aSAndroid Build Coastguard Worker // network permission network set <permission> <netId> ...
1090*8542734aSAndroid Build Coastguard Worker // network permission network clear <netId> ...
1091*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "permission")) {
1092*8542734aSAndroid Build Coastguard Worker if (argc < 5) {
1093*8542734aSAndroid Build Coastguard Worker return syntaxError(cli, "Missing argument");
1094*8542734aSAndroid Build Coastguard Worker }
1095*8542734aSAndroid Build Coastguard Worker int nextArg = 4;
1096*8542734aSAndroid Build Coastguard Worker int permission = INetd::PERMISSION_NONE;
1097*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[3], "set")) {
1098*8542734aSAndroid Build Coastguard Worker permission = stringToINetdPermission(argv[4]);
1099*8542734aSAndroid Build Coastguard Worker if (permission == INetd::PERMISSION_NONE) {
1100*8542734aSAndroid Build Coastguard Worker return syntaxError(cli, "Unknown permission");
1101*8542734aSAndroid Build Coastguard Worker }
1102*8542734aSAndroid Build Coastguard Worker nextArg = 5;
1103*8542734aSAndroid Build Coastguard Worker } else if (strcmp(argv[3], "clear") != 0) {
1104*8542734aSAndroid Build Coastguard Worker return syntaxError(cli, "Unknown argument");
1105*8542734aSAndroid Build Coastguard Worker }
1106*8542734aSAndroid Build Coastguard Worker if (nextArg == argc) {
1107*8542734aSAndroid Build Coastguard Worker return syntaxError(cli, "Missing id");
1108*8542734aSAndroid Build Coastguard Worker }
1109*8542734aSAndroid Build Coastguard Worker
1110*8542734aSAndroid Build Coastguard Worker bool userPermissions = !strcmp(argv[2], "user");
1111*8542734aSAndroid Build Coastguard Worker bool networkPermissions = !strcmp(argv[2], "network");
1112*8542734aSAndroid Build Coastguard Worker if (!userPermissions && !networkPermissions) {
1113*8542734aSAndroid Build Coastguard Worker return syntaxError(cli, "Unknown argument");
1114*8542734aSAndroid Build Coastguard Worker }
1115*8542734aSAndroid Build Coastguard Worker
1116*8542734aSAndroid Build Coastguard Worker std::vector<int32_t> ids;
1117*8542734aSAndroid Build Coastguard Worker for (; nextArg < argc; ++nextArg) {
1118*8542734aSAndroid Build Coastguard Worker if (userPermissions) {
1119*8542734aSAndroid Build Coastguard Worker char* endPtr;
1120*8542734aSAndroid Build Coastguard Worker unsigned id = strtoul(argv[nextArg], &endPtr, 0);
1121*8542734aSAndroid Build Coastguard Worker if (!*argv[nextArg] || *endPtr) {
1122*8542734aSAndroid Build Coastguard Worker return syntaxError(cli, "Invalid id");
1123*8542734aSAndroid Build Coastguard Worker }
1124*8542734aSAndroid Build Coastguard Worker ids.push_back(id);
1125*8542734aSAndroid Build Coastguard Worker } else {
1126*8542734aSAndroid Build Coastguard Worker // networkPermissions
1127*8542734aSAndroid Build Coastguard Worker ids.push_back(stringToNetId(argv[nextArg]));
1128*8542734aSAndroid Build Coastguard Worker }
1129*8542734aSAndroid Build Coastguard Worker }
1130*8542734aSAndroid Build Coastguard Worker if (userPermissions) {
1131*8542734aSAndroid Build Coastguard Worker mNetd->networkSetPermissionForUser(permission, ids);
1132*8542734aSAndroid Build Coastguard Worker } else {
1133*8542734aSAndroid Build Coastguard Worker // networkPermissions
1134*8542734aSAndroid Build Coastguard Worker for (auto netId : ids) {
1135*8542734aSAndroid Build Coastguard Worker Status status = mNetd->networkSetPermissionForNetwork(netId, permission);
1136*8542734aSAndroid Build Coastguard Worker if (!status.isOk())
1137*8542734aSAndroid Build Coastguard Worker return operationError(cli, "setPermissionForNetworks() failed",
1138*8542734aSAndroid Build Coastguard Worker status.serviceSpecificErrorCode());
1139*8542734aSAndroid Build Coastguard Worker }
1140*8542734aSAndroid Build Coastguard Worker }
1141*8542734aSAndroid Build Coastguard Worker
1142*8542734aSAndroid Build Coastguard Worker return success(cli);
1143*8542734aSAndroid Build Coastguard Worker }
1144*8542734aSAndroid Build Coastguard Worker
1145*8542734aSAndroid Build Coastguard Worker // 0 1 2 3 4
1146*8542734aSAndroid Build Coastguard Worker // network users add <netId> [<uid>[-<uid>]] ...
1147*8542734aSAndroid Build Coastguard Worker // network users remove <netId> [<uid>[-<uid>]] ...
1148*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "users")) {
1149*8542734aSAndroid Build Coastguard Worker if (argc < 4) {
1150*8542734aSAndroid Build Coastguard Worker return syntaxError(cli, "Missing argument");
1151*8542734aSAndroid Build Coastguard Worker }
1152*8542734aSAndroid Build Coastguard Worker unsigned netId = stringToNetId(argv[3]);
1153*8542734aSAndroid Build Coastguard Worker UidRanges uidRanges;
1154*8542734aSAndroid Build Coastguard Worker if (!uidRanges.parseFrom(argc - 4, argv + 4)) {
1155*8542734aSAndroid Build Coastguard Worker return syntaxError(cli, "Invalid UIDs");
1156*8542734aSAndroid Build Coastguard Worker }
1157*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[2], "add")) {
1158*8542734aSAndroid Build Coastguard Worker if (Status status = mNetd->networkAddUidRanges(netId, uidRanges.getRanges());
1159*8542734aSAndroid Build Coastguard Worker !status.isOk()) {
1160*8542734aSAndroid Build Coastguard Worker return operationError(cli, "addUsersToNetwork() failed",
1161*8542734aSAndroid Build Coastguard Worker status.serviceSpecificErrorCode());
1162*8542734aSAndroid Build Coastguard Worker }
1163*8542734aSAndroid Build Coastguard Worker } else if (!strcmp(argv[2], "remove")) {
1164*8542734aSAndroid Build Coastguard Worker if (Status status = mNetd->networkRemoveUidRanges(netId, uidRanges.getRanges());
1165*8542734aSAndroid Build Coastguard Worker !status.isOk()) {
1166*8542734aSAndroid Build Coastguard Worker return operationError(cli, "removeUsersFromNetwork() failed",
1167*8542734aSAndroid Build Coastguard Worker status.serviceSpecificErrorCode());
1168*8542734aSAndroid Build Coastguard Worker }
1169*8542734aSAndroid Build Coastguard Worker } else {
1170*8542734aSAndroid Build Coastguard Worker return syntaxError(cli, "Unknown argument");
1171*8542734aSAndroid Build Coastguard Worker }
1172*8542734aSAndroid Build Coastguard Worker return success(cli);
1173*8542734aSAndroid Build Coastguard Worker }
1174*8542734aSAndroid Build Coastguard Worker
1175*8542734aSAndroid Build Coastguard Worker // 0 1 2 3
1176*8542734aSAndroid Build Coastguard Worker // network protect allow <uid> ...
1177*8542734aSAndroid Build Coastguard Worker // network protect deny <uid> ...
1178*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[1], "protect")) {
1179*8542734aSAndroid Build Coastguard Worker if (argc < 4) {
1180*8542734aSAndroid Build Coastguard Worker return syntaxError(cli, "Missing argument");
1181*8542734aSAndroid Build Coastguard Worker }
1182*8542734aSAndroid Build Coastguard Worker std::vector<uid_t> uids;
1183*8542734aSAndroid Build Coastguard Worker for (int i = 3; i < argc; ++i) {
1184*8542734aSAndroid Build Coastguard Worker uid_t uid = 0;
1185*8542734aSAndroid Build Coastguard Worker PARSE_UINT_RETURN_IF_FAIL(cli, argv[i], uid, "Unknown argument", false);
1186*8542734aSAndroid Build Coastguard Worker uids.push_back(uid);
1187*8542734aSAndroid Build Coastguard Worker }
1188*8542734aSAndroid Build Coastguard Worker if (!strcmp(argv[2], "allow")) {
1189*8542734aSAndroid Build Coastguard Worker for (auto uid : uids) {
1190*8542734aSAndroid Build Coastguard Worker mNetd->networkSetProtectAllow(uid);
1191*8542734aSAndroid Build Coastguard Worker }
1192*8542734aSAndroid Build Coastguard Worker } else if (!strcmp(argv[2], "deny")) {
1193*8542734aSAndroid Build Coastguard Worker for (auto uid : uids) {
1194*8542734aSAndroid Build Coastguard Worker mNetd->networkSetProtectDeny(uid);
1195*8542734aSAndroid Build Coastguard Worker }
1196*8542734aSAndroid Build Coastguard Worker } else {
1197*8542734aSAndroid Build Coastguard Worker return syntaxError(cli, "Unknown argument");
1198*8542734aSAndroid Build Coastguard Worker }
1199*8542734aSAndroid Build Coastguard Worker return success(cli);
1200*8542734aSAndroid Build Coastguard Worker }
1201*8542734aSAndroid Build Coastguard Worker
1202*8542734aSAndroid Build Coastguard Worker return syntaxError(cli, "Unknown argument");
1203*8542734aSAndroid Build Coastguard Worker }
1204*8542734aSAndroid Build Coastguard Worker
1205*8542734aSAndroid Build Coastguard Worker } // namespace net
1206*8542734aSAndroid Build Coastguard Worker } // namespace android
1207