···11{ lib }:
22let
33 inherit (import ./internal.nix { inherit lib; }) _ipv6;
44+ inherit (lib.strings) match concatStringsSep toLower;
55+ inherit (lib.trivial)
66+ pipe
77+ bitXor
88+ fromHexString
99+ toHexString
1010+ ;
1111+ inherit (lib.lists) elemAt;
412in
513{
614 ipv6 = {
···4553 {
4654 inherit address prefixLength;
4755 };
5656+5757+ /**
5858+ Converts a 48-bit MAC address into a EUI-64 IPv6 address suffix.
5959+6060+ # Example
6161+6262+ ```nix
6363+ mkEUI64Suffix "66:75:63:6B:20:75"
6464+ => "6475:63ff:fe6b:2075"
6565+ ```
6666+6767+ # Type
6868+6969+ ```
7070+ mkEUI64Suffix :: String -> String
7171+ ```
7272+7373+ # Inputs
7474+7575+ mac
7676+ : The MAC address (may contain these delimiters: `:`, `-` or `.` but it's not necessary)
7777+ */
7878+ mkEUI64Suffix =
7979+ mac:
8080+ pipe mac [
8181+ # match mac address
8282+ (match "^([0-9A-Fa-f]{2})[-:.]?([0-9A-Fa-f]{2})[-:.]?([0-9A-Fa-f]{2})[-:.]?([0-9A-Fa-f]{2})[-:.]?([0-9A-Fa-f]{2})[-:.]?([0-9A-Fa-f]{2})$")
8383+8484+ # check if there are matches
8585+ (
8686+ matches:
8787+ if matches == null then
8888+ throw ''"${mac}" is not a valid MAC address (expected 6 octets of hex digits)''
8989+ else
9090+ matches
9191+ )
9292+9393+ # transform to result hextets
9494+ (octets: [
9595+ # combine 1st and 2nd octets into first hextet, flip U/L bit, 512 = 0x200
9696+ (toHexString (bitXor 512 (fromHexString ((elemAt octets 0) + (elemAt octets 1)))))
9797+9898+ # combine 3rd and 4th octets, combine them, insert fffe pattern in between to get next two hextets
9999+ "${elemAt octets 2}ff"
100100+ "fe${elemAt octets 3}"
101101+102102+ # combine 5th and 6th octets into the last hextet
103103+ ((elemAt octets 4) + (elemAt octets 5))
104104+ ])
105105+106106+ # concat to result suffix
107107+ (concatStringsSep ":")
108108+109109+ toLower
110110+ ];
48111 };
49112}
+44
lib/tests/network.sh
···114114expectSuccess 'lib.network.ipv6.fromString "2001:DB8::ffff/64"' '{"address":"2001:db8:0:0:0:0:0:ffff","prefixLength":64}'
115115expectSuccess 'lib.network.ipv6.fromString "1234:5678:90ab:cdef:fedc:ba09:8765:4321/44"' '{"address":"1234:5678:90ab:cdef:fedc:ba09:8765:4321","prefixLength":44}'
116116117117+expectSuccess 'mkEUI64Suffix "00:11:22:AA:BB:CC"' '"211:22ff:feaa:bbcc"'
118118+expectSuccess 'mkEUI64Suffix "00-11-22-AA-BB-CC"' '"211:22ff:feaa:bbcc"'
119119+expectSuccess 'mkEUI64Suffix "00.11.22.AA.BB.CC"' '"211:22ff:feaa:bbcc"'
120120+expectSuccess 'mkEUI64Suffix "00:11:22:aa:bb:cc"' '"211:22ff:feaa:bbcc"'
121121+expectSuccess 'mkEUI64Suffix "00-11-22-aa-bb-cc"' '"211:22ff:feaa:bbcc"'
122122+expectSuccess 'mkEUI64Suffix "00.11.22.aa.bb.cc"' '"211:22ff:feaa:bbcc"'
123123+124124+expectSuccess 'mkEUI64Suffix "12:34:56:78:9A:bc"' '"1034:56ff:fe78:9abc"'
125125+expectSuccess 'mkEUI64Suffix "123456789ABC"' '"1034:56ff:fe78:9abc"'
126126+127127+expectSuccess 'mkEUI64Suffix "001122AABBCC"' '"211:22ff:feaa:bbcc"'
128128+expectSuccess 'mkEUI64Suffix "001122aabbcc"' '"211:22ff:feaa:bbcc"'
129129+130130+expectSuccess 'mkEUI64Suffix "ff-ff-ff-ff-ff-ff"' '"fdff:ffff:feff:ffff"'
131131+expectSuccess 'mkEUI64Suffix "ffffffffffff"' '"fdff:ffff:feff:ffff"'
132132+expectSuccess 'mkEUI64Suffix "00.00.00.00.00.00"' '"200:00ff:fe00:0000"'
133133+expectSuccess 'mkEUI64Suffix "000000000000"' '"200:00ff:fe00:0000"'
134134+135135+expectFailure 'mkEUI64Suffix "123456789AB"' "is not a valid MAC address \(expected 6 octets of hex digits\)"
136136+expectFailure 'mkEUI64Suffix "123456789A"' "is not a valid MAC address \(expected 6 octets of hex digits\)"
137137+expectFailure 'mkEUI64Suffix "123456789"' "is not a valid MAC address \(expected 6 octets of hex digits\)"
138138+expectFailure 'mkEUI64Suffix "12345678"' "is not a valid MAC address \(expected 6 octets of hex digits\)"
139139+expectFailure 'mkEUI64Suffix "1234567"' "is not a valid MAC address \(expected 6 octets of hex digits\)"
140140+expectFailure 'mkEUI64Suffix "123456"' "is not a valid MAC address \(expected 6 octets of hex digits\)"
141141+expectFailure 'mkEUI64Suffix "12345"' "is not a valid MAC address \(expected 6 octets of hex digits\)"
142142+expectFailure 'mkEUI64Suffix "1234"' "is not a valid MAC address \(expected 6 octets of hex digits\)"
143143+expectFailure 'mkEUI64Suffix "123"' "is not a valid MAC address \(expected 6 octets of hex digits\)"
144144+expectFailure 'mkEUI64Suffix "12"' "is not a valid MAC address \(expected 6 octets of hex digits\)"
145145+expectFailure 'mkEUI64Suffix "1"' "is not a valid MAC address \(expected 6 octets of hex digits\)"
146146+expectFailure 'mkEUI64Suffix ""' "is not a valid MAC address \(expected 6 octets of hex digits\)"
147147+expectFailure 'mkEUI64Suffix "------------"' "is not a valid MAC address \(expected 6 octets of hex digits\)"
148148+expectFailure 'mkEUI64Suffix "............"' "is not a valid MAC address \(expected 6 octets of hex digits\)"
149149+expectFailure 'mkEUI64Suffix "::::::::::::"' "is not a valid MAC address \(expected 6 octets of hex digits\)"
150150+expectFailure 'mkEUI64Suffix "1:2:3:4:5:6"' "is not a valid MAC address \(expected 6 octets of hex digits\)"
151151+expectFailure 'mkEUI64Suffix "0.0.0.0.0.0"' "is not a valid MAC address \(expected 6 octets of hex digits\)"
152152+expectFailure 'mkEUI64Suffix "00:11:-2:AA:BB:CC"' "is not a valid MAC address \(expected 6 octets of hex digits\)"
153153+expectFailure 'mkEUI64Suffix "00:-11:22:AA:BB:CC"' "is not a valid MAC address \(expected 6 octets of hex digits\)"
154154+expectFailure 'mkEUI64Suffix "ab:cd:ef:g0:12:34"' "is not a valid MAC address \(expected 6 octets of hex digits\)"
155155+expectFailure 'mkEUI64Suffix "AB:CD:EF:G0:12:34"' "is not a valid MAC address \(expected 6 octets of hex digits\)"
156156+expectFailure 'mkEUI64Suffix "ab:cd:ef:gh:jk:lm"' "is not a valid MAC address \(expected 6 octets of hex digits\)"
157157+expectFailure 'mkEUI64Suffix "AB:CD:EF:GH:JK:LM"' "is not a valid MAC address \(expected 6 octets of hex digits\)"
158158+expectFailure 'mkEUI64Suffix "01:23:3a:bc:de:fg"' "is not a valid MAC address \(expected 6 octets of hex digits\)"
159159+expectFailure 'mkEUI64Suffix "01:23:3A:BC:DE:FG"' "is not a valid MAC address \(expected 6 octets of hex digits\)"
160160+117161echo >&2 tests ok