diff options
Diffstat (limited to 'sys/net/options.nix')
| -rw-r--r-- | sys/net/options.nix | 89 |
1 files changed, 88 insertions, 1 deletions
diff --git a/sys/net/options.nix b/sys/net/options.nix index 2930567..11b913c 100644 --- a/sys/net/options.nix +++ b/sys/net/options.nix @@ -1,5 +1,46 @@ { config, lib, ... }: -with lib; { +with lib; let + v4PtrHierarchy = address: bits: reverseList (sublist 0 (bits / 8) (splitString "." address)); + + v6PtrHierarchy = address: bits: + let + separator = lists.findFirstIndex (hextet: hextet == "") null colonSplit; + colonSplit = splitString ":" address; + + zeroFill = replicate (8 - length colonSplit + 1) "0000"; + leftSplit = sublist 0 separator colonSplit; + rightSplit = sublist (separator + 1) (length colonSplit - separator - 1) colonSplit; + + fullSplit = + if separator != null + then leftSplit ++ zeroFill ++ rightSplit + else colonSplit; + + padded = map (hextet: strings.replicate (4 - stringLength hextet) "0" + hextet) fullSplit; + in + reverseList (sublist 0 (bits / 4) (flatten (map stringToCharacters padded))); + + matchPtrRecordName = { splitter, netAddress, netBits, targetAddress, targetBits }: + let + netSplit = splitter netAddress netBits; + targetSplit = splitter targetAddress targetBits; + + netLength = length netSplit; + lengthDelta = length targetSplit - netLength; + + withinNet = lengthDelta >= 0 && sublist lengthDelta netLength targetSplit == netSplit; + throwMessage = "${targetAddress}/${toString targetBits} is not a subset of ${netAddress}/${toString netBits}"; + + recordHierarchy = sublist 0 lengthDelta targetSplit; + + recordName = + if recordHierarchy != [ ] + then concatStringsSep "." recordHierarchy + else "@"; + in + throwIfNot withinNet throwMessage recordName; +in +{ options.local.nets = with lib.types; mkOption { readOnly = true; @@ -126,14 +167,37 @@ with lib; { type = str; readOnly = true; }; + + ptrDomain = mkOption { + type = str; + readOnly = true; + }; + + ptrRecordName = mkOption { + type = functionTo (functionTo str); + readOnly = true; + }; }; config = { cidr = "${config.subnet}/${toString config.bits}"; + subnet = if config.bits != 0 then config.prefix + strings.replicate (4 - config.bits / 8) ".0" else "0.0.0.0"; + + ptrDomain = concatStrings (map (x: x + ".") (v4PtrHierarchy config.subnet config.bits)) + "in-addr.arpa"; + + ptrRecordName = address: bits: matchPtrRecordName { + splitter = v4PtrHierarchy; + + netBits = config.bits; + netAddress = config.subnet; + + targetBits = bits; + targetAddress = address; + }; }; })); }; @@ -162,14 +226,37 @@ with lib; { type = str; readOnly = true; }; + + ptrDomain = mkOption { + type = str; + readOnly = true; + }; + + ptrRecordName = mkOption { + type = functionTo (functionTo str); + readOnly = true; + }; }; config = { cidr = "${config.subnet}/${toString config.bits}"; + subnet = if config.bits == 128 || length (splitString "::" config.prefix) > 1 then config.prefix else "${config.prefix}::"; + + ptrDomain = concatStrings (map (x: x + ".") (v6PtrHierarchy config.subnet config.bits)) + "ip6.arpa"; + + ptrRecordName = address: bits: matchPtrRecordName { + splitter = v6PtrHierarchy; + + netBits = config.bits; + netAddress = config.subnet; + + targetBits = bits; + targetAddress = address; + }; }; })); }; |
