packages feed

netlink (empty) → 0.1

raw patch · 9 files changed

+1183/−0 lines, 9 filesdep +basedep +bytestringdep +cerealsetup-changed

Dependencies added: base, bytestring, cereal, containers, monad-loops, unix

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright David Anderson 2010++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of David Anderson nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,3 @@+#!/usr/bin/env runhaskell+import Distribution.Simple+main = defaultMain
+ System/Linux/Netlink.hs view
@@ -0,0 +1,1 @@+module System.Linux.Netlink where
+ System/Linux/Netlink/Attributes.hs view
@@ -0,0 +1,115 @@+{-# LANGUAGE OverloadedStrings #-}++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++--+-- Link message 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)++-- TODO: IFLA_LINK - need to understand what it does++getLinkQDisc :: AttributeReader String+getLinkQDisc attrs = getString <$> lookup eIFLA_QDISC attrs++putLinkQDisc :: AttributeWriter String+putLinkQDisc disc = insert eIFLA_QDISC (putString disc)++-- TODO: IFLA_STATS - bloody huge message, will deal with it later.++-- TODO: IFLA_{COST,PRIORITY,MASTER,WIRELESS,PROTINFO} - need to+-- understand what they do.++getLinkTXQLen :: AttributeReader Word32+getLinkTXQLen attrs = get32 =<< lookup eIFLA_TXQLEN attrs++putLinkTXQLen :: AttributeWriter Word32+putLinkTXQLen len = insert eIFLA_TXQLEN (put32 len)++-- TODO: IFLA_{MAP,WEIGHT} - need to figure out++-- TODO: IFLA_{LINKMODE,LINKINFO} - see Documentation/networking/operstates.txt++-- TODO: IFLA_{NET_NS_PID,IFALIAS} - need to figure out++--+-- Helpers+--++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)
+ System/Linux/Netlink/C.chs view
@@ -0,0 +1,150 @@+{-# LANGUAGE ForeignFunctionInterface #-}+{-# OPTIONS_GHC -fno-warn-overlapping-patterns #-}++module System.Linux.Netlink.C+    (+      NetlinkSocket+    , makeSocket+    , closeSocket+    , sendmsg+    , recvmsg++    , cFromEnum+    , cToEnum+    ) where++import Control.Applicative ((<$>), (<*))+import Control.Monad (when)+import Data.Bits (Bits, (.|.), shiftL)+import Data.ByteString (ByteString)+import Data.ByteString.Internal (createAndTrim, toForeignPtr)+import Data.Unique (hashUnique, newUnique)+import Data.Word (Word32)+import Foreign.C.Error (throwErrnoIf, throwErrnoIfMinus1, throwErrnoIfMinus1_)+import Foreign.C.Types+import Foreign.ForeignPtr (touchForeignPtr)+import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)+import Foreign.Marshal.Array (withArrayLen)+import Foreign.Marshal.Utils (with)+import Foreign.Ptr (Ptr, castPtr, plusPtr)+import Foreign.Storable (Storable(..))+import System.Posix.Process (getProcessID)++import System.Linux.Netlink.Constants (eAF_NETLINK)++#include <unistd.h>+#include <string.h>+#include <sys/types.h>+#include <sys/socket.h>+#include <linux/netlink.h>++#c+typedef struct msghdr msdhdr;+typedef struct iovec iovec;+typedef struct sockaddr_nl sockaddr_nl;+#endc++newtype NetlinkSocket = NS CInt++makeSocket :: IO NetlinkSocket+makeSocket = do+    fd <- throwErrnoIfMinus1 "makeSocket.socket" $+          ({#call socket #}+           eAF_NETLINK+           (cFromEnum Raw)+           (cFromEnum Route))+    unique <- fromIntegral . hashUnique <$> newUnique+    pid <- fromIntegral <$> getProcessID+    let sockId = (unique `shiftL` 16) .|. pid+    with (SockAddrNetlink sockId) $ \addr ->+        throwErrnoIfMinus1_ "makeSocket.bind" $ do+            {#call bind #} fd (castPtr addr) {#sizeof sockaddr_nl #}+    return $ NS fd++closeSocket :: NetlinkSocket -> IO ()+closeSocket (NS fd) = throwErrnoIfMinus1_ "closeSocket" $ {#call close #} fd++sendmsg :: NetlinkSocket -> [ByteString] -> IO ()+sendmsg (NS fd) bs =+    useManyAsPtrLen bs $ \ptrs ->+    withArrayLen (map IoVec ptrs) $ \iovlen iov ->+    with (MsgHdr (castPtr iov, iovlen)) $ \msg ->+    throwErrnoIfMinus1_ "sendmsg" $ do+        {#call sendmsg as _sendmsg #} fd (castPtr msg) (0 :: CInt)++recvmsg :: NetlinkSocket -> Int -> IO ByteString+recvmsg (NS fd) len =+    createAndTrim len $ \ptr ->+    with (IoVec (castPtr ptr, len)) $ \vec ->+    with (MsgHdr (castPtr vec, 1)) $ \msg ->+    fmap fromIntegral . throwErrnoIf (<= 0) "recvmsg" $ do+        {#call recvmsg as _recvmsg #} fd (castPtr msg) (0 :: CInt)++{#enum define PF { NETLINK_ROUTE as Route } #}+{#enum define ST { SOCK_RAW as Raw } #}++data IoVec = IoVec (Ptr (), Int)++instance Storable IoVec where+    sizeOf    _ = {#sizeof iovec #}+    alignment _ = 4+    peek p = do+        addr <- {#get iovec.iov_base #} p+        len  <- {#get iovec.iov_len #}  p+        return $ IoVec (addr, (fromIntegral len))+    poke p (IoVec (addr, len)) = do+        zero p+        {#set iovec.iov_base #} p addr+        {#set iovec.iov_len  #} p (fromIntegral len)++data MsgHdr = MsgHdr (Ptr (), Int)++instance Storable MsgHdr where+    sizeOf    _ = {#sizeof iovec #}+    alignment _ = 4+    peek p = do+        iov     <- {#get msghdr.msg_iov     #} p+        iovlen  <- {#get msghdr.msg_iovlen  #} p+        return $ MsgHdr (iov, fromIntegral iovlen)+    poke p (MsgHdr (iov, iovlen)) = do+        zero p+        {#set msghdr.msg_iov     #} p iov+        {#set msghdr.msg_iovlen  #} p (fromIntegral iovlen)++data SockAddrNetlink = SockAddrNetlink Word32++instance Storable SockAddrNetlink where+    sizeOf    _ = {#sizeof sockaddr_nl #}+    alignment _ = 4+    peek p = do+        family <- {#get sockaddr_nl.nl_family #} p+        when (family /= eAF_NETLINK) $ fail "Bad address family"+        SockAddrNetlink . fromIntegral <$> {#get sockaddr_nl.nl_pid #} p+    poke p (SockAddrNetlink pid) = do+        zero p+        {#set sockaddr_nl.nl_family #} p eAF_NETLINK+        {#set sockaddr_nl.nl_pid    #} p (fromIntegral pid)++useManyAsPtrLen :: [ByteString] -> ([(Ptr (), Int)] -> IO a) -> IO a+useManyAsPtrLen bs act =+    let makePtrLen (fptr, off, len) =+            let ptr = plusPtr (unsafeForeignPtrToPtr fptr) off+            in (ptr, len)+        touchByteStringPtr (fptr, _, _) = touchForeignPtr fptr+        foreigns = map toForeignPtr bs+    in act (map makePtrLen foreigns) <* mapM_ touchByteStringPtr foreigns++sizeOfPtr :: (Storable a, Integral b) => Ptr a -> b+sizeOfPtr = fromIntegral . sizeOf . (undefined :: Ptr a -> a)++zero :: Storable a => Ptr a -> IO ()+zero p = void $ {#call memset #} (castPtr p) 0 (sizeOfPtr p)++void :: Monad m => m a -> m ()+void act = act >> return ()++cFromEnum :: (Enum e, Integral i) => e -> i+cFromEnum = fromIntegral . fromEnum++cToEnum :: (Integral i, Enum e) => i -> e+cToEnum = toEnum . fromIntegral
+ System/Linux/Netlink/Constants.hs view
@@ -0,0 +1,603 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+module System.Linux.Netlink.Constants (AddressFamily, eAF_UNSPEC, eAF_FILE, eAF_LOCAL, eAF_UNIX, eAF_INET, eAF_AX25, eAF_IPX, eAF_APPLETALK, eAF_NETROM, eAF_BRIDGE, eAF_ATMPVC, eAF_X25, eAF_INET6, eAF_ROSE, eAF_DECnet, eAF_NETBEUI, eAF_SECURITY, eAF_KEY, eAF_NETLINK, eAF_ROUTE, eAF_PACKET, eAF_ASH, eAF_ECONET, eAF_ATMSVC, eAF_RDS, eAF_SNA, eAF_IRDA, eAF_PPPOX, eAF_WANPIPE, eAF_LLC, eAF_CAN, eAF_TIPC, eAF_BLUETOOTH, eAF_IUCV, eAF_RXRPC, eAF_ISDN, eAF_PHONET, eAF_IEEE802154, eAF_MAX, MessageType, eNLMSG_NOOP, eNLMSG_ERROR, eNLMSG_DONE, eNLMSG_OVERRUN, eNLMSG_MIN_TYPE, eRTM_BASE, eRTM_NEWLINK, eRTM_DELLINK, eRTM_GETLINK, eRTM_SETLINK, eRTM_NEWADDR, eRTM_DELADDR, eRTM_GETADDR, eRTM_NEWROUTE, eRTM_DELROUTE, eRTM_GETROUTE, eRTM_NEWNEIGH, eRTM_DELNEIGH, eRTM_GETNEIGH, eRTM_NEWRULE, eRTM_DELRULE, eRTM_GETRULE, eRTM_NEWQDISC, eRTM_DELQDISC, eRTM_GETQDISC, eRTM_NEWTCLASS, eRTM_DELTCLASS, eRTM_GETTCLASS, eRTM_NEWTFILTER, eRTM_DELTFILTER, eRTM_GETTFILTER, eRTM_NEWACTION, eRTM_DELACTION, eRTM_GETACTION, eRTM_NEWPREFIX, eRTM_GETMULTICAST, eRTM_GETANYCAST, eRTM_NEWNEIGHTBL, eRTM_GETNEIGHTBL, eRTM_SETNEIGHTBL, eRTM_NEWNDUSEROPT, eRTM_NEWADDRLABEL, eRTM_DELADDRLABEL, eRTM_GETADDRLABEL, eRTM_GETDCB, eRTM_SETDCB, MessageFlags, fNLM_F_REQUEST, fNLM_F_MULTI, fNLM_F_ACK, fNLM_F_ECHO, fNLM_F_REPLACE, fNLM_F_ROOT, fNLM_F_EXCL, fNLM_F_MATCH, fNLM_F_ATOMIC, fNLM_F_CREATE, fNLM_F_APPEND, LinkType, eARPHRD_NETROM, eARPHRD_ETHER, eARPHRD_EETHER, eARPHRD_AX25, eARPHRD_PRONET, eARPHRD_CHAOS, eARPHRD_IEEE802, eARPHRD_ARCNET, eARPHRD_APPLETLK, eARPHRD_DLCI, eARPHRD_ATM, eARPHRD_METRICOM, eARPHRD_IEEE1394, eARPHRD_EUI64, eARPHRD_INFINIBAND, eARPHRD_SLIP, eARPHRD_CSLIP, eARPHRD_SLIP6, eARPHRD_CSLIP6, eARPHRD_RSRVD, eARPHRD_ADAPT, eARPHRD_ROSE, eARPHRD_X25, eARPHRD_HWX25, eARPHRD_CAN, eARPHRD_PPP, eARPHRD_CISCO, eARPHRD_HDLC, eARPHRD_LAPB, eARPHRD_DDCMP, eARPHRD_RAWHDLC, eARPHRD_TUNNEL, eARPHRD_TUNNEL6, eARPHRD_FRAD, eARPHRD_SKIP, eARPHRD_LOOPBACK, eARPHRD_LOCALTLK, eARPHRD_FDDI, eARPHRD_BIF, eARPHRD_SIT, eARPHRD_IPDDP, eARPHRD_IPGRE, eARPHRD_PIMREG, eARPHRD_HIPPI, eARPHRD_ASH, eARPHRD_ECONET, eARPHRD_IRDA, eARPHRD_FCPP, eARPHRD_FCAL, eARPHRD_FCPL, eARPHRD_FCFABRIC, eARPHRD_IEEE802_TR, eARPHRD_IEEE80211, eARPHRD_IEEE80211_PRISM, eARPHRD_IEEE80211_RADIOTAP, eARPHRD_IEEE802154, eARPHRD_PHONET, eARPHRD_PHONET_PIPE, LinkFlags, fIFF_802_1Q_VLAN, fIFF_TUN, fIFF_UP, fIFF_BROADCAST, fIFF_EBRIDGE, fIFF_TAP, fIFF_DEBUG, fIFF_SLAVE_INACTIVE, fIFF_LOOPBACK, fIFF_MASTER_8023AD, fIFF_MASTER_ALB, fIFF_POINTOPOINT, fIFF_BONDING, fIFF_NOTRAILERS, fIFF_RUNNING, fIFF_SLAVE_NEEDARP, fIFF_ISATAP, fIFF_NOARP, fIFF_MASTER_ARPMON, fIFF_PROMISC, fIFF_ALLMULTI, fIFF_WAN_HDLC, fIFF_MASTER, fIFF_XMIT_DST_RELEASE, fIFF_SLAVE, fIFF_MULTICAST, fIFF_NO_PI, fIFF_ONE_QUEUE, fIFF_PORTSEL, fIFF_AUTOMEDIA, fIFF_VNET_HDR, fIFF_DYNAMIC, fIFF_TUN_EXCL, fIFF_LOWER_UP, fIFF_DORMANT, fIFF_ECHO, LinkAttrType, eIFLA_UNSPEC, eIFLA_ADDRESS, eIFLA_BROADCAST, eIFLA_IFNAME, eIFLA_MTU, eIFLA_LINK, eIFLA_QDISC, eIFLA_STATS, eIFLA_COST, eIFLA_PRIORITY, eIFLA_MASTER, eIFLA_WIRELESS, eIFLA_PROTINFO, eIFLA_TXQLEN, eIFLA_MAP, eIFLA_WEIGHT, eIFLA_OPERSTATE, eIFLA_LINKMODE, eIFLA_LINKINFO, eIFLA_NET_NS_PID, eIFLA_IFALIAS, AddrFlags, fIFA_F_SECONDARY, fIFA_F_TEMPORARY, fIFA_F_NODAD, fIFA_F_OPTIMISTIC, fIFA_F_DADFAILED, fIFA_F_HOMEADDRESS, fIFA_F_DEPRECATED, fIFA_F_TENTATIVE, fIFA_F_PERMANENT, Scope, eRT_SCOPE_UNIVERSE, eRT_SCOPE_SITE, eRT_SCOPE_LINK, eRT_SCOPE_HOST, eRT_SCOPE_NOWHERE, AddrAttrType, eIFA_UNSPEC, eIFA_ADDRESS, eIFA_LOCAL, eIFA_LABEL, eIFA_BROADCAST, eIFA_ANYCAST, eIFA_CACHEINFO, eIFA_MULTICAST, RouteTableId, eRT_TABLE_UNSPEC, eRT_TABLE_COMPAT, eRT_TABLE_DEFAULT, eRT_TABLE_MAIN, eRT_TABLE_LOCAL, eRT_TABLE_MAX, RouteProto, eRTPROT_UNSPEC, eRTPROT_REDIRECT, eRTPROT_KERNEL, eRTPROT_BOOT, eRTPROT_STATIC, eRTPROT_GATED, eRTPROT_RA, eRTPROT_MRT, eRTPROT_ZEBRA, eRTPROT_BIRD, eRTPROT_DNROUTED, eRTPROT_XORP, eRTPROT_NTK, eRTPROT_DHCP, RouteType, eRTN_UNSPEC, eRTN_UNICAST, eRTN_LOCAL, eRTN_BROADCAST, eRTN_ANYCAST, eRTN_MULTICAST, eRTN_BLACKHOLE, eRTN_UNREACHABLE, eRTN_PROHIBIT, eRTN_THROW, eRTN_NAT, eRTN_XRESOLVE, RouteFlags, fRTM_F_NOTIFY, fRTM_F_CLONED, fRTM_F_EQUALIZE, fRTM_F_PREFIX, RouteAttrType, eRTA_UNSPEC, eRTA_DST, eRTA_SRC, eRTA_IIF, eRTA_OIF, eRTA_GATEWAY, eRTA_PRIORITY, eRTA_PREFSRC, eRTA_METRICS, eRTA_MULTIPATH, eRTA_PROTOINFO, eRTA_FLOW, eRTA_CACHEINFO, eRTA_SESSION, eRTA_MP_ALGO, eRTA_TABLE) where++import Data.Bits++newtype AddressFamily = AddressFamily Int deriving (Eq, Enum, Integral, Num, Ord, Real, Show)++eAF_UNSPEC :: (Num a) => a+eAF_UNSPEC = 0+eAF_FILE :: (Num a) => a+eAF_FILE = 1+eAF_LOCAL :: (Num a) => a+eAF_LOCAL = 1+eAF_UNIX :: (Num a) => a+eAF_UNIX = 1+eAF_INET :: (Num a) => a+eAF_INET = 2+eAF_AX25 :: (Num a) => a+eAF_AX25 = 3+eAF_IPX :: (Num a) => a+eAF_IPX = 4+eAF_APPLETALK :: (Num a) => a+eAF_APPLETALK = 5+eAF_NETROM :: (Num a) => a+eAF_NETROM = 6+eAF_BRIDGE :: (Num a) => a+eAF_BRIDGE = 7+eAF_ATMPVC :: (Num a) => a+eAF_ATMPVC = 8+eAF_X25 :: (Num a) => a+eAF_X25 = 9+eAF_INET6 :: (Num a) => a+eAF_INET6 = 10+eAF_ROSE :: (Num a) => a+eAF_ROSE = 11+eAF_DECnet :: (Num a) => a+eAF_DECnet = 12+eAF_NETBEUI :: (Num a) => a+eAF_NETBEUI = 13+eAF_SECURITY :: (Num a) => a+eAF_SECURITY = 14+eAF_KEY :: (Num a) => a+eAF_KEY = 15+eAF_NETLINK :: (Num a) => a+eAF_NETLINK = 16+eAF_ROUTE :: (Num a) => a+eAF_ROUTE = 16+eAF_PACKET :: (Num a) => a+eAF_PACKET = 17+eAF_ASH :: (Num a) => a+eAF_ASH = 18+eAF_ECONET :: (Num a) => a+eAF_ECONET = 19+eAF_ATMSVC :: (Num a) => a+eAF_ATMSVC = 20+eAF_RDS :: (Num a) => a+eAF_RDS = 21+eAF_SNA :: (Num a) => a+eAF_SNA = 22+eAF_IRDA :: (Num a) => a+eAF_IRDA = 23+eAF_PPPOX :: (Num a) => a+eAF_PPPOX = 24+eAF_WANPIPE :: (Num a) => a+eAF_WANPIPE = 25+eAF_LLC :: (Num a) => a+eAF_LLC = 26+eAF_CAN :: (Num a) => a+eAF_CAN = 29+eAF_TIPC :: (Num a) => a+eAF_TIPC = 30+eAF_BLUETOOTH :: (Num a) => a+eAF_BLUETOOTH = 31+eAF_IUCV :: (Num a) => a+eAF_IUCV = 32+eAF_RXRPC :: (Num a) => a+eAF_RXRPC = 33+eAF_ISDN :: (Num a) => a+eAF_ISDN = 34+eAF_PHONET :: (Num a) => a+eAF_PHONET = 35+eAF_IEEE802154 :: (Num a) => a+eAF_IEEE802154 = 36+eAF_MAX :: (Num a) => a+eAF_MAX = 37+newtype MessageType = MessageType Int deriving (Eq, Enum, Integral, Num, Ord, Real, Show)++eNLMSG_NOOP :: (Num a) => a+eNLMSG_NOOP = 1+eNLMSG_ERROR :: (Num a) => a+eNLMSG_ERROR = 2+eNLMSG_DONE :: (Num a) => a+eNLMSG_DONE = 3+eNLMSG_OVERRUN :: (Num a) => a+eNLMSG_OVERRUN = 4+eNLMSG_MIN_TYPE :: (Num a) => a+eNLMSG_MIN_TYPE = 16+eRTM_BASE :: (Num a) => a+eRTM_BASE = 16+eRTM_NEWLINK :: (Num a) => a+eRTM_NEWLINK = 16+eRTM_DELLINK :: (Num a) => a+eRTM_DELLINK = 17+eRTM_GETLINK :: (Num a) => a+eRTM_GETLINK = 18+eRTM_SETLINK :: (Num a) => a+eRTM_SETLINK = 19+eRTM_NEWADDR :: (Num a) => a+eRTM_NEWADDR = 20+eRTM_DELADDR :: (Num a) => a+eRTM_DELADDR = 21+eRTM_GETADDR :: (Num a) => a+eRTM_GETADDR = 22+eRTM_NEWROUTE :: (Num a) => a+eRTM_NEWROUTE = 24+eRTM_DELROUTE :: (Num a) => a+eRTM_DELROUTE = 25+eRTM_GETROUTE :: (Num a) => a+eRTM_GETROUTE = 26+eRTM_NEWNEIGH :: (Num a) => a+eRTM_NEWNEIGH = 28+eRTM_DELNEIGH :: (Num a) => a+eRTM_DELNEIGH = 29+eRTM_GETNEIGH :: (Num a) => a+eRTM_GETNEIGH = 30+eRTM_NEWRULE :: (Num a) => a+eRTM_NEWRULE = 32+eRTM_DELRULE :: (Num a) => a+eRTM_DELRULE = 33+eRTM_GETRULE :: (Num a) => a+eRTM_GETRULE = 34+eRTM_NEWQDISC :: (Num a) => a+eRTM_NEWQDISC = 36+eRTM_DELQDISC :: (Num a) => a+eRTM_DELQDISC = 37+eRTM_GETQDISC :: (Num a) => a+eRTM_GETQDISC = 38+eRTM_NEWTCLASS :: (Num a) => a+eRTM_NEWTCLASS = 40+eRTM_DELTCLASS :: (Num a) => a+eRTM_DELTCLASS = 41+eRTM_GETTCLASS :: (Num a) => a+eRTM_GETTCLASS = 42+eRTM_NEWTFILTER :: (Num a) => a+eRTM_NEWTFILTER = 44+eRTM_DELTFILTER :: (Num a) => a+eRTM_DELTFILTER = 45+eRTM_GETTFILTER :: (Num a) => a+eRTM_GETTFILTER = 46+eRTM_NEWACTION :: (Num a) => a+eRTM_NEWACTION = 48+eRTM_DELACTION :: (Num a) => a+eRTM_DELACTION = 49+eRTM_GETACTION :: (Num a) => a+eRTM_GETACTION = 50+eRTM_NEWPREFIX :: (Num a) => a+eRTM_NEWPREFIX = 52+eRTM_GETMULTICAST :: (Num a) => a+eRTM_GETMULTICAST = 58+eRTM_GETANYCAST :: (Num a) => a+eRTM_GETANYCAST = 62+eRTM_NEWNEIGHTBL :: (Num a) => a+eRTM_NEWNEIGHTBL = 64+eRTM_GETNEIGHTBL :: (Num a) => a+eRTM_GETNEIGHTBL = 66+eRTM_SETNEIGHTBL :: (Num a) => a+eRTM_SETNEIGHTBL = 67+eRTM_NEWNDUSEROPT :: (Num a) => a+eRTM_NEWNDUSEROPT = 68+eRTM_NEWADDRLABEL :: (Num a) => a+eRTM_NEWADDRLABEL = 72+eRTM_DELADDRLABEL :: (Num a) => a+eRTM_DELADDRLABEL = 73+eRTM_GETADDRLABEL :: (Num a) => a+eRTM_GETADDRLABEL = 74+eRTM_GETDCB :: (Num a) => a+eRTM_GETDCB = 78+eRTM_SETDCB :: (Num a) => a+eRTM_SETDCB = 79+newtype MessageFlags = MessageFlags Int deriving (Bits, Eq, Enum, Integral, Num, Ord, Real, Show)++fNLM_F_REQUEST :: (Num a, Bits a) => a+fNLM_F_REQUEST = 1+fNLM_F_MULTI :: (Num a, Bits a) => a+fNLM_F_MULTI = 2+fNLM_F_ACK :: (Num a, Bits a) => a+fNLM_F_ACK = 4+fNLM_F_ECHO :: (Num a, Bits a) => a+fNLM_F_ECHO = 8+fNLM_F_REPLACE :: (Num a, Bits a) => a+fNLM_F_REPLACE = 256+fNLM_F_ROOT :: (Num a, Bits a) => a+fNLM_F_ROOT = 256+fNLM_F_EXCL :: (Num a, Bits a) => a+fNLM_F_EXCL = 512+fNLM_F_MATCH :: (Num a, Bits a) => a+fNLM_F_MATCH = 512+fNLM_F_ATOMIC :: (Num a, Bits a) => a+fNLM_F_ATOMIC = 1024+fNLM_F_CREATE :: (Num a, Bits a) => a+fNLM_F_CREATE = 1024+fNLM_F_APPEND :: (Num a, Bits a) => a+fNLM_F_APPEND = 2048+newtype LinkType = LinkType Int deriving (Eq, Enum, Integral, Num, Ord, Real, Show)++eARPHRD_NETROM :: (Num a) => a+eARPHRD_NETROM = 0+eARPHRD_ETHER :: (Num a) => a+eARPHRD_ETHER = 1+eARPHRD_EETHER :: (Num a) => a+eARPHRD_EETHER = 2+eARPHRD_AX25 :: (Num a) => a+eARPHRD_AX25 = 3+eARPHRD_PRONET :: (Num a) => a+eARPHRD_PRONET = 4+eARPHRD_CHAOS :: (Num a) => a+eARPHRD_CHAOS = 5+eARPHRD_IEEE802 :: (Num a) => a+eARPHRD_IEEE802 = 6+eARPHRD_ARCNET :: (Num a) => a+eARPHRD_ARCNET = 7+eARPHRD_APPLETLK :: (Num a) => a+eARPHRD_APPLETLK = 8+eARPHRD_DLCI :: (Num a) => a+eARPHRD_DLCI = 15+eARPHRD_ATM :: (Num a) => a+eARPHRD_ATM = 19+eARPHRD_METRICOM :: (Num a) => a+eARPHRD_METRICOM = 23+eARPHRD_IEEE1394 :: (Num a) => a+eARPHRD_IEEE1394 = 24+eARPHRD_EUI64 :: (Num a) => a+eARPHRD_EUI64 = 27+eARPHRD_INFINIBAND :: (Num a) => a+eARPHRD_INFINIBAND = 32+eARPHRD_SLIP :: (Num a) => a+eARPHRD_SLIP = 256+eARPHRD_CSLIP :: (Num a) => a+eARPHRD_CSLIP = 257+eARPHRD_SLIP6 :: (Num a) => a+eARPHRD_SLIP6 = 258+eARPHRD_CSLIP6 :: (Num a) => a+eARPHRD_CSLIP6 = 259+eARPHRD_RSRVD :: (Num a) => a+eARPHRD_RSRVD = 260+eARPHRD_ADAPT :: (Num a) => a+eARPHRD_ADAPT = 264+eARPHRD_ROSE :: (Num a) => a+eARPHRD_ROSE = 270+eARPHRD_X25 :: (Num a) => a+eARPHRD_X25 = 271+eARPHRD_HWX25 :: (Num a) => a+eARPHRD_HWX25 = 272+eARPHRD_CAN :: (Num a) => a+eARPHRD_CAN = 280+eARPHRD_PPP :: (Num a) => a+eARPHRD_PPP = 512+eARPHRD_CISCO :: (Num a) => a+eARPHRD_CISCO = 513+eARPHRD_HDLC :: (Num a) => a+eARPHRD_HDLC = 513+eARPHRD_LAPB :: (Num a) => a+eARPHRD_LAPB = 516+eARPHRD_DDCMP :: (Num a) => a+eARPHRD_DDCMP = 517+eARPHRD_RAWHDLC :: (Num a) => a+eARPHRD_RAWHDLC = 518+eARPHRD_TUNNEL :: (Num a) => a+eARPHRD_TUNNEL = 768+eARPHRD_TUNNEL6 :: (Num a) => a+eARPHRD_TUNNEL6 = 769+eARPHRD_FRAD :: (Num a) => a+eARPHRD_FRAD = 770+eARPHRD_SKIP :: (Num a) => a+eARPHRD_SKIP = 771+eARPHRD_LOOPBACK :: (Num a) => a+eARPHRD_LOOPBACK = 772+eARPHRD_LOCALTLK :: (Num a) => a+eARPHRD_LOCALTLK = 773+eARPHRD_FDDI :: (Num a) => a+eARPHRD_FDDI = 774+eARPHRD_BIF :: (Num a) => a+eARPHRD_BIF = 775+eARPHRD_SIT :: (Num a) => a+eARPHRD_SIT = 776+eARPHRD_IPDDP :: (Num a) => a+eARPHRD_IPDDP = 777+eARPHRD_IPGRE :: (Num a) => a+eARPHRD_IPGRE = 778+eARPHRD_PIMREG :: (Num a) => a+eARPHRD_PIMREG = 779+eARPHRD_HIPPI :: (Num a) => a+eARPHRD_HIPPI = 780+eARPHRD_ASH :: (Num a) => a+eARPHRD_ASH = 781+eARPHRD_ECONET :: (Num a) => a+eARPHRD_ECONET = 782+eARPHRD_IRDA :: (Num a) => a+eARPHRD_IRDA = 783+eARPHRD_FCPP :: (Num a) => a+eARPHRD_FCPP = 784+eARPHRD_FCAL :: (Num a) => a+eARPHRD_FCAL = 785+eARPHRD_FCPL :: (Num a) => a+eARPHRD_FCPL = 786+eARPHRD_FCFABRIC :: (Num a) => a+eARPHRD_FCFABRIC = 787+eARPHRD_IEEE802_TR :: (Num a) => a+eARPHRD_IEEE802_TR = 800+eARPHRD_IEEE80211 :: (Num a) => a+eARPHRD_IEEE80211 = 801+eARPHRD_IEEE80211_PRISM :: (Num a) => a+eARPHRD_IEEE80211_PRISM = 802+eARPHRD_IEEE80211_RADIOTAP :: (Num a) => a+eARPHRD_IEEE80211_RADIOTAP = 803+eARPHRD_IEEE802154 :: (Num a) => a+eARPHRD_IEEE802154 = 804+eARPHRD_PHONET :: (Num a) => a+eARPHRD_PHONET = 820+eARPHRD_PHONET_PIPE :: (Num a) => a+eARPHRD_PHONET_PIPE = 821+newtype LinkFlags = LinkFlags Int deriving (Bits, Eq, Enum, Integral, Num, Ord, Real, Show)++fIFF_802_1Q_VLAN :: (Num a, Bits a) => a+fIFF_802_1Q_VLAN = 1+fIFF_TUN :: (Num a, Bits a) => a+fIFF_TUN = 1+fIFF_UP :: (Num a, Bits a) => a+fIFF_UP = 1+fIFF_BROADCAST :: (Num a, Bits a) => a+fIFF_BROADCAST = 2+fIFF_EBRIDGE :: (Num a, Bits a) => a+fIFF_EBRIDGE = 2+fIFF_TAP :: (Num a, Bits a) => a+fIFF_TAP = 2+fIFF_DEBUG :: (Num a, Bits a) => a+fIFF_DEBUG = 4+fIFF_SLAVE_INACTIVE :: (Num a, Bits a) => a+fIFF_SLAVE_INACTIVE = 4+fIFF_LOOPBACK :: (Num a, Bits a) => a+fIFF_LOOPBACK = 8+fIFF_MASTER_8023AD :: (Num a, Bits a) => a+fIFF_MASTER_8023AD = 8+fIFF_MASTER_ALB :: (Num a, Bits a) => a+fIFF_MASTER_ALB = 16+fIFF_POINTOPOINT :: (Num a, Bits a) => a+fIFF_POINTOPOINT = 16+fIFF_BONDING :: (Num a, Bits a) => a+fIFF_BONDING = 32+fIFF_NOTRAILERS :: (Num a, Bits a) => a+fIFF_NOTRAILERS = 32+fIFF_RUNNING :: (Num a, Bits a) => a+fIFF_RUNNING = 64+fIFF_SLAVE_NEEDARP :: (Num a, Bits a) => a+fIFF_SLAVE_NEEDARP = 64+fIFF_ISATAP :: (Num a, Bits a) => a+fIFF_ISATAP = 128+fIFF_NOARP :: (Num a, Bits a) => a+fIFF_NOARP = 128+fIFF_MASTER_ARPMON :: (Num a, Bits a) => a+fIFF_MASTER_ARPMON = 256+fIFF_PROMISC :: (Num a, Bits a) => a+fIFF_PROMISC = 256+fIFF_ALLMULTI :: (Num a, Bits a) => a+fIFF_ALLMULTI = 512+fIFF_WAN_HDLC :: (Num a, Bits a) => a+fIFF_WAN_HDLC = 512+fIFF_MASTER :: (Num a, Bits a) => a+fIFF_MASTER = 1024+fIFF_XMIT_DST_RELEASE :: (Num a, Bits a) => a+fIFF_XMIT_DST_RELEASE = 1024+fIFF_SLAVE :: (Num a, Bits a) => a+fIFF_SLAVE = 2048+fIFF_MULTICAST :: (Num a, Bits a) => a+fIFF_MULTICAST = 4096+fIFF_NO_PI :: (Num a, Bits a) => a+fIFF_NO_PI = 4096+fIFF_ONE_QUEUE :: (Num a, Bits a) => a+fIFF_ONE_QUEUE = 8192+fIFF_PORTSEL :: (Num a, Bits a) => a+fIFF_PORTSEL = 8192+fIFF_AUTOMEDIA :: (Num a, Bits a) => a+fIFF_AUTOMEDIA = 16384+fIFF_VNET_HDR :: (Num a, Bits a) => a+fIFF_VNET_HDR = 16384+fIFF_DYNAMIC :: (Num a, Bits a) => a+fIFF_DYNAMIC = 32768+fIFF_TUN_EXCL :: (Num a, Bits a) => a+fIFF_TUN_EXCL = 32768+fIFF_LOWER_UP :: (Num a, Bits a) => a+fIFF_LOWER_UP = 65536+fIFF_DORMANT :: (Num a, Bits a) => a+fIFF_DORMANT = 131072+fIFF_ECHO :: (Num a, Bits a) => a+fIFF_ECHO = 262144+newtype LinkAttrType = LinkAttrType Int deriving (Eq, Enum, Integral, Num, Ord, Real, Show)++eIFLA_UNSPEC :: (Num a) => a+eIFLA_UNSPEC = 0+eIFLA_ADDRESS :: (Num a) => a+eIFLA_ADDRESS = 1+eIFLA_BROADCAST :: (Num a) => a+eIFLA_BROADCAST = 2+eIFLA_IFNAME :: (Num a) => a+eIFLA_IFNAME = 3+eIFLA_MTU :: (Num a) => a+eIFLA_MTU = 4+eIFLA_LINK :: (Num a) => a+eIFLA_LINK = 5+eIFLA_QDISC :: (Num a) => a+eIFLA_QDISC = 6+eIFLA_STATS :: (Num a) => a+eIFLA_STATS = 7+eIFLA_COST :: (Num a) => a+eIFLA_COST = 8+eIFLA_PRIORITY :: (Num a) => a+eIFLA_PRIORITY = 9+eIFLA_MASTER :: (Num a) => a+eIFLA_MASTER = 10+eIFLA_WIRELESS :: (Num a) => a+eIFLA_WIRELESS = 11+eIFLA_PROTINFO :: (Num a) => a+eIFLA_PROTINFO = 12+eIFLA_TXQLEN :: (Num a) => a+eIFLA_TXQLEN = 13+eIFLA_MAP :: (Num a) => a+eIFLA_MAP = 14+eIFLA_WEIGHT :: (Num a) => a+eIFLA_WEIGHT = 15+eIFLA_OPERSTATE :: (Num a) => a+eIFLA_OPERSTATE = 16+eIFLA_LINKMODE :: (Num a) => a+eIFLA_LINKMODE = 17+eIFLA_LINKINFO :: (Num a) => a+eIFLA_LINKINFO = 18+eIFLA_NET_NS_PID :: (Num a) => a+eIFLA_NET_NS_PID = 19+eIFLA_IFALIAS :: (Num a) => a+eIFLA_IFALIAS = 20+newtype AddrFlags = AddrFlags Int deriving (Bits, Eq, Enum, Integral, Num, Ord, Real, Show)++fIFA_F_SECONDARY :: (Num a, Bits a) => a+fIFA_F_SECONDARY = 1+fIFA_F_TEMPORARY :: (Num a, Bits a) => a+fIFA_F_TEMPORARY = 1+fIFA_F_NODAD :: (Num a, Bits a) => a+fIFA_F_NODAD = 2+fIFA_F_OPTIMISTIC :: (Num a, Bits a) => a+fIFA_F_OPTIMISTIC = 4+fIFA_F_DADFAILED :: (Num a, Bits a) => a+fIFA_F_DADFAILED = 8+fIFA_F_HOMEADDRESS :: (Num a, Bits a) => a+fIFA_F_HOMEADDRESS = 16+fIFA_F_DEPRECATED :: (Num a, Bits a) => a+fIFA_F_DEPRECATED = 32+fIFA_F_TENTATIVE :: (Num a, Bits a) => a+fIFA_F_TENTATIVE = 64+fIFA_F_PERMANENT :: (Num a, Bits a) => a+fIFA_F_PERMANENT = 128+newtype Scope = Scope Int deriving (Eq, Enum, Integral, Num, Ord, Real, Show)++eRT_SCOPE_UNIVERSE :: (Num a) => a+eRT_SCOPE_UNIVERSE = 0+eRT_SCOPE_SITE :: (Num a) => a+eRT_SCOPE_SITE = 200+eRT_SCOPE_LINK :: (Num a) => a+eRT_SCOPE_LINK = 253+eRT_SCOPE_HOST :: (Num a) => a+eRT_SCOPE_HOST = 254+eRT_SCOPE_NOWHERE :: (Num a) => a+eRT_SCOPE_NOWHERE = 255+newtype AddrAttrType = AddrAttrType Int deriving (Eq, Enum, Integral, Num, Ord, Real, Show)++eIFA_UNSPEC :: (Num a) => a+eIFA_UNSPEC = 0+eIFA_ADDRESS :: (Num a) => a+eIFA_ADDRESS = 1+eIFA_LOCAL :: (Num a) => a+eIFA_LOCAL = 2+eIFA_LABEL :: (Num a) => a+eIFA_LABEL = 3+eIFA_BROADCAST :: (Num a) => a+eIFA_BROADCAST = 4+eIFA_ANYCAST :: (Num a) => a+eIFA_ANYCAST = 5+eIFA_CACHEINFO :: (Num a) => a+eIFA_CACHEINFO = 6+eIFA_MULTICAST :: (Num a) => a+eIFA_MULTICAST = 7+newtype RouteTableId = RouteTableId Int deriving (Eq, Enum, Integral, Num, Ord, Real, Show)++eRT_TABLE_UNSPEC :: (Num a) => a+eRT_TABLE_UNSPEC = 0+eRT_TABLE_COMPAT :: (Num a) => a+eRT_TABLE_COMPAT = 252+eRT_TABLE_DEFAULT :: (Num a) => a+eRT_TABLE_DEFAULT = 253+eRT_TABLE_MAIN :: (Num a) => a+eRT_TABLE_MAIN = 254+eRT_TABLE_LOCAL :: (Num a) => a+eRT_TABLE_LOCAL = 255+eRT_TABLE_MAX :: (Num a) => a+eRT_TABLE_MAX = 4294967295+newtype RouteProto = RouteProto Int deriving (Eq, Enum, Integral, Num, Ord, Real, Show)++eRTPROT_UNSPEC :: (Num a) => a+eRTPROT_UNSPEC = 0+eRTPROT_REDIRECT :: (Num a) => a+eRTPROT_REDIRECT = 1+eRTPROT_KERNEL :: (Num a) => a+eRTPROT_KERNEL = 2+eRTPROT_BOOT :: (Num a) => a+eRTPROT_BOOT = 3+eRTPROT_STATIC :: (Num a) => a+eRTPROT_STATIC = 4+eRTPROT_GATED :: (Num a) => a+eRTPROT_GATED = 8+eRTPROT_RA :: (Num a) => a+eRTPROT_RA = 9+eRTPROT_MRT :: (Num a) => a+eRTPROT_MRT = 10+eRTPROT_ZEBRA :: (Num a) => a+eRTPROT_ZEBRA = 11+eRTPROT_BIRD :: (Num a) => a+eRTPROT_BIRD = 12+eRTPROT_DNROUTED :: (Num a) => a+eRTPROT_DNROUTED = 13+eRTPROT_XORP :: (Num a) => a+eRTPROT_XORP = 14+eRTPROT_NTK :: (Num a) => a+eRTPROT_NTK = 15+eRTPROT_DHCP :: (Num a) => a+eRTPROT_DHCP = 16+newtype RouteType = RouteType Int deriving (Eq, Enum, Integral, Num, Ord, Real, Show)++eRTN_UNSPEC :: (Num a) => a+eRTN_UNSPEC = 0+eRTN_UNICAST :: (Num a) => a+eRTN_UNICAST = 1+eRTN_LOCAL :: (Num a) => a+eRTN_LOCAL = 2+eRTN_BROADCAST :: (Num a) => a+eRTN_BROADCAST = 3+eRTN_ANYCAST :: (Num a) => a+eRTN_ANYCAST = 4+eRTN_MULTICAST :: (Num a) => a+eRTN_MULTICAST = 5+eRTN_BLACKHOLE :: (Num a) => a+eRTN_BLACKHOLE = 6+eRTN_UNREACHABLE :: (Num a) => a+eRTN_UNREACHABLE = 7+eRTN_PROHIBIT :: (Num a) => a+eRTN_PROHIBIT = 8+eRTN_THROW :: (Num a) => a+eRTN_THROW = 9+eRTN_NAT :: (Num a) => a+eRTN_NAT = 10+eRTN_XRESOLVE :: (Num a) => a+eRTN_XRESOLVE = 11+newtype RouteFlags = RouteFlags Int deriving (Bits, Eq, Enum, Integral, Num, Ord, Real, Show)++fRTM_F_NOTIFY :: (Num a, Bits a) => a+fRTM_F_NOTIFY = 256+fRTM_F_CLONED :: (Num a, Bits a) => a+fRTM_F_CLONED = 512+fRTM_F_EQUALIZE :: (Num a, Bits a) => a+fRTM_F_EQUALIZE = 1024+fRTM_F_PREFIX :: (Num a, Bits a) => a+fRTM_F_PREFIX = 2048+newtype RouteAttrType = RouteAttrType Int deriving (Eq, Enum, Integral, Num, Ord, Real, Show)++eRTA_UNSPEC :: (Num a) => a+eRTA_UNSPEC = 0+eRTA_DST :: (Num a) => a+eRTA_DST = 1+eRTA_SRC :: (Num a) => a+eRTA_SRC = 2+eRTA_IIF :: (Num a) => a+eRTA_IIF = 3+eRTA_OIF :: (Num a) => a+eRTA_OIF = 4+eRTA_GATEWAY :: (Num a) => a+eRTA_GATEWAY = 5+eRTA_PRIORITY :: (Num a) => a+eRTA_PRIORITY = 6+eRTA_PREFSRC :: (Num a) => a+eRTA_PREFSRC = 7+eRTA_METRICS :: (Num a) => a+eRTA_METRICS = 8+eRTA_MULTIPATH :: (Num a) => a+eRTA_MULTIPATH = 9+eRTA_PROTOINFO :: (Num a) => a+eRTA_PROTOINFO = 10+eRTA_FLOW :: (Num a) => a+eRTA_FLOW = 11+eRTA_CACHEINFO :: (Num a) => a+eRTA_CACHEINFO = 12+eRTA_SESSION :: (Num a) => a+eRTA_SESSION = 13+eRTA_MP_ALGO :: (Num a) => a+eRTA_MP_ALGO = 14+eRTA_TABLE :: (Num a) => a+eRTA_TABLE = 15
+ System/Linux/Netlink/Internal.hs view
@@ -0,0 +1,55 @@+module System.Linux.Netlink.Internal+    (+      query+    , queryOne+      +    , module System.Linux.Netlink.Attributes+    , module System.Linux.Netlink.C+    , module System.Linux.Netlink.Constants+    , module System.Linux.Netlink.Protocol+    ) where++import Control.Applicative ((<$>))+import Control.Monad (when)+import Data.Bits (Bits, (.&.))++import System.Linux.Netlink.Attributes+import System.Linux.Netlink.C+import System.Linux.Netlink.Constants+import System.Linux.Netlink.Protocol++query :: NetlinkSocket -> Packet -> IO [Packet]+query sock req = do+    sendmsg sock (putPacket req)+    recvMulti sock++queryOne :: NetlinkSocket -> Packet -> IO Packet+queryOne sock req = do+    sendmsg sock (putPacket req)+    pkts <- recvMulti sock+    let len = length pkts+    when (len /= 1) $ fail ("Expected one packet, received " ++ show len)+    return $ head pkts++recvMulti :: NetlinkSocket -> IO [Packet]+recvMulti sock = do+    pkts <- recvOne sock+    if isMulti (head pkts)+        then if isDone (last pkts)+             then return $ init pkts+             else (pkts ++) <$> recvMulti sock+        else return pkts+  where+    isMulti = isFlagSet fNLM_F_MULTI . messageFlags . packetHeader+    isDone  = (== eNLMSG_DONE) . messageType . packetHeader++recvOne :: NetlinkSocket -> IO [Packet]+recvOne sock = recvmsg sock bufferSize >>= \b -> case (getPacket b) of+    Left err   -> fail err+    Right pkts -> return pkts++isFlagSet :: Bits a => a -> a -> Bool+isFlagSet f v = (f .&. v) == f++bufferSize :: Num a => a+bufferSize = 8192
+ System/Linux/Netlink/Protocol.hs view
@@ -0,0 +1,191 @@+module System.Linux.Netlink.Protocol +    (+      Header(..)+    , Message(..)+    , Attributes+    , Packet(..)+    +    , getPacket+    , putPacket+    ) where++import Prelude hiding (length)++import Control.Applicative ((<$>))+import Control.Monad (when)+import Control.Monad.Loops (whileM)+import Data.ByteString (ByteString, length)+import Data.Map (Map, fromList, toList)+import Data.Serialize.Get+import Data.Serialize.Put+import Data.Word (Word8, Word16, Word32)+import Foreign.C.Types (CInt)++import System.Linux.Netlink.Constants++data Header = Header+    {+      messageType   :: MessageType+    , messageFlags  :: Word16+    , messageSeqNum :: Word32+    , messagePID    :: Word32+    } deriving (Eq, Show)++data Message = DoneMsg+             | ErrorMsg+    {+      errorCode    :: CInt+    , errorPacket  :: Packet+    }+             | LinkMsg+    {+      interfaceType  :: LinkType+    , interfaceIndex :: Word32+    , interfaceFlags :: Word32+    }+             | AddrMsg+    {+      addrFamily         :: AddressFamily+    , addrMaskLength     :: Word8+    , addrFlags          :: Word8+    , addrScope          :: Word8+    , addrInterfaceIndex :: Word32+    } deriving (Eq, Show)++type Attributes = Map Int ByteString++data Packet = Packet+    {+      packetHeader     :: Header +    , packetMessage    :: Message+    , packetAttributes :: Attributes+    } deriving (Eq, Show)++--+-- Packet decoding+--+getPacket :: ByteString -> Either String [Packet]+getPacket bytes = flip runGet bytes $ do+    pkts <- whileM (not <$> isEmpty) getPacketInternal+    isEmpty >>= \e -> when (not e) $ fail "Incomplete message parse"+    return pkts++getPacketInternal :: Get Packet+getPacketInternal = do+    len <- fromIntegral <$> g32+    isolate (len - 4) $ do+        header <- getHeader+        msg    <- getMessage (messageType header)+        attrs <- whileM (not <$> isEmpty) getSingleAttribute+        return $ Packet header msg (fromList attrs)++getHeader :: Get Header+getHeader = do+    ty     <- fromIntegral <$> g16+    flags  <- fromIntegral <$> g16+    seqnum <- g32+    pid    <- g32+    return $ Header ty flags seqnum pid++getMessage :: MessageType -> Get Message+getMessage msgtype | msgtype == eNLMSG_DONE  = skip 4 >> return DoneMsg+                   | msgtype == eNLMSG_ERROR = getMessageError+                   | msgtype == eRTM_NEWLINK = getMessageLink+                   | msgtype == eRTM_GETLINK = getMessageLink+                   | msgtype == eRTM_DELLINK = getMessageLink+                   | msgtype == eRTM_NEWADDR = getMessageAddr+                   | msgtype == eRTM_GETADDR = getMessageAddr+                   | msgtype == eRTM_DELADDR = getMessageAddr+                   | otherwise               =+                       error $ "Can't decode message " ++ show msgtype++getMessageError :: Get Message+getMessageError = do+    code <- abs . fromIntegral <$> g32+    pkt  <- getPacketInternal+    return $ ErrorMsg code pkt++getMessageLink :: Get Message+getMessageLink = do+    skip 2+    ty    <- fromIntegral <$> g16+    idx   <- g32+    flags <- g32+    skip 4+    return $ LinkMsg ty idx flags++getMessageAddr :: Get Message+getMessageAddr = do+    fam <- fromIntegral <$> g8+    maskLen <- g8+    flags <- g8+    scope <- fromIntegral <$> g8+    idx <- g32+    return $ AddrMsg fam maskLen flags scope idx++getSingleAttribute :: Get (Int, ByteString)+getSingleAttribute = do+    len <- fromIntegral <$> g16+    ty <- fromIntegral <$> g16+    val <- getByteString (len - 4)+    isEmpty >>= \e -> when (not e && len `mod` 4 /= 0) $ skip (4 - (len `mod` 4))+    return (ty, val)++--+-- Packet serialization+--+putPacket :: Packet -> [ByteString]+putPacket (Packet header message attributes) =+    let attrs  = runPut $ putAttributes attributes+        msg    = runPut $ putMessage message+        hdr = runPut $ putHeader (length msg + length attrs + 16) header+    in [hdr, msg, attrs]++putHeader :: Int -> Header -> Put+putHeader len (Header ty flags seqnum pid) = do+    p32 (fromIntegral len)+    p16 (fromIntegral ty)+    p16 (fromIntegral flags)+    p32 seqnum+    p32 pid++putMessage :: Message -> Put+putMessage DoneMsg = p32 0+putMessage (LinkMsg ty idx flags) = do+    p8 eAF_UNSPEC >> p8 0+    p16 (fromIntegral ty)+    p32 idx+    p32 flags+    p32 0xFFFFFFFF+putMessage (AddrMsg fam maskLen flags scope idx) = do+    p8 (fromIntegral fam)+    p8 maskLen+    p8 flags+    p8 (fromIntegral scope)+    p32 idx+putMessage _ = error "Can't transmit this message to the kernel."++putAttributes :: Attributes -> Put+putAttributes = mapM_ putAttr . toList+  where+    putAttr (ty, value) = do+        p16 (fromIntegral ty)+        p16 (fromIntegral . length $ value)+        putByteString value++--+-- Helpers+--+p8 :: Word8 -> Put+p8  = putWord8+p16 :: Word16 -> Put+p16 = putWord16host+p32 :: Word32 -> Put+p32 = putWord32host++g8 :: Get Word8+g8  = getWord8+g16:: Get Word16+g16 = getWord16host+g32 :: Get Word32+g32 = getWord32host
+ netlink.cabal view
@@ -0,0 +1,35 @@+Name:                netlink+Version:             0.1+Synopsis:            Netlink communication for Haskell+Description:         Library to comminicate with Linux kernel via Netlink+Homepage:            http://netlink-hs.googlecode.com/+License:             BSD3+License-file:        LICENSE+Author:              David Anderson+Maintainer:          Max Treskin <mtreskin@metachord.com>+Copyright:           Google Inc. 2010+Stability:           Alpha+Category:            System+Build-type:          Simple+Cabal-version:       >=1.6++Source-repository head+  type:       git+  location:   https://github.com/metachord/netlink-hs++Library+  Exposed-modules:   System.Linux.Netlink+                     System.Linux.Netlink.Internal+  Other-modules:     System.Linux.Netlink.C+                     System.Linux.Netlink.Constants+                     System.Linux.Netlink.Protocol+                     System.Linux.Netlink.Attributes+  Build-depends:     base >=4 && <5,+                     bytestring >=0.9,+                     cereal >=0.3 && <0.4,+                     containers >=0.3,+                     monad-loops >=0.3,+                     unix >=2.4+  Build-tools:       c2hs > 0.16+  Ghc-options:       -Wall -fwarn-tabs+  Ghc-prof-options:  -auto-all