--- /dev/null
+import Data.Binary
+import qualified Data.ByteString.Lazy as LBS
+import Data.Word
+import Network.DNS.Message
+import Test.HUnit
+
+
+parseMsg :: [Word8] -> Message
+parseMsg = decode . LBS.pack
+
+
+testData :: [Test]
+testData = [ (parseMsg [ 0x22, 0x79, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00
+ , 0x00, 0x00, 0x00, 0x00, 0x04, 0x6D, 0x61, 0x69
+ , 0x6C, 0x0A, 0x63, 0x69, 0x65, 0x6C, 0x6F, 0x6E
+ , 0x65, 0x67, 0x72, 0x6F, 0x03, 0x6F, 0x72, 0x67
+ , 0x00, 0x00, 0x05, 0x00, 0x01
+ ]
+ ~?=
+ Message {
+ msgHeader = Header {
+ hdMessageID = 8825
+ , hdMessageType = Query
+ , hdOpcode = StandardQuery
+ , hdIsAuthoritativeAnswer = False
+ , hdIsTruncated = False
+ , hdIsRecursionDesired = True
+ , hdIsRecursionAvailable = False
+ , hdResponseCode = NoError
+ }
+ , msgQuestions = [ Question {
+ qName = mkDomainName "mail.cielonegro.org."
+ , qType = mkQueryType CNAME
+ , qClass = IN
+ }
+ ]
+ , msgAnswers = []
+ , msgAuthorities = []
+ , msgAdditionals = []
+ }
+ )
+ ]
+
+
+main :: IO ()
+main = runTestTT (test testData) >> return ()
\ No newline at end of file
, CNAME(..)
, HINFO(..)
+
+ , mkQueryType
+ , mkDomainName
)
where
+import Control.Exception
import Control.Monad
import Data.Binary
import Data.Binary.BitPut as BP
import Data.Binary.Put as P
import Data.Binary.Strict.BitGet as BG
import qualified Data.ByteString as BS
+import qualified Data.ByteString.Char8 as C8 hiding (ByteString)
import qualified Data.ByteString.Lazy as LBS
import Data.Typeable
import qualified Data.IntMap as IM
, msgAuthorities :: ![SomeRR]
, msgAdditionals :: ![SomeRR]
}
+ deriving (Show, Eq)
data Header
= Header {
-- + NSCOUNT
-- + ARCOUNT
}
+ deriving (Show, Eq)
type MessageID = Word16
data Question
= Question {
qName :: !DomainName
- , qType :: !SomeRT
+ , qType :: !SomeQT
, qClass :: !RecordClass
}
deriving (Show, Eq)
+type SomeQT = SomeRT
+
+mkQueryType :: RecordType rt dt => rt -> SomeQT
+mkQueryType = SomeRT
+
putQ :: Question -> Put
putQ q
= do putDomainName $ qName q
labelsToName :: [DomainLabel] -> DomainName
labelsToName = DN
+mkDomainName :: String -> DomainName
+mkDomainName = labelsToName . mkLabels [] . notEmpty
+ where
+ notEmpty :: String -> String
+ notEmpty xs = assert (not $ null xs) xs
+
+ mkLabels :: [DomainLabel] -> String -> [DomainLabel]
+ mkLabels soFar [] = reverse (C8.empty : soFar)
+ mkLabels soFar xs = case break (== '.') xs of
+ (l, ('.':rest))
+ -> mkLabels (C8.pack l : soFar) rest
+ _ -> error ("Illegal domain name: " ++ xs)
data RecordClass
= IN