module System.Linux.Netlink.Attributes
( getLinkAddress
, getLinkBroadcast
, getLinkName
, getLinkMTU
, getLinkQDisc
, getLinkTXQLen
, putLinkAddress
, putLinkBroadcast
, putLinkName
, putLinkMTU
, putLinkQDisc
, putLinkTXQLen
) where
import Prelude hiding (init, lookup)
import Control.Applicative ((<$>))
import Data.ByteString.Char8 (ByteString, append, init, pack, unpack)
import Data.Char (chr, ord)
import Data.Map (insert, lookup)
import Data.Serialize.Get (runGet, getWord32host)
import Data.Serialize.Put (runPut, putWord32host)
import Data.Word (Word8, Word32)
import System.Linux.Netlink.Constants
import System.Linux.Netlink.Protocol
type AttributeReader a = Attributes -> Maybe a
type AttributeWriter a = a -> Attributes -> Attributes
type LinkAddress = (Word8, Word8, Word8, Word8, Word8, Word8)
getLinkAddress :: AttributeReader LinkAddress
getLinkAddress attrs = decodeMAC <$> lookup eIFLA_ADDRESS attrs
putLinkAddress :: AttributeWriter LinkAddress
putLinkAddress addr = insert eIFLA_ADDRESS (encodeMAC addr)
getLinkBroadcast :: AttributeReader LinkAddress
getLinkBroadcast attrs = decodeMAC <$> lookup eIFLA_BROADCAST attrs
putLinkBroadcast :: AttributeWriter LinkAddress
putLinkBroadcast addr = insert eIFLA_BROADCAST (encodeMAC addr)
getLinkName :: AttributeReader String
getLinkName attrs = getString <$> lookup eIFLA_IFNAME attrs
putLinkName :: AttributeWriter String
putLinkName ifname = insert eIFLA_IFNAME (putString ifname)
getLinkMTU :: AttributeReader Word32
getLinkMTU attrs = get32 =<< lookup eIFLA_MTU attrs
putLinkMTU :: AttributeWriter Word32
putLinkMTU mtu = insert eIFLA_MTU (put32 mtu)
getLinkQDisc :: AttributeReader String
getLinkQDisc attrs = getString <$> lookup eIFLA_QDISC attrs
putLinkQDisc :: AttributeWriter String
putLinkQDisc disc = insert eIFLA_QDISC (putString disc)
getLinkTXQLen :: AttributeReader Word32
getLinkTXQLen attrs = get32 =<< lookup eIFLA_TXQLEN attrs
putLinkTXQLen :: AttributeWriter Word32
putLinkTXQLen len = insert eIFLA_TXQLEN (put32 len)
decodeMAC :: ByteString -> LinkAddress
decodeMAC = tuplify . map (fromIntegral . ord) . unpack
where tuplify [a,b,c,d,e,f] = (a,b,c,d,e,f)
tuplify _ = error "Bad encoded MAC"
encodeMAC :: LinkAddress -> ByteString
encodeMAC = pack . map (chr . fromIntegral) . listify
where listify (a,b,c,d,e,f) = [a,b,c,d,e,f]
getString :: ByteString -> String
getString b = unpack (init b)
putString :: String -> ByteString
putString s = append (pack s) "\0"
get32 :: ByteString -> Maybe Word32
get32 bs = case runGet getWord32host bs of
Left _ -> Nothing
Right w -> Just w
put32 :: Word32 -> ByteString
put32 w = runPut (putWord32host w)