network-data 0.0.2 → 0.1.0
raw patch · 4 files changed
+50/−45 lines, 4 filesdep ~basedep ~binarydep ~parsecPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base, binary, parsec, pretty, prettyclass
API changes (from Hackage documentation)
- Data.IP: payloadLength :: IPv4Header -> Int
- Data.UDP: data UDPPort
+ Data.IP: totalLength :: IPv4Header -> Int
+ Data.IPv6: ipv6 :: GenParser Char st IPv6
+ Data.UDP: UDPPort :: Word16 -> UDPPort
+ Data.UDP: newtype UDPPort
Files
- Data/IP.hs +16/−12
- Data/IPv6.hs +25/−26
- Data/UDP.hs +1/−1
- network-data.cabal +8/−6
Data/IP.hs view
@@ -1,21 +1,19 @@ {-# LANGUAGE DisambiguateRecordFields, FlexibleInstances, MultiParamTypeClasses #-}-{- |The Data.IP library exports IPv4 and IPv6 address and header structures.-- Patches to add more parsing and pretty printing are welcome.+{- |The Data.IP library exports IPv4 address and header structures. FIXME: There is currently no support for options fields of the IP header. -} module Data.IP- ( IPv4 (..)- , IPv4Header (..)- , IPv4Flag (..)+ ( IPv4(..)+ , IPv4Header(..)+ , IPv4Flag(..) , dummyIPv4Header , module Data.IPv6 , ipv4 ) where -import Control.Monad (sequence)+import Control.Monad (sequence, when) import qualified Data.ByteString.Lazy as B import Data.Binary import Data.Binary.Put@@ -52,12 +50,12 @@ -- |This IPv4 header structure lacks support for options. Ints are used -- for most integral data types and the binary instance hands the bit packing. ----- No warning is provided if a field is overflowed!+-- No warning is provided if a value is trunkated when packed! data IPv4Header = IPv4Hdr { hdrLength :: Int , version :: Int , tos :: Int- , payloadLength :: Int+ , totalLength :: Int , ipID :: Int , flags :: [IPv4Flag] , fragmentOffset :: Int@@ -121,7 +119,7 @@ put (dst h) putWord8 0 pW8 $ fromIntegral (protocol h)- pW16 (payloadLength h))+ pW16 (totalLength h)) computeChecksum h = csum16 (encode (zeroChecksum h)) instance L3Address IPv4 IPv4Header where@@ -132,6 +130,8 @@ instance Pretty IPv4 where pPrint (IPv4 i) = cat . intersperse (char '.') . map (int . fromIntegral) $ (B.unpack i) +-- |Parsec parser for IPv4 strings (ex: "33.44.255.17")+ipv4 :: GenParser Char st IPv4 ipv4 = do a <- octet P.char '.'@@ -142,9 +142,13 @@ d <- octet return $ IPv4 $ B.pack [a, b, c, d] <?>- "Expected IPv4 Address"+ "IPv4 Address" octet = do d <- P.many1 P.digit- let s = toEnum $ read d+ let n = read d :: Int+ when (n > 255) (fail "IPv4 octet invalid")+ let s = toEnum n return s+ <?>+ "IPv4 digits for an octet"
Data/IPv6.hs view
@@ -2,19 +2,20 @@ module Data.IPv6 ( IPv6 (..)+ , ipv6 ) where -import Control.Monad (sequence)+import Control.Monad (sequence, when) import qualified Data.ByteString.Lazy as B import Data.Binary import Data.Binary.Put import Data.Binary.Get import Data.Bits-import Numeric (showHex)+import Data.List (group)+import Numeric (showHex, readHex) import Text.PrettyPrint import Text.PrettyPrint.HughesPJClass import Text.ParserCombinators.Parsec as P-import Data.Maybe (maybeToList) gW8 = getWord8 >>= return . fromIntegral gW16 = getWord16be >>= return . fromIntegral@@ -68,7 +69,7 @@ get = return E put _ = return () --- TODO: Header and Address instanes+-- TODO: Header and Address instances instance Pretty IPv6 where pPrint (IPv6 i) = cat . alternate colon . map (pHex 2) $ (B.unpack i)@@ -84,27 +85,25 @@ go (a:b:c:xs) = a : b : f : go (c:xs) go x = x -second :: GenParser Char st [String]-second = do- P.char ':'- x <- many1 hexDigit- xs <- second- return (x : xs)- <|>- return []--first :: GenParser Char st [String]-first = do- x <- many1 hexDigit- (do P.char ':'- xs <- first- return (x:xs)- <|> return [x])- <|> return []- ipv6 :: GenParser Char st IPv6-ipv6 = do error "blah"+ipv6 = do+ blocks <- sepBy1 (many hexDigit) (P.char ':')+ let blocks' = expand blocks+ vals = map (fst . head . readHex) blocks'+ -- bs = runPut (mapM_ putWord16be vals)+ cblks = combine blocks+ bs = runPut . mapM_ putWord16be . map (fst . head . readHex) . expand $ cblks+ when (1 < length (filter (=="") cblks)) (fail "IPv6 Address with only one :: entry")+ when (B.length bs /= 16) (fail "IPv6 Address of proper length")+ return (IPv6 bs) where- replace :: (Eq a) => a -> [a] -> [a] -> [a]- replace _ _ [] = []- replace n r (x:xs) = if n == x then r ++ xs else x : replace n r xs+ expand :: [String] -> [String]+ expand as = replace (replicate (8 - length as + 1) "0") as++replace :: (Eq a) => [[a]] -> [[a]] -> [[a]]+replace _ [] = []+replace r ([]:xs) = r ++ xs+replace r (x:xs) = x : replace r xs++combine :: (Eq a) => [[a]] -> [[a]]+combine = concat . map (\x -> if [] `elem` x then [[]] else x) . group
Data/UDP.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE GeneralizedNewtypeDeriving, MultiParamTypeClasses #-} module Data.UDP- ( UDPPort+ ( UDPPort(..) , UDPHeader (..) ) where
network-data.cabal view
@@ -1,5 +1,5 @@ name: network-data-version: 0.0.2+version: 0.1.0 license: BSD3 license-file: LICENSE author: Thomas DuBuisson <thomas.dubuisson@gmail.com>@@ -9,7 +9,7 @@ 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, Networking+category: Data, Network stability: stable build-type: Simple cabal-version: >= 1.2@@ -20,10 +20,12 @@ Description: Choose the split-up base package. Library- if flag(small_base)- Build-Depends: base >= 3, bytestring >= 0.9 && < 1.0, binary >= 0.4.0 && < 0.5.0, prettyclass, pretty, parsec- else- Build-Depends: base >= 3, bytestring >= 0.9 && < 1.0, binary >= 0.4.0 && <0.5.0, prettyclass, pretty, parsec+ Build-Depends: base >= 3 && < 5,+ bytestring >= 0.9 && < 1.0,+ binary >= 0.5.0 && < 0.6.0,+ prettyclass >= 1.0.0.0 && < 1.1,+ pretty >= 1.0.0 && < 1.1.0,+ parsec >= 3 && < 4 hs-source-dirs: exposed-modules: Data.IP, Data.IPv6, Data.Header, Data.TCP, Data.UDP, Data.CSum ghc-options: