module Resolve.DNS.Types where
import Data.Word
import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as BS
import qualified Data.HashMap as HM
import Data.Tuple (swap)
import Data.Maybe
import Data.Bits
import Data.BitVector
import Data.List
import Data.IP
import Data.Typeable
import Resolve.Types
import Control.Exception
data DNSException where
DNSException :: Exception e => e -> DNSException
deriving (Typeable)
instance Show DNSException where
show (DNSException e) = show e
instance Exception DNSException where
toException = resolveExceptionToException
fromException = resolveExceptionFromException
dnsExceptionToException :: Exception e => e -> SomeException
dnsExceptionToException = toException . DNSException
dnsExceptionFromException x = do
DNSException a <- fromException x
cast a
type LABEL = ByteString
newtype NAME = NAME [LABEL] deriving (Eq, Ord)
qclass_word = map (\(a, b) -> (CLASS a, b)) class_word
++ [(ANY, 5)]
:: [(QCLASS, Word16)]
class_word = [ (IN, 1)
, (CH, 3)
, (HS, 4)
] :: [(CLASS, Word16)]
qtype_word = [ (Q_A, 1 :: Word16)
, (Q_NS, 2)
, (Q_CNAME, 5)
, (Q_SOA, 6)
, (Q_PTR, 12)
, (Q_MX, 15)
, (Q_TXT, 16)
]
opcode_word = map (\(a, b) -> (a, bitVec 4 b))
[ (STD, bitVec 4 0)
, (INV, bitVec 4 1)
, (SSR, bitVec 4 2)
]
rcode_word = map (\(a, b) -> (a, bitVec 4 b))
[ (NoErr, 0)
, (FormatErr, 1)
, (ServFail, 2)
, (NameErr, 3)
, (NotImpl, 4)
, (Refused, 5)
]
qr_word = [ (Query, False)
, (Response, True)]
data Message = Message {
header :: Header
, question :: [Question]
, answer :: [RR]
, authority :: [RR]
, additional :: [RR]
} deriving (Eq, Show)
data Header = Header { ident :: Word16
, qr :: QR
, opcode :: OPCODE
, aa :: Bool
, tc :: Bool
, rd :: Bool
, ra :: Bool
, zero :: Word8
, rcode :: RCODE
} deriving (Eq, Show)
data QR = Query | Response deriving (Eq, Show)
toBool :: QR -> Bool
toBool Query = False
toBool Response = True
data OPCODE
= STD
| INV
| SSR
deriving (Eq, Show, Bounded)
data RCODE
= NoErr
| FormatErr
| ServFail
| NameErr
| NotImpl
| Refused
| Other Word8
deriving (Eq, Ord, Show)
data CLASS = IN
| CH
| HS
| OTHER Word16
deriving (Eq, Show, Ord)
data QCLASS = CLASS CLASS
| ANY
deriving (Eq, Show, Ord)
data QTYPE = Q_A
| Q_NS
| Q_CNAME
| Q_SOA
| Q_PTR
| Q_MX
| Q_TXT
| Q_AXFR
| Q_ALL
| Q_OTHER Word16
deriving (Eq, Show, Ord)
data Question = Question { qname :: NAME
, qtype :: QTYPE
, qclass :: QCLASS
} deriving (Eq, Show)
data RR = RR { name :: NAME
, ttl :: Word32
, rdata :: RDATA
}
deriving (Eq, Show)
data RDATA_COM = CNAME NAME
| MX Word16 NAME
| NS NAME
| PTR NAME
| SOA NAME NAME Word32 Word32 Word32 Word32 Word32
| TXT [ByteString]
deriving (Eq, Ord, Show)
data RDATA = RR_COM CLASS RDATA_COM
| RR_A IPv4
| RR_OTHER CLASS Word16 ByteString
deriving (Eq, Ord, Show)
instance Show NAME where
show (NAME xs) = intercalate "." (map BS.unpack xs)