2 // System.Net.NetworkInformation.IPInterfaceProperties
5 // Gonzalo Paniagua Javier (gonzalo@novell.com)
6 // Atsushi Enomoto (atsushi@ximian.com)
8 // Copyright (c) 2006-2007 Novell, Inc. (http://www.novell.com)
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System
.Collections
.Generic
;
31 using System
.Globalization
;
33 using System
.Net
.Sockets
;
34 using System
.Text
.RegularExpressions
;
36 namespace System
.Net
.NetworkInformation
{
37 public abstract class IPInterfaceProperties
{
38 protected IPInterfaceProperties ()
42 public abstract IPv4InterfaceProperties
GetIPv4Properties ();
43 public abstract IPv6InterfaceProperties
GetIPv6Properties ();
45 public abstract IPAddressInformationCollection AnycastAddresses { get; }
46 public abstract IPAddressCollection DhcpServerAddresses { get; }
47 public abstract IPAddressCollection DnsAddresses { get; }
48 public abstract string DnsSuffix { get; }
49 public abstract GatewayIPAddressInformationCollection GatewayAddresses { get; }
50 public abstract bool IsDnsEnabled { get; }
51 public abstract bool IsDynamicDnsEnabled { get; }
52 public abstract MulticastIPAddressInformationCollection MulticastAddresses { get; }
53 public abstract UnicastIPAddressInformationCollection UnicastAddresses { get; }
54 public abstract IPAddressCollection WinsServersAddresses { get; }
57 abstract class UnixIPInterfaceProperties
: IPInterfaceProperties
59 protected IPv4InterfaceProperties ipv4iface_properties
;
60 protected UnixNetworkInterface iface
;
61 List
<IPAddress
> addresses
;
62 IPAddressCollection dns_servers
;
63 IPAddressCollection gateways
;
67 public UnixIPInterfaceProperties (UnixNetworkInterface iface
, List
<IPAddress
> addresses
)
70 this.addresses
= addresses
;
73 public override IPv6InterfaceProperties
GetIPv6Properties ()
75 throw new NotImplementedException ();
78 void ParseRouteInfo (string iface
)
81 gateways
= new IPAddressCollection ();
82 using (StreamReader reader
= new StreamReader ("/proc/net/route")) {
84 reader
.ReadLine (); // Ignore first line
85 while ((line
= reader
.ReadLine ()) != null) {
90 string [] parts
= line
.Split ('\t');
93 string gw_address
= parts
[2].Trim ();
94 byte [] ipbytes
= new byte [4];
95 if (gw_address
.Length
== 8 && iface
.Equals (parts
[0], StringComparison
.OrdinalIgnoreCase
)) {
96 for (int i
= 0; i
< 4; i
++) {
97 if (!Byte
.TryParse (gw_address
.Substring (i
* 2, 2), NumberStyles
.HexNumber
, null, out ipbytes
[3 - i
]))
100 IPAddress ip
= new IPAddress (ipbytes
);
101 if (!ip
.Equals (IPAddress
.Any
))
110 static Regex ns
= new Regex (@"\s*nameserver\s+(?<address>.*)");
111 static Regex search
= new Regex (@"\s*search\s+(?<domain>.*)");
112 void ParseResolvConf ()
115 DateTime wt
= File
.GetLastWriteTime ("/etc/resolv.conf");
116 if (wt
<= last_parse
)
121 dns_servers
= new IPAddressCollection ();
122 using (StreamReader reader
= new StreamReader ("/etc/resolv.conf")) {
125 while ((line
= reader
.ReadLine ()) != null) {
127 if (line
.Length
== 0 || line
[0] == '#')
129 Match match
= ns
.Match (line
);
132 str
= match
.Groups
["address"].Value
;
134 dns_servers
.Add (IPAddress
.Parse (str
));
138 match
= search
.Match (line
);
140 str
= match
.Groups
["domain"].Value
;
141 string [] parts
= str
.Split (',');
142 dns_suffix
= parts
[0].Trim ();
149 dns_servers
.SetReadOnly ();
153 public override IPAddressInformationCollection AnycastAddresses
{
155 List
<IPAddress
> anycastAddresses
= new List
<IPAddress
> ();
157 foreach (IPAddress address in addresses) {
158 if (is_anycast_address (address)) {
159 anycastAddresses.Add (address);
163 return IPAddressInformationImplCollection
.LinuxFromAnycast (anycastAddresses
);
167 [MonoTODO ("Always returns an empty collection.")]
168 public override IPAddressCollection DhcpServerAddresses
{
170 // There are lots of different DHCP clients
171 // that all store their configuration differently.
172 // I'm not sure what to do here.
173 IPAddressCollection coll
= new IPAddressCollection ();
179 public override IPAddressCollection DnsAddresses
{
186 public override string DnsSuffix
{
193 public override GatewayIPAddressInformationCollection GatewayAddresses
{
195 ParseRouteInfo (this.iface
.Name
.ToString());
196 if (gateways
.Count
> 0)
197 return new LinuxGatewayIPAddressInformationCollection (gateways
);
199 return LinuxGatewayIPAddressInformationCollection
.Empty
;
203 [MonoTODO ("Always returns true")]
204 public override bool IsDnsEnabled
{
210 [MonoTODO ("Always returns false")]
211 public override bool IsDynamicDnsEnabled
{
217 public override MulticastIPAddressInformationCollection MulticastAddresses
{
219 List
<IPAddress
> multicastAddresses
= new List
<IPAddress
> ();
220 foreach (IPAddress address
in addresses
) {
221 byte[] addressBytes
= address
.GetAddressBytes ();
222 if (addressBytes
[0] >= 224 && addressBytes
[0] <= 239) {
223 multicastAddresses
.Add (address
);
226 return MulticastIPAddressInformationImplCollection
.LinuxFromList (multicastAddresses
);
230 public override UnicastIPAddressInformationCollection UnicastAddresses
{
232 List
<IPAddress
> unicastAddresses
= new List
<IPAddress
> ();
233 foreach (IPAddress address
in addresses
) {
234 switch (address
.AddressFamily
) {
235 case AddressFamily
.InterNetwork
:
236 byte top
= address
.GetAddressBytes () [0];
237 if (top
>= 224 && top
<= 239)
239 unicastAddresses
.Add (address
);
242 case AddressFamily
.InterNetworkV6
:
243 if (address
.IsIPv6Multicast
)
245 unicastAddresses
.Add (address
);
249 return UnicastIPAddressInformationImplCollection
.LinuxFromList (unicastAddresses
);
253 [MonoTODO ("Always returns an empty collection.")]
254 public override IPAddressCollection WinsServersAddresses
{
256 // I do SUPPOSE we could scrape /etc/samba/smb.conf, but.. yeesh.
257 return new IPAddressCollection ();
262 class LinuxIPInterfaceProperties
: UnixIPInterfaceProperties
264 public LinuxIPInterfaceProperties (LinuxNetworkInterface iface
, List
<IPAddress
> addresses
)
265 : base (iface
, addresses
)
269 public override IPv4InterfaceProperties
GetIPv4Properties ()
271 if (ipv4iface_properties
== null)
272 ipv4iface_properties
= new LinuxIPv4InterfaceProperties (iface
as LinuxNetworkInterface
);
274 return ipv4iface_properties
;
278 class MacOsIPInterfaceProperties
: UnixIPInterfaceProperties
280 public MacOsIPInterfaceProperties (MacOsNetworkInterface iface
, List
<IPAddress
> addresses
)
281 : base (iface
, addresses
)
285 public override IPv4InterfaceProperties
GetIPv4Properties ()
287 if (ipv4iface_properties
== null)
288 ipv4iface_properties
= new MacOsIPv4InterfaceProperties (iface
as MacOsNetworkInterface
);
290 return ipv4iface_properties
;
294 class Win32IPInterfaceProperties2
: IPInterfaceProperties
296 readonly Win32_IP_ADAPTER_ADDRESSES addr
;
297 readonly Win32_MIB_IFROW mib4
, mib6
;
299 public Win32IPInterfaceProperties2 (Win32_IP_ADAPTER_ADDRESSES addr
, Win32_MIB_IFROW mib4
, Win32_MIB_IFROW mib6
)
306 public override IPv4InterfaceProperties
GetIPv4Properties ()
308 Win32_IP_ADAPTER_INFO v4info
= Win32NetworkInterface2
.GetAdapterInfoByIndex (mib4
.Index
);
309 return v4info
!= null ? new Win32IPv4InterfaceProperties (v4info
, mib4
) : null;
312 public override IPv6InterfaceProperties
GetIPv6Properties ()
314 Win32_IP_ADAPTER_INFO v6info
= Win32NetworkInterface2
.GetAdapterInfoByIndex (mib6
.Index
);
315 return v6info
!= null ? new Win32IPv6InterfaceProperties (mib6
) : null;
318 public override IPAddressInformationCollection AnycastAddresses
{
319 get { return IPAddressInformationImplCollection.Win32FromAnycast (addr.FirstAnycastAddress); }
322 public override IPAddressCollection DhcpServerAddresses
{
324 Win32_IP_ADAPTER_INFO v4info
= Win32NetworkInterface2
.GetAdapterInfoByIndex (mib4
.Index
);
325 // FIXME: should ipv6 DhcpServer be considered?
326 return v4info
!= null ? new Win32IPAddressCollection (v4info
.DhcpServer
) : Win32IPAddressCollection
.Empty
;
330 public override IPAddressCollection DnsAddresses
{
331 get { return Win32IPAddressCollection.FromDnsServer (addr.FirstDnsServerAddress); }
334 public override string DnsSuffix
{
335 get { return addr.DnsSuffix; }
338 public override GatewayIPAddressInformationCollection GatewayAddresses
{
340 Win32_IP_ADAPTER_INFO v4info
= Win32NetworkInterface2
.GetAdapterInfoByIndex (mib4
.Index
);
341 // FIXME: should ipv6 DhcpServer be considered?
342 return v4info
!= null ? new Win32GatewayIPAddressInformationCollection (v4info
.GatewayList
) : Win32GatewayIPAddressInformationCollection
.Empty
;
346 public override bool IsDnsEnabled
{
347 get { return Win32_FIXED_INFO.Instance.EnableDns != 0; }
350 public override bool IsDynamicDnsEnabled
{
351 get { return addr.DdnsEnabled; }
354 public override MulticastIPAddressInformationCollection MulticastAddresses
{
355 get { return MulticastIPAddressInformationImplCollection.Win32FromMulticast (addr.FirstMulticastAddress); }
358 public override UnicastIPAddressInformationCollection UnicastAddresses
{
360 Win32_IP_ADAPTER_INFO ai
= Win32NetworkInterface2
.GetAdapterInfoByIndex (mib4
.Index
);
361 // FIXME: should ipv6 DhcpServer be considered?
362 return ai
!= null ? UnicastIPAddressInformationImplCollection
.Win32FromUnicast ((int) ai
.Index
, addr
.FirstUnicastAddress
) : UnicastIPAddressInformationImplCollection
.Empty
;
366 public override IPAddressCollection WinsServersAddresses
{
368 Win32_IP_ADAPTER_INFO v4info
= Win32NetworkInterface2
.GetAdapterInfoByIndex (mib4
.Index
);
369 // FIXME: should ipv6 DhcpServer be considered?
370 return v4info
!= null ? new Win32IPAddressCollection (v4info
.PrimaryWinsServer
, v4info
.SecondaryWinsServer
) : Win32IPAddressCollection
.Empty
;