1 /* 2 * Copyright 2018 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 17 #include <regex> 18 #include <string> 19 #include <vector> 20 21 #include <errno.h> 22 #include <sys/socket.h> 23 #include <sys/types.h> 24 #include <unistd.h> 25 26 #include <android-base/stringprintf.h> 27 #include <android/multinetwork.h> 28 29 #include "VtsHalNetNetdTestUtils.h" 30 31 using android::base::StringPrintf; 32 33 int checkNetworkExists(net_handle_t netHandle) { 34 int sock = socket(AF_INET6, SOCK_STREAM, 0); 35 if (sock == -1) { 36 return -ENOTSOCK; 37 } 38 int ret = android_setsocknetwork(netHandle, sock); 39 if (ret) { 40 ret = -errno; 41 } 42 close(sock); 43 return ret; 44 } 45 46 // TODO: deduplicate this with system/netd/tests/binder_test.cpp. 47 static std::vector<std::string> runCommand(const std::string& command) { 48 std::vector<std::string> lines; 49 FILE* f; 50 51 if ((f = popen(command.c_str(), "r")) == nullptr) { 52 perror("popen"); 53 return lines; 54 } 55 56 char* line = nullptr; 57 size_t bufsize = 0; 58 ssize_t linelen = 0; 59 while ((linelen = getline(&line, &bufsize, f)) >= 0) { 60 lines.push_back(std::string(line, linelen)); 61 } 62 63 free(line); 64 pclose(f); 65 return lines; 66 } 67 68 static std::vector<std::string> listIpRules(const char* ipVersion) { 69 std::string command = StringPrintf("%s %s rule list", IP_PATH, ipVersion); 70 return runCommand(command); 71 } 72 73 int countMatchingIpRules(const std::string& regexString) { 74 const std::regex regex(regexString, std::regex_constants::extended); 75 int matches = 0; 76 77 for (const char* version : {"-4", "-6"}) { 78 std::vector<std::string> rules = listIpRules(version); 79 for (const auto& rule : rules) { 80 if (std::regex_search(rule, regex)) { 81 matches++; 82 } 83 } 84 } 85 86 return matches; 87 } 88 89 int countRulesForFwmark(const uint32_t fwmark) { 90 // Skip top nibble, which differs between rules. 91 std::string regex = 92 StringPrintf("from all fwmark 0x(%x|[0-9a-f]+%04x)/.* lookup ", fwmark, fwmark); 93 return countMatchingIpRules(regex); 94 } 95 96 int checkReachability(net_handle_t netHandle, const char* addrStr) { 97 addrinfo *ai, hints = {.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV}; 98 int ret = getaddrinfo(addrStr, "53", &hints, &ai); 99 if (ret) { 100 return -EINVAL; 101 } 102 103 int sock = socket(ai->ai_family, SOCK_DGRAM, 0); 104 if (sock == -1 || android_setsocknetwork(netHandle, sock) == -1) { 105 ret = -errno; 106 freeaddrinfo(ai); 107 return ret; 108 } 109 110 ret = connect(sock, ai->ai_addr, ai->ai_addrlen); 111 close(sock); 112 if (ret == -1) { 113 ret = -errno; 114 } 115 freeaddrinfo(ai); 116 return ret; 117 } 118