Forum Discussion

matt_wheeler_11's avatar
matt_wheeler_11
Historic F5 Account
Jul 18, 2007

Binary Scan help with an iRule

I am working with a customer where we are trying to grab specific content from a SQL response to create persistence. However, when the rule get to the line where I log line "0004 clientdata: $clientdata" I get the following response in my log file. I was wondering if someone could assist in figuring out where I went wrong. Here is the return in my log file:

 

 

 

 

 

Jul 18 13:22:48 tmm tmm[1121]: Rule RecDB-iRule2 : 0002 New client connection from 172.20.5.30:4833

 

Jul 18 13:22:48 tmm tmm[1121]: Rule RecDB-iRule2 : 0003 Collecting

 

Jul 18 13:22:48 tmm tmm[1121]: 01220001:3: TCL error: Rule RecDB-iRule2 - can't read "clientdata": no such variable while executing "log local0. "0004 clientdata: $clientdata""

 

 

 

 

when RULE_INIT {

 

log local0. "0001 iRule RealEC-iRule initialized"

 

Convert Text to HEX before Client_Accepted so we only do this task once.

 

set InsertService "0049006e00730065007200740053006500720076006900630065"

 

set TranOrigID "005400720061006e004f00720069006700490044"

 

set TranRefNum "005400720061006e005200650066004e0075006d"

 

}

 

 

when CLIENT_ACCEPTED {

 

log local0. "0002 New client connection from [IP::client_addr]:[TCP::client_port]"

 

TCP::collect

 

log local0. "0003 Collecting"

 

}

 

 

when CLIENT_DATA {

 

binary scan [TCP::payload] H128 clientdata

 

log local0. "0004 clientdata: $clientdata"

 

Look for InsertService 128 bites into the TCP Payload

 

set svc_event [findstr $clientdata $InsertService 52 ]

 

If we see Insert Service set Persist

 

if { [string first $InsertService $clientdata] != -1 } {

 

Look for TranOrigID, offset 40 (Hex) and stop at &

 

set trans_id [findstr $clientdata $TranOrigID 40 "26"]

 

Look for TranRefNum, offset 40 (Hex) and stop at &

 

set ref_id [findstr $clientdata $TranRefNum 40 "26"]

 

Concantenate the two values and persist

 

set db_id $trans_id:$ref_id

 

if { $db_id != "" } {

 

log local0. "0005 DB-ID=$db_id"

 

persist uie $db_id

 

log local0. "Persisting $db_id to [persist lookup uie $db_id]"

 

TCP::release

 

}

 

}

 

}

 

