github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/test/syscalls/linux/socket_bind_to_device_util.cc (about) 1 // Copyright 2019 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "test/syscalls/linux/socket_bind_to_device_util.h" 16 17 #include <arpa/inet.h> 18 #include <fcntl.h> 19 #include <linux/if_tun.h> 20 #include <net/if.h> 21 #include <netinet/in.h> 22 #include <sys/ioctl.h> 23 #include <sys/socket.h> 24 #include <sys/types.h> 25 #include <sys/un.h> 26 #include <unistd.h> 27 28 #include <cstdio> 29 #include <cstring> 30 #include <map> 31 #include <memory> 32 #include <unordered_map> 33 #include <unordered_set> 34 #include <utility> 35 #include <vector> 36 37 #include "test/util/test_util.h" 38 39 namespace gvisor { 40 namespace testing { 41 42 using std::string; 43 44 PosixErrorOr<std::unique_ptr<Tunnel>> Tunnel::New(string tunnel_name) { 45 int fd; 46 RETURN_ERROR_IF_SYSCALL_FAIL(fd = open("/dev/net/tun", O_RDWR)); 47 48 // Using `new` to access a non-public constructor. 49 auto new_tunnel = absl::WrapUnique(new Tunnel(fd)); 50 51 ifreq ifr = {}; 52 ifr.ifr_flags = IFF_TUN; 53 strncpy(ifr.ifr_name, tunnel_name.c_str(), sizeof(ifr.ifr_name)); 54 55 RETURN_ERROR_IF_SYSCALL_FAIL(ioctl(fd, TUNSETIFF, &ifr)); 56 new_tunnel->name_ = ifr.ifr_name; 57 return new_tunnel; 58 } 59 60 std::unordered_set<string> GetInterfaceNames() { 61 std::unordered_set<string> names; 62 #ifndef ANDROID 63 // Android does not support if_nameindex in r22. 64 struct if_nameindex* interfaces = if_nameindex(); 65 if (interfaces == nullptr) { 66 return names; 67 } 68 for (auto interface = interfaces; 69 interface->if_index != 0 || interface->if_name != nullptr; interface++) { 70 names.insert(interface->if_name); 71 } 72 if_freenameindex(interfaces); 73 #endif 74 return names; 75 } 76 77 } // namespace testing 78 } // namespace gvisor