NetUtilsWrapper-1.0.cpp revision 2dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0
19b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil/* 29b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil * Copyright (C) 2017 The Android Open Source Project 39b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil * 49b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil * Licensed under the Apache License, Version 2.0 (the "License"); 59b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil * you may not use this file except in compliance with the License. 69b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil * You may obtain a copy of the License at 79b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil * 89b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil * http://www.apache.org/licenses/LICENSE-2.0 99b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil * 109b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil * Unless required by applicable law or agreed to in writing, software 119b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil * distributed under the License is distributed on an "AS IS" BASIS, 129b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil * See the License for the specific language governing permissions and 149b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil * limitations under the License. 159b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil */ 169b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil 172dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti#include <regex> 182dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti#include <string> 192dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti 209b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil#include <libgen.h> 219b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil#include <stdio.h> 229b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil#include <stdlib.h> 239b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil#include <string.h> 249b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil#include <unistd.h> 259b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil 262dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti#include <android-base/strings.h> 272dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti 282dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti#define LOG_TAG "NetUtilsWrapper" 292dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti#include <cutils/log.h> 302dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti 312dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti#include "NetUtilsWrapper.h" 322dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti 339b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil#define SYSTEM_DIRNAME "/system/bin/" 349b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil 352dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti#define OEM_IFACE "[^ ]*oem[0-9]+" 362dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti#define RMNET_IFACE "(r_)?rmnet_(data)?[0-9]+" 372dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti#define VENDOR_IFACE "(" OEM_IFACE "|" RMNET_IFACE ")" 382dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti#define VENDOR_CHAIN "(oem_.*|nm_.*|qcom_.*)" 392dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti 409b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil// List of net utils wrapped by this program 419b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil// The list MUST be in descending order of string length 429b9e9770dbac53fec5afab127af38067adab2952Sandeep Patilconst char *netcmds[] = { 439b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil "ip6tables", 449b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil "iptables", 459b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil "ndc", 469b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil "tc", 479b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil "ip", 489b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil NULL, 499b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil}; 509b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil 512dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti// List of regular expressions of expected commands. 522dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitticonst char *EXPECTED_REGEXPS[] = { 532dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti#define CMD "^" SYSTEM_DIRNAME 542dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti // Create, delete, and manage OEM networks. 552dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti CMD "ndc network (create|destroy) oem[0-9]+( |$)", 562dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti CMD "ndc network interface (add|remove) oem[0-9]+ " VENDOR_IFACE, 572dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti CMD "ndc network route (add|remove) oem[0-9]+ ", 582dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti CMD "ndc ipfwd (enable|disable) ", 592dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti CMD "ndc ipfwd (add|remove) .*" VENDOR_IFACE, 602dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti 612dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti // Manage vendor iptables rules. 622dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti CMD "ip(6)?tables -w.* (-A|-D|-F|-I|-N|-X) " VENDOR_CHAIN, 632dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti CMD "ip(6)?tables -w.* (-i|-o) " VENDOR_IFACE, 642dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti 652dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti // Manage IPsec state. 662dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti CMD "ip xfrm .*", 672dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti 682dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti // Manage vendor interfaces. 692dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti CMD "tc .* dev " VENDOR_IFACE, 702dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti CMD "ip( -4| -6)? (addr|address) (add|del|delete|flush).* dev " VENDOR_IFACE, 712dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti 722dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti // Other activities observed on current devices. In future releases, these should be supported 732dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti // in a way that is less likely to interfere with general Android networking behaviour. 742dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti CMD "tc qdisc del dev root", 752dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti CMD "ip( -4| -6)? rule .* goto 13000 prio 11999", 762dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti CMD "ip( -4| -6)? rule .* prio 25000", 772dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti CMD "ip(6)?tables -w .* -j " VENDOR_CHAIN, 782dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti CMD "iptables -w -t mangle -[AD] PREROUTING -m socket --nowildcard --restore-skmark -j ACCEPT", 792dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti CMD "ndc network interface (add|remove) oem[0-9]+$", // Invalid command: no interface removed. 802dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti#undef CMD 812dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti}; 822dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti 832dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colittibool checkExpectedCommand(int argc, char **argv) { 842dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti std::vector<const char*> allArgs(argc); 852dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti for (int i = 0; i < argc; i++) { 862dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti allArgs[i] = argv[i]; 872dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti } 882dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti std::string fullCmd = android::base::Join(allArgs, ' '); 892dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti for (size_t i = 0; i < ARRAY_SIZE(EXPECTED_REGEXPS); i++) { 902dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti const std::regex expectedRegexp(EXPECTED_REGEXPS[i], std::regex_constants::extended); 912dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti if (std::regex_search(fullCmd, expectedRegexp)) { 922dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti return true; 932dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti } 942dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti } 952dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti ALOGI("Unexpected command: %s", fullCmd.c_str()); 962dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti return false; 972dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti} 982dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti 992dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti 1009b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil// This is the only gateway for vendor programs to reach net utils. 1012dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colittiint doMain(int argc, char **argv) { 1029b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil char *progname = argv[0]; 1039b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil char *basename = NULL; 1049b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil 1059b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil basename = strrchr(progname, '/'); 1069b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil basename = basename ? basename + 1 : progname; 1079b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil 1089b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil for (int i = 0; netcmds[i]; ++i) { 1099b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil size_t len = strlen(netcmds[i]); 1109b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil if (!strncmp(basename, netcmds[i], len)) { 1119b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil // truncate to match netcmds[i] 1129b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil basename[len] = '\0'; 1139b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil 1149b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil // hardcode the path to /system so it cannot be overwritten 1159b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil char *cmd; 1169b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil if (asprintf(&cmd, "%s%s", SYSTEM_DIRNAME, basename) == -1) { 1179b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil perror("asprintf"); 1189b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil exit(EXIT_FAILURE); 1199b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil } 1209b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil argv[0] = cmd; 1212dd1bc3476aa4ae0dab2b27b3c04cb4c780f89e0Lorenzo Colitti checkExpectedCommand(argc, argv); 1229b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil execv(cmd, argv); 1239b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil } 1249b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil } 1259b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil 1269b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil // must never reach here 1279b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil fprintf(stderr, "(%s:%d) is not a supported net util\n", progname, errno); 1289b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil exit(EXIT_FAILURE); 1299b9e9770dbac53fec5afab127af38067adab2952Sandeep Patil} 130