--- /dev/null
+-- | Helpers to perform DNS queries.
+module DNS (
+ Domain,
+ lookup_ptrs
+ )
+where
+
+import qualified Data.ByteString.Char8 as BS (
+ append,
+ intercalate,
+ pack,
+ split )
+import Network.DNS (
+ Domain,
+ ResolvConf(..),
+ defaultResolvConf,
+ lookupPTR,
+ makeResolvSeed,
+ withResolver
+ )
+
+
+-- | Convert the given IP address (as a ByteString) to the format
+-- required for a PTR lookup. For example, "192.168.0.0" should be
+-- converted to "0.0.168.192.in-addr.arpa".
+ip_to_in_addr_arpa :: Domain -> Domain
+ip_to_in_addr_arpa ip =
+ rev_ip `BS.append` suffix
+ where
+ dot = BS.pack "."
+ suffix = BS.pack ".in-addr.arpa"
+ rev_ip = BS.intercalate dot (reverse (BS.split '.' ip))
+
+-- | Take the default ResolvConf and increase the timeout to 15
+-- seconds.
+our_resolv_conf :: ResolvConf
+our_resolv_conf =
+ defaultResolvConf { resolvTimeout = 15*1000*1000 } -- 15s
+
+
+-- | Takes a list of IP addresses (as ByteStrings) and performs
+-- reverse (PTR) lookups on each of them.
+lookup_ptrs :: [Domain] -> IO [Maybe [Domain]]
+lookup_ptrs ips = do
+ rs <- makeResolvSeed our_resolv_conf
+ withResolver rs $ \resolver ->
+ mapM (lookupPTR resolver) in_addrs
+ where
+ in_addrs = map ip_to_in_addr_arpa ips