The Assimilation Project  based on Assimilation version 1.1.7.1474836767
netconfig.cs
Go to the documentation of this file.
1 
23 using System;
24 using System.Collections;
25 using System.Collections.Generic;
26 using System.Linq;
27 using System.Text;
28 using System.Management;
29 using System.ComponentModel;
30 using System.Web.Script.Serialization;
31 using System.Runtime.InteropServices;
32 using Microsoft.Win32;
33 using System.Net;
34 using System.Net.Sockets;
35 using System.Net.NetworkInformation;
36 using System.Diagnostics;
37 
38 using netconfig;
39 
40 namespace netconfig
41 {
42 
44  public class NetDisc
45  {
46  public const Int32 MAX_ADAPTER_NAME = 128;
47  public const Int32 MAX_ADAPTER_NAME_LENGTH = 256;
48  public const Int32 MAX_ADAPTER_DESCRIPTION_LENGTH = 128;
49  public const Int32 MAX_ADAPTER_ADDRESS_LENGTH = 8;
50  public const UInt32 ERROR_BUFFER_OVERFLOW = (UInt32)111;
51  public const Int32 ERROR_SUCCESS = 0;
52 
53  [Flags]
54  public enum GAA_FLAGS
55  {
56  GAA_NONE = 0x0000,
57  GAA_SKIP_UNICAST = 0x0001,
58  GAA_SKIP_ANYCAST = 0x0002,
59  GAA_SKIP_MULTICAST = 0x0004,
60  GAA_SKIP_DNS_SERVER = 0x0008,
61  GAA_INCLUDE_PREFIX = 0x0010,
62  GAA_SKIP_FRIENDLY_NAME = 0x0020,
63  GAA_INCLUDE_WINS_INFO = 0x0040,
64  GAA_INCLUDE_GATEWAYS = 0x0080,
65  GAA_INCLUDE_ALL_INTERFACES = 0x0100,
66  GAA_INCLUDE_ALL_COMPARTMENTS = 0x0200,
67  GAA_INCLUDE_TUNNEL_BINDINGORDER = 0x0400
68  }
69 
70  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
71  public struct SOCKET_ADDRESS
72  {
73  public IntPtr lpSockAddr;
74  public Int32 iSockaddrLength;
75  }
76  public enum IP_PREFIX_ORIGIN
77  {
78  IpPrefixOriginOther = 0,
79  IpPrefixOriginManual,
80  IpPrefixOriginWellKnown,
81  IpPrefixOriginDhcp,
82  IpPrefixOriginRouterAdvertisement
83  }
84  public enum IP_SUFFIX_ORIGIN
85  {
86  IpSuffixOriginOther = 0,
87  IpSuffixOriginManual,
88  IpSuffixOriginWellKnown,
89  IpSuffixOriginDhcp,
90  IpSuffixOriginLinkLayerAddress,
91  IpSuffixOriginRandom
92  }
93  public enum IP_DAD_STATE
94  {
95  IpDadStateInvalid = 0,
96  IpDadStateTentative,
97  IpDadStateDuplicate,
98  IpDadStateDeprecated,
99  IpDadStatePreferred
100  }
101  public enum SCOPE_LEVEL
102  {
103  ScopeLevelInterface = 1,
104  ScopeLevelLink = 2,
105  ScopeLevelSubnet = 3,
106  ScopeLevelAdmin = 4,
107  ScopeLevelSite = 5,
108  ScopeLevelOrganization = 8,
109  ScopeLevelGlobal = 14
110  }
111 
112  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
114  {
115  public UInt32 Length;
116  public UInt32 Flags;
117 
118  public IntPtr Next;
123  public UInt32 ValidLifetime;
124  public UInt32 PreferredLifetime;
125  public UInt32 LeaseLifetime;
126  public Byte OnLinkPrefixLength;
127  }
128 
129  [StructLayout(LayoutKind.Sequential)]
130  private struct IP_ADAPTER_GATEWAY_ADDRESS {
131  public UInt64 Alignment;
132  public IntPtr Next;
133  SOCKET_ADDRESS Address;
134  }
135 
136  [StructLayout(LayoutKind.Sequential)]
137  public struct SOCKADDR
138  {
139  public Int32 sa_family; /* address family */
140 
141  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
142  public byte[] sa_data; /* up to 4 bytes of direct address */
143  };
144  [StructLayout(LayoutKind.Sequential)]
145  public struct SOCKADDRIPV6
146  {
147  public Int64 sa_family; /* address family */
148 
149  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
150  public byte[] sa_data; /* up to 16 bytes of direct address */
151  };
152 
153  private static TraceSource mySource =
154  new TraceSource("netconfig");
155 
157  static void Main(string[] args)
158  {
159  mySource.Switch = new SourceSwitch("netconfig", "Error");
160  mySource.Listeners.Remove("Default");
161  EventLogTraceListener evl = new EventLogTraceListener("netconfig");
162 
163  //Off, Critical, Error, Warning, Information, Verbose, ActivityTracing, All
164  evl.Filter = new EventTypeFilter(SourceLevels.All);
165 
166  mySource.Listeners.Add(evl);
167 
168  Trace.WriteLine("start netconfig");
169 
170  // build the json output string
171  String jout = NetworkExplorer();
172 
173  // add the final brace
174  jout += "}";
175 
176  // send to our stdout
177  System.Console.WriteLine(jout);
178 
179  Trace.WriteLine("end netconfig");
180  mySource.Close();
181  }
182 
184  static private String NetworkExplorer()
185  {
186  List<IP_ADAPTER_ADDRESSES> aAL; // a list of all adapters
187  StringBuilder json_out = new StringBuilder(); // json string builder
188  bool firstadapter = true; // to comma or not to comma
189 
190  Trace.WriteLine("start NetworkExplorer");
191  // build the boiler plate
192  json_out.Append("{\n \"discovertype\": \"netconfig\",\n \"description\": \"IP Network Configuration\",\n");
193  json_out.Append(" \"source\": \"netconfig\",\n");
194  json_out.Append(" \"host\": ");
195 
196  json_out.Append("\"");
197  json_out.Append(System.Environment.GetEnvironmentVariable("COMPUTERNAME"));
198  json_out.Append("\",\n");
199 
200  json_out.Append(" \"data\": {\n");
201 
202  //get the list of all adapters
203  Adapter.GetAdaptersAddresses(AddressFamily.Unspecified, GAA_FLAGS.GAA_NONE, out aAL);
204 
205  foreach (IP_ADAPTER_ADDRESSES A in aAL)
206  {
207  string tmps;
208  string adapterName = Marshal.PtrToStringAnsi(A.AdapterName);
209  string FriendlyName = Marshal.PtrToStringAuto(A.FriendlyName);
210  string description = Marshal.PtrToStringAuto(A.Description);
211 
212  uint operationstatus = A.OperStatus;
213  if (operationstatus != 1)
214  {
215  continue;
216  }
217  /*
218  if (A.IfType == 24) // loopback
219  {
220  continue;
221  }
222  */
223  if (firstadapter)
224  {
225  json_out.Append(" \"");
226  firstadapter = false;
227  }
228  else
229  {
230  json_out.Append(",\n \"");
231  }
232  json_out.Append(FriendlyName);
233  json_out.Append("\": {\n");
234 
235  // build the mac address string
236  tmps = "";
237  for (int i = 0; i < 6; i++)
238  {
239  tmps += string.Format("{0:X2}", A.PhysicalAddress[i]);
240  if (i < 5)
241  {
242  tmps += ":";
243  }
244  }
245 
246  json_out.Append(" \"address\": \"");
247  json_out.Append(tmps);
248  json_out.Append("\",\n");
249 
250  json_out.Append(" \"mtu\": ");
251  json_out.Append(A.Mtu);
252  json_out.Append(",\n");
253 
254  // this doesn't work on my xp development machine, this field + others require vista or later
255  //json_out.Append(" \"speed\": "); //doesn't work
256  //json_out.Append(A.TransmitLinkSpeed);
257  //json_out.Append(",\n");
258 
259  json_out.Append(" \"operstate\": \"");
260  json_out.Append((operationstatus == 1 ? "UP" : "DOWN"));
261  json_out.Append("\",\n");
262 
263  // check for ip address
265  IntPtr next = A.FirstUnicastAddress;
266  bool firstipaddr = true;
267 
268  json_out.Append(" \"ipaddrs\": {\n");
269 
270  if (next != (IntPtr)0)
271  {
272  /*TODO -- doesn't work on xp, it should on vista or later */
273  // IP_ADAPTER_GATEWAY_ADDRESS ipG;
274  // IntPtr gNext = A.FirstGatewayAddress;
275  // if (gNext != (IntPtr)0)
276  // {
277  // ipG = (IP_ADAPTER_GATEWAY_ADDRESS)Marshal.PtrToStructure(gNext, typeof(IP_ADAPTER_GATEWAY_ADDRESS));
278  // }
279  /*TODO*/
280  do
281  {
282  ipua = (IP_ADAPTER_UNICAST_ADDRESS)Marshal.PtrToStructure(next, typeof(IP_ADAPTER_UNICAST_ADDRESS));
283  SOCKET_ADDRESS sock_addr;
284  sock_addr = (SOCKET_ADDRESS)ipua.Address;
285  next = ipua.Next;
286 
287  SOCKADDR sockaddr;
288  SOCKADDRIPV6 sockaddripv6;
289  IPAddress ipaddr = null;
290 
291  //Marshal memory pointer into a struct
292  sockaddr = (SOCKADDR)Marshal.PtrToStructure(sock_addr.lpSockAddr, typeof(SOCKADDR));
293 
294  //Check if the address family is IPV4
295  if (sockaddr.sa_family == (Int32)System.Net.Sockets.AddressFamily.InterNetwork)
296  {
297  ipaddr = new IPAddress(sockaddr.sa_data);
298  }
299  else if (sockaddr.sa_family == (Int32)System.Net.Sockets.AddressFamily.InterNetworkV6)
300  {
301  //Marshal memory pointer into a struct
302  sockaddripv6 = (SOCKADDRIPV6)Marshal.PtrToStructure(sock_addr.lpSockAddr, typeof(SOCKADDRIPV6));
303  ipaddr = new IPAddress(sockaddripv6.sa_data);
304  }
305 
306  if (ipaddr == null)
307  {
308  Trace.WriteLine("unable to create socket" + sockaddr.ToString());
309  throw new MemberAccessException("Could not parse the interface's IP Address.");
310  }
311 
312  int bc = 128;
313  String ba = "";
314 
315  // the mumbo jumbo in GetIPv4gateway gets netmask & broadcast address for ipv4 on xp
316  // it probably could be deleted if we required vista or later
317  if (sockaddr.sa_family == (Int32)System.Net.Sockets.AddressFamily.InterNetwork)
318  {
319  GetIPv4gateway(A, ipaddr, out bc, out ba);
320  }
321 
322  if (firstipaddr)
323  {
324  json_out.Append(" \"");
325  firstipaddr = false;
326  }
327  else
328  {
329  json_out.Append(",\n \"");
330  }
331  json_out.Append(ipaddr.ToString() + "/" + bc.ToString());
332 
333  if (ipaddr.AddressFamily == AddressFamily.InterNetworkV6)
334  {
335  json_out.Append("\": {");
336  if (A.IfType == 24)
337  { // loopback
338  json_out.Append("\"scope\":\"host\"");
339  }
340  else if (ipaddr.IsIPv6LinkLocal)
341  {
342  json_out.Append("\"scope\":\"link\"");
343  }
344  else if (ipaddr.IsIPv6SiteLocal)
345  {
346  json_out.Append("\"scope\":\"host\"");
347  }
348  else if (ipaddr.IsIPv6Multicast)
349  {
350  json_out.Append("\"scope\":\"multicast\"");
351  }
352  else
353  {
354  json_out.Append("\"scope\":\"global\"");
355  }
356  json_out.Append("}");
357  }
358  else
359  {
360  if (ba.Length > 0)
361  {
362  json_out.Append("\": {\"brd\":\"");
363  json_out.Append(ba);
364  json_out.Append("\"}\n");
365  }
366  else
367  {
368  json_out.Append("\": {}");
369  }
370 
371 
372  }
373 
374  } while (next != (IntPtr)0);
375  json_out.Append(" }\n");
376  }
377  json_out.Append(" }\n");
378  }
379  json_out.Append(" }\n");
380 
381  Trace.WriteLine("end NetworkExplorer");
382 
383  return (json_out.ToString());
384  }
385 
386  public static void GetIPv4gateway(IP_ADAPTER_ADDRESSES A, IPAddress ipaddr, out int bc, out string ba)
387  {
388  bc = 32;
389  ba = "";
390  string first_multi = "";
391 
392  Trace.WriteLine("start GetIPv4gateway");
393 
394  NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces();
395  foreach (NetworkInterface adapter in adapters)
396  {
397  // match c# adapter to win32 adapter A passed in
398  if (adapter.Name.CompareTo(Marshal.PtrToStringAuto(A.FriendlyName)) != 0)
399  {
400  continue;
401  }
402  // get a c# view of adapter properties
403  IPInterfaceProperties adapterProperties = adapter.GetIPProperties();
404 
405  // get the first multicast address
406  MulticastIPAddressInformationCollection multiCast = adapterProperties.MulticastAddresses;
407  if (multiCast != null)
408  {
409  foreach (IPAddressInformation multi in multiCast)
410  {
411  if (first_multi.Length == 0)
412  {
413  multi.Address.ToString();
414  }
415  Trace.WriteLine(" multi " + multi.Address.ToString());
416  continue;
417  }
418  }
419 
420  UnicastIPAddressInformationCollection uniCast = adapterProperties.UnicastAddresses;
421  if (uniCast != null)
422  {
423  foreach (UnicastIPAddressInformation uni in uniCast)
424  {
425  // chop off any % char and what trails it
426  string s1 = uni.Address.ToString();
427  string s2 = ipaddr.ToString();
428  if (s1.IndexOf((char)'%') != -1)
429  {
430  s1 = s1.Substring(0, s1.IndexOf((char)'%'));
431  }
432  if (s2.IndexOf((char)'%') != -1)
433  {
434  s2 = s2.Substring(0, s2.IndexOf((char)'%'));
435  }
436  if (s1.Equals(s2))
437  {
438  Trace.WriteLine("unicast addr " + s1);
439  if (uni.IPv4Mask != null)
440  {
441  byte[] bcast_add = uni.Address.GetAddressBytes();
442 
443  // check for ipv4
444  if (uni.IPv4Mask.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
445  {
446  ba = uni.IPv4Mask.ToString();
447 
448  byte[] ipAdressBytes = uni.Address.GetAddressBytes();
449  byte[] subnetMaskBytes = uni.IPv4Mask.GetAddressBytes();
450 
451  if (ipAdressBytes.Length != subnetMaskBytes.Length)
452  {
453  if (ipAdressBytes.Length > 4)
454  {
455  Trace.WriteLine(" ipAdressBytes.Length = " + ipAdressBytes.Length.ToString());
456  Trace.WriteLine(" different addr length " + uni.Address.ToString() + " " + uni.IPv4Mask.ToString());
457  ba = first_multi;
458  bc = 64;
459  }
460  break;
461  }
462  bc = 0;
463  int totbits = subnetMaskBytes.Length * 8;
464  for (int i = 0; i < subnetMaskBytes.Length; i++)
465  {
466  for (int j = 0; j < totbits; j++)
467  {
468  byte maskbit = (byte)(1 << j);
469  if ((maskbit & subnetMaskBytes[i]) != 0)
470  {
471  bc++;
472  }
473  else
474  {
475  bcast_add[i] |= maskbit;
476  }
477  }
478  }
479 
480  StringBuilder sb = new StringBuilder(bcast_add.Length * 4);
481  foreach (byte b in bcast_add)
482  {
483  sb.AppendFormat("{0}", b);
484  sb.Append(".");
485  }
486  sb.Remove(sb.Length - 1, 1);
487  ba = sb.ToString();
488  }
489  }
490  else
491  {
492  ba = first_multi;
493  if (A.IfType == 24)
494  { // loopback
495  bc = 8;
496  }
497  else
498  {
499  bc = 32;
500  }
501  break;
502  }
503  }
504  }
505  }
506  /* the code below doesn't display any gateways on win7, seems like it should
507  if (System.Environment.OSVersion.Version.Major >= 6) //vista or later
508  {
509  Trace.WriteLine("Gateways");
510  GatewayIPAddressInformationCollection addresses = adapterProperties.GatewayAddresses;
511  if (addresses.Count > 0)
512  {
513  Trace.WriteLine(adapter.Description);
514  foreach (GatewayIPAddressInformation address in addresses)
515  {
516  Trace.WriteLine(" Gateway Address : {0}",
517  address.Address.ToString());
518  }
519  }
520  }
521  */
522  break;
523  }
524  Trace.WriteLine("end GetIPv4gateway");
525  }
526  }
527 
529  public class Adapter
530  {
531  [DllImport("Iphlpapi.dll", CharSet = CharSet.Auto)]
532  private static extern uint GetAdaptersAddresses(uint Family,
533  uint flags,
534  IntPtr Reserved,
535  IntPtr PAdaptersAddresses,
536  ref uint pOutBufLen);
537 
538  public static void GetAdaptersAddresses(System.Net.Sockets.AddressFamily addressFamily,
539  NetDisc.GAA_FLAGS gaaFlags,
540  out List<IP_ADAPTER_ADDRESSES> adaptAddrList)
541  {
542 
543  adaptAddrList = new List<IP_ADAPTER_ADDRESSES>();
544  UInt32 size = (UInt32)Marshal.SizeOf(typeof(IP_ADAPTER_ADDRESSES));
545  IntPtr pAdaptAddrBuffer = Marshal.AllocHGlobal((Int32)size);
546 
547  uint result = GetAdaptersAddresses((UInt32)addressFamily, (UInt32)gaaFlags, (IntPtr)0, pAdaptAddrBuffer, ref size);
548 
549  if (result == NetDisc.ERROR_BUFFER_OVERFLOW)
550  {
551  Marshal.FreeHGlobal(pAdaptAddrBuffer);
552  pAdaptAddrBuffer = Marshal.AllocHGlobal((Int32)size);
553  result = GetAdaptersAddresses((UInt32)addressFamily, (UInt32)gaaFlags, (IntPtr)0, pAdaptAddrBuffer, ref size);
554  }
555 
556  if (result != NetDisc.ERROR_SUCCESS)
557  {
558  throw new Win32Exception((Int32)result, "GetAdaptersAddresses FAILED.");
559  }
560 
561  if ((result == NetDisc.ERROR_SUCCESS) && (pAdaptAddrBuffer != IntPtr.Zero))
562  {
563  IntPtr pTemp = pAdaptAddrBuffer;
564 
565  do
566  {
568  aAB = (IP_ADAPTER_ADDRESSES)Marshal.PtrToStructure((IntPtr)pTemp, typeof(IP_ADAPTER_ADDRESSES));
569  adaptAddrList.Add(aAB);
570 
571  pTemp = (IntPtr)aAB.Next;
572  }
573  while (pTemp != IntPtr.Zero);
574  }
575  }
576  }
577  /* the win32 struct definition, ZoneIndices is the last valid field on xp
578  typedef struct _IP_ADAPTER_ADDRESSES {
579  union {
580  ULONGLONG Alignment;
581  struct {
582  ULONG Length;
583  DWORD IfIndex;
584  };
585  };
586  struct _IP_ADAPTER_ADDRESSES *Next;
587  PCHAR AdapterName;
588  PIP_ADAPTER_UNICAST_ADDRESS FirstUnicastAddress;
589  PIP_ADAPTER_ANYCAST_ADDRESS FirstAnycastAddress;
590  PIP_ADAPTER_MULTICAST_ADDRESS FirstMulticastAddress;
591  PIP_ADAPTER_DNS_SERVER_ADDRESS FirstDnsServerAddress;
592  PWCHAR DnsSuffix;
593  PWCHAR Description;
594  PWCHAR FriendlyName;
595  BYTE PhysicalAddress[MAX_ADAPTER_ADDRESS_LENGTH];
596  DWORD PhysicalAddressLength;
597  DWORD Flags;
598  DWORD Mtu;
599  DWORD IfType;
600  IF_OPER_STATUS OperStatus;
601  DWORD Ipv6IfIndex;
602  DWORD ZoneIndices[16];
603  PIP_ADAPTER_PREFIX FirstPrefix;
604  ULONG64 TransmitLinkSpeed;
605  ULONG64 ReceiveLinkSpeed;
606  PIP_ADAPTER_WINS_SERVER_ADDRESS_LH FirstWinsServerAddress;
607  PIP_ADAPTER_GATEWAY_ADDRESS_LH FirstGatewayAddress;
608  ULONG Ipv4Metric;
609  ULONG Ipv6Metric;
610  IF_LUID Luid;
611  SOCKET_ADDRESS Dhcpv4Server;
612  NET_IF_COMPARTMENT_ID CompartmentId;
613  NET_IF_NETWORK_GUID NetworkGuid;
614  NET_IF_CONNECTION_TYPE ConnectionType;
615  TUNNEL_TYPE TunnelType;
616  SOCKET_ADDRESS Dhcpv6Server;
617  BYTE Dhcpv6ClientDuid[MAX_DHCPV6_DUID_LENGTH];
618  ULONG Dhcpv6ClientDuidLength;
619  ULONG Dhcpv6Iaid;
620  PIP_ADAPTER_DNS_SUFFIX FirstDnsSuffix;
621  } IP_ADAPTER_ADDRESSES, *PIP_ADAPTER_ADDRESSES;
622 
623  */
624  /*typedef struct _IP_ADAPTER_GATEWAY_ADDRESS_LH {
625  union {
626  ULONGLONG Alignment;
627  struct {
628  ULONG Length;
629  DWORD Reserved;
630  };
631  };
632  struct _IP_ADAPTER_GATEWAY_ADDRESS_LH *Next;
633  SOCKET_ADDRESS Address;
634 } IP_ADAPTER_GATEWAY_ADDRESS_LH, *PIP_ADAPTER_GATEWAY_ADDRESS_LH;
635  * */
636 
638  // the c# layout of the above struct _IP_ADAPTER_ADDRESSES
639  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
640  public class IP_ADAPTER_ADDRESSES
641  {
642  public uint Length;
643  public uint IfIndex;
644 
645 
646  public IntPtr Next;
647  public IntPtr AdapterName;
648  public IntPtr FirstUnicastAddress;
649  public IntPtr FirstAnycastAddress;
650  public IntPtr FirstMulticastAddress;
651  public IntPtr FirstDnsServerAddress;
652 
653  public IntPtr DnsSuffix;
654  public IntPtr Description;
655 
656  public IntPtr FriendlyName;
657 
658  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
659  public Byte[] PhysicalAddress;
660 
662  public uint flags;
663  public uint Mtu;
664  public uint IfType;
665 
666  public uint OperStatus;
667 
668  public uint Ipv6IfIndex;
669 
670  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
671  public uint[] ZoneIndices;
672 
673  public IntPtr FirstPrefix;
674 
675  public UInt64 TransmitLinkSpeed;
676  public UInt64 ReceiveLinkSpeed;
677  public IntPtr FirstWinsServerAddress;
678  public IntPtr FirstGatewayAddress;
679 
680  }
681 
682 }
const Int32 MAX_ADAPTER_NAME
Definition: netconfig.cs:46
const Int32 MAX_ADAPTER_DESCRIPTION_LENGTH
Definition: netconfig.cs:48
static void GetIPv4gateway(IP_ADAPTER_ADDRESSES A, IPAddress ipaddr, out int bc, out string ba)
Definition: netconfig.cs:386
static void GetAdaptersAddresses(System.Net.Sockets.AddressFamily addressFamily, NetDisc.GAA_FLAGS gaaFlags, out List< IP_ADAPTER_ADDRESSES > adaptAddrList)
Definition: netconfig.cs:538
const Int32 MAX_ADAPTER_NAME_LENGTH
Definition: netconfig.cs:47
const Int32 MAX_ADAPTER_ADDRESS_LENGTH
Definition: netconfig.cs:49
This class implements network discovery for the Assimilation Project.
Definition: netconfig.cs:44
Class to discover all our adapters.
Definition: netconfig.cs:529
const UInt32 ERROR_BUFFER_OVERFLOW
Definition: netconfig.cs:50
IP_ADAPTER_ADDRESSES defines the layout of information we know about an adapter Address.
Definition: netconfig.cs:640
const Int32 ERROR_SUCCESS
Definition: netconfig.cs:51