summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/options.nix89
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;
+ };
};
}));
};