module Frenetic.EthernetAddress ( EthernetAddress (..) , ethernetAddress , broadcastAddress , ethernetAddress64 , unpackEthernetAddress ) where import Data.Binary import Data.Binary.Get import Data.Binary.Put import Numeric (showHex) import Data.Word import Data.Bits import Data.List (intersperse) data EthernetAddress = EthernetAddress { unpackEth64 :: Word64 } deriving (Eq, Ord) instance Show EthernetAddress where show eth = concat $ intersperse ":" (map (\n -> showHex n "") [w0,w1,w2,w3,w4,w5]) where (w0,w1,w2,w3,w4,w5) = unpackEthernetAddress eth instance Enum EthernetAddress where toEnum n = EthernetAddress (toEnum n) fromEnum (EthernetAddress w64) = fromEnum w64 instance Binary EthernetAddress where get = do w32 <- getWord32be w16 <- getWord16be let w64 = (fromIntegral w32 `shiftL` 16) .|. fromIntegral w16 return (EthernetAddress w64) put (EthernetAddress w64) = do putWord32be (fromIntegral (shiftR w64 16)) putWord16be (fromIntegral (w64 `mod` 0x010000)) ethernetAddress :: Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> EthernetAddress ethernetAddress w1 w2 w3 w4 w5 w6 = EthernetAddress w64 where w64 = shiftL (fromIntegral w1) 40 .|. shiftL (fromIntegral w2) 32 .|. shiftL (fromIntegral w3) 24 .|. shiftL (fromIntegral w4) 16 .|. shiftL (fromIntegral w5) 8 .|. fromIntegral w6 broadcastAddress :: EthernetAddress broadcastAddress = EthernetAddress 0xffffffffffff unpackEthernetAddress :: EthernetAddress -> (Word8,Word8,Word8,Word8,Word8,Word8) unpackEthernetAddress (EthernetAddress w64) = let a1 = fromIntegral (shiftR w64 40) a2 = fromIntegral (shiftR w64 32 `mod` 0x0100) a3 = fromIntegral (shiftR w64 24 `mod` 0x0100) a4 = fromIntegral (shiftR w64 16 `mod` 0x0100) a5 = fromIntegral (shiftR w64 8 `mod` 0x0100) a6 = fromIntegral (w64 `mod` 0x0100) in (a1,a2,a3,a4,a5,a6) ethernetAddress64 :: Word64 -> EthernetAddress ethernetAddress64 w64 = EthernetAddress (w64 `mod` 0x01000000000000)