NdcDispatcher.cpp 46 KB

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