This repository has been archived by the owner on Aug 26, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 13
/
arp.cs
187 lines (157 loc) · 6.47 KB
/
arp.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
// Source: https://stackoverflow.com/questions/1148778/how-do-i-access-arp-protocol-information-through-net
// Modified to more closely match the formatting of native arp
// To Compile:
// C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:exe /out:arp.exe arp.cs
using System;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Net;
namespace Arp
{
class Program
{
// The max number of physical addresses.
const int MAXLEN_PHYSADDR = 8;
// Define the MIB_IPNETROW structure.
[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;
}
// Declare the GetIpNetTable function.
[DllImport("IpHlpApi.dll")]
[return: MarshalAs(UnmanagedType.U4)]
static extern int GetIpNetTable(
IntPtr pIpNetTable,
[MarshalAs(UnmanagedType.U4)]
ref int pdwSize,
bool bOrder);
[DllImport("IpHlpApi.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern int FreeMibTable(IntPtr plpNetTable);
// The insufficient buffer error.
const int ERROR_INSUFFICIENT_BUFFER = 122;
private static void PrintUsage()
{
Console.WriteLine(@"Dumps a mapping of IP to hardware (MAC) addresses from the Address Resolution Protocol (ARP) cache
USAGE:
arp.exe [/?]");
}
static void Main(string[] args)
{
// The number of bytes needed.
int bytesNeeded = 0;
// The result from the API call.
int result = GetIpNetTable(IntPtr.Zero, ref bytesNeeded, false);
// Allocate the memory, do it in a try/finally block, to ensure
// that it is released.
IntPtr buffer = IntPtr.Zero;
// Try/finally.
try
{
// Parse arguments
for (int i = 0; i < args.Length; i++)
{
string arg = args[i];
switch (arg.ToUpper())
{
case "/?":
PrintUsage();
return;
}
}
// Call the function, expecting an insufficient buffer.
if (result != ERROR_INSUFFICIENT_BUFFER)
{
// Throw an exception.
throw new Win32Exception(result);
}
// Allocate the memory.
buffer = Marshal.AllocCoTaskMem(bytesNeeded);
// Make the call again. If it did not succeed, then
// raise an error.
result = GetIpNetTable(buffer, ref bytesNeeded, false);
// If the result is not 0 (no error), then throw an exception.
if (result != 0)
{
// Throw an exception.
throw new Win32Exception(result);
}
// Now we have the buffer, we have to marshal it. We can read
// the first 4 bytes to get the length of the buffer.
int entries = Marshal.ReadInt32(buffer);
// Increment the memory pointer by the size of the int.
IntPtr currentBuffer = new IntPtr(buffer.ToInt64() +
Marshal.SizeOf(typeof(int)));
// Allocate an array of entries.
MIB_IPNETROW[] table = new MIB_IPNETROW[entries];
// Cycle through the entries.
for (int index = 0; index < entries; index++)
{
// Call PtrToStructure, getting the structure information.
table[index] = (MIB_IPNETROW)Marshal.PtrToStructure(new
IntPtr(currentBuffer.ToInt64() + (index *
Marshal.SizeOf(typeof(MIB_IPNETROW)))), typeof(MIB_IPNETROW));
}
Console.WriteLine("\n Internet Address Physical Address Type");
for (int index = 0; index < entries; index++)
{
MIB_IPNETROW row = table[index];
IPAddress ip = new IPAddress(BitConverter.GetBytes(row.dwAddr));
string[] mac_arr = {
row.mac0.ToString("X2"),
row.mac1.ToString("X2"),
row.mac2.ToString("X2"),
row.mac3.ToString("X2"),
row.mac4.ToString("X2"),
row.mac5.ToString("X2")
};
string ip_str = String.Format("{0,-22}", ip.ToString());
string mac_str = String.Format("{0,-22}", string.Join("-", mac_arr));
string type = "static";
if (mac_str == "00-00-00-00-00-00 ")
{
continue;
}
if (row.dwType == 3)
{
type = "dynamic";
}
Console.WriteLine(" " + ip_str + mac_str + type);
}
}
catch (Exception e)
{
Console.Error.WriteLine("[-] ERROR: {0}", e.Message.Trim());
}
finally
{
// Release the memory.
FreeMibTable(buffer);
Console.WriteLine("\nDONE");
}
}
}
}