Merge pull request #3028 from lateralusX/jlorenss/threadpool_warning
[mono.git] / mcs / class / referencesource / System / net / System / Net / NetworkInformation / SystemUnicastIPAddressInformation.cs
1
2     /// <summary><para>
3     ///    Provides support for ip configuation information and statistics.
4     ///</para></summary>
5     ///
6 namespace System.Net.NetworkInformation {
7
8     using System.Net;
9     using System.Net.Sockets;
10     using System;
11     using System.Runtime.InteropServices;
12     using System.Diagnostics.Contracts;
13  
14     /// <include file='doc\NetworkInterface.uex' path='docs/doc[@for="IPUnicastAddressInformation"]/*' />
15     /// <summary>Specifies the unicast addresses for an interface.</summary>
16     internal class SystemUnicastIPAddressInformation:UnicastIPAddressInformation {
17         private long dhcpLeaseLifetime;
18         private SystemIPAddressInformation innerInfo;
19         private IPAddress ipv4Mask;
20         private PrefixOrigin prefixOrigin;
21         private SuffixOrigin suffixOrigin;
22         private DuplicateAddressDetectionState dadState;
23         private uint validLifetime;
24         private uint preferredLifetime;
25         private byte prefixLength;
26
27 #if !MONO
28         internal SystemUnicastIPAddressInformation(IpAdapterUnicastAddress adapterAddress) {
29             IPAddress ipAddress = adapterAddress.address.MarshalIPAddress();
30             this.innerInfo = new SystemIPAddressInformation(ipAddress, adapterAddress.flags);
31             this.prefixOrigin = adapterAddress.prefixOrigin;
32             this.suffixOrigin = adapterAddress.suffixOrigin;
33             this.dadState = adapterAddress.dadState;
34             this.validLifetime = adapterAddress.validLifetime;
35             this.preferredLifetime = adapterAddress.preferredLifetime;
36             this.dhcpLeaseLifetime = adapterAddress.leaseLifetime;
37
38             this.prefixLength = adapterAddress.prefixLength;
39
40             // IPv6 returns 0.0.0.0 for consistancy with XP
41             if (ipAddress.AddressFamily == AddressFamily.InterNetwork) {
42                 ipv4Mask = PrefixLengthToSubnetMask(prefixLength, ipAddress.AddressFamily);
43             }
44         }
45 #endif
46
47        /// <include file='doc\NetworkInterface.uex' path='docs/doc[@for="IPAddressInformation.Address"]/*' />
48         public override IPAddress Address{get {return innerInfo.Address;}}
49
50
51         public override IPAddress IPv4Mask{
52             get {
53                 // The IPv6 equivilant was never available on XP, and we've kept this behavior for legacy reasons.
54                 // For IPv6 use PrefixLength instead.
55                 if(Address.AddressFamily != AddressFamily.InterNetwork){
56                     return IPAddress.Any;
57                 }
58                 
59                 return ipv4Mask;
60             }
61         }
62         
63         public override int PrefixLength {
64             get {
65                 return prefixLength;
66             }
67         }
68
69         /// <include file='doc\NetworkInterface.uex' path='docs/doc[@for="IPAddressInformation.Transient"]/*' />
70         /// <summary>The address is a cluster address and shouldn't be used by most applications.</summary>
71         public override bool IsTransient{
72             get {
73                 return (innerInfo.IsTransient);
74             }
75         }
76
77         /// <include file='doc\NetworkInterface.uex' path='docs/doc[@for="IPAddressInformation.DnsEligible"]/*' />
78         /// <summary>This address can be used for DNS.</summary>
79         public override bool IsDnsEligible{
80             get {
81                 return (innerInfo.IsDnsEligible);
82             }
83         }
84
85
86         /// <include file='doc\NetworkInterface.uex' path='docs/doc[@for="IPUnicastAddressInformation.PrefixOrigin"]/*' />
87         public override PrefixOrigin PrefixOrigin{
88             get {
89                 return prefixOrigin;
90             }
91         }
92
93         /// <include file='doc\NetworkInterface.uex' path='docs/doc[@for="IPUnicastAddressInformation.SuffixOrigin"]/*' />
94         public override SuffixOrigin SuffixOrigin{
95             get {
96                 return suffixOrigin;
97             }
98         }
99         /// <include file='doc\NetworkInterface.uex' path='docs/doc[@for="IPUnicastAddressInformation.DuplicateAddressDetectionState"]/*' />
100         /// <summary>IPv6 only.  Specifies the duplicate address detection state. Only supported
101         /// for IPv6. If called on an IPv4 address, will throw a "not supported" exception.</summary>
102         public override DuplicateAddressDetectionState DuplicateAddressDetectionState{
103             get {
104                 return dadState;
105             }
106         }
107
108
109         /// <include file='doc\NetworkInterface.uex' path='docs/doc[@for="IPUnicastAddressInformation.ValidLifetime"]/*' />
110         /// <summary>Specifies the valid lifetime of the address in seconds.</summary>
111         public override long AddressValidLifetime{
112             get {
113                 return validLifetime;
114                 }
115             }
116         /// <include file='doc\NetworkInterface.uex' path='docs/doc[@for="IPUnicastAddressInformation.PreferredLifetime"]/*' />
117         /// <summary>Specifies the prefered lifetime of the address in seconds.</summary>
118
119         public override long AddressPreferredLifetime{
120             get {
121                 return preferredLifetime;
122                 }
123             }
124         /// <include file='doc\NetworkInterface.uex' path='docs/doc[@for="IPUnicastAddressInformation.PreferredLifetime"]/*' />
125
126         /// <include file='doc\NetworkInterface.uex' path='docs/doc[@for="IPUnicastAddressInformation.DhcpLeaseLifetime"]/*' />
127         /// <summary>Specifies the prefered lifetime of the address in seconds.</summary>
128         public override long DhcpLeaseLifetime{
129             get {
130                 return dhcpLeaseLifetime;
131                 }
132             }
133 #if !MONO
134         // Helper method that marshals the addressinformation into the classes
135         internal static UnicastIPAddressInformationCollection MarshalUnicastIpAddressInformationCollection(IntPtr ptr) {
136             UnicastIPAddressInformationCollection addressList = new UnicastIPAddressInformationCollection();
137
138             while (ptr != IntPtr.Zero) {
139                 // Get the address
140                 IpAdapterUnicastAddress addr = 
141                     (IpAdapterUnicastAddress)Marshal.PtrToStructure(ptr, typeof(IpAdapterUnicastAddress));
142                 // Add the address to the list
143                 addressList.InternalAdd(new SystemUnicastIPAddressInformation(addr));
144                 // Move to the next address in the list
145                 ptr = addr.next;
146             }
147
148             return addressList;
149         }
150
151         // Convert a CIDR prefix length to a subnet mask "255.255.255.0" format
152         private static IPAddress PrefixLengthToSubnetMask(byte prefixLength, AddressFamily family) {
153             Contract.Requires((0 <= prefixLength) && (prefixLength <= 126));
154             Contract.Requires((family == AddressFamily.InterNetwork) || (family == AddressFamily.InterNetworkV6));
155
156             byte[] addressBytes;
157             if (family == AddressFamily.InterNetwork) {
158                 addressBytes = new byte[4];
159             } else { // v6
160                 addressBytes = new byte[16];
161             }
162
163             Contract.Assert(prefixLength < (addressBytes.Length * 8));
164             
165             // Enable bits one at a time from left/high to right/low
166             for (int bit = 0; bit < prefixLength; bit++) {
167                 addressBytes[bit / 8] |= (byte)(0x80 >> (bit % 8));
168             }
169
170             return new IPAddress(addressBytes);
171         }
172 #endif
173     }
174 }