1{ lib }:
2let
3 inherit (import ./internal.nix { inherit lib; }) _ipv6;
4 inherit (lib.strings) match concatStringsSep toLower;
5 inherit (lib.trivial)
6 pipe
7 bitXor
8 fromHexString
9 toHexString
10 ;
11 inherit (lib.lists) elemAt;
12in
13{
14 ipv6 = {
15 /**
16 Creates an `IPv6Address` object from an IPv6 address as a string. If
17 the prefix length is omitted, it defaults to 64. The parser is limited
18 to the first two versions of IPv6 addresses addressed in RFC 4291.
19 The form "x:x:x:x:x:x:d.d.d.d" is not yet implemented. Addresses are
20 NOT compressed, so they are not always the same as the canonical text
21 representation of IPv6 addresses defined in RFC 5952.
22
23 # Type
24
25 ```
26 fromString :: String -> IPv6Address
27 ```
28
29 # Examples
30
31 ```nix
32 fromString "2001:DB8::ffff/32"
33 => {
34 address = "2001:db8:0:0:0:0:0:ffff";
35 prefixLength = 32;
36 }
37 ```
38
39 # Arguments
40
41 - [addr] An IPv6 address with optional prefix length.
42 */
43 fromString =
44 addr:
45 let
46 splittedAddr = _ipv6.split addr;
47
48 addrInternal = splittedAddr.address;
49 prefixLength = splittedAddr.prefixLength;
50
51 address = _ipv6.toStringFromExpandedIp addrInternal;
52 in
53 {
54 inherit address prefixLength;
55 };
56
57 /**
58 Converts a 48-bit MAC address into a EUI-64 IPv6 address suffix.
59
60 # Example
61
62 ```nix
63 mkEUI64Suffix "66:75:63:6B:20:75"
64 => "6475:63ff:fe6b:2075"
65 ```
66
67 # Type
68
69 ```
70 mkEUI64Suffix :: String -> String
71 ```
72
73 # Inputs
74
75 mac
76 : The MAC address (may contain these delimiters: `:`, `-` or `.` but it's not necessary)
77 */
78 mkEUI64Suffix =
79 mac:
80 pipe mac [
81 # match mac address
82 (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})$")
83
84 # check if there are matches
85 (
86 matches:
87 if matches == null then
88 throw ''"${mac}" is not a valid MAC address (expected 6 octets of hex digits)''
89 else
90 matches
91 )
92
93 # transform to result hextets
94 (octets: [
95 # combine 1st and 2nd octets into first hextet, flip U/L bit, 512 = 0x200
96 (toHexString (bitXor 512 (fromHexString ((elemAt octets 0) + (elemAt octets 1)))))
97
98 # combine 3rd and 4th octets, combine them, insert fffe pattern in between to get next two hextets
99 "${elemAt octets 2}ff"
100 "fe${elemAt octets 3}"
101
102 # combine 5th and 6th octets into the last hextet
103 ((elemAt octets 4) + (elemAt octets 5))
104 ])
105
106 # concat to result suffix
107 (concatStringsSep ":")
108
109 toLower
110 ];
111 };
112}