module Hans.Message.EthernetFrame (
EtherType(..)
, parseEtherType, renderEtherType
, EthernetFrame(..)
, parseEthernetFrame, renderEthernetFrame
) where
import Hans.Address.Mac (Mac,parseMac,renderMac)
import Hans.Utils (chunk)
import Control.Applicative ((<$>),(<*>))
import Data.Serialize.Get (Get,remaining,getWord16be,getBytes,runGet)
import Data.Serialize.Put (Putter,putWord16be,runPut)
import Data.Word (Word16)
import Numeric (showHex)
import qualified Data.ByteString.Lazy as L
import qualified Data.ByteString as S
newtype EtherType = EtherType { getEtherType :: Word16 }
deriving (Eq,Num,Ord)
instance Show EtherType where
showsPrec _ (EtherType et) = showString "EtherType 0x" . showHex et
parseEtherType :: Get EtherType
parseEtherType = EtherType <$> getWord16be
renderEtherType :: Putter EtherType
renderEtherType = putWord16be . getEtherType
data EthernetFrame = EthernetFrame
{ etherDest :: !Mac
, etherSource :: !Mac
, etherType :: !EtherType
} deriving (Eq,Show)
parseEthernetFrame :: S.ByteString -> Either String (EthernetFrame,S.ByteString)
parseEthernetFrame = runGet ((,) <$> header <*> (getBytes =<< remaining))
where
header = EthernetFrame
<$> parseMac
<*> parseMac
<*> parseEtherType
renderEthernetFrame :: EthernetFrame -> L.ByteString -> L.ByteString
renderEthernetFrame frame body = chunk hdr `L.append` body
where
hdr = runPut $ do
renderMac (etherDest frame)
renderMac (etherSource frame)
renderEtherType (etherType frame)