Forum Discussion
Parsing IP to extract subnet
Hi,
I wonder if there is more elegant and fastest way to extract specific part of IP - like get only part of IP up to second dot, third dot.
I know that I can use scan to separate IP in four parts then combine first and second, etc.
But maybe there is easier and fastest way?
Piotr
11 Replies
- VernonWells
Employee
That depends somewhat on what you intend to do with the information. For example, if you want to choose a conditional branch based on subnet, you can do something like this:
when CLIENT_ACCEPTED { if { [IP::addr [IP::client_addr] equals "192.168.0.0/16" } { pool pool-internal } }If you're simply trying to extract dotted-quad octets, then
is probably as good an approach as any.scan- dragonflymr
Cirrostratus
Thanks, not exactly what I am looking for - as I wrote below - my fault, I was not precise enough. Piotr
- Vernon_97235Historic F5 Account
That depends somewhat on what you intend to do with the information. For example, if you want to choose a conditional branch based on subnet, you can do something like this:
when CLIENT_ACCEPTED { if { [IP::addr [IP::client_addr] equals "192.168.0.0/16" } { pool pool-internal } }If you're simply trying to extract dotted-quad octets, then
is probably as good an approach as any.scan- dragonflymr
Cirrostratus
Thanks, not exactly what I am looking for - as I wrote below - my fault, I was not precise enough. Piotr
- StephanManthey
Nacreous
Hi Piotr,
I hope you are doing well. I am using
to access the IP address digits i.e. as follows:getfieldwhen CLIENT_ACCEPTED { snat 10.10.10.[expr ( [getfield [IP::client_addr] "." 4] % 32 ) + 1] snat 10.10.[getfield [IP::client_addr] "." 3].[getfield [IP::client_addr] "." 4] }The second line would apply a SNAT address based on replacing the first three digits the original IP address by "10.10.10." and calculates the last digit by reading the last digit from the original client IP and applies a modulus of 32 + 1 (i.e. turns a 47 into 16 to vary the SNATs in a range of 10.10.10.1 to 10.10.10.32 and persist to this value as long as client IP doesnt change). (Make sure to use a virtual address space or have "real" SNATs configured to avoid ARP issues.) The third line (commented) is using the original third and fourth digit of the original client IP to define a new SNAT. (Same ARP issues to expect as described above.)
Thanks, Stephan - StephanManthey
Nacreous
Perhaps I got your question wrong. Following Vernons solution you can check the following if you already know the relevant networks:
when CLIENT_ACCEPTED { switch [IP::addr [IP::client_addr]] { "10.131.131.0/26" { log local0. "client [IP::client_addr] in 10.131.131.0/25 detected" "10.131.131.64/26" { log local0. "client [IP::client_addr] in 10.131.131.64/25 detected" "10.131.131.128/26" { log local0. "client [IP::client_addr] in 10.131.131.128/25 detected" "10.131.131.192/26" { log local0. "client [IP::client_addr] in 10.131.131.192/25 detected" } }Thanks, Stephan
PS: I am pretty sure I wrote a subnet calculator iRule a while ago and will post it if you think it would be helpful to solve your requirements. - dragonflymr
Cirrostratus
Hi,
First of all, thanks for help. Second, it was my fault. I did not describe my goal precise enough. Idea is to create keys (for tables or iStats) using variable mask (depending on some iRule logic). IPs are not know in advance and right now there is no idea of using them for some if or switch operations.
Below my crude iRule that should shed some light on what I mean - at least I hope so 🙂
when CLIENT_ACCEPTED { set addr [IP::client_addr] log local0. "Client IP: $addr" scan $addr {%d.%d.%d.%d} a b c d } when HTTP_REQUEST { switch -glob [string tolower [HTTP::uri]] { "*/24" { set newaddr "$a.$b.$c.0" set uri [string map -nocase {"/24" "/"} [HTTP::uri]] HTTP::uri $uri } "*/16" { set newaddr "$a.$b.0.0" set uri [string map -nocase {"/16" "/"} [HTTP::uri]] HTTP::uri $uri } "*/8" { set newaddr "$a.0.0.0" set uri [string map -nocase {"/8" "/"} [HTTP::uri]] HTTP::uri $uri } default { set newaddr $addr } } log local0. "scan result: $newaddr" ISTATS::incr "ltm.virtual [virtual name] c $newaddr" 1 }Point is if I can perform subnet creation in some more elegant, faster way that the one above (scan cmd).
Piotr
- dragonflymr
Cirrostratus
Well, probably I found solution - question is if it's the best use something like that: set sub_var [IP::addr [IP::client_addr] mask 255.255.0.0] and adjusting mask parameter as needed - is that right track. I am a bit lost how to use IP:addr Piotr
- dragonflymr
Cirrostratus
Hi Kai,
Thanks for advice. That is great base to choose the right path depending of use case!
Piotr
Hi Piotr,
the "best solution" will strongly depend on how often you've to contruct the $newaddr on a single TCP connection.
1.) Using the [scan] command to split an IP into octets will cost more cpu cycles than transforming the IP using the [IP::addr] command. So for a single transformation the [IP::addr] command should be used.
2.) Using a [scan] command once during CLIENT_ACCEPTED and then substitute different subnet variations and/or perform this action on multiple consecutive HTTP_REQUEST would be faster than calling [IP::addr] multiple times.
Cheers, Kai
Hi Piotr,
the "best solution" will strongly depend on how often you've to contruct the $newaddr on a single TCP connection.
1.) Using the [scan] command to split an IP into octets will cost more cpu cycles than transforming the IP using the [IP::addr] command. So for a single transformation the [IP::addr] command should be used.
2.) Using a [scan] command once during CLIENT_ACCEPTED and then substitute different subnet variation and/or on multiple consecutive HTTP_REQUEST would be faster than calling [IP::addr] multiple times.
Cheers, Kai
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com