Network Translations
Problem this snippet solves:
This iRule translates (SNAT) the network bits of the client IP (it keeps the host bits).
It requires a data group dg_network_translations of type Address.
Example:
* Entry in the data group: 1.1.1.0/24 := 10.10.10.0
* Client IP: 1.1.1.5 -> 10.10.10.5
How to use this snippet:
Create the data group. Make sure its name matches the name in the iRule (default name of the data group is "dg_network_translations", and load the iRule on a Virtual Server.
Uncomment the debug lines to test/troubleshoot.
Code :
# Gregory Thiell - 2016-11-15 # This iRule translates (SNAT) the network bits of the client IP (it keeps the host bits). # It requires a data group dg_network_translations of type Address # Example: # - Entry in the data group: 1.1.1.0/24 := 10.10.10.0 # - Client IP: 1.1.1.5 -> 10.10.10.5 # Procedures for hex conversion -- from http://wiki.tcl.tk/8909 proc IPtoHex { IP } { binary scan [binary format c4 [split $IP .]] H8 Hex return $Hex } proc hexToIP { Hex } { binary scan [binary format H8 $Hex] c4 IPtmp foreach num $IPtmp { # binary scan "c" format gives signed int - the following # [expr]-ology converts to unsigned (from [binary] manpage) lappend IP [expr ($num + 0x100) % 0x100] } set IP [join $IP .] return $IP } proc CIDRtoHexNetmask { CIDR } { set zeros [expr 32 - $CIDR] set ones $CIDR set binaryCIDR [string repeat 1 $ones] append binaryCIDR [string repeat 0 $zeros] binary scan [binary format B32 $binaryCIDR] H8 HexNetmask return $HexNetmask } when RULE_INIT { set static::dg_net_tsl "dg_network_translations" } when CLIENT_ACCEPTED { set original_ip [IP::client_addr] # Debug -- To overwrite original_ip # set original_ip 1.1.1.5 # Read Data Group set dg_elements [class match -element $original_ip equals $static::dg_net_tsl] set original_network [getfield [lindex $dg_elements 0] "/" 1] set cidr [getfield [lindex $dg_elements 0] "/" 2] set translated_network [lindex $dg_elements 1] if { $dg_elements != "" } { # Hex conversion set hex_original_ip [call IPtoHex $original_ip] set hex_netmask [call CIDRtoHexNetmask $cidr] set hex_translated_network [call IPtoHex $translated_network] # Calculate the hostmask (= inverted netmask) set hex_hostmask [expr 0x$hex_netmask ^ 0xffffffff] binary scan [binary format I $hex_hostmask] H8 hex_hostmask set hostmask [call hexToIP $hex_hostmask] # Extract the host bits (bit-wise AND between original_ip and hostmask) set hex_host [expr 0x$hex_original_ip & 0x$hex_hostmask] binary scan [binary format I $hex_host] H8 hex_host set host [call hexToIP $hex_host] # Translate the network bits (bit-wise OR between host bits and translated_network) set hex_translated_ip [expr 0x$hex_host | 0x$hex_translated_network] binary scan [binary format I $hex_translated_ip] H8 hex_translated_ip set translated_ip [call hexToIP $hex_translated_ip] # SNAT snat $translated_ip # Debug -- Log # log local0. "Client IP (dec, hex): ($original_ip, $hex_original_ip)" # log local0. "Original network (dec): ($original_network)" # log local0. "Netmask (CIDR, hex): ($cidr, $hex_netmask)" # log local0. "Translated network (dec, hex): ($translated_network, $hex_translated_network)" # log local0. "Hostmask (dec, hex): ($hostmask, $hex_hostmask)" # log local0. "Host (dec, hex): ($host, $hex_host)" # log local0. "Translated IP (dec, hex): ($translated_ip, $hex_translated_ip)" } }
Tested this on version:
11.6Published Nov 15, 2016
Version 1.0Gregory_Thiell
Employee
Joined August 12, 2019
Gregory_Thiell
Employee
Joined August 12, 2019
No CommentsBe the first to comment