Skip to content

Commit e772233

Browse files
authored
Merge pull request #976 from Unity-Technologies/unity-master-fix-ip-exceptions
Fix issue where loopback interface causes exception 1027045
2 parents 8ecb87c + 5311365 commit e772233

File tree

5 files changed

+83
-43
lines changed

5 files changed

+83
-43
lines changed

mcs/class/System/System.Net.NetworkInformation/IPAddressCollection.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,25 @@ public static Win32IPAddressCollection FromDnsServer (IntPtr ptr)
8484
return c;
8585
}
8686

87+
public static Win32IPAddressCollection FromSocketAddress (Win32_SOCKET_ADDRESS addr)
88+
{
89+
Win32IPAddressCollection c = new Win32IPAddressCollection ();
90+
if (addr.Sockaddr != IntPtr.Zero)
91+
c.InternalAdd (addr.GetIPAddress ());
92+
return c;
93+
}
94+
95+
public static Win32IPAddressCollection FromWinsServer (IntPtr ptr)
96+
{
97+
Win32IPAddressCollection c = new Win32IPAddressCollection ();
98+
Win32_IP_ADAPTER_WINS_SERVER_ADDRESS a;
99+
for (IntPtr p = ptr; p != IntPtr.Zero; p = a.Next) {
100+
a = (Win32_IP_ADAPTER_WINS_SERVER_ADDRESS) Marshal.PtrToStructure (p, typeof (Win32_IP_ADAPTER_WINS_SERVER_ADDRESS));
101+
c.InternalAdd (a.Address.GetIPAddress ());
102+
}
103+
return c;
104+
}
105+
87106
void AddSubsequentlyString (IntPtr head)
88107
{
89108
Win32_IP_ADDR_STRING a;

mcs/class/System/System.Net.NetworkInformation/IPInterfaceProperties.cs

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -341,13 +341,11 @@ public Win32IPInterfaceProperties2 (Win32_IP_ADAPTER_ADDRESSES addr, Win32_MIB_I
341341

342342
public override IPv4InterfaceProperties GetIPv4Properties ()
343343
{
344-
Win32_IP_ADAPTER_INFO v4info = Win32NetworkInterface2.GetAdapterInfoByIndex (mib4.Index);
345-
return new Win32IPv4InterfaceProperties (v4info, mib4);
344+
return new Win32IPv4InterfaceProperties (addr, mib4);
346345
}
347346

348347
public override IPv6InterfaceProperties GetIPv6Properties ()
349348
{
350-
Win32_IP_ADAPTER_INFO v6info = Win32NetworkInterface2.GetAdapterInfoByIndex (mib6.Index);
351349
return new Win32IPv6InterfaceProperties (mib6);
352350
}
353351

@@ -371,10 +369,9 @@ static IPAddressInformationCollection Win32FromAnycast (IntPtr ptr)
371369

372370
public override IPAddressCollection DhcpServerAddresses {
373371
get {
374-
Win32_IP_ADAPTER_INFO v4info = Win32NetworkInterface2.GetAdapterInfoByIndex (mib4.Index);
375372
// FIXME: should ipv6 DhcpServer be considered?
376373
try {
377-
return new Win32IPAddressCollection (v4info.DhcpServer);
374+
return Win32IPAddressCollection.FromSocketAddress (addr.Dhcpv4Server);
378375
} catch (IndexOutOfRangeException) {
379376
return Win32IPAddressCollection.Empty;
380377
}
@@ -393,28 +390,17 @@ public override GatewayIPAddressInformationCollection GatewayAddresses {
393390
get {
394391
var col = new GatewayIPAddressInformationCollection ();
395392
try {
396-
Win32_IP_ADAPTER_INFO v4info = Win32NetworkInterface2.GetAdapterInfoByIndex (mib4.Index);
397393
// FIXME: should ipv6 DhcpServer be considered?
398-
399-
var a = v4info.GatewayList;
400-
if (!String.IsNullOrEmpty (a.IpAddress)) {
401-
col.InternalAdd(new SystemGatewayIPAddressInformation(IPAddress.Parse (a.IpAddress)));
402-
AddSubsequently (a.Next, col);
394+
Win32_IP_ADAPTER_GATEWAY_ADDRESS a;
395+
for (IntPtr p = addr.FirstGatewayAddress; p != IntPtr.Zero; p = a.Next) {
396+
a = (Win32_IP_ADAPTER_GATEWAY_ADDRESS) Marshal.PtrToStructure (p, typeof (Win32_IP_ADAPTER_GATEWAY_ADDRESS));
397+
col.InternalAdd (new SystemGatewayIPAddressInformation (a.Address.GetIPAddress ()));
403398
}
404399
} catch (IndexOutOfRangeException) {}
405400
return col;
406401
}
407402
}
408403

409-
static void AddSubsequently (IntPtr head, GatewayIPAddressInformationCollection col)
410-
{
411-
Win32_IP_ADDR_STRING a;
412-
for (IntPtr p = head; p != IntPtr.Zero; p = a.Next) {
413-
a = (Win32_IP_ADDR_STRING) Marshal.PtrToStructure (p, typeof (Win32_IP_ADDR_STRING));
414-
col.InternalAdd (new SystemGatewayIPAddressInformation (IPAddress.Parse (a.IpAddress)));
415-
}
416-
}
417-
418404
public override bool IsDnsEnabled {
419405
get { return Win32NetworkInterface.FixedInfo.EnableDns != 0; }
420406
}
@@ -444,7 +430,6 @@ static MulticastIPAddressInformationCollection Win32FromMulticast (IntPtr ptr)
444430
public override UnicastIPAddressInformationCollection UnicastAddresses {
445431
get {
446432
try {
447-
Win32_IP_ADAPTER_INFO ai = Win32NetworkInterface2.GetAdapterInfoByIndex (mib4.Index);
448433
// FIXME: should ipv6 DhcpServer be considered?
449434
return Win32FromUnicast (addr.FirstUnicastAddress);
450435
} catch (IndexOutOfRangeException) {
@@ -467,9 +452,7 @@ static UnicastIPAddressInformationCollection Win32FromUnicast (IntPtr ptr)
467452
public override IPAddressCollection WinsServersAddresses {
468453
get {
469454
try {
470-
Win32_IP_ADAPTER_INFO v4info = Win32NetworkInterface2.GetAdapterInfoByIndex (mib4.Index);
471-
// FIXME: should ipv6 DhcpServer be considered?
472-
return new Win32IPAddressCollection (v4info.PrimaryWinsServer, v4info.SecondaryWinsServer);
455+
return Win32IPAddressCollection.FromWinsServer (addr.FirstWinsServerAddress);
473456
} catch (IndexOutOfRangeException) {
474457
return Win32IPAddressCollection.Empty;
475458
}

mcs/class/System/System.Net.NetworkInformation/IPv4InterfaceProperties.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,13 @@ sealed class Win32IPv4InterfaceProperties : IPv4InterfaceProperties
129129
[DllImport ("iphlpapi.dll")]
130130
static extern int GetPerAdapterInfo (int IfIndex, Win32_IP_PER_ADAPTER_INFO pPerAdapterInfo, ref int pOutBufLen);
131131

132-
Win32_IP_ADAPTER_INFO ainfo;
132+
Win32_IP_ADAPTER_ADDRESSES addr;
133133
Win32_IP_PER_ADAPTER_INFO painfo;
134134
Win32_MIB_IFROW mib;
135135

136-
public Win32IPv4InterfaceProperties (Win32_IP_ADAPTER_INFO ainfo, Win32_MIB_IFROW mib)
136+
public Win32IPv4InterfaceProperties (Win32_IP_ADAPTER_ADDRESSES addr, Win32_MIB_IFROW mib)
137137
{
138-
this.ainfo = ainfo;
138+
this.addr = addr;
139139
this.mib = mib;
140140

141141
// get per-adapter info.
@@ -160,7 +160,7 @@ public override bool IsAutomaticPrivateAddressingEnabled {
160160
}
161161

162162
public override bool IsDhcpEnabled {
163-
get { return ainfo.DhcpEnabled != 0; }
163+
get { return addr.DhcpEnabled; }
164164
}
165165

166166
public override bool IsForwardingEnabled {
@@ -173,7 +173,7 @@ public override int Mtu {
173173
}
174174

175175
public override bool UsesWins {
176-
get { return ainfo.HaveWins; }
176+
get { return addr.FirstWinsServerAddress != IntPtr.Zero; }
177177
}
178178
}
179179

mcs/class/System/System.Net.NetworkInformation/NetworkInterface.cs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -465,9 +465,13 @@ static Win32_IP_ADAPTER_ADDRESSES [] GetAdaptersAddresses ()
465465
{
466466
IntPtr ptr = IntPtr.Zero;
467467
int len = 0;
468-
GetAdaptersAddresses (0, 0, IntPtr.Zero, ptr, ref len);
468+
uint flags = Win32_IP_ADAPTER_ADDRESSES.GAA_FLAG_INCLUDE_WINS_INFO | Win32_IP_ADAPTER_ADDRESSES.GAA_FLAG_INCLUDE_GATEWAYS;
469+
GetAdaptersAddresses (0, flags, IntPtr.Zero, ptr, ref len);
470+
if (Marshal.SizeOf (typeof (Win32_IP_ADAPTER_ADDRESSES)) > len)
471+
throw new NetworkInformationException ();
472+
469473
ptr = Marshal.AllocHGlobal(len);
470-
int ret = GetAdaptersAddresses (0, 0, IntPtr.Zero, ptr, ref len);
474+
int ret = GetAdaptersAddresses (0, flags, IntPtr.Zero, ptr, ref len);
471475
if (ret != 0)
472476
throw new NetworkInformationException (ret);
473477

@@ -829,14 +833,6 @@ class Win32NetworkInterface2 : NetworkInterface
829833
[DllImport ("iphlpapi.dll", SetLastError = true)]
830834
static extern int GetIfEntry (ref Win32_MIB_IFROW row);
831835

832-
public static Win32_IP_ADAPTER_INFO GetAdapterInfoByIndex (int index)
833-
{
834-
foreach (Win32_IP_ADAPTER_INFO info in GetAdaptersInfo ())
835-
if (info.Index == index)
836-
return info;
837-
throw new IndexOutOfRangeException ("No adapter found for index " + index);
838-
}
839-
840836
static Win32_IP_ADAPTER_INFO [] GetAdaptersInfo ()
841837
{
842838
int len = 0;

mcs/class/System/System.Net.NetworkInformation/Win32NetworkInterfaceMarshal.cs

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,22 +121,48 @@ struct Win32_IP_ADAPTER_ADDRESSES {
121121
public NetworkInterfaceType IfType;
122122
public OperationalStatus OperStatus;
123123
public int Ipv6IfIndex;
124-
[MarshalAs (UnmanagedType.ByValArray, SizeConst = 16 * 4)]
124+
[MarshalAs (UnmanagedType.ByValArray, SizeConst = 16)]
125125
public uint [] ZoneIndices;
126-
127-
// Note that Vista-only members and XP-SP1-only member are
128-
// omitted.
126+
public IntPtr FirstPrefix; // to PIP_ADAPTER_PREFIX
127+
public UInt64 TransmitLinkSpeed;
128+
public UInt64 ReceiveLinkSpeed;
129+
public IntPtr FirstWinsServerAddress; // to PIP_ADAPTER_WINS_SERVER_ADDRESS_LH
130+
public IntPtr FirstGatewayAddress; // to PIP_ADAPTER_GATEWAY_ADDRESS_LH
131+
public uint Ipv4Metric;
132+
public uint Ipv6Metric;
133+
public UInt64 Luid;
134+
public Win32_SOCKET_ADDRESS Dhcpv4Server;
135+
public uint CompartmentId;
136+
public UInt64 NetworkGuid;
137+
public int ConnectionType;
138+
public int TunnelType;
139+
public Win32_SOCKET_ADDRESS Dhcpv6Server;
140+
[MarshalAs (UnmanagedType.ByValArray, SizeConst = MAX_DHCPV6_DUID_LENGTH)]
141+
public byte [] Dhcpv6ClientDuid;
142+
public ulong Dhcpv6ClientDuidLength;
143+
public ulong Dhcpv6Iaid;
144+
public IntPtr FirstDnsSuffix; // to PIP_ADAPTER_DNS_SUFFIX
145+
146+
//Flags For GetAdapterAddresses
147+
public const int GAA_FLAG_INCLUDE_WINS_INFO = 0x0040;
148+
public const int GAA_FLAG_INCLUDE_GATEWAYS = 0x0080;
129149

130150
const int MAX_ADAPTER_ADDRESS_LENGTH = 8;
151+
const int MAX_DHCPV6_DUID_LENGTH = 130;
131152

132153
const int IP_ADAPTER_DDNS_ENABLED = 1;
154+
const int IP_ADAPTER_DHCP_ENABLED = 4;
133155
const int IP_ADAPTER_RECEIVE_ONLY = 8;
134156
const int IP_ADAPTER_NO_MULTICAST = 0x10;
135157

136158
public bool DdnsEnabled {
137159
get { return (Flags & IP_ADAPTER_DDNS_ENABLED) != 0; }
138160
}
139161

162+
public bool DhcpEnabled {
163+
get { return (Flags & IP_ADAPTER_DHCP_ENABLED) != 0; }
164+
}
165+
140166
public bool IsReceiveOnly {
141167
get { return (Flags & IP_ADAPTER_RECEIVE_ONLY) != 0; }
142168
}
@@ -267,6 +293,22 @@ struct Win32_IP_ADAPTER_MULTICAST_ADDRESS
267293
public Win32_SOCKET_ADDRESS Address;
268294
}
269295

296+
[StructLayout (LayoutKind.Sequential)]
297+
struct Win32_IP_ADAPTER_GATEWAY_ADDRESS
298+
{
299+
public Win32LengthFlagsUnion LengthFlags;
300+
public IntPtr Next; // to Win32_IP_ADAPTER_GATEWAY_ADDRESS
301+
public Win32_SOCKET_ADDRESS Address;
302+
}
303+
304+
[StructLayout (LayoutKind.Sequential)]
305+
struct Win32_IP_ADAPTER_WINS_SERVER_ADDRESS
306+
{
307+
public Win32LengthFlagsUnion LengthFlags;
308+
public IntPtr Next; // to Win32_IP_ADAPTER_WINS_SERVER_ADDRESS
309+
public Win32_SOCKET_ADDRESS Address;
310+
}
311+
270312
[StructLayout (LayoutKind.Sequential)]
271313
struct Win32_IP_ADAPTER_UNICAST_ADDRESS
272314
{

0 commit comments

Comments
 (0)