/// <summary> /// Modifies an existing ARP entry in the ARP table on the local computer. /// </summary> /// <param name="entry"> /// The entry to modify. All fields must be valid. /// </param> /// <returns> /// Returns true for success, false otherwise. /// </returns> public bool SetArpEntry(ArpEntry entry) { bool ret = false; // allocate 24 bytes for the entry IntPtr pArpEntry = Marshal.AllocHGlobal (24); Marshal.WriteInt32 (pArpEntry, entry.AdapterIndex); Marshal.WriteInt32 (new IntPtr(pArpEntry.ToInt32() + 4), entry.MediaAccessControlAddress.Address.Length); // write the MAC address for (int i = 0; i < entry.MediaAccessControlAddress.Address.Length; i++) { Marshal.WriteByte (new IntPtr(pArpEntry.ToInt32() + 8 + i), entry.MediaAccessControlAddress.Address[i]); } // pad out the MAC address to 8 bytes for (int i = 0; i < 8 - entry.MediaAccessControlAddress.Address.Length; i++) { Marshal.WriteByte (new IntPtr(pArpEntry.ToInt32() + 8 + i), 0); } // write the IP address byte[] ip = entry.IPAddress.GetAddressBytes (); for (int i = 0; i < ip.Length; i++) { Marshal.WriteByte (new IntPtr(pArpEntry.ToInt32() + 16 + i), ip[i]); } Marshal.WriteInt32 (new IntPtr(pArpEntry.ToInt32() + 20), (int)entry.EntryType); // try to modify the entry ret = SetIpNetEntry (pArpEntry) == 0; // free the allocated memory Marshal.FreeHGlobal (pArpEntry); return ret; }
/// <summary> /// Read the ARP table. Returns null if reading failed. /// </summary> public ArpEntry[] ReadArpTable() { // pointer to the block of memory we will use IntPtr pBuffer = IntPtr.Zero; // size of the buffer int bufferSize = 0; // return value int ret = 0; // the table ArpEntry[] entries; // make an initial call to the method to recieve the correct buffer // size ret = GetIpNetTable (pBuffer, ref bufferSize, true); // if an error other than insufficient buffer size occurs then return // null if (ret != ERROR_INSUFFICIENT_BUFFER) { Marshal.FreeHGlobal (pBuffer); return null; } // now we know how much memory to allocate, allocate it pBuffer = Marshal.AllocHGlobal (bufferSize); // make the real call now ret = GetIpNetTable (pBuffer, ref bufferSize, true); // check for failure if (ret != 0) { Marshal.FreeHGlobal (pBuffer); return null; } // the first 4 bytes is the number of entries int nEntries = Marshal.ReadInt32 (new IntPtr (pBuffer.ToInt32())); // allocate space for each entry entries = new ArpEntry[nEntries]; // loop through each entry for (int i = 0; i < nEntries; i++) { entries[i] = new ArpEntry (); // read the adapter index entries[i].AdapterIndex = Marshal.ReadInt32 (new IntPtr (pBuffer.ToInt32() + (24*i) + 4)); // read the physical address int addressLength = Marshal.ReadInt32 (new IntPtr (pBuffer.ToInt32() + (24*i) + 8)); byte[] macAddress = new byte[addressLength]; for (int j = 0; j < addressLength; j++) { macAddress[j] = Marshal.ReadByte (new IntPtr (pBuffer.ToInt32() + (24*i) + 12 + j)); } entries[i].MediaAccessControlAddress = new MACAddress (macAddress); // read the IP address entries[i].IPAddress = new IPAddress (Marshal.ReadInt32 (new IntPtr (pBuffer.ToInt32() + (24*i) + 20))); // read the entry type entries[i].EntryType = (ArpEntryType)Marshal.ReadInt32 (new IntPtr (pBuffer.ToInt32() + (24*i) + 24)); } // free the allocated memory Marshal.FreeHGlobal (pBuffer); return entries; }
/// <summary> /// Creates an Address Resolution Protocol (ARP) entry in the ARP table on /// the local computer. /// </summary> /// <param name="entry"> /// The entry to add. All fields must be valid. /// </param> /// <returns> /// Returns true for success, false otherwise. /// </returns> public bool CreateArpEntry(ArpEntry entry) { bool ret = false; // allocate 24 bytes for the entry IntPtr pArpEntry = Marshal.AllocHGlobal(24); Marshal.WriteInt32(pArpEntry, entry.AdapterIndex); Marshal.WriteInt32(new IntPtr(pArpEntry.ToInt32() + 4), entry.MediaAccessControlAddress.Address.Length); // write the MAC address for (int i = 0; i < entry.MediaAccessControlAddress.Address.Length; i++) { Marshal.WriteByte(new IntPtr(pArpEntry.ToInt32() + 8 + i), entry.MediaAccessControlAddress.Address[i]); } // pad out the MAC address to 8 bytes for (int i = 0; i < 8 - entry.MediaAccessControlAddress.Address.Length; i++) { Marshal.WriteByte(new IntPtr(pArpEntry.ToInt32() + 8 + i), 0); } // write the IP address byte[] ip = entry.IPAddress.GetAddressBytes(); for (int i = 0; i < ip.Length; i++) { Marshal.WriteByte(new IntPtr(pArpEntry.ToInt32() + 16 + i), ip[i]); } Marshal.WriteInt32(new IntPtr(pArpEntry.ToInt32() + 20), (int)entry.EntryType); // try to modify the entry ret = CreateIpNetEntry(pArpEntry) == 0; // free the allocated memory Marshal.FreeHGlobal(pArpEntry); return(ret); }
/// <summary> /// Read the ARP table. Returns null if reading failed. /// </summary> public ArpEntry[] ReadArpTable() { // pointer to the block of memory we will use IntPtr pBuffer = IntPtr.Zero; // size of the buffer int bufferSize = 0; // return value int ret = 0; // the table ArpEntry[] entries; // make an initial call to the method to recieve the correct buffer // size ret = GetIpNetTable(pBuffer, ref bufferSize, true); // if an error other than insufficient buffer size occurs then return // null if (ret != ERROR_INSUFFICIENT_BUFFER) { Marshal.FreeHGlobal(pBuffer); return(null); } // now we know how much memory to allocate, allocate it pBuffer = Marshal.AllocHGlobal(bufferSize); // make the real call now ret = GetIpNetTable(pBuffer, ref bufferSize, true); // check for failure if (ret != 0) { Marshal.FreeHGlobal(pBuffer); return(null); } // the first 4 bytes is the number of entries int nEntries = Marshal.ReadInt32(new IntPtr(pBuffer.ToInt32())); // allocate space for each entry entries = new ArpEntry[nEntries]; // loop through each entry for (int i = 0; i < nEntries; i++) { entries[i] = new ArpEntry(); // read the adapter index entries[i].AdapterIndex = Marshal.ReadInt32(new IntPtr(pBuffer.ToInt32() + (24 * i) + 4)); // read the physical address int addressLength = Marshal.ReadInt32(new IntPtr(pBuffer.ToInt32() + (24 * i) + 8)); byte[] macAddress = new byte[addressLength]; for (int j = 0; j < addressLength; j++) { macAddress[j] = Marshal.ReadByte(new IntPtr(pBuffer.ToInt32() + (24 * i) + 12 + j)); } entries[i].MediaAccessControlAddress = new MACAddress(macAddress); // read the IP address entries[i].IPAddress = new IPAddress(Marshal.ReadInt32(new IntPtr(pBuffer.ToInt32() + (24 * i) + 20))); // read the entry type entries[i].EntryType = (ArpEntryType)Marshal.ReadInt32(new IntPtr(pBuffer.ToInt32() + (24 * i) + 24)); } // free the allocated memory Marshal.FreeHGlobal(pBuffer); return(entries); }