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