hans-2.1.0.0: src/Hans/Address/Mac.hs
module Hans.Address.Mac (
Mac(..)
, showsMac
, macMask
) where
import Hans.Address
import Hans.Utils (showPaddedHex)
import Data.Serialize (Serialize(..))
import Data.Serialize.Get (getWord16be,getWord32be)
import Data.Serialize.Put (putByteString)
import Data.Bits (Bits(shiftR,testBit,complement))
import Data.List (intersperse)
import Data.Word (Word8)
import Numeric (readHex)
import qualified Data.ByteString as S
-- | Mac addresses.
data Mac = Mac
{-# UNPACK #-} !Word8
{-# UNPACK #-} !Word8
{-# UNPACK #-} !Word8
{-# UNPACK #-} !Word8
{-# UNPACK #-} !Word8
{-# UNPACK #-} !Word8
deriving ( Eq, Ord )
-- | Show a Mac address.
showsMac :: Mac -> ShowS
showsMac (Mac a b c d e f) = foldl1 (.)
$ intersperse (showChar ':')
$ map showPaddedHex [a,b,c,d,e,f]
-- | Generates a mask tailored to the given MAC address.
macMask :: Mac -> Mac
macMask (Mac a b c d e f) =
Mac (complement a)
(complement b)
(complement c)
(complement d)
(complement e)
(complement f)
instance Show Mac where
showsPrec _ = showsMac
instance Read Mac where
readsPrec _ = loop 6 []
where
loop :: Int -> [Word8] -> String -> [(Mac,String)]
loop 0 [f,e,d,c,b,a] str = [(Mac a b c d e f,str)]
loop 0 _ _ = []
loop n acc str = case readHex str of
[(a,':':rest)] -> loop (n-1) (a:acc) rest
[(a, rest)] -> loop 0 (a:acc) rest
_ -> []
instance Address Mac where
addrSize _ = 6
toBits (Mac a b c d e f) = concatMap k [a,b,c,d,e,f]
where k i = map (testBit i) [0 .. 7]
instance Serialize Mac where
get = do
n <- getWord32be
m <- getWord16be
let f x d = fromIntegral (x `shiftR` d)
return $! Mac (f n 24) (f n 16) (f n 8) (fromIntegral n)
(f m 8) (fromIntegral m)
put (Mac a b c d e f) = putByteString (S.pack [a,b,c,d,e,f])