Topics


Blogs


Forums


Samples


Media


Labs


Resources

Login | Register




Subscriptions: Video  |  Audio  |  Tutorials  |  Tech Tips  |  Features  |  More...
Docs & Tips

Current Articles | Categories | Search | Syndication

iRules 101 - #16 - Parsing Strings with the TCL Scan Command

posted @ Friday, November 06, 2009 9:26 AM by citizen_elah - 1081 views


Introduction

An iRule is a powerful and flexible feature of BIG-IP devices based on F5's exclusive TMOS architecture.  iRules provide you with unprecedented control to directly manipulate and manage any IP application traffic.  iRules utilizes an easy to learn scripting syntax and enables you to customize how you intercept, inspect, transform, and direct inbound or outbound application traffic.  In this series of tech tips, we'll talk about the TCL language, its usage and control structures, as well as iRule extensions to the TCL language.

The Scan Command

Scan is used to parse out strings.  It takes a string and based on your format parameters, stores the matches in one or more variables.  It also returns the number of conversions performed, so it can be used in a conditional as well.  For all the options available in the command, the scan man page is available here at http://tmml.sourceforge.net/doc/tcl/scan.html.  I'll highlight a couple of the options I see used in iRules examples hitting the forums below.

scan string format ?varName varName ...?

Options

  • d - The input substring must be  a decimal integer.
  • s - The input substring consists of all the characters up to the next white-space character.
  • n - No input is consumed from the input string.  Instead, the total number of characters scanned from the input string so far is stored in the variable.
  • [chars] - The input substring consist of one or more characters in chars.  The matching string is stored in the variable.
  • [^chars] - The input substring consists of one or more characters not in chars.

Examples

So how do we put scan to use in iRules?  Consider this first example:

Scanning the Host

 

when HTTP_REQUEST {
  if { [scan [HTTP::host] {%[^:]:%s} host port] == 2 } {
    log local0. "Parsed \$host:\$port: $host:$port
  }
}

Here we are scanning the host contents.  The HTTP::host command only returns a port if it is not port 80 for http traffic and port 443 for ssl traffic, so if it is standard, the second conversion (%s) will not populate the port variable and the conditional will be false.  In the scan commands format section, %[^:] tells the scan command to store all the characters in string from the beginning until the first occurrence of the colon.  We then put a colon before the %s (which tells scan to store the remaining characters until the end or white space) so it is not included in the port variables contents.  Also note that the format string is wrapped in curly braces so that the brackets are not evaluated as a command.  Below is the functionality of the scan command in a tcl shell:

% set httphost "www.test.com:8080"
www.test.com:8080
% scan $httphost {%[^:]:%s} host port
2
% puts "$host $port"
www.test.com 8080

Another use case--splitting up an IP address into multiple variables--is accomplished in one easy step below.

% set ip 10.15.25.30
10.15.25.30
% scan $ip %d.%d.%d.%d ip1 ip2 ip3 ip4
4
% puts "$ip1 $ip2 $ip3 $ip4"
10 15 25 30

As with most things with iRules, there are many paths to the same result, even if they require more steps.  Here's another way to arrive at the same split IP with variables for each octet.  This method requires four sets of a nested split/lindex evaluation to achieve the same result.

% set ip 10.15.20.25
10.15.20.25
% set ip1 [lindex [split $ip "."] 0]
10
% set ip2 [lindex [split $ip "."] 1]
15
% set ip3 [lindex [split $ip "."] 2]
20
% set ip4 [lindex [split $ip "."] 3]
25
% puts "$ip1 $ip2 $ip3 $ip4"
10 15 20 25

If you're wondering why you'd split the IP like this, the use case in the forums was to extract each octet so they could then do some bit shifiting to create a unique ID for their stores based on IP subnets.  The post is here if interested. One final example before closing.  This example can be found in entirety in this forum post, but the scan specific operations are below.  The scan string is refined over a few steps to show the elimination of unwanted characters in the variables.

% set sipinfo {<sip:214365981110@10.15.20.25:3232>}
<sip:214365981110@10.15.20.25:3232>
% scan $sipinfo {%[^:]%s} garbage sessid
2
% puts "$garbage $sessid"
<sip :214365981110@10.15.20.25:3232>

You can see that at the first colon it dumped the contents up to that character into the garbage variable.  Everything else, including the colon, is dumped into the sessID variable.  Close but we don't want that colon, so we need to include it in the scan format string.

% scan $sipinfo {%[^:]:%s} garbage sessid
2
% puts "$garbage $sessid"
<sip 214365981110@10.15.20.25:3232>

