2007-08-29 Atsushi Enomoto <atsushi@ximian.com>
[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 #if NET_2_0
29 using System;
30 using System.Collections.Generic;
31 using System.Net;
32 using System.Runtime.InteropServices;
33 using System.Text;
34
35 namespace System.Net.NetworkInformation
36 {
37         // They are mostly defined in iptypes.h (included by iphlpapi.h).
38         // grep around /usr/include/w32api/* for identifiers you are curious.
39
40         [StructLayout (LayoutKind.Sequential)]
41         class Win32_FIXED_INFO
42         {
43                 const int MAX_HOSTNAME_LEN = 128;
44                 const int MAX_DOMAIN_NAME_LEN = 128;
45                 const int MAX_SCOPE_ID_LEN = 256;
46
47                 [MarshalAs (UnmanagedType.ByValTStr, SizeConst = MAX_HOSTNAME_LEN + 4)]
48                 public string HostName;
49                 [MarshalAs (UnmanagedType.ByValTStr, SizeConst = MAX_DOMAIN_NAME_LEN + 4)]
50                 public string DomainName;
51                 public IntPtr CurrentDnsServer; // to Win32IP_ADDR_STRING
52                 public Win32_IP_ADDR_STRING DnsServerList;
53                 public uint NodeType;
54                 [MarshalAs (UnmanagedType.ByValTStr, SizeConst = MAX_SCOPE_ID_LEN + 4)]
55                 public string ScopeId;
56                 public uint EnableRouting;
57                 public uint EnableProxy;
58                 public uint EnableDns;
59         }
60
61         [StructLayout (LayoutKind.Explicit)]
62         struct AlignmentUnion
63         {
64                 [FieldOffset (0)] // 1
65                 public ulong Alignment;
66                 [FieldOffset (0)] // 2-1
67                 public int Length;
68                 [FieldOffset (4)] // 2-2
69                 public int IfIndex;
70         }
71
72         [StructLayout (LayoutKind.Sequential, CharSet = CharSet.Unicode)]
73         class Win32_IP_ADAPTER_ADDRESSES {
74                 public AlignmentUnion Alignment;
75                 public IntPtr Next; // to Win32_IP_ADAPTER_ADDRESSES
76                 [MarshalAs (UnmanagedType.LPStr)]
77                 public string AdapterName; // PCHAR
78                 public IntPtr FirstUnicastAddress; //to IP_ADAPTER_UNICAST_ADDRESS
79                 public IntPtr FirstAnycastAddress; // to IP_ADAPTER_ANYCAST_ADDRESS
80                 public IntPtr FirstMulticastAddress; // to IP_ADAPTER_MULTICAST_ADDRESS
81                 public IntPtr FirstDnsServerAddress; // to IP_ADAPTER_DNS_SERVER_ADDRESS
82                 public string DnsSuffix;
83                 public string Description;
84                 public string FriendlyName;
85                 [MarshalAs (UnmanagedType.ByValArray, SizeConst = MAX_ADAPTER_ADDRESS_LENGTH)]
86                 public byte [] PhysicalAddress;
87                 public uint PhysicalAddressLength;
88                 public uint Flags;
89                 public uint Mtu;
90                 public NetworkInterfaceType IfType;
91                 public OperationalStatus OperStatus;
92                 public int Ipv6IfIndex;
93                 [MarshalAs (UnmanagedType.ByValArray, SizeConst = 16 * 4)]
94                 public uint [] ZoneIndices;
95
96                 // Note that Vista-only members and XP-SP1-only member are
97                 // omitted.
98
99                 const int MAX_ADAPTER_ADDRESS_LENGTH = 8;
100
101                 const int IP_ADAPTER_DDNS_ENABLED = 1;
102                 const int IP_ADAPTER_RECEIVE_ONLY = 8;
103                 const int IP_ADAPTER_NO_MULTICAST = 0x10;
104
105                 public bool DdnsEnabled {
106                         get { return (Flags & IP_ADAPTER_DDNS_ENABLED) != 0; }
107                 }
108
109                 public bool IsReceiveOnly {
110                         get { return (Flags & IP_ADAPTER_RECEIVE_ONLY) != 0; }
111                 }
112
113                 public bool NoMulticast {
114                         get { return (Flags & IP_ADAPTER_NO_MULTICAST) != 0; }
115                 }
116         }
117
118         [StructLayout (LayoutKind.Sequential)]
119         class Win32_IP_ADAPTER_INFO
120         {
121                 const int MAX_ADAPTER_NAME_LENGTH = 256;
122                 const int MAX_ADAPTER_DESCRIPTION_LENGTH = 128;
123                 const int MAX_ADAPTER_ADDRESS_LENGTH = 8;
124
125                 public IntPtr Next; // to Win32_IP_ADAPTER_INFO
126                 public int ComboIndex;
127                 [MarshalAs (UnmanagedType.ByValTStr, SizeConst = MAX_ADAPTER_NAME_LENGTH + 4)]
128                 public string AdapterName;
129                 [MarshalAs (UnmanagedType.ByValTStr, SizeConst = MAX_ADAPTER_DESCRIPTION_LENGTH + 4)]
130                 public string Description;
131                 public uint AddressLength;
132                 [MarshalAs (UnmanagedType.ByValArray, SizeConst = MAX_ADAPTER_ADDRESS_LENGTH)]
133                 public byte [] Address;
134                 public uint Index;
135                 public uint Type;
136                 public uint DhcpEnabled;
137                 public IntPtr CurrentIpAddress; // Win32_IP_ADDR_STRING
138                 public Win32_IP_ADDR_STRING IpAddressList;
139                 public Win32_IP_ADDR_STRING GatewayList;
140                 public Win32_IP_ADDR_STRING DhcpServer;
141                 public bool HaveWins;
142                 public Win32_IP_ADDR_STRING PrimaryWinsServer;
143                 public Win32_IP_ADDR_STRING SecondaryWinsServer;
144                 public long LeaseObtained;
145                 public long LeaseExpires;
146         }
147
148         [StructLayout (LayoutKind.Sequential)]
149         struct Win32_MIB_IFROW
150         {
151                 const int MAX_INTERFACE_NAME_LEN = 256;
152                 const int MAXLEN_PHYSADDR = 8;
153                 const int MAXLEN_IFDESCR = 256;
154
155                 [MarshalAs (UnmanagedType.ByValArray, SizeConst = MAX_INTERFACE_NAME_LEN * 2)]
156                 public char [] Name;
157                 public int Index;
158                 public NetworkInterfaceType Type;
159                 public int Mtu;
160                 public uint Speed;
161                 public int PhysAddrLen;
162                 [MarshalAs (UnmanagedType.ByValArray, SizeConst = MAXLEN_PHYSADDR)]
163                 public byte [] PhysAddr;
164                 public uint AdminStatus;
165                 public uint OperStatus;
166                 public uint LastChange;
167                 public int InOctets;
168                 public int InUcastPkts;
169                 public int InNUcastPkts;
170                 public int InDiscards;
171                 public int InErrors;
172                 public int InUnknownProtos;
173                 public int OutOctets;
174                 public int OutUcastPkts;
175                 public int OutNUcastPkts;
176                 public int OutDiscards;
177                 public int OutErrors;
178                 public int OutQLen;
179                 public int DescrLen;
180                 [MarshalAs (UnmanagedType.ByValArray, SizeConst = MAXLEN_IFDESCR)]
181                 public byte [] Descr;
182         }
183
184         struct Win32_IP_ADDR_STRING
185         {
186                 public IntPtr Next; // to Win32_IP_ADDR_STRING
187                 [MarshalAs (UnmanagedType.ByValTStr, SizeConst = 16)]
188                 public string IpAddress;
189                 [MarshalAs (UnmanagedType.ByValTStr, SizeConst = 16)]
190                 public string IpMask;
191                 public uint Context;
192         }
193
194         [StructLayout (LayoutKind.Sequential)]
195         struct Win32LengthFlagsUnion
196         {
197                 const int IP_ADAPTER_ADDRESS_DNS_ELIGIBLE = 1;
198                 const int IP_ADAPTER_ADDRESS_TRANSIENT = 2;
199
200                 // union { struct {
201                 public uint Length;
202                 public uint Flags;
203                 // }; };
204
205                 public bool IsDnsEligible {
206                         get { return (Flags & IP_ADAPTER_ADDRESS_DNS_ELIGIBLE) != 0; }
207                 }
208
209                 public bool IsTransient {
210                         get { return (Flags & IP_ADAPTER_ADDRESS_TRANSIENT) != 0; }
211                 }
212         }
213
214         [StructLayout (LayoutKind.Sequential)]
215         struct Win32_IP_ADAPTER_ANYCAST_ADDRESS
216         {
217                 public Win32LengthFlagsUnion LengthFlags;
218                 public IntPtr Next; // to Win32_IP_ADAPTER_ANYCAST_ADDRESS
219                 public Win32_SOCKET_ADDRESS Address;
220         }
221
222         [StructLayout (LayoutKind.Sequential)]
223         struct Win32_IP_ADAPTER_DNS_SERVER_ADDRESS
224         {
225                 public Win32LengthFlagsUnion LengthFlags;
226                 public IntPtr Next; // to Win32_IP_ADAPTER_DNS_SERVER_ADDRESS
227                 public Win32_SOCKET_ADDRESS Address;
228         }
229
230         [StructLayout (LayoutKind.Sequential)]
231         struct Win32_IP_ADAPTER_MULTICAST_ADDRESS
232         {
233                 public Win32LengthFlagsUnion LengthFlags;
234                 public IntPtr Next; // to Win32_IP_ADAPTER_MULTICAST_ADDRESS
235                 public Win32_SOCKET_ADDRESS Address;
236         }
237
238         [StructLayout (LayoutKind.Sequential)]
239         struct Win32_IP_ADAPTER_UNICAST_ADDRESS
240         {
241                 public Win32LengthFlagsUnion LengthFlags;
242                 public IntPtr Next; // to Win32_IP_ADAPTER_UNICAST_ADDRESS
243                 public Win32_SOCKET_ADDRESS Address;
244                 public PrefixOrigin PrefixOrigin;
245                 public SuffixOrigin SuffixOrigin;
246                 public DuplicateAddressDetectionState DadState;
247                 public uint ValidLifetime;
248                 public uint PreferredLifetime;
249                 public uint LeaseLifetime;
250                 public byte OnLinkPrefixLength;
251
252         }
253
254         struct Win32_SOCKADDR
255         {
256                 public ushort AddressFamily;
257                 [MarshalAs (UnmanagedType.ByValArray, SizeConst = 14 * 2)]
258                 public byte [] AddressData;
259         }
260
261         // FIXME: it somehow fails to marshal.
262         struct Win32_SOCKET_ADDRESS
263         {
264                 public IntPtr Sockaddr; // to Win32_SOCKADDR
265                 public int SockaddrLength;
266
267                 public IPAddress GetIPAddress ()
268                 {
269                         Win32_SOCKADDR sa = (Win32_SOCKADDR) Marshal.PtrToStructure (Sockaddr, typeof (Win32_SOCKADDR));
270 //foreach (byte b in sa.AddressData) Console.Write ("{0:X02}", b); Console.WriteLine ();
271                         byte [] arr;
272                         if (sa.AddressFamily == AF_INET6) {
273                                 arr = new byte [16];
274                                 Array.Copy (sa.AddressData, 6, arr, 0, 16);
275                         } else {
276                                 arr = new byte [4];
277                                 Array.Copy (sa.AddressData, 2, arr, 0, 4);
278                         }
279 //foreach (byte b in arr) Console.Write ("{0:X02}", b); Console.WriteLine ();
280                         return new IPAddress (arr);
281                 }
282
283                 const int AF_INET6 = 23;
284         }
285 }
286 #endif
287