Implement mono_gc_alloc_fixed on Boehm to be uncollectable. This matches SGen behavio...
[mono.git] / mcs / class / System / System.Net.NetworkInformation / UnicastIPAddressInformation.cs
1 //
2 // System.Net.NetworkInformation.UnicastIPAddressInformation
3 //
4 // Authors:
5 //      Gonzalo Paniagua Javier (gonzalo@novell.com)
6 //      Atsushi Enomoto (atsushi@ximian.com)
7 //      Eric Butler (eric@extremeboredom.net)
8 //
9 // Copyright (c) 2006-2007 Novell, Inc. (http://www.novell.com)
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 using System;
31 using System.Runtime.InteropServices;
32 using System.Net.Sockets;
33 using System.Diagnostics.Contracts;
34
35 namespace System.Net.NetworkInformation {
36 #if !MOBILE
37         class Win32UnicastIPAddressInformation : UnicastIPAddressInformation 
38         {
39                 Win32_IP_ADAPTER_UNICAST_ADDRESS info;
40                 IPAddress ipv4Mask;
41
42                 public Win32UnicastIPAddressInformation (Win32_IP_ADAPTER_UNICAST_ADDRESS info)
43                 {
44                         this.info = info;
45                         IPAddress ipAddress = info.Address.GetIPAddress ();
46                         // IPv6 returns 0.0.0.0 for consistancy with XP
47                         if (ipAddress.AddressFamily == AddressFamily.InterNetwork) {
48                                 ipv4Mask = PrefixLengthToSubnetMask (info.OnLinkPrefixLength, ipAddress.AddressFamily);
49                         }
50                 }
51
52                 public override IPAddress Address {
53                         get { return info.Address.GetIPAddress (); }
54                 }
55
56                 public override bool IsDnsEligible {
57                         get { return info.LengthFlags.IsDnsEligible; }
58                 }
59
60                 public override bool IsTransient {
61                         get { return info.LengthFlags.IsTransient; }
62                 }
63
64                 // UnicastIPAddressInformation members
65
66                 public override long AddressPreferredLifetime {
67                         get { return info.PreferredLifetime; }
68                 }
69
70                 public override long AddressValidLifetime {
71                         get { return info.ValidLifetime; }
72                 }
73
74                 public override long DhcpLeaseLifetime {
75                         get { return info.LeaseLifetime; }
76                 }
77
78                 public override DuplicateAddressDetectionState DuplicateAddressDetectionState {
79                         get { return info.DadState; }
80                 }
81
82                 public override IPAddress IPv4Mask{
83                         get {
84                                 // The IPv6 equivilant was never available on XP, and we've kept this behavior for legacy reasons.
85                                 // For IPv6 use PrefixLength instead.
86                                 if (Address.AddressFamily != AddressFamily.InterNetwork) {
87                                         return IPAddress.Any;
88                                 }
89
90                                 return ipv4Mask;
91                         }
92                 }
93
94                 public override PrefixOrigin PrefixOrigin {
95                         get { return info.PrefixOrigin; }
96                 }
97
98                 public override SuffixOrigin SuffixOrigin {
99                         get { return info.SuffixOrigin; }
100                 }
101
102                 // Convert a CIDR prefix length to a subnet mask "255.255.255.0" format
103                 private static IPAddress PrefixLengthToSubnetMask (byte prefixLength, AddressFamily family) {
104                         Contract.Requires ((0 <= prefixLength) && (prefixLength <= 126));
105                         Contract.Requires ((family == AddressFamily.InterNetwork) || (family == AddressFamily.InterNetworkV6));
106
107                         byte[] addressBytes;
108                         if (family == AddressFamily.InterNetwork) {
109                                 addressBytes = new byte [4];
110                         } else { // v6
111                                 addressBytes = new byte [16];
112                         }
113
114                         Contract.Assert (prefixLength < (addressBytes.Length * 8));
115
116                         // Enable bits one at a time from left/high to right/low
117                         for (int bit = 0; bit < prefixLength; bit++) {
118                                 addressBytes [bit / 8] |= (byte) (0x80 >> (bit % 8));
119                         }
120
121                         return new IPAddress (addressBytes);
122                 }
123         }
124 #endif
125
126         class LinuxUnicastIPAddressInformation : UnicastIPAddressInformation
127         {
128                 IPAddress address;
129                 IPAddress ipv4Mask;
130
131                 public LinuxUnicastIPAddressInformation (IPAddress address)
132                 {
133                         this.address = address;
134                 }
135
136                 public override IPAddress Address {
137                         get { return address; }
138                 }
139
140                 public override bool IsDnsEligible {
141                         get {
142                                 byte[] addressBytes = address.GetAddressBytes ();
143                                 return !(addressBytes[0] == 169 && addressBytes[1] == 254);
144                         }
145                 }
146
147                 [MonoTODO("Always returns false")]
148                 public override bool IsTransient {
149                         get { return false; }
150                 }
151
152                 // UnicastIPAddressInformation members
153
154                 public override long AddressPreferredLifetime {
155                         get { throw new NotImplementedException (); }
156                 }
157
158                 public override long AddressValidLifetime {
159                         get { throw new NotImplementedException (); }
160                 }
161
162                 public override long DhcpLeaseLifetime {
163                         get { throw new NotImplementedException (); }
164                 }
165
166                 public override DuplicateAddressDetectionState DuplicateAddressDetectionState {
167                         get { throw new NotImplementedException (); }
168                 }
169
170                 public override IPAddress IPv4Mask {
171                         get {
172                                 // The IPv6 equivilant (for .net compatibility)
173                                 if (Address.AddressFamily != AddressFamily.InterNetwork)
174                                         return IPAddress.Any;
175
176                                 if (ipv4Mask == null)
177                                         ipv4Mask = SystemNetworkInterface.GetNetMask (address);
178
179                                 return ipv4Mask;
180                         }
181                 }
182
183                 public override PrefixOrigin PrefixOrigin {
184                         get { throw new NotImplementedException (); }
185                 }
186
187                 public override SuffixOrigin SuffixOrigin {
188                         get { throw new NotImplementedException (); }
189                 }
190         }
191 }
192