summaryrefslogtreecommitdiff
path: root/src/core/network
diff options
context:
space:
mode:
authorGravatar bunnei2021-08-29 00:04:58 -0700
committerGravatar GitHub2021-08-29 00:04:58 -0700
commit5f19b6618930d33857fa2a4785ad7404b9e8c41c (patch)
treee55dcef495ae7ae2d777eb1bdf0262d4fcc5e8be /src/core/network
parentMerge pull request #6921 from ameerj/vp9-unused (diff)
parentservice: nifm: Populate fields in GetCurrentNetworkProfile (diff)
downloadyuzu-5f19b6618930d33857fa2a4785ad7404b9e8c41c.tar.gz
yuzu-5f19b6618930d33857fa2a4785ad7404b9e8c41c.tar.xz
yuzu-5f19b6618930d33857fa2a4785ad7404b9e8c41c.zip
Merge pull request #6905 from Morph1984/nifm-misc
nifm/network_interface: Cleanup and populate fields in GetCurrentNetworkProfile
Diffstat (limited to 'src/core/network')
-rw-r--r--src/core/network/network_interface.cpp171
1 files changed, 89 insertions, 82 deletions
diff --git a/src/core/network/network_interface.cpp b/src/core/network/network_interface.cpp
index cecc9aa11..6811f21b1 100644
--- a/src/core/network/network_interface.cpp
+++ b/src/core/network/network_interface.cpp
@@ -37,73 +37,73 @@ std::vector<NetworkInterface> GetAvailableNetworkInterfaces() {
37 AF_INET, GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_INCLUDE_GATEWAYS, 37 AF_INET, GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_INCLUDE_GATEWAYS,
38 nullptr, adapter_addresses.data(), &buf_size); 38 nullptr, adapter_addresses.data(), &buf_size);
39 39
40 if (ret == ERROR_BUFFER_OVERFLOW) { 40 if (ret != ERROR_BUFFER_OVERFLOW) {
41 adapter_addresses.resize((buf_size / sizeof(IP_ADAPTER_ADDRESSES)) + 1);
42 } else {
43 break; 41 break;
44 } 42 }
43
44 adapter_addresses.resize((buf_size / sizeof(IP_ADAPTER_ADDRESSES)) + 1);
45 } 45 }
46 46
47 if (ret == NO_ERROR) { 47 if (ret != NO_ERROR) {
48 std::vector<NetworkInterface> result; 48 LOG_ERROR(Network, "Failed to get network interfaces with GetAdaptersAddresses");
49 return {};
50 }
49 51
50 for (auto current_address = adapter_addresses.data(); current_address != nullptr; 52 std::vector<NetworkInterface> result;
51 current_address = current_address->Next) {
52 if (current_address->FirstUnicastAddress == nullptr ||
53 current_address->FirstUnicastAddress->Address.lpSockaddr == nullptr) {
54 continue;
55 }
56 53
57 if (current_address->OperStatus != IfOperStatusUp) { 54 for (auto current_address = adapter_addresses.data(); current_address != nullptr;
58 continue; 55 current_address = current_address->Next) {
59 } 56 if (current_address->FirstUnicastAddress == nullptr ||
57 current_address->FirstUnicastAddress->Address.lpSockaddr == nullptr) {
58 continue;
59 }
60 60
61 const auto ip_addr = Common::BitCast<struct sockaddr_in>( 61 if (current_address->OperStatus != IfOperStatusUp) {
62 *current_address->FirstUnicastAddress->Address.lpSockaddr) 62 continue;
63 .sin_addr; 63 }
64 64
65 ULONG mask = 0; 65 const auto ip_addr = Common::BitCast<struct sockaddr_in>(
66 if (ConvertLengthToIpv4Mask(current_address->FirstUnicastAddress->OnLinkPrefixLength, 66 *current_address->FirstUnicastAddress->Address.lpSockaddr)
67 &mask) != NO_ERROR) { 67 .sin_addr;
68 LOG_ERROR(Network, "Failed to convert IPv4 prefix length to subnet mask");
69 continue;
70 }
71 68
72 struct in_addr gateway = {.S_un{.S_addr{0}}}; 69 ULONG mask = 0;
73 if (current_address->FirstGatewayAddress != nullptr && 70 if (ConvertLengthToIpv4Mask(current_address->FirstUnicastAddress->OnLinkPrefixLength,
74 current_address->FirstGatewayAddress->Address.lpSockaddr != nullptr) { 71 &mask) != NO_ERROR) {
75 gateway = Common::BitCast<struct sockaddr_in>( 72 LOG_ERROR(Network, "Failed to convert IPv4 prefix length to subnet mask");
76 *current_address->FirstGatewayAddress->Address.lpSockaddr) 73 continue;
77 .sin_addr; 74 }
78 }
79 75
80 result.push_back(NetworkInterface{ 76 struct in_addr gateway = {.S_un{.S_addr{0}}};
81 .name{Common::UTF16ToUTF8(std::wstring{current_address->FriendlyName})}, 77 if (current_address->FirstGatewayAddress != nullptr &&
82 .ip_address{ip_addr}, 78 current_address->FirstGatewayAddress->Address.lpSockaddr != nullptr) {
83 .subnet_mask = in_addr{.S_un{.S_addr{mask}}}, 79 gateway = Common::BitCast<struct sockaddr_in>(
84 .gateway = gateway}); 80 *current_address->FirstGatewayAddress->Address.lpSockaddr)
81 .sin_addr;
85 } 82 }
86 83
87 return result; 84 result.emplace_back(NetworkInterface{
88 } else { 85 .name{Common::UTF16ToUTF8(std::wstring{current_address->FriendlyName})},
89 LOG_ERROR(Network, "Failed to get network interfaces with GetAdaptersAddresses"); 86 .ip_address{ip_addr},
90 return {}; 87 .subnet_mask = in_addr{.S_un{.S_addr{mask}}},
88 .gateway = gateway});
91 } 89 }
90
91 return result;
92} 92}
93 93
94#else 94#else
95 95
96std::vector<NetworkInterface> GetAvailableNetworkInterfaces() { 96std::vector<NetworkInterface> GetAvailableNetworkInterfaces() {
97 std::vector<NetworkInterface> result;
98
99 struct ifaddrs* ifaddr = nullptr; 97 struct ifaddrs* ifaddr = nullptr;
100 98
101 if (getifaddrs(&ifaddr) != 0) { 99 if (getifaddrs(&ifaddr) != 0) {
102 LOG_ERROR(Network, "Failed to get network interfaces with getifaddrs: {}", 100 LOG_ERROR(Network, "Failed to get network interfaces with getifaddrs: {}",
103 std::strerror(errno)); 101 std::strerror(errno));
104 return result; 102 return {};
105 } 103 }
106 104
105 std::vector<NetworkInterface> result;
106
107 for (auto ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) { 107 for (auto ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) {
108 if (ifa->ifa_addr == nullptr || ifa->ifa_netmask == nullptr) { 108 if (ifa->ifa_addr == nullptr || ifa->ifa_netmask == nullptr) {
109 continue; 109 continue;
@@ -117,55 +117,62 @@ std::vector<NetworkInterface> GetAvailableNetworkInterfaces() {
117 continue; 117 continue;
118 } 118 }
119 119
120 std::uint32_t gateway{0}; 120 u32 gateway{};
121
121 std::ifstream file{"/proc/net/route"}; 122 std::ifstream file{"/proc/net/route"};
122 if (file.is_open()) { 123 if (!file.is_open()) {
124 LOG_ERROR(Network, "Failed to open \"/proc/net/route\"");
123 125
124 // ignore header 126 result.emplace_back(NetworkInterface{
125 file.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 127 .name{ifa->ifa_name},
128 .ip_address{Common::BitCast<struct sockaddr_in>(*ifa->ifa_addr).sin_addr},
129 .subnet_mask{Common::BitCast<struct sockaddr_in>(*ifa->ifa_netmask).sin_addr},
130 .gateway{in_addr{.s_addr = gateway}}});
131 continue;
132 }
126 133
127 bool gateway_found = false; 134 // ignore header
135 file.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
128 136
129 for (std::string line; std::getline(file, line);) { 137 bool gateway_found = false;
130 std::istringstream iss{line};
131 138
132 std::string iface_name{}; 139 for (std::string line; std::getline(file, line);) {
133 iss >> iface_name; 140 std::istringstream iss{line};
134 if (iface_name != ifa->ifa_name) {
135 continue;
136 }
137 141
138 iss >> std::hex; 142 std::string iface_name;
143 iss >> iface_name;
144 if (iface_name != ifa->ifa_name) {
145 continue;
146 }
139 147
140 std::uint32_t dest{0}; 148 iss >> std::hex;
141 iss >> dest;
142 if (dest != 0) {
143 // not the default route
144 continue;
145 }
146 149
147 iss >> gateway; 150 u32 dest{};
151 iss >> dest;
152 if (dest != 0) {
153 // not the default route
154 continue;
155 }
148 156
149 std::uint16_t flags{0}; 157 iss >> gateway;
150 iss >> flags;
151 158
152 // flag RTF_GATEWAY (defined in <linux/route.h>) 159 u16 flags{};
153 if ((flags & 0x2) == 0) { 160 iss >> flags;
154 continue;
155 }
156 161
157 gateway_found = true; 162 // flag RTF_GATEWAY (defined in <linux/route.h>)
158 break; 163 if ((flags & 0x2) == 0) {
164 continue;
159 } 165 }
160 166
161 if (!gateway_found) { 167 gateway_found = true;
162 gateway = 0; 168 break;
163 }
164 } else {
165 LOG_ERROR(Network, "Failed to open \"/proc/net/route\"");
166 } 169 }
167 170
168 result.push_back(NetworkInterface{ 171 if (!gateway_found) {
172 gateway = 0;
173 }
174
175 result.emplace_back(NetworkInterface{
169 .name{ifa->ifa_name}, 176 .name{ifa->ifa_name},
170 .ip_address{Common::BitCast<struct sockaddr_in>(*ifa->ifa_addr).sin_addr}, 177 .ip_address{Common::BitCast<struct sockaddr_in>(*ifa->ifa_addr).sin_addr},
171 .subnet_mask{Common::BitCast<struct sockaddr_in>(*ifa->ifa_netmask).sin_addr}, 178 .subnet_mask{Common::BitCast<struct sockaddr_in>(*ifa->ifa_netmask).sin_addr},
@@ -180,11 +187,11 @@ std::vector<NetworkInterface> GetAvailableNetworkInterfaces() {
180#endif 187#endif
181 188
182std::optional<NetworkInterface> GetSelectedNetworkInterface() { 189std::optional<NetworkInterface> GetSelectedNetworkInterface() {
183 const std::string& selected_network_interface = Settings::values.network_interface.GetValue(); 190 const auto& selected_network_interface = Settings::values.network_interface.GetValue();
184 const auto network_interfaces = Network::GetAvailableNetworkInterfaces(); 191 const auto network_interfaces = Network::GetAvailableNetworkInterfaces();
185 if (network_interfaces.size() == 0) { 192 if (network_interfaces.size() == 0) {
186 LOG_ERROR(Network, "GetAvailableNetworkInterfaces returned no interfaces"); 193 LOG_ERROR(Network, "GetAvailableNetworkInterfaces returned no interfaces");
187 return {}; 194 return std::nullopt;
188 } 195 }
189 196
190 const auto res = 197 const auto res =
@@ -192,12 +199,12 @@ std::optional<NetworkInterface> GetSelectedNetworkInterface() {
192 return iface.name == selected_network_interface; 199 return iface.name == selected_network_interface;
193 }); 200 });
194 201
195 if (res != network_interfaces.end()) { 202 if (res == network_interfaces.end()) {
196 return *res;
197 } else {
198 LOG_ERROR(Network, "Couldn't find selected interface \"{}\"", selected_network_interface); 203 LOG_ERROR(Network, "Couldn't find selected interface \"{}\"", selected_network_interface);
199 return {}; 204 return std::nullopt;
200 } 205 }
206
207 return *res;
201} 208}
202 209
203} // namespace Network 210} // namespace Network