Merge pull request #3066 from alexanderkyte/pedump_sgen
[mono.git] / mcs / class / System / System.Net.NetworkInformation / Win32NetworkInterfaceMarshal.cs
1 //
2 // System.Net.NetworkInformation.NetworkInterface
3 //
4 // Author:
5 //      Atsushi Enomoto (atsushi@ximian.com)
6 //
7 // Copyright (c) 2007 Novell, Inc. (http://www.novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 using System;
29 using System.Collections.Generic;
30 using System.Net;
31 using System.Runtime.InteropServices;
32 using System.Text;
33
34 namespace System.Net.NetworkInformation
35 {
36         // They are mostly defined in iptypes.h (included by iphlpapi.h).
37         // grep around /usr/include/w32api/* for identifiers you are curious.
38
39         [StructLayout (LayoutKind.Sequential)]
40         class Win32_FIXED_INFO
41         {
42                 // Can't have unresolvable pinvokes on ios
43 #if !MOBILE
44                 [DllImport ("iphlpapi.dll", SetLastError = true)]
45                 static extern int GetNetworkParams (byte [] bytes, ref int size);
46 #endif
47
48                 static Win32_FIXED_INFO fixed_info;
49
50                 public static Win32_FIXED_INFO Instance {
51                         get {
52                                 if (fixed_info == null)
53                                         fixed_info = GetInstance ();
54                                 return fixed_info;
55                         }
56                 }
57
58                 static Win32_FIXED_INFO GetInstance ()
59                 {
60 #if !MOBILE
61                         int len = 0;
62                         byte [] bytes = null;
63                         GetNetworkParams (null, ref len);
64                         bytes = new byte [len];
65                         GetNetworkParams (bytes, ref len);
66                         Win32_FIXED_INFO info = new Win32_FIXED_INFO ();
67                         unsafe {
68                                 fixed (byte* ptr = bytes) {
69                                         Marshal.PtrToStructure ((IntPtr) ptr, info);
70                                 }
71                         }
72                         return info;
73 #else
74                 throw new NotImplementedException ();
75 #endif
76                 }
77
78                 const int MAX_HOSTNAME_LEN = 128;
79                 const int MAX_DOMAIN_NAME_LEN = 128;
80                 const int MAX_SCOPE_ID_LEN = 256;
81
82                 [MarshalAs (UnmanagedType.ByValTStr, SizeConst = MAX_HOSTNAME_LEN + 4)]
83                 public string HostName;
84                 [MarshalAs (UnmanagedType.ByValTStr, SizeConst = MAX_DOMAIN_NAME_LEN + 4)]
85                 public string DomainName;
86                 public IntPtr CurrentDnsServer; // to Win32IP_ADDR_STRING
87                 public Win32_IP_ADDR_STRING DnsServerList;
88                 public NetBiosNodeType NodeType;
89                 [MarshalAs (UnmanagedType.ByValTStr, SizeConst = MAX_SCOPE_ID_LEN + 4)]
90                 public string ScopeId;
91                 public uint EnableRouting;
92                 public uint EnableProxy;
93                 public uint EnableDns;
94         }
95
96         [StructLayout (LayoutKind.Explicit)]
97         struct AlignmentUnion
98         {
99                 [FieldOffset (0)] // 1
100                 public ulong Alignment;
101                 [FieldOffset (0)] // 2-1
102                 public int Length;
103                 [FieldOffset (4)] // 2-2
104                 public int IfIndex;
105         }
106
107         [StructLayout (LayoutKind.Sequential, CharSet = CharSet.Unicode)]
108         class Win32_IP_ADAPTER_ADDRESSES {
109                 public AlignmentUnion Alignment;
110                 public IntPtr Next; // to Win32_IP_ADAPTER_ADDRESSES
111                 [MarshalAs (UnmanagedType.LPStr)]
112                 public string AdapterName; // PCHAR
113                 public IntPtr FirstUnicastAddress; //to IP_ADAPTER_UNICAST_ADDRESS
114                 public IntPtr FirstAnycastAddress; // to IP_ADAPTER_ANYCAST_ADDRESS
115                 public IntPtr FirstMulticastAddress; // to IP_ADAPTER_MULTICAST_ADDRESS
116                 public IntPtr FirstDnsServerAddress; // to IP_ADAPTER_DNS_SERVER_ADDRESS
117                 public string DnsSuffix;
118                 public string Description;
119                 public string FriendlyName;
120                 [MarshalAs (UnmanagedType.ByValArray, SizeConst = MAX_ADAPTER_ADDRESS_LENGTH)]
121                 public byte [] PhysicalAddress;
122                 public uint PhysicalAddressLength;
123                 public uint Flags;
124                 public uint Mtu;
125                 public NetworkInterfaceType IfType;
126                 public OperationalStatus OperStatus;
127                 public int Ipv6IfIndex;
128                 [MarshalAs (UnmanagedType.ByValArray, SizeConst = 16 * 4)]
129                 public uint [] ZoneIndices;
130
131                 // Note that Vista-only members and XP-SP1-only member are
132                 // omitted.
133
134                 const int MAX_ADAPTER_ADDRESS_LENGTH = 8;
135
136                 const int IP_ADAPTER_DDNS_ENABLED = 1;
137                 const int IP_ADAPTER_RECEIVE_ONLY = 8;
138                 const int IP_ADAPTER_NO_MULTICAST = 0x10;
139
140                 public bool DdnsEnabled {
141                         get { return (Flags & IP_ADAPTER_DDNS_ENABLED) != 0; }
142                 }
143
144                 public bool IsReceiveOnly {
145                         get { return (Flags & IP_ADAPTER_RECEIVE_ONLY) != 0; }
146                 }
147
148                 public bool NoMulticast {
149                         get { return (Flags & IP_ADAPTER_NO_MULTICAST) != 0; }
150                 }
151         }
152
153         [StructLayout (LayoutKind.Sequential)]
154         class Win32_IP_ADAPTER_INFO
155         {
156                 const int MAX_ADAPTER_NAME_LENGTH = 256;
157                 const int MAX_ADAPTER_DESCRIPTION_LENGTH = 128;
158                 const int MAX_ADAPTER_ADDRESS_LENGTH = 8;
159
160                 public IntPtr Next; // to Win32_IP_ADAPTER_INFO
161                 public int ComboIndex;
162                 [MarshalAs (UnmanagedType.ByValTStr, SizeConst = MAX_ADAPTER_NAME_LENGTH + 4)]
163                 public string AdapterName;
164                 [MarshalAs (UnmanagedType.ByValTStr, SizeConst = MAX_ADAPTER_DESCRIPTION_LENGTH + 4)]
165                 public string Description;
166                 public uint AddressLength;
167                 [MarshalAs (UnmanagedType.ByValArray, SizeConst = MAX_ADAPTER_ADDRESS_LENGTH)]
168                 public byte [] Address;
169                 public uint Index;
170                 public uint Type;
171                 public uint DhcpEnabled;
172                 public IntPtr CurrentIpAddress; // Win32_IP_ADDR_STRING
173                 public Win32_IP_ADDR_STRING IpAddressList;
174                 public Win32_IP_ADDR_STRING GatewayList;
175                 public Win32_IP_ADDR_STRING DhcpServer;
176                 public bool HaveWins;
177                 public Win32_IP_ADDR_STRING PrimaryWinsServer;
178                 public Win32_IP_ADDR_STRING SecondaryWinsServer;
179                 public long LeaseObtained;
180                 public long LeaseExpires;
181         }
182
183         [StructLayout (LayoutKind.Sequential)]
184         struct Win32_MIB_IFROW
185         {
186                 const int MAX_INTERFACE_NAME_LEN = 256;
187                 const int MAXLEN_PHYSADDR = 8;
188                 const int MAXLEN_IFDESCR = 256;
189
190                 [MarshalAs (UnmanagedType.ByValArray, SizeConst = MAX_INTERFACE_NAME_LEN * 2)]
191                 public char [] Name;
192                 public int Index;
193                 public NetworkInterfaceType Type;
194                 public int Mtu;
195                 public uint Speed;
196                 public int PhysAddrLen;
197                 [MarshalAs (UnmanagedType.ByValArray, SizeConst = MAXLEN_PHYSADDR)]
198                 public byte [] PhysAddr;
199                 public uint AdminStatus;
200                 public uint OperStatus;
201                 public uint LastChange;
202                 public int InOctets;
203                 public int InUcastPkts;
204                 public int InNUcastPkts;
205                 public int InDiscards;
206                 public int InErrors;
207                 public int InUnknownProtos;
208                 public int OutOctets;
209                 public int OutUcastPkts;
210                 public int OutNUcastPkts;
211                 public int OutDiscards;
212                 public int OutErrors;
213                 public int OutQLen;
214                 public int DescrLen;
215                 [MarshalAs (UnmanagedType.ByValArray, SizeConst = MAXLEN_IFDESCR)]
216                 public byte [] Descr;
217         }
218
219         [StructLayout (LayoutKind.Sequential)]
220         struct Win32_IP_ADDR_STRING
221         {
222                 public IntPtr Next; // to Win32_IP_ADDR_STRING
223                 [MarshalAs (UnmanagedType.ByValTStr, SizeConst = 16)]
224                 public string IpAddress;
225                 [MarshalAs (UnmanagedType.ByValTStr, SizeConst = 16)]
226                 public string IpMask;
227                 public uint Context;
228         }
229
230         [StructLayout (LayoutKind.Sequential)]
231         struct Win32LengthFlagsUnion
232         {
233                 const int IP_ADAPTER_ADDRESS_DNS_ELIGIBLE = 1;
234                 const int IP_ADAPTER_ADDRESS_TRANSIENT = 2;
235
236                 // union { struct {
237                 public uint Length;
238                 public uint Flags;
239                 // }; };
240
241                 public bool IsDnsEligible {
242                         get { return (Flags & IP_ADAPTER_ADDRESS_DNS_ELIGIBLE) != 0; }
243                 }
244
245                 public bool IsTransient {
246                         get { return (Flags & IP_ADAPTER_ADDRESS_TRANSIENT) != 0; }
247                 }
248         }
249
250         [StructLayout (LayoutKind.Sequential)]
251         struct Win32_IP_ADAPTER_ANYCAST_ADDRESS
252         {
253                 public Win32LengthFlagsUnion LengthFlags;
254                 public IntPtr Next; // to Win32_IP_ADAPTER_ANYCAST_ADDRESS
255                 public Win32_SOCKET_ADDRESS Address;
256         }
257
258         [StructLayout (LayoutKind.Sequential)]
259         struct Win32_IP_ADAPTER_DNS_SERVER_ADDRESS
260         {
261                 public Win32LengthFlagsUnion LengthFlags;
262                 public IntPtr Next; // to Win32_IP_ADAPTER_DNS_SERVER_ADDRESS
263                 public Win32_SOCKET_ADDRESS Address;
264         }
265
266         [StructLayout (LayoutKind.Sequential)]
267         struct Win32_IP_ADAPTER_MULTICAST_ADDRESS
268         {
269                 public Win32LengthFlagsUnion LengthFlags;
270                 public IntPtr Next; // to Win32_IP_ADAPTER_MULTICAST_ADDRESS
271                 public Win32_SOCKET_ADDRESS Address;
272         }
273
274         [StructLayout (LayoutKind.Sequential)]
275         struct Win32_IP_ADAPTER_UNICAST_ADDRESS
276         {
277                 public Win32LengthFlagsUnion LengthFlags;
278                 public IntPtr Next; // to Win32_IP_ADAPTER_UNICAST_ADDRESS
279                 public Win32_SOCKET_ADDRESS Address;
280                 public PrefixOrigin PrefixOrigin;
281                 public SuffixOrigin SuffixOrigin;
282                 public DuplicateAddressDetectionState DadState;
283                 public uint ValidLifetime;
284                 public uint PreferredLifetime;
285                 public uint LeaseLifetime;
286                 public byte OnLinkPrefixLength;
287
288         }
289
290         [StructLayout (LayoutKind.Sequential)]
291         struct Win32_SOCKADDR
292         {
293                 public ushort AddressFamily;
294                 [MarshalAs (UnmanagedType.ByValArray, SizeConst = 14 * 2)]
295                 public byte [] AddressData;
296         }
297
298         // FIXME: it somehow fails to marshal.
299         [StructLayout (LayoutKind.Sequential)]
300         struct Win32_SOCKET_ADDRESS
301         {
302                 public IntPtr Sockaddr; // to Win32_SOCKADDR
303                 public int SockaddrLength;
304
305                 public IPAddress GetIPAddress ()
306                 {
307                         Win32_SOCKADDR sa = (Win32_SOCKADDR) Marshal.PtrToStructure (Sockaddr, typeof (Win32_SOCKADDR));
308 //foreach (byte b in sa.AddressData) Console.Write ("{0:X02}", b); Console.WriteLine ();
309                         byte [] arr;
310                         if (sa.AddressFamily == AF_INET6) {
311                                 arr = new byte [16];
312                                 Array.Copy (sa.AddressData, 6, arr, 0, 16);
313                         } else {
314                                 arr = new byte [4];
315                                 Array.Copy (sa.AddressData, 2, arr, 0, 4);
316                         }
317 //foreach (byte b in arr) Console.Write ("{0:X02}", b); Console.WriteLine ();
318                         return new IPAddress (arr);
319                 }
320
321                 const int AF_INET6 = 23;
322         }
323 }
324