|
| 1 | +module TemplateHelpers |
| 2 | + # Embed IPv4 address or CIDR in Pref64::/n |
| 3 | + def embed_v4(pref64n, v4) |
| 4 | + v4addr, v4prefixlen = v4.split(?/, 2) |
| 5 | + v6prefixlen = v4prefixlen.to_i + 96 if v4prefixlen |
| 6 | + |
| 7 | + pref64n.sub('::/96', [sprintf(':%02x%02x:%02x%02x', *v4addr.split(?.).map(&:to_i)), *v6prefixlen].join(?/)) or fail 'pref64n is not /96' |
| 8 | + end |
| 9 | + |
| 10 | + # Parse the IPv6 string representation into an array of hextets. |
| 11 | + def parse_v6addr(str) |
| 12 | + head, tail = str.split('::', 2) |
| 13 | + hextets = head.split(?:).map {|h| h.to_i(16) } |
| 14 | + if tail |
| 15 | + tail = tail.split(?:).map {|h| h.to_i(16) } |
| 16 | + hextets << Array.new(8 - hextets.count - tail.count, 0) << tail |
| 17 | + end |
| 18 | + fail 'invalid IPv6 addr' if hextets.size != 8 |
| 19 | + hextets |
| 20 | + end |
| 21 | + |
| 22 | + # Format the array of hextets into IPv6 string representation. |
| 23 | + def format_v6addr(addr) |
| 24 | + addr.map {|h| h.to_s(16) }.join(?:) |
| 25 | + end |
| 26 | + |
| 27 | + # Convert IPv6 CIDR to min-max range |
| 28 | + def v6range(v6cidr) |
| 29 | + v6addr, v6prefixlen = v6cidr.split(?/, 2) |
| 30 | + v6prefixlen = v6prefixlen&.to_i |
| 31 | + return "[#{v6addr}]" if !v6prefixlen || v6prefixlen == 128 |
| 32 | + v6addr = parse_v6addr(v6addr) |
| 33 | + |
| 34 | + hostmask = 8.times.map do |i| |
| 35 | + n = (i+1) * 16 - v6prefixlen |
| 36 | + n > 0 ? (1 << n) - 1 : 0 |
| 37 | + end |
| 38 | + |
| 39 | + min = v6addr.zip(hostmask).map {|a, b| a & ~b } |
| 40 | + max = v6addr.zip(hostmask).map {|a, b| a | b } |
| 41 | + "[#{format_v6addr(min)}]-[#{format_v6addr(max)}]" |
| 42 | + end |
| 43 | +end |
| 44 | + |
| 45 | +MItamae::ResourceExecutor::Template::RenderContext.include(TemplateHelpers) |
0 commit comments