private unsafe static void GetAddressesForAdapter(byte *pData, ref UnicastIPAddressInformationCollection addressList) { addressList.InternalClear(); /* * typedef struct _IP_ADAPTER_ADDRESSES { * union { * ULONGLONG Alignment; * struct { * ULONG Length; * DWORD IfIndex; * }; * }; * struct _IP_ADAPTER_ADDRESSES* Next; * PCHAR AdapterName; * PIP_ADAPTER_UNICAST_ADDRESS FirstUnicastAddress; * PIP_ADAPTER_ANYCAST_ADDRESS FirstAnycastAddress; * PIP_ADAPTER_MULTICAST_ADDRESS FirstMulticastAddress; * PIP_ADAPTER_DNS_SERVER_ADDRESS FirstDnsServerAddress; * PWCHAR DnsSuffix; * PWCHAR Description; * PWCHAR FriendlyName; * BYTE PhysicalAddress[MAX_ADAPTER_ADDRESS_LENGTH]; * DWORD PhysicalAddressLength; * DWORD Flags; * * * typedef struct _SOCKET_ADDRESS { * LPSOCKADDR lpSockaddr ; * INT iSockaddrLength ; * } SOCKET_ADDRESS, *PSOCKET_ADDRESS, FAR * LPSOCKET_ADDRESS ; * * */ int addressListOffset = 0; byte *p = pData; uint *pNext = null; addressListOffset = 16; p += addressListOffset; /* * typedef struct _IP_ADAPTER_UNICAST_ADDRESS { * union { * ULONGLONG Alignment; * struct { * ULONG Length; * DWORD Flags; * } * }; * struct _IP_ADAPTER_UNICAST_ADDRESS* Next; * SOCKET_ADDRESS Address; * IP_PREFIX_ORIGIN PrefixOrigin; * IP_SUFFIX_ORIGIN SuffixOrigin; * IP_DAD_STATE DadState; * ULONG ValidLifetime; * ULONG PreferredLifetime; * ULONG LeaseLifetime; * } IP_ADAPTER_UNICAST_ADDRESS*, PIP_ADAPTER_UNICAST_ADDRESS; */ uint pAddress = (uint)*((uint *)p); p = (byte *)pAddress; if (p == null) { return; } UnicastIPAddressInformation info; do { info = new UnicastIPAddressInformation(); // past length p += 4; // flags info.AdapterFlags = (PerAdapterFlags)((int)*((int *)p)); p += 4; // next pNext = (uint *)*((uint *)p); p += 4; // socket address pointer info.Address = GetAddressFromSocketAddressPointer(p); p += 4; // prefix origin info.PrefixOrigin = (PrefixOrigin)((int)*((int *)p)); p += 4; // suffix origin info.SuffixOrigin = (SuffixOrigin)((int)*((int *)p)); p += 4; // dad state info.DuplicateAddressDetectionState = (DuplicateAddressDetectionState)((int)*((int *)p)); p += 4; // valid lifetime info.AddressValidLifetime = (uint)*((uint *)p); p += 4; // preferred lifetime info.AddressPreferredLifetime = (uint)*((uint *)p); p += 4; // lease lifetime info.DhcpLeaseLifetime = (uint)*((uint *)p); p += 4; p = (byte *)pNext; addressList.InternalAdd(info); }while (pNext != null); }
internal unsafe static UnicastIPAddressInformationCollection ParseAddressesFromPointer(byte *pdata, string adapterName) { UnicastIPAddressInformationCollection addressList = new UnicastIPAddressInformationCollection(adapterName); byte *p = pdata; uint pNext = 0; do { UnicastIPAddressInformation address = new UnicastIPAddressInformation(); pNext = (uint)*((uint *)p); p += 4; // skip pNext // once for the IP, once for the mask for (int index = 0; index < 2; index++) { string addressString; // see if there's an IP at all if (*p == '\0') { addressString = string.Empty; // if the address is empty skip the whole thing, // but if the mask is empty, just skip it if (index == 0) { System.Diagnostics.Debug.WriteLine("ParseAddressesFromPointer: Empty address detected"); p += 32; } else { System.Diagnostics.Debug.WriteLine("ParseAddressesFromPointer: Empty netmask detected"); address.IPv4Mask = IPAddress.None; p += 16; } } else { byte[] stringBytes = new byte[16]; for (int i = 0; i < stringBytes.Length; i++) { stringBytes[i] = *p; p++; } addressString = Encoding.ASCII.GetString(stringBytes, 0, stringBytes.Length); // trim nulls int nullIndex = addressString.IndexOf('\0'); if (nullIndex >= 0) { addressString = addressString.Substring(0, nullIndex); } if (addressString != string.Empty) { // store the result if (index == 0) { address.Address = IPAddress.Parse(addressString); } else { address.IPv4Mask = IPAddress.Parse(addressString); } } } // else } // for address.NetworkTableEntryContext = *((int *)p); p += 4; // skip the Context if (address.Address != null) { addressList.InternalAdd(address); } } while (pNext != 0); return(addressList); }