Good.  Now we need to break off the host and the port as well.  We want all characters up until the @ sign for the session id, then all the characters between the @ sign and the colon for the host, and finally all the characters after the color for the port.

% scan $sipinfo {%[^:]:%[^@]@%[^:]:%s} garbage sessid host port
4
% puts "$sessid $host $port"
214365981110 10.15.20.25 3232>

OK, all looks good except the port.  We definitely don't want the > on the port.  So one final fix.

% scan $sipinfo {%[^:]:%[^@]@%[^:]:%[^>]} garbage sessid host port
4
% puts "$sessid $host $port"
214365981110 10.15.20.25 3232

Scan is a great command to have available in your iRules arsenal.  Thanks to Hoolio, cmbhatt, sre, and natty76 for some great examples.

Email This   Bookmark and Share

Previous Page | Next Page

COMMENTS

Hey Citizen,

Thanks, that's a useful article. A few of the square braces were corrupted in the post though. Here are some examples:

if { [scan ]HTTP::host[ {%]^:[:%s} host port] == 2 } {

% set ip1 [lindex ]split $ip "."[ 0]

Thanks, Aaron

posted @ Monday, November 09, 2009 6:02 AM by hoolio


Oh yeah, that's fun. I was so excited the spacing was working that I didn't validate everything else turned out. Let me see what I can do to fix that.

posted @ Monday, November 09, 2009 7:03 AM by citizen_elah


Joe fixed the issue with the module, should be OK now. Thanks for the heads up, Aaron.

posted @ Monday, November 09, 2009 9:30 AM by citizen_elah


Only registered users may post comments.

Essentials

Features

 Videos

 Audio
v10.1 - Configuring GTM's DNS Security Extensions
v.10 - Remote Authorization via TACACS+
v.10 - New class features in iRules
v.10 - iRules and the after command
v.10 - FastHTTP and Cookie Persistence
v.10 - A new iRules Namespace
Unbind your LDAP servers with iRules
Ten Steps to iRules Optimization
Ruby Meets iControl: Switching Policies
Ruby meets iControl: Making Wide IPs
Ruby meets iControl: Creating VIPs
Replacing the WebSphere Apache Plugin with iRules
Persisting SSL Connections
Managing The System Boot Location with iControl
iRules Event Order
iRules 101 - #15 - TCL List Handling Commands
iRules 101 - #14 - TCL String Commands Part 2
Investigating the LTM TCP Profile: Windows & Buffers
Investigating the LTM TCP Profile: The Finish Line
Investigating the LTM TCP Profile: Nagle’s Algorithm
Investigating the LTM TCP Profile: ECN & LTR
Investigating the LTM TCP Profile: Congestion Control Algorithms
Investigating the LTM TCP Profile: Acknowledgements
iControl Apps - #18 - Virtual Server Reverse Lookup
iControl Apps - #14 - Global Statistics
iControl Apps - #13 - System PVA Statistics
iControl Apps - #12 - Global SSL Statistics
iControl Apps - #11 - Global GTM Statistics
iControl Apps - #10 - Bigpipe List
iControl Apps - #09 - TMM Statistics
iControl Apps - #08 - System IP Statistics
iControl Apps - #07 - System Http Statistics
iControl Apps - #06 - Configuration Archiving
iControl Apps - #05 - Rate Based Statistics
iControl Apps - #04 - Graceful Server Shutdown
iControl Apps - #03 - Local Traffic Map
iControl 101 - #22 - GTM Data Centers
iControl 101 - #21 - Rate Classes
iControl 101 - #20 - Port Lockdown
iControl 101 - #19 - Time Conversions
Getting Started with pyControl
FTPS Offload via iRules
Exchange Persistence Duality and iRules
Custom SNMP Traps
Creating An iControl PowerShell Monitoring Dashboard With Google Charts
Cookie LoJack vi iRules
Concurrent iControl Programming Explained
Can iRules fix my cert mismatch errors?
Cache in with LTM and iRules
Investigating the LTM TCP Profile: Max Syn Retransmissions & Idle Timeout


Quick Start Guides

Tutorials

iControl

iRules

Monitoring & Management

Advanced Design & Config

DC4
ASM       Best Practices       BIG-IP       cacti       cookie       DNS       FirePass       http redirect       https       iControl       iRule Editor       iRules       LB_FAILED       log       matchclass       monitor       persist       persistence       pool       PowerShell       proxy       radius       redirect       SIP       SNAT       SNMP       SSL       stream       switch       syslog       wiki       X-Forwarded-For