module Net.ARP where -- Address Resolution Protocol, limited to IPv4 over Ethernet -- See http://www.networksorcery.com/enp/protocol/arp.htm import Net.Bits(Word8,Word16) import Net.Ethernet as Eth(Addr) import Net.IPv4 as IPv4(Addr) import Net.PacketParsing data Packet = Packet { --hwType :: !Word16, -- Always 0x0001 (Ethernet) --protocolType :: !Eth.PacketType, -- Always 0x0800 (IPv4) --hLen, pLen :: !Word8, -- Always 0x06, 0x04 opcode :: Operation, -- 16 bits, see below senderHA :: Eth.Addr, senderIP :: IPv4.Addr, targetHA :: Eth.Addr, targetIP :: IPv4.Addr } deriving (Show) data Operation = Request -- 0x0001, RFC 826 | Reply -- 0x0002, RFC 826 deriving (Eq,Show) instance Parse Packet where parse = return Packet #! check16 0x0001 #! check16 0x0800 #! check8 0x06 #! check8 0x04 <# parse <# parse <# parse <# parse <# parse #! therest instance Unparse Packet where unparse (Packet op sHA sIP tHA tIP) = unparse (1::Word16,0x800::Word16,6::Word8,4::Word8) . unparse (op,sHA,sIP,tHA,tIP) instance Parse Operation where parse = lift . conv =<< word16 where conv 1 = Just Request conv 2 = Just Reply conv w = Nothing instance Unparse Operation where unparse op = unparse (conv op) where conv Request = 1::Word16 conv Reply = 2