7 Replies

  • matt_wheeler_11's avatar
    matt_wheeler_11
    Historic F5 Account
    Okay that worked but now I am getting the following...man it is a drag when you are new to iRules. Any ideas would be great...

     

     

    Jul 19 08:06:51 tmm tmm[1121]: Rule : 0001 iRule RealEC-iRule initialized

     

    Jul 19 08:07:17 tmm tmm[1121]: Rule RecDB-iRule2 : 0002 New client connection from 172.20.5.30:3413

     

    Jul 19 08:07:17 tmm tmm[1121]: Rule RecDB-iRule2 : 0003 Collecting

     

    Jul 19 08:07:17 tmm tmm[1121]: Rule RecDB-iRule2 : 0004 clientdata: 1201003400000000000015000601001b000102001c000c0300280004ff080001550000004d5353514c53657276657200140b0000

     

    Jul 19 08:07:17 tmm tmm[1121]: 01220001:3: TCL error: Rule RecDB-iRule2 - can't read "InsertService": no such variable while executing "findstr $clientdata $InsertService 52 "

     

  • Most of the time I've seen variables in the RULE_INIT section defined with a leading double colon.

    
    when RULE_INIT {
      set ::InsertService "0049006e00730065007200740053006500720076006900630065"
    }
    ...
    ...
    set svc_event [findstr $clientdata $::InsertService 52 ]
     If we see Insert Service set Persist
    if { [string first $::InsertService $clientdata] != -1 } {

    I know it has something to do with being a global variable; the programmers on the board could explain the details better than me.

  • Deb_Allen_18's avatar
    Deb_Allen_18
    Historic F5 Account
    Yes, citizen_elah is correct, those should have been defined as global vars, my bad, sorry guys:
    when RULE_INIT {
      log local0. "0001 iRule RealEC-iRule initialized"
       Convert Text to HEX before Client_Accepted so we only do this task once.
      set ::InsertService "0049006e00730065007200740053006500720076006900630065"
      set ::TranOrigID "005400720061006e004f00720069006700490044"
      set ::TranRefNum "005400720061006e005200650066004e0075006d"
    }
    when CLIENT_ACCEPTED {
      log local0. "0002 New client connection from [IP::client_addr]:[TCP::client_port]"
      TCP::collect
      log local0. "0003 Collecting"
    }
    when CLIENT_DATA {
      binary scan [TCP::payload] H128 clientdata
      log local0. "0004 clientdata: $clientdata"
       Look for InsertService 128 bites into the TCP Payload
      set svc_event [findstr $clientdata $::InsertService 52 ]
       If we see Insert Service set Persist
      if { [string first $::InsertService $clientdata] != -1 } {
         Look for TranOrigID, offset 40 (Hex) and stop at "&" (0x26)
        set trans_id [findstr $clientdata $::TranOrigID 40 "26"]
         Look for TranRefNum, offset 40 (Hex) and stop at "&" (0x26)
        set ref_id [findstr $clientdata $::TranRefNum 40 "26"]
         Concantenate the two values and persist
        set db_id $trans_id:$ref_id
        if { $db_id != "" } {
          log local0. "0005 DB-ID=$db_id"
          persist uie $db_id
          log local0. "Persisting $db_id to [persist lookup uie $db_id]"
          TCP::release
        }
      }
    }
    Global variables are shared across all connections, so anything that's constant for all connections should be defined as a global variable to save memory. Any variable whose value is expected to vary per connection must be defined as a non-global variable.

    HTH

    /deb
  • matt_wheeler_11's avatar
    matt_wheeler_11
    Historic F5 Account
    Here is the irule that I got to work...However, does anyone know how to convert the ASCII into text so that I can just grab the InsertService from the packets?

     

     

    when RULE_INIT {

     

    log local0. "0001 iRule RealEC-iRule initialized"

     

     

    }

     

     

    when CLIENT_ACCEPTED {

     

    log local0. "0002 New client connection from [IP::client_addr]:[TCP::client_port]"

     

    TCP::collect

     

    log local0. "0003 Collecting"

     

    }

     

     

    when CLIENT_DATA {

     

    binary scan [TCP::payload] H* clientdata

     

     

    Convert Text to HEX before Client_Accepted so we only do this task once.

     

    set ::InsertServiceEvent "1201003400000000000015000601001b000102001c000c0300280004ff080001550000004d5353514c53657276657200140b0000"

     

    set ::TranOrigID "005400720061006e004f00720069006700490044"

     

    set ::TranRefNum "005400720061006e005200650066004e0075006d"

     

     

    log local0. "0004 clientdata: $clientdata"

     

     

    Look for InsertService 128 bites into the TCP Payload

     

    set svc_event [findstr $clientdata $::InsertServiceEvent]

     

     

    log local0. "0004a svc_event: $svc_event"

     

     

    If we see Insert Service set Persist

     

    if { [findstr $clientdata $::InsertServiceEvent] != "" } {

     

    Look for TranOrigID, offset 40 (Hex) and stop at &

     

    set trans_id [findstr $clientdata $::TranOrigID 40 "26"]

     

     

    Look for TranRefNum, offset 40 (Hex) and stop at &

     

    set ref_id [findstr $clientdata $::TranRefNum 40 "26"]

     

     

    Concantenate the two values and persist

     

    set db_id $trans_id:$ref_id

     

     

    if { $db_id != "" } {

     

    log local0. "0005 DB-ID=$db_id"

     

    persist uie $db_id

     

    log local0. "Persisting $db_id to [persist lookup uie $db_id]"

     

    TCP::release

     

    }

     

    }

     

    }

     

     

    when LB_SELECTED {

     

    After logic is run and server is selected, log which one

     

    log local0. "Selected server [LB::server]"

     

    }

     

  • You can use binary format to convert from HEX encoded ASCII to text. Binary format is just the opposite of binary scan.