Last active
March 7, 2024 23:19
-
-
Save AfroThundr3007730/69172b2f60a9c3dc120ef66561777dd3 to your computer and use it in GitHub Desktop.
PowerShell wrapper of C# function to retrieve system ARP table entries
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Set-StrictMode -Version Latest | |
function Get-ArpEntry { | |
<# .SYNOPSIS | |
Retrieve system ARP table entries #> | |
Param( | |
# Retrieve all entries (not just learned) | |
[switch]$All | |
) | |
$arpCode = @' | |
[StructLayout(LayoutKind.Sequential)] | |
struct MIB_IPNETROW | |
{ | |
[MarshalAs(UnmanagedType.U4)] | |
public int dwIndex; | |
[MarshalAs(UnmanagedType.U4)] | |
public int dwPhysAddrLen; | |
[MarshalAs(UnmanagedType.U1)] | |
public byte mac0; | |
[MarshalAs(UnmanagedType.U1)] | |
public byte mac1; | |
[MarshalAs(UnmanagedType.U1)] | |
public byte mac2; | |
[MarshalAs(UnmanagedType.U1)] | |
public byte mac3; | |
[MarshalAs(UnmanagedType.U1)] | |
public byte mac4; | |
[MarshalAs(UnmanagedType.U1)] | |
public byte mac5; | |
[MarshalAs(UnmanagedType.U1)] | |
public byte mac6; | |
[MarshalAs(UnmanagedType.U1)] | |
public byte mac7; | |
[MarshalAs(UnmanagedType.U4)] | |
public int dwAddr; | |
[MarshalAs(UnmanagedType.U4)] | |
public int dwType; | |
} | |
[DllImport("IpHlpApi.dll")] | |
private static extern long GetIpNetTable(IntPtr pIpNetTable, ref int pdwSize, bool bOrder); | |
public class ArpEntry | |
{ | |
public string IPAddress { get; set; } | |
public string MACAddress { get; set; } | |
} | |
public static System.Collections.Generic.List<ArpEntry> ArpCache() | |
{ | |
IntPtr buff; | |
int requiredLen = 0; | |
System.Collections.Generic.List<ArpEntry> set = new System.Collections.Generic.List<ArpEntry>(); | |
long result = GetIpNetTable(IntPtr.Zero, ref requiredLen, false); | |
try | |
{ | |
buff = Marshal.AllocCoTaskMem(requiredLen); | |
result = GetIpNetTable(buff, ref requiredLen, false); | |
int entries = Marshal.ReadInt32(buff); | |
IntPtr entryBuffer = new IntPtr(buff.ToInt64() + Marshal.SizeOf(typeof(int))); | |
for(int i = 0; i < entries; i++) | |
{ | |
int currentIndex = i * Marshal.SizeOf(typeof(MIB_IPNETROW)); | |
IntPtr newStruct = new IntPtr(entryBuffer.ToInt64() + currentIndex); | |
MIB_IPNETROW entry = (MIB_IPNETROW)Marshal.PtrToStructure(newStruct, typeof(MIB_IPNETROW)); | |
System.Net.IPAddress addr = new System.Net.IPAddress(BitConverter.GetBytes(entry.dwAddr)); | |
set.Add(new ArpEntry { IPAddress = addr.ToString(), MACAddress = String.Format("{0}-{1}-{2}-{3}-{4}-{5}", | |
entry.mac0.ToString("X2"), entry.mac1.ToString("X2"), entry.mac2.ToString("X2"), | |
entry.mac3.ToString("X2"), entry.mac4.ToString("X2"), entry.mac5.ToString("X2")) | |
}); | |
} | |
} | |
catch(Exception e) | |
{ | |
Console.WriteLine("Exception occurred: " + e.Message); | |
} | |
return set; | |
} | |
'@ | |
if (!('Win32.Arp+ArpEntry' -as [type])) { Add-Type -MemberDefinition $arpCode -Name 'Arp' -Namespace 'Win32' } | |
if ($All) { | |
return [Win32.Arp]::ArpCache() | |
} else { | |
return [Win32.Arp]::ArpCache().Where{ | |
$_.IPAddress -notmatch '^127\.|224\.|239\.|255\.' -and $_.MACAddress -notmatch '^[F-]+$' | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This basically does the same thing as
Get-NetNeighbor
, but using C# to wrapGetIpNetTable
. Inspired by this gist.