Skip to content

Instantly share code, notes, and snippets.

@AfroThundr3007730
Last active March 7, 2024 23:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AfroThundr3007730/69172b2f60a9c3dc120ef66561777dd3 to your computer and use it in GitHub Desktop.
Save AfroThundr3007730/69172b2f60a9c3dc120ef66561777dd3 to your computer and use it in GitHub Desktop.
PowerShell wrapper of C# function to retrieve system ARP table entries
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-]+$'
}
}
}
@AfroThundr3007730
Copy link
Author

This basically does the same thing as Get-NetNeighbor, but using C# to wrap GetIpNetTable. Inspired by this gist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment