/// <summary> /// Constructor /// </summary> /// <param name="interfaceAddress">The MAC address of the interface to receive the data on</param> public LLCSocket(PhysicalAddress interfaceAddress) { SocketHandle = socket(EAddressFamily.LLC, ESocketType.Datagram, EProtocol.Null); if (SocketHandle < 0) { throw new Exception("Failed to create socket for the LLC protocol family. Either permissions or missing kernel module (llc2.o)"); } //Console.WriteLine("Socket called " + SocketHandle.ToString()); var socketAddress = new SocketAddressLLC { sllc_family = EAddressFamily.LLC, sllc_arphrd = EAddressFamily.EthernetHardwareAddress, sllc_sap = (byte)ESapType.SNAP, }; socketAddress.MacAddress = interfaceAddress; var result = bind(SocketHandle, ref socketAddress, (IntPtr)16); if (result < 0) { throw new Exception("Error binding the socket to the LLC/SNAP protocol. Either permissions or missing module (llc2.o)."); } //Console.WriteLine("Bind called " + result.ToString()); }
/// <summary> /// Receive data from the remote host. This uses a fixed size buffer of 2000 bytes which should be safe for 802.2 packets. /// </summary> /// <param name="remoteHost">Return value of the remote host the the frame was received from</param> /// <returns>The buffer received from the remote host</returns> public byte [] ReceiveFrom(out PhysicalAddress remoteHost) { var buffer = new byte[2000]; var destinationAddress = new SocketAddressLLC(); IntPtr addressLength = (IntPtr)16; var result = recvfrom(SocketHandle, buffer, (IntPtr)2000, 0, ref destinationAddress, ref addressLength); //Console.WriteLine("recvfrom called " + result.ToString()); if ((long)result <= 0) { remoteHost = null; return(null); } // TODO : Use map instead remoteHost = destinationAddress.MacAddress; return(buffer.Take((int)result).ToArray()); }
private static extern IntPtr recvfrom(int sockfd, byte [] buf, IntPtr len, int flags, ref SocketAddressLLC src_addr, ref IntPtr addrlen);
private static extern int bind(int fd, ref SocketAddressLLC address, IntPtr addressLength);