TCL procedures to compress/expand a IPv6 address notation
Problem this snippet solves: Hi Folks,
the iRule below contains two TCL procedures to convert an IPv6 address from/to human readable IPv6 address notations within iRules.
The compress_ipv6_add...
Updated Jun 06, 2023
Version 2.0Kai_Wilke
My name is Kai Wilke and I'm working as a Principal Consultant for IT-Security at itacs GmbH - a German consulting company specialized in Microsoft Security cloud solutions, F5 customizations as well as for classic IT-Consulting.
You can find additional information about me and my work here:
https://devcentral.f5.com/articles/q-a-with-itacs-gmbhs-kai-wilke-devcentrals-featured-member-for-february-24890MVP
Stanislas_Piro2
Oct 10, 2017Cumulonimbus
Hi Kai,
good job.
for the compress procedure, I suggest to use this code which is more performant (around 5 clicks):
proc compress_ipv6_addr { addr } {
Enumerate and store IPv6 ZoneID / Route Domain suffix
if { [set id [getfield $addr "%" 2]] ne "" } then {
set id "%$id"
set addr [getfield $addr "%" 1]
}
return "[IP::addr $addr mask ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]$id"
}
and the following procedure (50% clicks more) to prevent the shared variables requirements
proc expand_ipv6_addr_sp { addr } {
if { [catch {
Enumerating and storing IPv6 ZoneID / Route Domain suffix
if { [set id [getfield $addr "%" 2]] ne "" } then {
set id "%$id"
set addr [getfield $addr "%" 1]
}
Parsing the first IPv6 address block of a possible :: notation by splitting the block into : separated IPv6 address groups
set blk1 ""
foreach val [split [getfield $addr "::" 1] ":"] {
if { $val contains "." } then {
The current group contains a IPv4 address notation. Trying to extract the four IPv4 address octets
scan $val {%d.%d.%d.%d} oct1 oct2 oct3 oct4
Convert the four IPv4 address octets into two IPv6 address groups
append blk1 [format "%02x%02x %02x%02x " $oct1 $oct2 $oct3 $oct4]
unset -nocomplain oct1 oct2 oct3 oct4
} else {
append blk1 "[format %04x 0x$val] "
}
}
set blk2 ""
foreach val [split [getfield $addr "::" 2] ":"] {
if { $val contains "." } then {
The current group contains a IPv4 address notation. Trying to extract the four IPv4 address octets
scan $val {%d.%d.%d.%d} oct1 oct2 oct3 oct4
Convert the four IPv4 address octets into two IPv6 address groups
append blk2 [format "%02x%02x %02x%02x " $oct1 $oct2 $oct3 $oct4]
unset -nocomplain oct1 oct2 oct3 oct4
} else {
append blk2 "[format %04x 0x$val] "
}
}
set addr "[join "$blk1[string repeat "0000 " [expr {8 - [string length "$blk1$blk2"]/5}]] $blk2" ":"]"
}] } then {
log local0.debug "errorInfo: [subst \$::errorInfo]"
return "errorInfo: [subst \$::errorInfo]"
return ""
}
Append the previously extracted IPv6 ZoneID / Route Domain suffix and return the expanded IPv6 address notation
return "$addr$id"
}