summaryrefslogtreecommitdiff
path: root/src/Propellor/Types/Dns.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Propellor/Types/Dns.hs')
-rw-r--r--src/Propellor/Types/Dns.hs28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/Propellor/Types/Dns.hs b/src/Propellor/Types/Dns.hs
index d78c78fd..3497b3ed 100644
--- a/src/Propellor/Types/Dns.hs
+++ b/src/Propellor/Types/Dns.hs
@@ -10,6 +10,8 @@ import Data.Word
import Data.Monoid
import qualified Data.Map as M
import qualified Data.Set as S
+import Data.List
+import Data.String.Utils (split, replace)
type Domain = String
@@ -91,8 +93,34 @@ data Record
| SRV Word16 Word16 Word16 BindDomain
| SSHFP Int Int String
| INCLUDE FilePath
+ | PTR ReverseIP
deriving (Read, Show, Eq, Ord, Typeable)
+-- | An in-addr.arpa record corresponding to an IPAddr.
+type ReverseIP = String
+
+reverseIP :: IPAddr -> ReverseIP
+reverseIP (IPv4 addr) = intercalate "." (reverse $ split "." addr) ++ ".in-addr.arpa"
+reverseIP addr@(IPv6 _) = reverse (intersperse '.' $ replace ":" "" $ fromIPAddr $ canonicalIP addr) ++ ".ip6.arpa"
+
+-- | Converts an IP address (particularly IPv6) to canonical, fully
+-- expanded form.
+canonicalIP :: IPAddr -> IPAddr
+canonicalIP (IPv4 addr) = IPv4 addr
+canonicalIP (IPv6 addr) = IPv6 $ intercalate ":" $ map canonicalGroup $ split ":" $ replaceImplicitGroups addr
+ where
+ canonicalGroup g
+ | l <= 4 = replicate (4 - l) '0' ++ g
+ | otherwise = error $ "IPv6 group " ++ g ++ "as more than 4 hex digits"
+ where
+ l = length g
+ emptyGroups n = iterate (++ ":") "" !! n
+ numberOfImplicitGroups a = 8 - length (split ":" $ replace "::" "" a)
+ replaceImplicitGroups a = concat $ aux $ split "::" a
+ where
+ aux [] = []
+ aux (x : xs) = x : emptyGroups (numberOfImplicitGroups a) : xs
+
getIPAddr :: Record -> Maybe IPAddr
getIPAddr (Address addr) = Just addr
getIPAddr _ = Nothing