network-data 0.2.1 → 0.3.0
raw patch · 8 files changed
+288/−224 lines, 8 filesdep ~bytestringdep ~cerealdep ~prettyPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: bytestring, cereal, pretty, prettyclass
API changes (from Hackage documentation)
- Data.TCP: data TCPPort
+ Data.Ethernet: Ethernet :: !Word8 -> !Word8 -> !Word8 -> !Word8 -> !Word8 -> !Word8 -> Ethernet
+ Data.Ethernet: EthernetHdr :: !Ethernet -> !Ethernet -> !Word16 -> EthernetHeader
+ Data.Ethernet: data Ethernet
+ Data.Ethernet: data EthernetHeader
+ Data.Ethernet: destination :: EthernetHeader -> !Ethernet
+ Data.Ethernet: etherType :: EthernetHeader -> !Word16
+ Data.Ethernet: instance Data Ethernet
+ Data.Ethernet: instance Data EthernetHeader
+ Data.Ethernet: instance Eq Ethernet
+ Data.Ethernet: instance Eq EthernetHeader
+ Data.Ethernet: instance Ord Ethernet
+ Data.Ethernet: instance Ord EthernetHeader
+ Data.Ethernet: instance Pretty Ethernet
+ Data.Ethernet: instance Read Ethernet
+ Data.Ethernet: instance Read EthernetHeader
+ Data.Ethernet: instance Serialize Ethernet
+ Data.Ethernet: instance Serialize EthernetHeader
+ Data.Ethernet: instance Show Ethernet
+ Data.Ethernet: instance Show EthernetHeader
+ Data.Ethernet: instance Typeable Ethernet
+ Data.Ethernet: instance Typeable EthernetHeader
+ Data.Ethernet: source :: EthernetHeader -> !Ethernet
+ Data.TCP: TCPPort :: Word16 -> TCPPort
+ Data.TCP: newtype TCPPort
Files
- Data/CSum.hs +6/−6
- Data/Ethernet.hs +65/−0
- Data/Header.hs +30/−30
- Data/IP.hs +65/−65
- Data/IPv6.hs +34/−34
- Data/TCP.hs +46/−46
- Data/UDP.hs +22/−22
- network-data.cabal +20/−21
Data/CSum.hs view
@@ -1,9 +1,9 @@ {-# LANGUAGE BangPatterns, GeneralizedNewtypeDeriving, DeriveDataTypeable #-} module Data.CSum- ( csum16- , CSum- , zeroCSum- ) where+ ( csum16+ , CSum+ , zeroCSum+ ) where import qualified Data.ByteString as B import Data.List (foldl')@@ -25,7 +25,7 @@ {-# INLINE csum16 #-} instance Serialize CSum where- put (CSum w) = putWord16be w- get = getWord16be >>= return . CSum+ put (CSum w) = putWord16be w+ get = getWord16be >>= return . CSum zeroCSum = CSum 0
+ Data/Ethernet.hs view
@@ -0,0 +1,65 @@+{-# LANGUAGE DisambiguateRecordFields, FlexibleInstances, MultiParamTypeClasses+ , DeriveDataTypeable #-}+{- |The Data.Ethernet module exports Ethernet header structures.+ -}+module Data.Ethernet+ ( Ethernet(..)+ , EthernetHeader(..)+ ) where++import Control.Monad (sequence, when, liftM)+import qualified Data.ByteString as B+import Data.Serialize+import Data.Serialize.Put+import Data.Serialize.Get+import Data.CSum+import Data.Data+import Data.List+import Data.Bits+import Text.PrettyPrint+import Text.PrettyPrint.HughesPJClass+import Data.Word+import Numeric++-- | An Ethernet hardware address or MAC address.+data Ethernet = Ethernet !Word8 !Word8 !Word8 !Word8 !Word8 !Word8+ deriving (Eq, Ord, Show, Read, Data, Typeable)++instance Serialize Ethernet where+ put (Ethernet o0 o1 o2 o3 o4 o5) = do putWord8 o0+ putWord8 o1+ putWord8 o2+ putWord8 o3+ putWord8 o4+ putWord8 o5+ get = do o0 <- getWord8+ o1 <- getWord8+ o2 <- getWord8+ o3 <- getWord8+ o4 <- getWord8+ o5 <- getWord8+ return $ Ethernet o0 o1 o2 o3 o4 o5++data EthernetHeader =+ EthernetHdr { destination :: !Ethernet,+ source :: !Ethernet,+ etherType :: !Word16+ } deriving (Eq, Ord, Show, Read, Data, Typeable)++instance Serialize EthernetHeader where+ put (EthernetHdr dst src ty) = do put dst+ put src+ putWord16be ty+ get = do dst <- get+ src <- get+ ty <- getWord16be+ return $ EthernetHdr dst src ty++-- Pretty Printing and parsing instances+instance Pretty Ethernet where+ pPrint (Ethernet o0 o1 o2 o3 o4 o5)+ = text+ . concat + . intersperse "::" + . map (flip showHex "") + $ [o0, o1, o2, o3, o4, o5]
Data/Header.hs view
@@ -1,51 +1,51 @@ {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-} module Data.Header- ( L3Header (..)- , L3Address (..)- ) where+ ( L3Header (..)+ , L3Address (..)+ ) where import Data.Serialize (encode, Serialize) import qualified Data.ByteString as B -- |A class of network headers that assumes a checksum is present. class (Eq c, Num c,Serialize h) => L3Header h a c | h -> a, a -> h, h -> c where- -- |Returns the checksum from the header- getChecksum :: h -> c+ -- |Returns the checksum from the header+ getChecksum :: h -> c - -- |Sets the checksum in the header- setChecksum :: h -> c -> h+ -- |Sets the checksum in the header+ setChecksum :: h -> c -> h - -- |Returns a 'source' for the header.- src :: h -> a+ -- |Returns a 'source' for the header.+ src :: h -> a - -- |Returns a 'destination' for the header.- dst :: h -> a+ -- |Returns a 'destination' for the header.+ dst :: h -> a - -- |Returns a header with all the same fields except the checksum is zeroed- zeroChecksum :: h -> h- zeroChecksum h = setChecksum h 0+ -- |Returns a header with all the same fields except the checksum is zeroed+ zeroChecksum :: h -> h+ zeroChecksum h = setChecksum h 0 - -- |Computes the checksum- computeChecksum :: h -> c+ -- |Computes the checksum+ computeChecksum :: h -> c - -- |Computes the checksum, returns a header with the proper checksum- fillChecksum :: h -> h- fillChecksum h = setChecksum h (computeChecksum h)+ -- |Computes the checksum, returns a header with the proper checksum+ fillChecksum :: h -> h+ fillChecksum h = setChecksum h (computeChecksum h) - -- |Used by various layer 4 protocols (UDP, TCP),- -- a pseudo header is needed to compute the checksum- pseudoHeader :: h -> B.ByteString+ -- |Used by various layer 4 protocols (UDP, TCP),+ -- a pseudo header is needed to compute the checksum+ pseudoHeader :: h -> B.ByteString - -- |Returns True iff the checksum is valid- valid :: h -> Bool- valid h = computeChecksum h == getChecksum h+ -- |Returns True iff the checksum is valid+ valid :: h -> Bool+ valid h = computeChecksum h == getChecksum h -- |A class of network addresses that assumes there is a 'broadcast' concept. class (Serialize a) => L3Address a h | a -> h, h -> a where- localBroadcast :: a -> a- globalBroadcast :: a+ localBroadcast :: a -> a+ globalBroadcast :: a class (Serialize h, Serialize p) => L4Header h p | h -> p where- fixChecksum :: (L3Header l3 a c) => h -> l3 -> h- srcPort :: h -> p- dstPort :: h -> p+ fixChecksum :: (L3Header l3 a c) => h -> l3 -> h+ srcPort :: h -> p+ dstPort :: h -> p
Data/IP.hs view
@@ -5,14 +5,14 @@ There is currently no support for options fields of the IP header. -} module Data.IP- ( IPv4(..)- , IPv4Header(..)- , IPv4Flag(..)- , IP- , IPHeader- , dummyIPv4Header- , module Data.IPv6- ) where+ ( IPv4(..)+ , IPv4Header(..)+ , IPv4Flag(..)+ , IP+ , IPHeader+ , dummyIPv4Header+ , module Data.IPv6+ ) where import Control.Monad (sequence, when, liftM) import qualified Data.ByteString as B@@ -37,15 +37,15 @@ data IPv4 = IPv4 Word32 deriving (Eq, Ord, Show, Read, Data, Typeable) instance Serialize IPv4 where- put (IPv4 b) = putWord32be b- get = liftM IPv4 getWord32be+ put (IPv4 b) = putWord32be b+ get = liftM IPv4 getWord32be -- |Don't fragment, more fragment and reserved flags data IPv4Flag = DF | MF | Res deriving (Eq, Ord, Show, Read, Data, Typeable) instance Enum [IPv4Flag] where- fromEnum xs = foldl' (.|.) 0 $ map fromEnum1 xs- toEnum f = map snd $ filter fst [(testBit f 0, Res), (testBit f 1, MF), (testBit f 2, DF)]+ fromEnum xs = foldl' (.|.) 0 $ map fromEnum1 xs+ toEnum f = map snd $ filter fst [(testBit f 0, Res), (testBit f 1, MF), (testBit f 2, DF)] fromEnum1 DF = 4 fromEnum1 MF = 2@@ -56,19 +56,19 @@ -- -- No warning is provided if a value is trunkated when packed! data IPv4Header =- IPv4Hdr { hdrLength :: Int- , version :: Int- , tos :: Int- , totalLength :: Int- , ipID :: Int- , flags :: [IPv4Flag]- , fragmentOffset :: Int- , ttl :: Int- , protocol :: Int- , checksum :: CSum- , source :: IPv4- , destination :: IPv4- } deriving (Eq, Ord, Show, Read, Data, Typeable)+ IPv4Hdr { hdrLength :: Int+ , version :: Int+ , tos :: Int+ , totalLength :: Int+ , ipID :: Int+ , flags :: [IPv4Flag]+ , fragmentOffset :: Int+ , ttl :: Int+ , protocol :: Int+ , checksum :: CSum+ , source :: IPv4+ , destination :: IPv4+ } deriving (Eq, Ord, Show, Read, Data, Typeable) -- |A dummy header with zeroed fields except version, header length and TTL (255). dummyIPv4Header = IPv4Hdr 5 4 0 0 0 [] 0 255 0 0 ipv4zero ipv4zero@@ -77,34 +77,34 @@ instance Serialize IPv4Header where put (IPv4Hdr ihl ver tos len id flags off ttl prot csum src dst) = do- pW8 $ (ihl .&. 0xF) .|. (ver `shiftL` 4 .&. 0xF0)- pW8 tos- pW16 len- pW16 id- let offFlags = (off .&. 0x1FFF) .|. fromIntegral (fromEnum flags `shiftL` 13)- pW16 offFlags- pW8 ttl- pW8 prot- put csum- put src- put dst+ pW8 $ (ihl .&. 0xF) .|. (ver `shiftL` 4 .&. 0xF0)+ pW8 tos+ pW16 len+ pW16 id+ let offFlags = (off .&. 0x1FFF) .|. fromIntegral (fromEnum flags `shiftL` 13)+ pW16 offFlags+ pW8 ttl+ pW8 prot+ put csum+ put src+ put dst get = do- ihlVer <- gW8- let ihl = (ihlVer .&. 0xF)- ver = (ihlVer `shiftR` 4) .&. 0xF- tos <- gW8- len <- gW16- id <- gW16- offFlags <- gW16- let off = offFlags .&. 0x1FFF- flags = toEnum $ offFlags `shiftR` 13- ttl <- gW8- prot <- gW8- csum <- get- src <- get- dst <- get- return $ IPv4Hdr ihl ver tos len id flags off ttl prot csum src dst+ ihlVer <- gW8+ let ihl = (ihlVer .&. 0xF)+ ver = (ihlVer `shiftR` 4) .&. 0xF+ tos <- gW8+ len <- gW16+ id <- gW16+ offFlags <- gW16+ let off = offFlags .&. 0x1FFF+ flags = toEnum $ offFlags `shiftR` 13+ ttl <- gW8+ prot <- gW8+ csum <- get+ src <- get+ dst <- get+ return $ IPv4Hdr ihl ver tos len id flags off ttl prot csum src dst gW8 = getWord8 >>= return . fromIntegral gW16 = getWord16be >>= return . fromIntegral@@ -114,22 +114,22 @@ -- L3Header and L3Address instances (see Data.Header) instance L3Header IPv4Header IPv4 CSum where- getChecksum = checksum- setChecksum h c = h { checksum = c }- src = source- dst = destination- pseudoHeader h = runPut (do- put (src h)- put (dst h)- putWord8 0- pW8 $ fromIntegral (protocol h)- pW16 (totalLength h))- computeChecksum h = csum16 (encode (zeroChecksum h))+ getChecksum = checksum+ setChecksum h c = h { checksum = c }+ src = source+ dst = destination+ pseudoHeader h = runPut (do+ put (src h)+ put (dst h)+ putWord8 0+ pW8 $ fromIntegral (protocol h)+ pW16 (totalLength h))+ computeChecksum h = csum16 (encode (zeroChecksum h)) instance L3Address IPv4 IPv4Header where- localBroadcast (IPv4 a) = IPv4 (0xFFFFFF00 .|. (0x000000FF .&. a))- globalBroadcast = IPv4 0xFFFFFFFF+ localBroadcast (IPv4 a) = IPv4 (0xFFFFFF00 .|. (0x000000FF .&. a))+ globalBroadcast = IPv4 0xFFFFFFFF -- Pretty Printing and parsing instances instance Pretty IPv4 where- pPrint (IPv4 i) = text . concat . intersperse "." . map show $ unfoldr (\(i,v) -> if i /= 0 then Just (v .&. 0xFF, (i-1, v `shiftR` 8)) else Nothing) (4,i)+ pPrint (IPv4 i) = text . concat . intersperse "." . map show $ unfoldr (\(i,v) -> if i /= 0 then Just (v .&. 0xFF, (i-1, v `shiftR` 8)) else Nothing) (4,i)
Data/IPv6.hs view
@@ -1,9 +1,9 @@ {-# LANGUAGE DisambiguateRecordFields, DeriveDataTypeable #-} module Data.IPv6- ( IPv6 (..)- , IPv6Header- ) where+ ( IPv6 (..)+ , IPv6Header+ ) where import Control.Monad (sequence, when) import qualified Data.ByteString as B@@ -27,52 +27,52 @@ data IPv6 = IPv6 B.ByteString deriving (Eq, Ord, Show, Read, Data, Typeable) instance Serialize IPv6 where- put (IPv6 b) = putByteString b- get = getByteString 16 >>= return . IPv6+ put (IPv6 b) = putByteString b+ get = getByteString 16 >>= return . IPv6 data IPv6Header =- IPv6Hdr { version :: Int- , trafficClass :: Int- , flowLabel :: Int- , payloadLength :: Int- , nextHeader :: IPv6Ext- , hopLimit :: Int- , source :: IPv6- , destination :: IPv6- } deriving (Eq, Ord, Show, Read, Data, Typeable)+ IPv6Hdr { version :: Int+ , trafficClass :: Int+ , flowLabel :: Int+ , payloadLength :: Int+ , nextHeader :: IPv6Ext+ , hopLimit :: Int+ , source :: IPv6+ , destination :: IPv6+ } deriving (Eq, Ord, Show, Read, Data, Typeable) instance Serialize IPv6Header where put (IPv6Hdr ver tc fl len nh hop src dst) = do- let verTCFlow = (ver .&. 0xF `shiftL` 28) .|. (tc .&. 0xFF `shiftL` 20) .|. (fl .&. 0xFFFFF)- pW32 verTCFlow- pW16 len- put nh- pW8 hop- put src- put dst+ let verTCFlow = (ver .&. 0xF `shiftL` 28) .|. (tc .&. 0xFF `shiftL` 20) .|. (fl .&. 0xFFFFF)+ pW32 verTCFlow+ pW16 len+ put nh+ pW8 hop+ put src+ put dst get = do- verTCFlow <- gW32- let ver = (verTCFlow `shiftR` 28) .&. 0xF- tc = (verTCFlow `shiftR` 20) .&. 0xFF- fl = verTCFlow .&. 0xFFFFF- len <- gW16- nh <- get- hop <- gW8- src <- get- dst <- get- return $ IPv6Hdr ver tc fl len nh hop src dst+ verTCFlow <- gW32+ let ver = (verTCFlow `shiftR` 28) .&. 0xF+ tc = (verTCFlow `shiftR` 20) .&. 0xFF+ fl = verTCFlow .&. 0xFFFFF+ len <- gW16+ nh <- get+ hop <- gW8+ src <- get+ dst <- get+ return $ IPv6Hdr ver tc fl len nh hop src dst data IPv6Ext = IPv6Ext Int deriving (Eq, Ord, Show, Read, Data, Typeable) instance Serialize IPv6Ext where- get = fmap (IPv6Ext . fromIntegral) getWord8- put (IPv6Ext x) = putWord8 (fromIntegral x)+ get = fmap (IPv6Ext . fromIntegral) getWord8+ put (IPv6Ext x) = putWord8 (fromIntegral x) -- TODO: Header and Address instances instance Pretty IPv6 where- pPrint (IPv6 i) = cat . alternate colon . map (pHex 2) $ (B.unpack i)+ pPrint (IPv6 i) = cat . alternate colon . map (pHex 2) $ (B.unpack i) -- Until 'hex' is part of the pretty printer pHex nr n = text $ pad nr $ showHex n ""
Data/TCP.hs view
@@ -1,8 +1,8 @@ {-# LANGUAGE GeneralizedNewtypeDeriving, FlexibleInstances, DeriveDataTypeable #-} module Data.TCP- ( TCPPort- , TCPHeader (..)- ) where+ ( TCPPort (..)+ , TCPHeader (..)+ ) where import Data.Serialize import Data.Serialize.Get@@ -16,63 +16,63 @@ newtype TCPPort = TCPPort Word16 deriving (Eq, Ord, Show, Read, Num, Bounded, Data, Typeable) instance Serialize TCPPort where- put (TCPPort p) = putWord16be p- get = getWord16be >>= return . TCPPort+ put (TCPPort p) = putWord16be p+ get = getWord16be >>= return . TCPPort newtype SeqNumber = SN Word32 deriving (Eq, Ord, Show, Read, Num, Bounded, Data, Typeable) newtype AckNumber = AN Word32 deriving (Eq, Ord, Show, Read, Num, Bounded, Data, Typeable) instance Serialize SeqNumber where- put (SN n) = putWord32be n- get = getWord32be >>= return . SN+ put (SN n) = putWord32be n+ get = getWord32be >>= return . SN instance Serialize AckNumber where- put (AN n) = putWord32be n- get = getWord32be >>= return . AN+ put (AN n) = putWord32be n+ get = getWord32be >>= return . AN data TCPFlag = FIN | SYN | RST | PSH | ACK | URG | ECE | CWR deriving (Eq, Ord, Show, Read, Enum, Data, Typeable) instance Enum [TCPFlag] where- fromEnum fs = foldl' (+) 0 $ map (bit . fromEnum) fs- toEnum i = map (toEnum . snd) . filter fst . flip zip [0..7] . map (testBit i) $ [0..7]+ fromEnum fs = foldl' (+) 0 $ map (bit . fromEnum) fs+ toEnum i = map (toEnum . snd) . filter fst . flip zip [0..7] . map (testBit i) $ [0..7] data TCPHeader =- TCPHdr { srcPort :: TCPPort- , dstPort :: TCPPort- , seqNumber :: SeqNumber- , ackNumber :: AckNumber- , dataOffset :: Int- , res :: Int- , flags :: [TCPFlag]- , windowSize :: Int- , checksum :: CSum- , urgentPtr :: Int- } deriving (Eq, Ord, Show, Read, Data, Typeable)+ TCPHdr { srcPort :: TCPPort+ , dstPort :: TCPPort+ , seqNumber :: SeqNumber+ , ackNumber :: AckNumber+ , dataOffset :: Int+ , res :: Int+ , flags :: [TCPFlag]+ , windowSize :: Int+ , checksum :: CSum+ , urgentPtr :: Int+ } deriving (Eq, Ord, Show, Read, Data, Typeable) instance Serialize TCPHeader where- put (TCPHdr s d seq ack dat res fs w c u) = do- put s- put d- put seq- put ack- let datRes = ((dat .&. 0xF) `shiftL` 4) .|. (res .&. 0xF)- put datRes- put (fromEnum fs)- putWord16be (fromIntegral w .&. 0xFFFF)- put c- putWord16be (fromIntegral u .&. 0xFFFF)- get = do- s <- get- d <- get- seq <- get- ack <- get- datRes <- get- let dat = (datRes `shiftR` 4) .&. 0xF- res = datRes .&. 0xF- fs <- get >>= return . toEnum- w <- getWord16be >>= return . fromIntegral- c <- get- u <- getWord16be >>= return . fromIntegral- return $ TCPHdr s d seq ack dat res fs w c u+ put (TCPHdr s d seq ack dat res fs w c u) = do+ put s+ put d+ put seq+ put ack+ let datRes = ((dat .&. 0xF) `shiftL` 4) .|. (res .&. 0xF)+ putWord8 (fromIntegral datRes)+ putWord8 (fromIntegral $ fromEnum fs)+ putWord16be (fromIntegral w .&. 0xFFFF)+ put c+ putWord16be (fromIntegral u .&. 0xFFFF)+ get = do+ s <- get+ d <- get+ seq <- get+ ack <- get+ datRes <- fmap fromIntegral getWord8+ let dat = (datRes `shiftR` 4) .&. 0xF+ res = datRes .&. 0xF+ fs <- fmap (toEnum . fromIntegral) getWord8+ w <- getWord16be >>= return . fromIntegral+ c <- get+ u <- getWord16be >>= return . fromIntegral+ return $ TCPHdr s d seq ack dat res fs w c u -- FIXME need parser for TCPPort, L4Header instance
Data/UDP.hs view
@@ -1,8 +1,8 @@ {-# LANGUAGE GeneralizedNewtypeDeriving, MultiParamTypeClasses, DeriveDataTypeable #-} module Data.UDP- ( UDPPort(..)- , UDPHeader (..)- ) where+ ( UDPPort(..)+ , UDPHeader (..)+ ) where import Data.Serialize import Data.Serialize.Get@@ -16,28 +16,28 @@ newtype UDPPort = UDPPort Word16 deriving (Eq, Ord, Show, Read, Num, Bounded, Data, Typeable) instance Pretty UDPPort where- pPrint (UDPPort p) = text (show p)+ pPrint (UDPPort p) = text (show p) instance Serialize UDPPort where- put (UDPPort p) = putWord16be p- get = getWord16be >>= return . UDPPort+ put (UDPPort p) = putWord16be p+ get = getWord16be >>= return . UDPPort data UDPHeader =- UDPHdr { srcPort :: UDPPort- , dstPort :: UDPPort- , payloadLength :: Int- , checksum :: CSum- } deriving (Eq, Ord, Show, Read, Data, Typeable)+ UDPHdr { srcPort :: UDPPort+ , dstPort :: UDPPort+ , payloadLength :: Int+ , checksum :: CSum+ } deriving (Eq, Ord, Show, Read, Data, Typeable) instance Serialize UDPHeader where- put (UDPHdr s d l c) = do- put s- put d- putWord16be $ fromIntegral l- put c- get = do- s <- get- d <- get- l <- getWord16be >>= return . fromIntegral- c <- get- return $ UDPHdr s d l c+ put (UDPHdr s d l c) = do+ put s+ put d+ putWord16be $ fromIntegral l+ put c+ get = do+ s <- get+ d <- get+ l <- getWord16be >>= return . fromIntegral+ c <- get+ return $ UDPHdr s d l c
network-data.cabal view
@@ -1,19 +1,18 @@-name: network-data-version: 0.2.1-license: BSD3-license-file: LICENSE-author: Thomas DuBuisson <thomas.dubuisson@gmail.com>-maintainer: Thomas DuBuisson-synopsis: Library for network data structures (ex: ip/udp/tcp headers and helper functions)-description: This library includes definitions for common headers such as IPv4, IPv6, UDP, TCP, etc.- Data type/functions for full packets, better typeclass setup, and a more agreeable interface- with a berkeley sockets like API should be coming soon. Also, test cases - this code is- untested as of yet.-category: Data, Network-stability: stable-build-type: Simple-cabal-version: >= 1.2-tested-with: GHC == 6.10.1+name: network-data+version: 0.3.0+license: BSD3+license-file: LICENSE+author: Thomas DuBuisson <thomas.dubuisson@gmail.com>+maintainer: Thomas DuBuisson+synopsis: Library for network data structures (ex: ethernet/ip/udp/tcp headers and helper functions)+description: This library includes definitions for common headers such as+ Ethernet, IPv4, IPv6, UDP, TCP, etc. This code is untested for any serious+ work - use at your own risk.+category: Data, Network+stability: stable+build-type: Simple+cabal-version: >= 1.2+tested-with: GHC == 6.10.1 extra-source-files: Flag small_base@@ -21,10 +20,10 @@ Library Build-Depends: base >= 3 && < 5,- bytestring >= 0.9 && < 1.0,- cereal >= 0.2 && < 0.4,- prettyclass >= 1.0 && < 1.1,- pretty >= 1.0 && < 1.2+ bytestring >= 0.9,+ cereal >= 0.2,+ prettyclass >= 1.0,+ pretty >= 1.0 hs-source-dirs:- exposed-modules: Data.IP, Data.IPv6, Data.Header, Data.TCP, Data.UDP, Data.CSum+ exposed-modules: Data.Ethernet, Data.IP, Data.IPv6, Data.Header, Data.TCP, Data.UDP, Data.CSum ghc-options: