aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThog <me@thog.eu>2020-02-17 16:28:41 +0100
committerGitHub <noreply@github.com>2020-02-17 16:28:41 +0100
commite9a37ca6a85346c05149deac916dc90de43ad240 (patch)
tree48757b69598faf04f5c0e77e5d17aefea5002f37
parentd89e90a16ec361ff6384061787e9968b90a2a5ce (diff)
Implement GetCurrentIpConfigInfo (#943)
* Implement GetCurrentIpConfigInfo This is needed by Rocket League. Also fix GetCurrentIpConfigInfo to not return ipv6 addresses * Address Ac_K comment
-rw-r--r--Ryujinx.HLE/HOS/Services/Nifm/StaticService/IGeneralService.cs74
-rw-r--r--Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/DnsSetting.cs21
-rw-r--r--Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpAddressSetting.cs23
-rw-r--r--Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpV4Address.cs24
4 files changed, 137 insertions, 5 deletions
diff --git a/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IGeneralService.cs b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IGeneralService.cs
index c1642c3f..eaa9be49 100644
--- a/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IGeneralService.cs
+++ b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IGeneralService.cs
@@ -3,10 +3,12 @@ using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Services.Nifm.StaticService.GeneralService;
using Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types;
using System;
+using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
+using System.Runtime.CompilerServices;
namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService
{
@@ -57,18 +59,35 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService
// GetCurrentIpAddress() -> nn::nifm::IpV4Address
public ResultCode GetCurrentIpAddress(ServiceCtx context)
{
- if (!NetworkInterface.GetIsNetworkAvailable())
+ (_, UnicastIPAddressInformation unicastAddress) = GetLocalInterface();
+
+ if (unicastAddress == null)
{
return ResultCode.NoInternetConnection;
}
- IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
+ context.ResponseData.WriteStruct(new IpV4Address(unicastAddress.Address));
+
+ Logger.PrintInfo(LogClass.ServiceNifm, $"Console's local IP is \"{unicastAddress.Address}\".");
+
+ return ResultCode.Success;
+ }
+
+ [Command(15)]
+ // GetCurrentIpConfigInfo() -> (nn::nifm::IpAddressSetting, nn::nifm::DnsSetting)
+ public ResultCode GetCurrentIpConfigInfo(ServiceCtx context)
+ {
+ (IPInterfaceProperties interfaceProperties, UnicastIPAddressInformation unicastAddress) = GetLocalInterface();
- IPAddress address = host.AddressList.FirstOrDefault(a => a.AddressFamily == AddressFamily.InterNetwork);
+ if (interfaceProperties == null)
+ {
+ return ResultCode.NoInternetConnection;
+ }
- context.ResponseData.Write(BitConverter.ToUInt32(address.GetAddressBytes()));
+ Logger.PrintInfo(LogClass.ServiceNifm, $"Console's local IP is \"{unicastAddress.Address}\".");
- Logger.PrintInfo(LogClass.ServiceNifm, $"Console's local IP is \"{address}\".");
+ context.ResponseData.WriteStruct(new IpAddressSetting(interfaceProperties, unicastAddress));
+ context.ResponseData.WriteStruct(new DnsSetting(interfaceProperties));
return ResultCode.Success;
}
@@ -108,6 +127,51 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService
return ResultCode.Success;
}
+ private (IPInterfaceProperties, UnicastIPAddressInformation) GetLocalInterface()
+ {
+ if (!NetworkInterface.GetIsNetworkAvailable())
+ {
+ return (null, null);
+ }
+
+ IPInterfaceProperties targetProperties = null;
+ UnicastIPAddressInformation targetAddressInfo = null;
+
+ NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces();
+
+ foreach (NetworkInterface adapter in interfaces)
+ {
+ // Ignore loopback and non IPv4 capable interface.
+ if (adapter.NetworkInterfaceType != NetworkInterfaceType.Loopback && adapter.Supports(NetworkInterfaceComponent.IPv4))
+ {
+ IPInterfaceProperties properties = adapter.GetIPProperties();
+
+ if (properties.GatewayAddresses.Count > 0 && properties.DnsAddresses.Count > 1)
+ {
+ foreach (UnicastIPAddressInformation info in properties.UnicastAddresses)
+ {
+ // Only accept an IPv4 address
+ if (info.Address.GetAddressBytes().Length == 4)
+ {
+ targetProperties = properties;
+ targetAddressInfo = info;
+
+ break;
+ }
+ }
+ }
+
+ // Found the target interface, stop here.
+ if (targetProperties != null)
+ {
+ break;
+ }
+ }
+ }
+
+ return (targetProperties, targetAddressInfo);
+ }
+
public void Dispose()
{
GeneralServiceManager.Remove(_generalServiceDetail.ClientId);
diff --git a/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/DnsSetting.cs b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/DnsSetting.cs
new file mode 100644
index 00000000..96f99dfa
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/DnsSetting.cs
@@ -0,0 +1,21 @@
+using System.Net.NetworkInformation;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types
+{
+ [StructLayout(LayoutKind.Sequential, Pack = 1, Size = 9)]
+ struct DnsSetting
+ {
+ [MarshalAs(UnmanagedType.U1)]
+ public bool IsDynamicDnsEnabled;
+ public IpV4Address PrimaryDns;
+ public IpV4Address SecondaryDns;
+
+ public DnsSetting(IPInterfaceProperties interfaceProperties)
+ {
+ IsDynamicDnsEnabled = interfaceProperties.IsDynamicDnsEnabled;
+ PrimaryDns = new IpV4Address(interfaceProperties.DnsAddresses[0]);
+ SecondaryDns = new IpV4Address(interfaceProperties.DnsAddresses[1]);
+ }
+ }
+}
diff --git a/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpAddressSetting.cs b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpAddressSetting.cs
new file mode 100644
index 00000000..50e6b01c
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpAddressSetting.cs
@@ -0,0 +1,23 @@
+using System.Net.NetworkInformation;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types
+{
+ [StructLayout(LayoutKind.Sequential, Pack = 1, Size = 0xd)]
+ struct IpAddressSetting
+ {
+ [MarshalAs(UnmanagedType.U1)]
+ public bool IsDhcpEnabled;
+ public IpV4Address Address;
+ public IpV4Address IPv4Mask;
+ public IpV4Address GatewayAddress;
+
+ public IpAddressSetting(IPInterfaceProperties interfaceProperties, UnicastIPAddressInformation unicastIPAddressInformation)
+ {
+ IsDhcpEnabled = interfaceProperties.DhcpServerAddresses.Count != 0;
+ Address = new IpV4Address(unicastIPAddressInformation.Address);
+ IPv4Mask = new IpV4Address(unicastIPAddressInformation.IPv4Mask);
+ GatewayAddress = new IpV4Address(interfaceProperties.GatewayAddresses[0].Address);
+ }
+ }
+}
diff --git a/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpV4Address.cs b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpV4Address.cs
new file mode 100644
index 00000000..e5c2f39a
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpV4Address.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Net;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types
+{
+ [StructLayout(LayoutKind.Sequential)]
+ struct IpV4Address
+ {
+ public uint Address;
+
+ public IpV4Address(IPAddress address)
+ {
+ if (address == null)
+ {
+ Address = 0;
+ }
+ else
+ {
+ Address = BitConverter.ToUInt32(address.GetAddressBytes());
+ }
+ }
+ }
+}