module Network.DNS.RBL.Host where import Data.ByteString.Char8 ( ByteString, intercalate, pack, split ) import qualified Network.DNS as DNS ( Domain ) import Network.DNS.RBL.Domain ( UserDomain(..) ) import Network.DNS.RBL.Pretty ( Pretty(..) ) -- | A data type representing a host that we would like to look up on -- a blacklist. This can be either an IP address (for normal -- blacklists) or a domain name (for name-based blacklists). -- -- Rather than make a distinction, we rely on the fact that we can -- parse all-digit \"domain names\". That is, we'll happily accept -- e.g. \"127.0.0.1\" as a name, and anything that isn't a valid IP -- address will implicitly be treated as a name and not an address. -- newtype Host = Host UserDomain instance Pretty Host where pretty_show (Host d) = pretty_show d -- | Reverse the labels of this host in preparation for making a -- lookup (using the DNS library). We need to reverse the labels -- (the stuff between the dots) whether we're looking up a host or a -- name. The only tricky part here is that we need to turn an -- absolute 'UserDomain' into a relative one. -- -- ==== _Examples_ -- -- >>> import Text.Parsec ( parse ) -- >>> import Network.DNS.RBL.Domain ( user_domain ) -- -- >>> let (Right r) = parse user_domain "" "1.2.3.4" -- >>> let h = Host r -- >>> reverse_labels h -- "4.3.2.1" -- -- >>> let (Right r) = parse user_domain "" "www.example.com" -- >>> let h = Host r -- >>> reverse_labels h -- "com.example.www" -- -- Make sure absolute names are made relative: -- -- >>> let (Right r) = parse user_domain "" "www.example.com." -- >>> let h = Host r -- >>> reverse_labels h -- "com.example.www" -- reverse_labels :: Host -> DNS.Domain reverse_labels (Host h) = reversed where -- | It's possible that we are given an absolute domain name to -- look up. This is legit; say I want to look up -- \"www.example.com.\" That's fine, but before we make the -- actual query we'll need to make it relative and then append -- the DNSBL's suffix to it. relative_host_string :: String relative_host_string = case h of (UserDomainRelative _) -> pretty_show h (UserDomainAbsolute d) -> pretty_show d dot = pack "." labels = split '.' (pack relative_host_string) reversed = intercalate dot (reverse labels)