2 // System.Net.NetworkInformation.IPGlobalProperties
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
.Collections
.Specialized
;
32 using System
.Globalization
;
34 using System
.Net
.Sockets
;
35 using System
.Runtime
.InteropServices
;
38 namespace System
.Net
.NetworkInformation
{
39 public abstract class IPGlobalProperties
{
40 protected IPGlobalProperties ()
44 public static IPGlobalProperties
GetIPGlobalProperties ()
46 switch (Environment
.OSVersion
.Platform
) {
48 MibIPGlobalProperties impl
= null;
49 if (Directory
.Exists (MibIPGlobalProperties
.ProcDir
)) {
50 impl
= new MibIPGlobalProperties (MibIPGlobalProperties
.ProcDir
);
51 if (File
.Exists (impl
.StatisticsFile
))
54 if (Directory
.Exists (MibIPGlobalProperties
.CompatProcDir
)) {
55 impl
= new MibIPGlobalProperties (MibIPGlobalProperties
.CompatProcDir
);
56 if (File
.Exists (impl
.StatisticsFile
))
59 throw new NotSupportedException ("This platform is not supported");
61 return new Win32IPGlobalProperties ();
65 public abstract TcpConnectionInformation
[] GetActiveTcpConnections ();
66 public abstract IPEndPoint
[] GetActiveTcpListeners ();
67 public abstract IPEndPoint
[] GetActiveUdpListeners ();
68 public abstract IcmpV4Statistics
GetIcmpV4Statistics ();
69 public abstract IcmpV6Statistics
GetIcmpV6Statistics ();
70 public abstract IPGlobalStatistics
GetIPv4GlobalStatistics ();
71 public abstract IPGlobalStatistics
GetIPv6GlobalStatistics ();
72 public abstract TcpStatistics
GetTcpIPv4Statistics ();
73 public abstract TcpStatistics
GetTcpIPv6Statistics ();
74 public abstract UdpStatistics
GetUdpIPv4Statistics ();
75 public abstract UdpStatistics
GetUdpIPv6Statistics ();
77 public abstract string DhcpScopeName { get; }
78 public abstract string DomainName { get; }
79 public abstract string HostName { get; }
80 public abstract bool IsWinsProxy { get; }
81 public abstract NetBiosNodeType NodeType { get; }
84 // It expects /proc/net/snmp (or /usr/compat/linux/proc/net/snmp),
86 // http://www.linuxdevcenter.com/linux/2000/11/16/example5.html
87 // http://www.linuxdevcenter.com/linux/2000/11/16/example2.html
88 class MibIPGlobalProperties
: IPGlobalProperties
91 static extern int gethostname ([MarshalAs (UnmanagedType
.LPArray
, SizeParamIndex
= 1)] byte [] name
, int len
);
94 static extern int getdomainname ([MarshalAs (UnmanagedType
.LPArray
, SizeParamIndex
= 1)] byte [] name
, int len
);
96 public const string ProcDir
= "/proc";
97 public const string CompatProcDir
= "/usr/compat/linux/proc";
99 public readonly string StatisticsFile
, StatisticsFileIPv6
, TcpFile
, Tcp6File
, UdpFile
, Udp6File
;
101 public MibIPGlobalProperties (string procDir
)
103 StatisticsFile
= Path
.Combine (procDir
, "net/snmp");
104 StatisticsFileIPv6
= Path
.Combine (procDir
, "net/snmp6");
105 TcpFile
= Path
.Combine (procDir
,"net/tcp");
106 Tcp6File
= Path
.Combine (procDir
,"net/tcp6");
107 UdpFile
= Path
.Combine (procDir
,"net/udp");
108 Udp6File
= Path
.Combine (procDir
,"net/udp6");
111 StringDictionary
GetProperties4 (string item
)
113 string file
= StatisticsFile
;
115 string head
= item
+ ": ";
116 using (StreamReader sr
= new StreamReader (file
, Encoding
.ASCII
)) {
117 string [] keys
= null;
118 string [] values
= null;
119 string s
= String
.Empty
;
122 if (String
.IsNullOrEmpty (s
))
124 if (s
.Length
<= head
.Length
|| String
.CompareOrdinal (s
, 0, head
, 0, head
.Length
) != 0)
127 keys
= s
.Substring (head
.Length
).Split (' ');
128 else if (values
!= null)
129 // hmm, there may be better error type...
130 throw CreateException (file
, String
.Format ("Found duplicate line for values for the same item '{0}'", item
));
132 values
= s
.Substring (head
.Length
).Split (' ');
135 } while (!sr
.EndOfStream
);
138 throw CreateException (file
, String
.Format ("No corresponding line was not found for '{0}'", item
));
139 if (keys
.Length
!= values
.Length
)
140 throw CreateException (file
, String
.Format ("The counts in the header line and the value line do not match for '{0}'", item
));
141 StringDictionary dic
= new StringDictionary ();
142 for (int i
= 0; i
< keys
.Length
; i
++)
143 dic
[keys
[i
]] = values
[i
];
148 StringDictionary
GetProperties6 (string item
)
150 if (!File
.Exists (StatisticsFileIPv6
))
151 throw new NetworkInformationException ();
153 string file
= StatisticsFileIPv6
;
156 using (StreamReader sr
= new StreamReader (file
, Encoding
.ASCII
)) {
157 StringDictionary dic
= new StringDictionary ();
158 string s
= String
.Empty
;
161 if (String
.IsNullOrEmpty (s
))
163 if (s
.Length
<= head
.Length
|| String
.CompareOrdinal (s
, 0, head
, 0, head
.Length
) != 0)
165 int idx
= s
.IndexOfAny (wsChars
, head
.Length
);
167 throw CreateException (file
, null);
168 dic
[s
.Substring (head
.Length
, idx
- head
.Length
)] = s
.Substring (idx
+ 1).Trim (wsChars
);
169 } while (!sr
.EndOfStream
);
175 static readonly char [] wsChars
= new char [] {' ', '\t'}
;
177 Exception
CreateException (string file
, string msg
)
179 return new InvalidOperationException (String
.Format ("Unsupported (unexpected) '{0}' file format. ", file
) + msg
);
181 IPEndPoint
[] GetLocalAddresses (List
<string []> list
)
183 IPEndPoint
[] ret
= new IPEndPoint
[list
.Count
];
184 for (int i
= 0; i
< ret
.Length
; i
++)
185 ret
[i
] = ToEndpoint (list
[i
] [1]);
189 IPEndPoint
ToEndpoint (string s
)
191 int idx
= s
.IndexOf (':');
192 int port
= int.Parse (s
.Substring (idx
+ 1), NumberStyles
.HexNumber
);
194 return new IPEndPoint (long.Parse (s
.Substring (0, idx
), NumberStyles
.HexNumber
), port
);
196 byte [] bytes
= new byte [16];
197 for (int i
= 0; (i
<< 1) < idx
; i
++)
198 bytes
[i
] = byte.Parse (s
.Substring (i
<< 1, 2), NumberStyles
.HexNumber
);
199 return new IPEndPoint (new IPAddress (bytes
), port
);
203 void GetRows (string file
, List
<string []> list
)
205 if (!File
.Exists (file
))
207 using (StreamReader sr
= new StreamReader (file
, Encoding
.ASCII
)) {
208 sr
.ReadLine (); // skip first line
209 while (!sr
.EndOfStream
) {
210 string [] item
= sr
.ReadLine ().Split (wsChars
, StringSplitOptions
.RemoveEmptyEntries
);
212 throw CreateException (file
, null);
218 public override TcpConnectionInformation
[] GetActiveTcpConnections ()
220 List
<string []> list
= new List
<string []> ();
221 GetRows (TcpFile
, list
);
222 GetRows (Tcp6File
, list
);
224 TcpConnectionInformation
[] ret
= new TcpConnectionInformation
[list
.Count
];
225 for (int i
= 0; i
< ret
.Length
; i
++) {
226 // sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
227 IPEndPoint local
= ToEndpoint (list
[i
] [1]);
228 IPEndPoint remote
= ToEndpoint (list
[i
] [2]);
229 TcpState state
= (TcpState
) int.Parse (list
[i
] [3], NumberStyles
.HexNumber
);
230 ret
[i
] = new TcpConnectionInformationImpl (local
, remote
, state
);
235 public override IPEndPoint
[] GetActiveTcpListeners ()
237 List
<string []> list
= new List
<string []> ();
238 GetRows (TcpFile
, list
);
239 GetRows (Tcp6File
, list
);
240 return GetLocalAddresses (list
);
243 public override IPEndPoint
[] GetActiveUdpListeners ()
245 List
<string []> list
= new List
<string []> ();
246 GetRows (UdpFile
, list
);
247 GetRows (Udp6File
, list
);
248 return GetLocalAddresses (list
);
251 public override IcmpV4Statistics
GetIcmpV4Statistics ()
253 return new MibIcmpV4Statistics (GetProperties4 ("Icmp"));
256 public override IcmpV6Statistics
GetIcmpV6Statistics ()
258 return new MibIcmpV6Statistics (GetProperties6 ("Icmp6"));
261 public override IPGlobalStatistics
GetIPv4GlobalStatistics ()
263 return new MibIPGlobalStatistics (GetProperties4 ("Ip"));
266 public override IPGlobalStatistics
GetIPv6GlobalStatistics ()
268 return new MibIPGlobalStatistics (GetProperties6 ("Ip6"));
271 public override TcpStatistics
GetTcpIPv4Statistics ()
273 return new MibTcpStatistics (GetProperties4 ("Tcp"));
276 public override TcpStatistics
GetTcpIPv6Statistics ()
278 // There is no TCP info in /proc/net/snmp,
279 // so it is shared with IPv4 info.
280 return new MibTcpStatistics (GetProperties4 ("Tcp"));
283 public override UdpStatistics
GetUdpIPv4Statistics ()
285 return new MibUdpStatistics (GetProperties4 ("Udp"));
288 public override UdpStatistics
GetUdpIPv6Statistics ()
290 return new MibUdpStatistics (GetProperties6 ("Udp6"));
293 public override string DhcpScopeName
{
294 get { return String.Empty; }
297 public override string DomainName
{
299 byte [] bytes
= new byte [256];
300 if (getdomainname (bytes
, 256) != 0)
301 throw new NetworkInformationException ();
302 int len
= Array
.IndexOf
<byte> (bytes
, 0);
303 return Encoding
.ASCII
.GetString (bytes
, 0, len
< 0 ? 256 : len
);
307 public override string HostName
{
309 byte [] bytes
= new byte [256];
310 if (gethostname (bytes
, 256) != 0)
311 throw new NetworkInformationException ();
312 int len
= Array
.IndexOf
<byte> (bytes
, 0);
313 return Encoding
.ASCII
.GetString (bytes
, 0, len
< 0 ? 256 : len
);
317 public override bool IsWinsProxy
{
318 get { return false; }
// no WINS
321 public override NetBiosNodeType NodeType
{
322 get { return NetBiosNodeType.Unknown; }
// no NetBios
326 class Win32IPGlobalProperties
: IPGlobalProperties
328 public const int AF_INET
= 2;
329 public const int AF_INET6
= 23;
331 // FIXME: it might be getting wrong table. I'm getting
332 // different results from .NET 2.0.
333 unsafe void FillTcpTable (out List
<Win32_MIB_TCPROW
> tab4
, out List
<Win32_MIB_TCP6ROW
> tab6
)
335 tab4
= new List
<Win32_MIB_TCPROW
> ();
337 GetTcpTable (null, ref size4
, true); // get size
338 byte [] bytes4
= new byte [size4
];
339 GetTcpTable (bytes4
, ref size4
, true); // get list
341 int structSize4
= Marshal
.SizeOf (typeof (Win32_MIB_TCPROW
));
343 fixed (byte* ptr
= bytes4
) {
344 int count
= Marshal
.ReadInt32 ((IntPtr
) ptr
);
345 for (int i
= 0; i
< count
; i
++) {
346 Win32_MIB_TCPROW row
= new Win32_MIB_TCPROW ();
347 Marshal
.PtrToStructure ((IntPtr
) (ptr
+ i
* structSize4
+ 4), row
);
352 tab6
= new List
<Win32_MIB_TCP6ROW
> ();
353 if (Environment
.OSVersion
.Version
.Major
>= 6) { // Vista
355 GetTcp6Table (null, ref size6
, true); // get size
356 byte [] bytes6
= new byte [size6
];
357 GetTcp6Table (bytes6
, ref size6
, true); // get list
359 int structSize6
= Marshal
.SizeOf (typeof (Win32_MIB_TCP6ROW
));
361 fixed (byte* ptr
= bytes6
) {
362 int count
= Marshal
.ReadInt32 ((IntPtr
) ptr
);
363 for (int i
= 0; i
< count
; i
++) {
364 Win32_MIB_TCP6ROW row
= new Win32_MIB_TCP6ROW ();
365 Marshal
.PtrToStructure ((IntPtr
) (ptr
+ i
* structSize6
+ 4), row
);
372 bool IsListenerState (TcpState state
)
375 case TcpState
.SynSent
:
376 case TcpState
.Listen
:
377 case TcpState
.FinWait1
:
378 case TcpState
.FinWait2
:
379 case TcpState
.CloseWait
:
385 public override TcpConnectionInformation
[] GetActiveTcpConnections ()
387 List
<Win32_MIB_TCPROW
> tab4
= null;
388 List
<Win32_MIB_TCP6ROW
> tab6
= null;
389 FillTcpTable (out tab4
, out tab6
);
390 int size4
= tab4
.Count
;
392 TcpConnectionInformation
[] ret
= new TcpConnectionInformation
[size4
+ tab6
.Count
];
393 for (int i
= 0; i
< size4
; i
++)
394 ret
[i
] = tab4
[i
].TcpInfo
;
395 for (int i
= 0; i
< tab6
.Count
; i
++)
396 ret
[size4
+ i
] = tab6
[i
].TcpInfo
;
400 public override IPEndPoint
[] GetActiveTcpListeners ()
402 List
<Win32_MIB_TCPROW
> tab4
= null;
403 List
<Win32_MIB_TCP6ROW
> tab6
= null;
404 FillTcpTable (out tab4
, out tab6
);
406 List
<IPEndPoint
> ret
= new List
<IPEndPoint
> ();
407 for (int i
= 0, count
= tab4
.Count
; i
< count
; i
++)
408 if (IsListenerState (tab4
[i
].State
))
409 ret
.Add (tab4
[i
].LocalEndPoint
);
410 for (int i
= 0, count
= tab6
.Count
; i
< count
; i
++)
411 if (IsListenerState (tab6
[i
].State
))
412 ret
.Add (tab6
[i
].LocalEndPoint
);
413 return ret
.ToArray ();
416 public unsafe override IPEndPoint
[] GetActiveUdpListeners ()
418 List
<IPEndPoint
> list
= new List
<IPEndPoint
> ();
420 byte [] bytes4
= null;
422 GetUdpTable (null, ref size4
, true); // get size
423 bytes4
= new byte [size4
];
424 GetUdpTable (bytes4
, ref size4
, true); // get list
426 int structSize4
= Marshal
.SizeOf (typeof (Win32_MIB_UDPROW
));
428 fixed (byte* ptr
= bytes4
) {
429 int count
= Marshal
.ReadInt32 ((IntPtr
) ptr
);
430 for (int i
= 0; i
< count
; i
++) {
431 Win32_MIB_UDPROW row
= new Win32_MIB_UDPROW ();
432 Marshal
.PtrToStructure ((IntPtr
) (ptr
+ i
* structSize4
+ 4), row
);
433 list
.Add (row
.LocalEndPoint
);
437 if (Environment
.OSVersion
.Version
.Major
>= 6) { // Vista
438 byte [] bytes6
= null;
440 GetUdp6Table (null, ref size6
, true); // get size
441 bytes6
= new byte [size6
];
442 GetUdp6Table (bytes6
, ref size6
, true); // get list
444 int structSize6
= Marshal
.SizeOf (typeof (Win32_MIB_UDP6ROW
));
446 fixed (byte* ptr
= bytes6
) {
447 int count
= Marshal
.ReadInt32 ((IntPtr
) ptr
);
448 for (int i
= 0; i
< count
; i
++) {
449 Win32_MIB_UDP6ROW row
= new Win32_MIB_UDP6ROW ();
450 Marshal
.PtrToStructure ((IntPtr
) (ptr
+ i
* structSize6
+ 4), row
);
451 list
.Add (row
.LocalEndPoint
);
456 return list
.ToArray ();
459 public override IcmpV4Statistics
GetIcmpV4Statistics ()
461 if (!Socket
.SupportsIPv4
)
462 throw new NetworkInformationException ();
463 Win32_MIBICMPINFO stats
;
464 GetIcmpStatistics (out stats
, AF_INET
);
465 return new Win32IcmpV4Statistics (stats
);
468 public override IcmpV6Statistics
GetIcmpV6Statistics ()
470 if (!Socket
.OSSupportsIPv6
)
471 throw new NetworkInformationException ();
472 Win32_MIB_ICMP_EX stats
;
473 GetIcmpStatisticsEx (out stats
, AF_INET6
);
474 return new Win32IcmpV6Statistics (stats
);
477 public override IPGlobalStatistics
GetIPv4GlobalStatistics ()
479 if (!Socket
.SupportsIPv4
)
480 throw new NetworkInformationException ();
481 Win32_MIB_IPSTATS stats
;
482 GetIPStatisticsEx (out stats
, AF_INET
);
483 return new Win32IPGlobalStatistics (stats
);
486 public override IPGlobalStatistics
GetIPv6GlobalStatistics ()
488 if (!Socket
.OSSupportsIPv6
)
489 throw new NetworkInformationException ();
490 Win32_MIB_IPSTATS stats
;
491 GetIPStatisticsEx (out stats
, AF_INET6
);
492 return new Win32IPGlobalStatistics (stats
);
495 public override TcpStatistics
GetTcpIPv4Statistics ()
497 if (!Socket
.SupportsIPv4
)
498 throw new NetworkInformationException ();
499 Win32_MIB_TCPSTATS stats
;
500 GetTcpStatisticsEx (out stats
, AF_INET
);
501 return new Win32TcpStatistics (stats
);
504 public override TcpStatistics
GetTcpIPv6Statistics ()
506 if (!Socket
.OSSupportsIPv6
)
507 throw new NetworkInformationException ();
508 Win32_MIB_TCPSTATS stats
;
509 GetTcpStatisticsEx (out stats
, AF_INET6
);
510 return new Win32TcpStatistics (stats
);
513 public override UdpStatistics
GetUdpIPv4Statistics ()
515 if (!Socket
.SupportsIPv4
)
516 throw new NetworkInformationException ();
517 Win32_MIB_UDPSTATS stats
;
518 GetUdpStatisticsEx (out stats
, AF_INET
);
519 return new Win32UdpStatistics (stats
);
522 public override UdpStatistics
GetUdpIPv6Statistics ()
524 if (!Socket
.OSSupportsIPv6
)
525 throw new NetworkInformationException ();
526 Win32_MIB_UDPSTATS stats
;
527 GetUdpStatisticsEx (out stats
, AF_INET6
);
528 return new Win32UdpStatistics (stats
);
531 public override string DhcpScopeName
{
532 get { return Win32_FIXED_INFO.Instance.ScopeId; }
535 public override string DomainName
{
536 get { return Win32_FIXED_INFO.Instance.DomainName; }
539 public override string HostName
{
540 get { return Win32_FIXED_INFO.Instance.HostName; }
543 public override bool IsWinsProxy
{
544 get { return Win32_FIXED_INFO.Instance.EnableProxy != 0; }
547 public override NetBiosNodeType NodeType
{
548 get { return Win32_FIXED_INFO.Instance.NodeType; }
553 [DllImport ("Iphlpapi.dll")]
554 static extern int GetTcpTable (byte [] pTcpTable
, ref int pdwSize
, bool bOrder
);
556 [DllImport ("Iphlpapi.dll")]
557 static extern int GetTcp6Table (byte [] TcpTable
, ref int SizePointer
, bool Order
);
559 [DllImport ("Iphlpapi.dll")]
560 static extern int GetUdpTable (byte [] pUdpTable
, ref int pdwSize
, bool bOrder
);
562 [DllImport ("Iphlpapi.dll")]
563 static extern int GetUdp6Table (byte [] Udp6Table
, ref int SizePointer
, bool Order
);
565 [DllImport ("Iphlpapi.dll")]
566 static extern int GetTcpStatisticsEx (out Win32_MIB_TCPSTATS pStats
, int dwFamily
);
568 [DllImport ("Iphlpapi.dll")]
569 static extern int GetUdpStatisticsEx (out Win32_MIB_UDPSTATS pStats
, int dwFamily
);
571 [DllImport ("Iphlpapi.dll")]
572 static extern int GetIcmpStatistics (out Win32_MIBICMPINFO pStats
, int dwFamily
);
574 [DllImport ("Iphlpapi.dll")]
575 static extern int GetIcmpStatisticsEx (out Win32_MIB_ICMP_EX pStats
, int dwFamily
);
577 [DllImport ("Iphlpapi.dll")]
578 static extern int GetIPStatisticsEx (out Win32_MIB_IPSTATS pStats
, int dwFamily
);
582 [StructLayout (LayoutKind
.Explicit
)]
583 struct Win32_IN6_ADDR
586 [MarshalAs ((short) UnmanagedType
.U1
, SizeConst
= 16)]
587 public byte [] Bytes
;
590 [StructLayout (LayoutKind
.Sequential
)]
591 class Win32_MIB_TCPROW
593 public TcpState State
;
594 public uint LocalAddr
;
595 public int LocalPort
;
596 public uint RemoteAddr
;
597 public int RemotePort
;
599 public IPEndPoint LocalEndPoint
{
600 get { return new IPEndPoint (LocalAddr, LocalPort); }
603 public IPEndPoint RemoteEndPoint
{
604 get { return new IPEndPoint (RemoteAddr, RemotePort); }
607 public TcpConnectionInformation TcpInfo
{
608 get { return new TcpConnectionInformationImpl (LocalEndPoint, RemoteEndPoint, State); }
612 [StructLayout (LayoutKind
.Sequential
)]
613 class Win32_MIB_TCP6ROW
615 public TcpState State
;
616 public Win32_IN6_ADDR LocalAddr
;
617 public uint LocalScopeId
;
618 public int LocalPort
;
619 public Win32_IN6_ADDR RemoteAddr
;
620 public uint RemoteScopeId
;
621 public int RemotePort
;
623 public IPEndPoint LocalEndPoint
{
624 get { return new IPEndPoint (new IPAddress (LocalAddr.Bytes, LocalScopeId), LocalPort); }
627 public IPEndPoint RemoteEndPoint
{
628 get { return new IPEndPoint (new IPAddress (RemoteAddr.Bytes, RemoteScopeId), RemotePort); }
631 public TcpConnectionInformation TcpInfo
{
632 get { return new TcpConnectionInformationImpl (LocalEndPoint, RemoteEndPoint, State); }
636 [StructLayout (LayoutKind
.Sequential
)]
637 class Win32_MIB_UDPROW
639 public uint LocalAddr
;
640 public int LocalPort
;
642 public IPEndPoint LocalEndPoint
{
643 get { return new IPEndPoint (LocalAddr, LocalPort); }
647 [StructLayout (LayoutKind
.Sequential
)]
648 class Win32_MIB_UDP6ROW
650 public Win32_IN6_ADDR LocalAddr
;
651 public uint LocalScopeId
;
652 public int LocalPort
;
654 public IPEndPoint LocalEndPoint
{
655 get { return new IPEndPoint (new IPAddress (LocalAddr.Bytes, LocalScopeId), LocalPort); }