summaryrefslogtreecommitdiffhomepage
path: root/Network/DNS/Query.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Network/DNS/Query.hs')
-rw-r--r--Network/DNS/Query.hs78
1 files changed, 78 insertions, 0 deletions
diff --git a/Network/DNS/Query.hs b/Network/DNS/Query.hs
new file mode 100644
index 0000000..8fcf694
--- /dev/null
+++ b/Network/DNS/Query.hs
@@ -0,0 +1,78 @@
+module Network.DNS.Query (composeQuery) where
+
+import Data.ByteString.Lazy (ByteString)
+import Data.Char
+import Network.DNS.StateBinary
+import Network.DNS.Types
+
+----------------------------------------------------------------
+
+composeQuery :: Int -> [Question] -> ByteString
+composeQuery idt qs = runSPut (encodeQuery qry)
+ where
+ hdr = header defaultQuery
+ qry = defaultQuery {
+ header = hdr {
+ identifier = idt
+ , qdCount = length qs
+ }
+ , question = qs
+ }
+
+----------------------------------------------------------------
+
+encodeQuery :: DNSFormat -> SPut
+encodeQuery fmt = do
+ let hdr = header fmt
+ qs = question fmt
+ encodeHeader hdr
+ encodeQuestion qs
+ return ()
+
+encodeHeader :: DNSHeader -> SPut
+encodeHeader hdr = do
+ encodeIdentifier $ identifier hdr
+ encodeFlags $ flags hdr
+ decodeQdCount $ qdCount hdr
+ decodeAnCount $ anCount hdr
+ decodeNsCount $ nsCount hdr
+ decodeArCount $ arCount hdr
+ where
+ encodeIdentifier = putInt16
+ decodeQdCount = putInt16
+ decodeAnCount = putInt16
+ decodeNsCount = putInt16
+ decodeArCount = putInt16
+
+encodeFlags :: DNSFlags -> SPut
+encodeFlags _ = put16 0x0100 -- xxx
+
+encodeQuestion :: [Question] -> SPut
+encodeQuestion qs = do
+ let q = head qs
+ dom = qname q
+ typ = qtype q
+ encodeDomain dom
+ putInt16 . typeToInt $ typ
+ put16 1
+
+----------------------------------------------------------------
+
+encodeDomain :: Domain -> SPut
+encodeDomain dom = do
+ let ss = split '.' dom
+ ls = map length ss
+ mapM_ encodeSubDomain $ zip ls ss
+ put8 0
+ where
+ encodeSubDomain (len,sub) = do
+ putInt8 len
+ mapM_ (putInt8 . ord) sub
+
+split :: Char -> String -> [String]
+split _ "" = []
+split c cs
+ | null rest = s : split c rest
+ | otherwise = s : split c (tail rest)
+ where
+ (s,rest) = break (c ==) cs