diff options
| author | bunnei <bunneidev@gmail.com> | 2021-08-29 00:04:58 -0700 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-08-29 00:04:58 -0700 | 
| commit | 5f19b6618930d33857fa2a4785ad7404b9e8c41c (patch) | |
| tree | e55dcef495ae7ae2d777eb1bdf0262d4fcc5e8be | |
| parent | 4e889894353c29b075a77fdfa1ee4d42bdcd5dc6 (diff) | |
| parent | c1e2063c0d4b3f25ff47a9f0ccc940615c2a2bd8 (diff) | |
Merge pull request #6905 from Morph1984/nifm-misc
nifm/network_interface: Cleanup and populate fields in GetCurrentNetworkProfile
| -rw-r--r-- | src/core/hle/service/nifm/nifm.cpp | 113 | ||||
| -rw-r--r-- | src/core/network/network_interface.cpp | 171 | 
2 files changed, 147 insertions, 137 deletions
| diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp index 0a53c0c81..9decb9290 100644 --- a/src/core/hle/service/nifm/nifm.cpp +++ b/src/core/hle/service/nifm/nifm.cpp @@ -277,37 +277,45 @@ private:      void GetCurrentNetworkProfile(Kernel::HLERequestContext& ctx) {          LOG_WARNING(Service_NIFM, "(STUBBED) called"); -        const SfNetworkProfileData network_profile_data{ -            .ip_setting_data{ -                .ip_address_setting{ -                    .is_automatic{true}, -                    .current_address{192, 168, 1, 100}, -                    .subnet_mask{255, 255, 255, 0}, -                    .gateway{192, 168, 1, 1}, -                }, -                .dns_setting{ -                    .is_automatic{true}, -                    .primary_dns{1, 1, 1, 1}, -                    .secondary_dns{1, 0, 0, 1}, +        const auto net_iface = Network::GetSelectedNetworkInterface(); + +        const SfNetworkProfileData network_profile_data = [&net_iface] { +            if (!net_iface) { +                return SfNetworkProfileData{}; +            } + +            return SfNetworkProfileData{ +                .ip_setting_data{ +                    .ip_address_setting{ +                        .is_automatic{true}, +                        .current_address{Network::TranslateIPv4(net_iface->ip_address)}, +                        .subnet_mask{Network::TranslateIPv4(net_iface->subnet_mask)}, +                        .gateway{Network::TranslateIPv4(net_iface->gateway)}, +                    }, +                    .dns_setting{ +                        .is_automatic{true}, +                        .primary_dns{1, 1, 1, 1}, +                        .secondary_dns{1, 0, 0, 1}, +                    }, +                    .proxy_setting{ +                        .enabled{false}, +                        .port{}, +                        .proxy_server{}, +                        .automatic_auth_enabled{}, +                        .user{}, +                        .password{}, +                    }, +                    .mtu{1500},                  }, -                .proxy_setting{ -                    .enabled{false}, -                    .port{}, -                    .proxy_server{}, -                    .automatic_auth_enabled{}, -                    .user{}, -                    .password{}, +                .uuid{0xdeadbeef, 0xdeadbeef}, +                .network_name{"yuzu Network"}, +                .wireless_setting_data{ +                    .ssid_length{12}, +                    .ssid{"yuzu Network"}, +                    .passphrase{"yuzupassword"},                  }, -                .mtu{1500}, -            }, -            .uuid{0xdeadbeef, 0xdeadbeef}, -            .network_name{"yuzu Network"}, -            .wireless_setting_data{ -                .ssid_length{12}, -                .ssid{"yuzu Network"}, -                .passphrase{"yuzupassword"}, -            }, -        }; +            }; +        }();          ctx.WriteBuffer(network_profile_data); @@ -352,38 +360,33 @@ private:          LOG_WARNING(Service_NIFM, "(STUBBED) called");          struct IpConfigInfo { -            IpAddressSetting ip_address_setting; -            DnsSetting dns_setting; +            IpAddressSetting ip_address_setting{}; +            DnsSetting dns_setting{};          };          static_assert(sizeof(IpConfigInfo) == sizeof(IpAddressSetting) + sizeof(DnsSetting),                        "IpConfigInfo has incorrect size."); -        IpConfigInfo ip_config_info{ -            .ip_address_setting{ -                .is_automatic{true}, -                .current_address{0, 0, 0, 0}, -                .subnet_mask{255, 255, 255, 0}, -                .gateway{192, 168, 1, 1}, -            }, -            .dns_setting{ -                .is_automatic{true}, -                .primary_dns{1, 1, 1, 1}, -                .secondary_dns{1, 0, 0, 1}, -            }, -        }; +        const auto net_iface = Network::GetSelectedNetworkInterface(); -        const auto iface = Network::GetSelectedNetworkInterface(); -        if (iface) { -            ip_config_info.ip_address_setting = -                IpAddressSetting{.is_automatic{true}, -                                 .current_address{Network::TranslateIPv4(iface->ip_address)}, -                                 .subnet_mask{Network::TranslateIPv4(iface->subnet_mask)}, -                                 .gateway{Network::TranslateIPv4(iface->gateway)}}; +        const IpConfigInfo ip_config_info = [&net_iface] { +            if (!net_iface) { +                return IpConfigInfo{}; +            } -        } else { -            LOG_ERROR(Service_NIFM, -                      "Couldn't get host network configuration info, using default values"); -        } +            return IpConfigInfo{ +                .ip_address_setting{ +                    .is_automatic{true}, +                    .current_address{Network::TranslateIPv4(net_iface->ip_address)}, +                    .subnet_mask{Network::TranslateIPv4(net_iface->subnet_mask)}, +                    .gateway{Network::TranslateIPv4(net_iface->gateway)}, +                }, +                .dns_setting{ +                    .is_automatic{true}, +                    .primary_dns{1, 1, 1, 1}, +                    .secondary_dns{1, 0, 0, 1}, +                }, +            }; +        }();          IPC::ResponseBuilder rb{ctx, 2 + (sizeof(IpConfigInfo) + 3) / sizeof(u32)};          rb.Push(ResultSuccess); 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() {              AF_INET, GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_INCLUDE_GATEWAYS,              nullptr, adapter_addresses.data(), &buf_size); -        if (ret == ERROR_BUFFER_OVERFLOW) { -            adapter_addresses.resize((buf_size / sizeof(IP_ADAPTER_ADDRESSES)) + 1); -        } else { +        if (ret != ERROR_BUFFER_OVERFLOW) {              break;          } + +        adapter_addresses.resize((buf_size / sizeof(IP_ADAPTER_ADDRESSES)) + 1);      } -    if (ret == NO_ERROR) { -        std::vector<NetworkInterface> result; +    if (ret != NO_ERROR) { +        LOG_ERROR(Network, "Failed to get network interfaces with GetAdaptersAddresses"); +        return {}; +    } -        for (auto current_address = adapter_addresses.data(); current_address != nullptr; -             current_address = current_address->Next) { -            if (current_address->FirstUnicastAddress == nullptr || -                current_address->FirstUnicastAddress->Address.lpSockaddr == nullptr) { -                continue; -            } +    std::vector<NetworkInterface> result; -            if (current_address->OperStatus != IfOperStatusUp) { -                continue; -            } +    for (auto current_address = adapter_addresses.data(); current_address != nullptr; +         current_address = current_address->Next) { +        if (current_address->FirstUnicastAddress == nullptr || +            current_address->FirstUnicastAddress->Address.lpSockaddr == nullptr) { +            continue; +        } -            const auto ip_addr = Common::BitCast<struct sockaddr_in>( -                                     *current_address->FirstUnicastAddress->Address.lpSockaddr) -                                     .sin_addr; +        if (current_address->OperStatus != IfOperStatusUp) { +            continue; +        } -            ULONG mask = 0; -            if (ConvertLengthToIpv4Mask(current_address->FirstUnicastAddress->OnLinkPrefixLength, -                                        &mask) != NO_ERROR) { -                LOG_ERROR(Network, "Failed to convert IPv4 prefix length to subnet mask"); -                continue; -            } +        const auto ip_addr = Common::BitCast<struct sockaddr_in>( +                                 *current_address->FirstUnicastAddress->Address.lpSockaddr) +                                 .sin_addr; -            struct in_addr gateway = {.S_un{.S_addr{0}}}; -            if (current_address->FirstGatewayAddress != nullptr && -                current_address->FirstGatewayAddress->Address.lpSockaddr != nullptr) { -                gateway = Common::BitCast<struct sockaddr_in>( -                              *current_address->FirstGatewayAddress->Address.lpSockaddr) -                              .sin_addr; -            } +        ULONG mask = 0; +        if (ConvertLengthToIpv4Mask(current_address->FirstUnicastAddress->OnLinkPrefixLength, +                                    &mask) != NO_ERROR) { +            LOG_ERROR(Network, "Failed to convert IPv4 prefix length to subnet mask"); +            continue; +        } -            result.push_back(NetworkInterface{ -                .name{Common::UTF16ToUTF8(std::wstring{current_address->FriendlyName})}, -                .ip_address{ip_addr}, -                .subnet_mask = in_addr{.S_un{.S_addr{mask}}}, -                .gateway = gateway}); +        struct in_addr gateway = {.S_un{.S_addr{0}}}; +        if (current_address->FirstGatewayAddress != nullptr && +            current_address->FirstGatewayAddress->Address.lpSockaddr != nullptr) { +            gateway = Common::BitCast<struct sockaddr_in>( +                          *current_address->FirstGatewayAddress->Address.lpSockaddr) +                          .sin_addr;          } -        return result; -    } else { -        LOG_ERROR(Network, "Failed to get network interfaces with GetAdaptersAddresses"); -        return {}; +        result.emplace_back(NetworkInterface{ +            .name{Common::UTF16ToUTF8(std::wstring{current_address->FriendlyName})}, +            .ip_address{ip_addr}, +            .subnet_mask = in_addr{.S_un{.S_addr{mask}}}, +            .gateway = gateway});      } + +    return result;  }  #else  std::vector<NetworkInterface> GetAvailableNetworkInterfaces() { -    std::vector<NetworkInterface> result; -      struct ifaddrs* ifaddr = nullptr;      if (getifaddrs(&ifaddr) != 0) {          LOG_ERROR(Network, "Failed to get network interfaces with getifaddrs: {}",                    std::strerror(errno)); -        return result; +        return {};      } +    std::vector<NetworkInterface> result; +      for (auto ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) {          if (ifa->ifa_addr == nullptr || ifa->ifa_netmask == nullptr) {              continue; @@ -117,55 +117,62 @@ std::vector<NetworkInterface> GetAvailableNetworkInterfaces() {              continue;          } -        std::uint32_t gateway{0}; +        u32 gateway{}; +          std::ifstream file{"/proc/net/route"}; -        if (file.is_open()) { +        if (!file.is_open()) { +            LOG_ERROR(Network, "Failed to open \"/proc/net/route\""); -            // ignore header -            file.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); +            result.emplace_back(NetworkInterface{ +                .name{ifa->ifa_name}, +                .ip_address{Common::BitCast<struct sockaddr_in>(*ifa->ifa_addr).sin_addr}, +                .subnet_mask{Common::BitCast<struct sockaddr_in>(*ifa->ifa_netmask).sin_addr}, +                .gateway{in_addr{.s_addr = gateway}}}); +            continue; +        } -            bool gateway_found = false; +        // ignore header +        file.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); -            for (std::string line; std::getline(file, line);) { -                std::istringstream iss{line}; +        bool gateway_found = false; -                std::string iface_name{}; -                iss >> iface_name; -                if (iface_name != ifa->ifa_name) { -                    continue; -                } +        for (std::string line; std::getline(file, line);) { +            std::istringstream iss{line}; -                iss >> std::hex; +            std::string iface_name; +            iss >> iface_name; +            if (iface_name != ifa->ifa_name) { +                continue; +            } -                std::uint32_t dest{0}; -                iss >> dest; -                if (dest != 0) { -                    // not the default route -                    continue; -                } +            iss >> std::hex; -                iss >> gateway; +            u32 dest{}; +            iss >> dest; +            if (dest != 0) { +                // not the default route +                continue; +            } -                std::uint16_t flags{0}; -                iss >> flags; +            iss >> gateway; -                // flag RTF_GATEWAY (defined in <linux/route.h>) -                if ((flags & 0x2) == 0) { -                    continue; -                } +            u16 flags{}; +            iss >> flags; -                gateway_found = true; -                break; +            // flag RTF_GATEWAY (defined in <linux/route.h>) +            if ((flags & 0x2) == 0) { +                continue;              } -            if (!gateway_found) { -                gateway = 0; -            } -        } else { -            LOG_ERROR(Network, "Failed to open \"/proc/net/route\""); +            gateway_found = true; +            break;          } -        result.push_back(NetworkInterface{ +        if (!gateway_found) { +            gateway = 0; +        } + +        result.emplace_back(NetworkInterface{              .name{ifa->ifa_name},              .ip_address{Common::BitCast<struct sockaddr_in>(*ifa->ifa_addr).sin_addr},              .subnet_mask{Common::BitCast<struct sockaddr_in>(*ifa->ifa_netmask).sin_addr}, @@ -180,11 +187,11 @@ std::vector<NetworkInterface> GetAvailableNetworkInterfaces() {  #endif  std::optional<NetworkInterface> GetSelectedNetworkInterface() { -    const std::string& selected_network_interface = Settings::values.network_interface.GetValue(); +    const auto& selected_network_interface = Settings::values.network_interface.GetValue();      const auto network_interfaces = Network::GetAvailableNetworkInterfaces();      if (network_interfaces.size() == 0) {          LOG_ERROR(Network, "GetAvailableNetworkInterfaces returned no interfaces"); -        return {}; +        return std::nullopt;      }      const auto res = @@ -192,12 +199,12 @@ std::optional<NetworkInterface> GetSelectedNetworkInterface() {              return iface.name == selected_network_interface;          }); -    if (res != network_interfaces.end()) { -        return *res; -    } else { +    if (res == network_interfaces.end()) {          LOG_ERROR(Network, "Couldn't find selected interface \"{}\"", selected_network_interface); -        return {}; +        return std::nullopt;      } + +    return *res;  }  } // namespace Network | 
