module Network.Socket.Msg.CMsg
( CMsg(..)
, CMsgable(..)
, filterCMsgs
, IpPktInfo(..)
) where
import Control.Applicative
import Data.Binary
import Data.Binary.Get (getWord32host)
import Data.Binary.Put (putWord32host)
import qualified Data.ByteString as B
import Data.ByteString.Lazy (fromStrict,toStrict)
import Network.Socket (HostAddress)
data CMsg = CMsg
{ cmsgLevel :: !Int
, cmsgType :: !Int
, cmsgData :: !B.ByteString
}
instance Show CMsg where
show cmsg = concat ["(",
"Level: ", show $ cmsgLevel cmsg, ", ",
"Type: ", show $ cmsgType cmsg, ", ",
"Data: ", show $ cmsgData cmsg, ")"]
class Binary a => CMsgable a where
getCMsgLevel :: a -> Int
getCMsgType :: a -> Int
toCMsg :: a -> CMsg
toCMsg x = CMsg { cmsgLevel = getCMsgLevel x
, cmsgType = getCMsgType x
, cmsgData = toStrict $ encode x }
fromCMsg :: CMsg -> Maybe a
fromCMsg cmsg = case decodeOrFail (fromStrict $ cmsgData cmsg) of
Left _ -> Nothing
Right (_,_,x) -> Just x
filterCMsgs :: (CMsgable a) => a -> [CMsg] -> [CMsg]
filterCMsgs x = filter $ \c -> (cmsgType c == getCMsgType x) && (cmsgLevel c == getCMsgLevel x)
data IpPktInfo = IpPktInfo
{ ipi_ifindex :: !Word32
, ipi_spec_dst :: !HostAddress
, ipi_addr :: !HostAddress
} deriving (Show)
instance Binary IpPktInfo where
put i = do
putWord32host $ ipi_ifindex i
putWord32host $ ipi_spec_dst i
putWord32host $ ipi_addr i
get = IpPktInfo <$> getWord32host
<*> getWord32host
<*> getWord32host
instance CMsgable IpPktInfo where
getCMsgLevel _ = 0
getCMsgType _ = 8