public static ArpNetEntry SearchingArpNetEntry(NetworkInterface interfaces, IEnumerable <ArpNetEntry> entries) { if (interfaces == null || entries == null) { return(null); } foreach (IPAddress address in interfaces.GetIPProperties().DhcpServerAddresses. Union(interfaces.GetIPProperties().GatewayAddresses.Select(i => i.Address))) { if (address.AddressFamily != AddressFamily.InterNetwork) { continue; } ArpNetEntry arpEntry = entries.FirstOrDefault(i => { if (!Equals(i.Address, address)) { return(false); } return(i.MacAddress != MacAddress.Zero && i.MacAddress != MaxMacAddress); }); if (arpEntry != null) { return(arpEntry); } } return(null); }
public Ethernet(IPAddress ethernet, bool supportTwoLayerLinks) { this.m_ethernet = new IPEndPoint(ethernet ?? throw new ArgumentNullException("The ethernet card binding address you provided is an null references"), 0); this.SupportTwoLayerLinks = supportTwoLayerLinks; if (this.SupportTwoLayerLinks) { #if NO_USAGE_PCAP_NET throw new NotSupportedException("The current ethernet instance is not SupportTwoLayerLinks"); #else this.m_device = SearchingLivePacketDevice(ethernet); if (this.m_device == null) { throw new ArgumentOutOfRangeException("The ethernet card device bound to this address could not be found"); } NetworkInterface networkInterface = this.GetNetworkInterface(); if (networkInterface == null) { throw new ArgumentOutOfRangeException("The NetworkInterface for the Ethernet device could not be found"); } this.IfIndex = GetNetifIndex(networkInterface); this.LocalMacAddress = GetMacAddress(networkInterface.GetPhysicalAddress().GetAddressBytes()); if (this.LocalMacAddress == MacAddress.Zero) { throw new ArgumentOutOfRangeException("Unable to obtain the mac address of the current ethernet card"); } ArpNetEntry arpNetEntry = SearchingArpNetEntry(networkInterface, this.GetArpNetEntryTable().Values); if (arpNetEntry == null) { throw new ArgumentOutOfRangeException("The current ethernet card device cannot retrieve the arp network cache entry for its gateway"); } else { this.RemoteMacAddress = arpNetEntry.MacAddress; } this.m_packetCommunicator = this.m_device.Open(65536, PacketDeviceOpenAttributes.Promiscuous | PacketDeviceOpenAttributes.MaximumResponsiveness, 1000); if (this.m_packetCommunicator == null) { throw new InvalidOperationException("Unable to open ethernet card packet communication layer"); } if (this.m_packetCommunicator.DataLink.Kind != DataLinkKind.Ethernet) { throw new InvalidOperationException("This is not a valid ethernet card network character device"); } #endif } else { this.m_socket = new NSocket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP); this.m_socket.Bind(this.m_ethernet); this.m_socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, true); this.m_socket.IOControl(IOControlCode.ReceiveAll, new byte[4] { 1, 0, 0, 0 }, new byte[4] { 1, 0, 0, 0 }); this.m_socket.IOControl(IOControlCode.ReceiveAllMulticast, new byte[4] { 1, 0, 0, 0 }, new byte[4] { 1, 0, 0, 0 }); this.m_socket.IOControl(IOControlCode.KeepAliveValues | IOControlCode.BindToInterface, new byte[1] { 0 }, new byte[1] { 0 }); } }
public static IEnumerable <ArpNetEntry> GetAllArpNetEntry() { IList <ArpNetEntry> arpEntries = new List <ArpNetEntry>(); // The number of bytes needed. int bytesNeeded = 0; // The result from the API call. int result = IPHelper.GetIpNetTable(IntPtr.Zero, ref bytesNeeded, false); // Call the function, expecting an insufficient buffer. if (result != IPHelper.ERROR_INSUFFICIENT_BUFFER) { // Throw an exception. throw new Win32Exception(result); } // Allocate the memory, do it in a try/finally block, to ensure // that it is released. IntPtr buffer = IntPtr.Zero; // Try/finally. try { // Allocate the memory. buffer = Marshal.AllocCoTaskMem(bytesNeeded); // Make the call again. If it did not succeed, then // raise an error. result = IPHelper.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. MIB_IPNETROW *mibi = (MIB_IPNETROW *)new IntPtr(buffer.ToInt64() + Marshal.SizeOf(typeof(int))); for (int i = 0; i < entries; i++) { MIB_IPNETROW *current = mibi + i; bool dynamic_ = (MIB_IPNET_TYPE)current->dwType == MIB_IPNET_TYPE.MIB_IPNET_TYPE_DYNAMIC; if (dynamic_ || (MIB_IPNET_TYPE)current->dwType == MIB_IPNET_TYPE.MIB_IPNET_TYPE_STATIC) { ArpNetEntry entry = new ArpNetEntry { Address = new IPAddress(current->dwAddr), Dynamic = dynamic_, IfIndex = current->dwIndex, MacAddress = GetMacAddress((byte *)¤t->bPhysAddr, current->dwPhysAddrLen), }; arpEntries.Add(entry); } } } finally { // Release the memory. Marshal.FreeCoTaskMem(buffer); } return(arpEntries); }