Forum Discussion

cjun's avatar
cjun
Icon for Nimbostratus rankNimbostratus
Jul 05, 2008

Extracting info for DHCP option

The iRule here is to find out value for DHCP option 82 for further processing. It can be used

 

for extracting info for other kind of packet as long as packet format is known.

 

 

Few important point here:

 

 

1. Use H option to scan the payload

 

binary scan [UDP::payload] x240H* dhcp_option_payload

 

 

This command will scan the payload in HEX string format

 

 

2. Use a2 option to scan individual options

 

binary scan $dhcp_option_payload x[expr $i]a2 option

 

 

Since every dhcp option has option type, which has a byte, so in HEX string, it will represent

 

as two character, for example, 52, which is option 82.

 

 

3. Convert the length from HEX string to Decimal

 

Every dhcp option has different length, the length ocupy a byte as well, so it will represent as

 

two charater in HEX string as well, for example, 0f. We needto convert that to decimal so that

 

we are able to scan next option, until option 82 found.

 

 

 

 

when CLIENT_DATA {

 

if { [UDP::payload length] < 200 } {

 

log local0. "drop due to length"

 

drop

 

return

 

} else {

 

extract out all dhcp options in Hex string

 

binary scan [UDP::payload] x240H* dhcp_option_payload

 

 

extract out circuit_id

 

set option 0

 

set option_length [expr {([UDP::payload length] -240) * 2 }]

 

 

for {set i 0} {$option != 52 && $i < $option_length} {incr i [expr { $length * 2 +2 }]} {

 

extract option value

 

binary scan $dhcp_option_payload x[expr $i]a2 option

 

 

move index to get length field

 

incr i 2

 

 

extract length value and convert length from Hex string to decimal

 

binary scan $dhcp_option_payload x[expr $i]a2 length_hex

 

set length [expr 0x$length_hex]

 

}

 

 

if { $i < $option_length } {

 

move index to suboption's length field of option 82

 

incr i -[expr { $length * 2 -2 }]

 

 

extract the length for suboption, and convert the length from Hex string to decimal

 

binary scan $dhcp_option_payload x[expr $i]a2 length_hex

 

set length [expr 0x$length_hex]

 

 

move index to suboption's value field

 

incr i 2

 

 

extract the suboption's value

 

binary scan $dhcp_option_payload x[expr $i]a[expr { $length * 2 }] circuit_id

 

} else {

 

Circuit_id not found

 

log local0. "Agent < [IP::remote_addr]> did not contain DHCP option 82"

 

drop

 

return

 

}

 

}

 

}

7 Replies

  • cjun's avatar
    cjun
    Icon for Nimbostratus rankNimbostratus
    Yes, that works, in fact, this is a POC for one big customer, it works perfect during the POC
  • Colin_Walker_12's avatar
    Colin_Walker_12
    Historic F5 Account
    Very cool example, I lifted most of it to show off in this week's 20 Lines or Less...good work!

     

     

    Colin
  • Hi heroes,

     

    I have used this irule to be able to parse the udp packet and find the option 82, all works well but when I try then to make a decision on the field I see on option 82 I get in troubles.

     

     

    I have just set an easy test to be sent to 2 different dhcp servers:

     

     

    binary scan $dhcp_option_payload x[expr { $option_82_6_offset + 2 } ]a[expr { $option_82_6_length * 2 } ] agent_remote_id

     

    log local0. "Agent Remote ID: $agent_remote_id" ** That one is correctly parsed**

     

     

    binary scan [UDP::payload] x028H12 dhcp_client_mac_address ** That mac address is correctly parsed **

     

     

     

     

     

     

    **This is the test that gives me issues: easily in some cases the 2 strings match and then I have to send the dhcp request to a pool of DHCP, else send to another pool of DHCP's**

     

     

     

     

    if { $agent_remote_id == $dhcp_client_mac_address } {

     

    log local0. "Using DHCP pool dhcp main" ** worls well, data is correct **

     

    pool dhcp-ut-group_main ** this is the line that gives me the error, see down **

     

     

     

    This test is performed but then instead of sending packet to the right pool I see a tcl error (and packet is sent to the default virtual server pool).

     

     

     

     

     

    This is what I see on ltm logs:

     

     

    May 11 11:05:42 local/tmm info tmm[6916]: Rule dhcp-extended-rule-2 : (Subscriber ID: 30304130424332354430464340756e636f6d6d697373696f6e6564)

     

    May 11 11:05:42 local/tmm info tmm[6916]: Rule dhcp-extended-rule-2 : NSP: 756e636f6d6d697373696f6e6564

     

    May 11 11:05:42 local/tmm info tmm[6916]: Rule dhcp-extended-rule-2 : (Option 82.6 offset: 108)

     

    May 11 11:05:42 local/tmm info tmm[6916]: Rule dhcp-extended-rule-2 : (Option 82.6 length: 06)

     

    May 11 11:05:42 local/tmm info tmm[6916]: Rule dhcp-extended-rule-2 : Agent Remote ID: 00a0bc25d0fc

     

    May 11 11:05:42 local/tmm info tmm[6916]: Rule dhcp-extended-rule-2 : Client MAC Address 00a0bc25d0fc

     

    May 11 11:05:42 local/tmm info tmm[6916]: Rule dhcp-extended-rule-2 : Using DHCP pool dhcp main

     

    May 11 11:05:42 local/tmm err tmm[6916]: 01220001:3: TCL error: dhcp-extended-rule-2 - Address in use (line 47) invoked from within "pool dhcp-ut-group_main"

     

     

     

    Can anyone help me with that "Address in use" error ?

     

    How can I use the right pool without the error ?

     

     

    PS

     

    if I change the evento to client_accepted it seems to work, without giving the "Address in use" error, but it happens that many DHCP requests are not triggering the irule, maybe because we're in UDP and not in TCP...

     

     

    I am stuck :/

     

     

     

    Thanx a lot for any tips,

     

    Nicola.

     

     

     

     

     

     

     

     

     

     

  • Have found this tip myself by Hoolio:

     

     

    http://devcentral.f5.com/Community/GroupDetails/tabid/1082223/asg/50/aft/1176465/showtab/groupforums/Default.aspx

     

     

    I managed by changing the event to client_accepted and modifying the UDP profile to immediate.

     

     

    Just too puzzled why it used to stuck with the tcl error when working into "when client_data"

     

     

    Client data makes more sense to me, since we inspect the data flowing and not the "session"...

     

     

    Ideas ?

     

     

    Thanx,

     

    Nicola

     

     

  • Hi Nicola,

     

     

    There is a bug specific to the CLIENT_DATA event that triggered this error (noted in CR69801). With UDP traffic there isn't any need to collect the payload so you can use CLIENT_ACCEPTED instead of CLIENT_DATA to avoid the error.

     

     

    Aaron
  • Yup, I saw it in your other post and managed to fix accordingly.

     

     

    Thanx a lot C-(H)oolio. :)

     

     

    Nicola.

     

  • With version 11.5.4 and 12 produces warnings about curly braces:

     

    There were warnings: /Common/rule_dhcp_mac_sticky_example:16: warning: [use curly braces to avoid double substitution][$i] /Common/rule_dhcp_mac_sticky_example:22: warning: [use curly braces to avoid double substitution][$i] /Common/rule_dhcp_mac_sticky_example:23: warning: [use curly braces to avoid double substitution][0x$length_hex] /Common/rule_dhcp_mac_sticky_example:31: warning: [use curly braces to avoid double substitution][$i] /Common/rule_dhcp_mac_sticky_example:32: warning: [use curly braces to avoid double substitution][0x$length_hex] /Common/rule_dhcp_mac_sticky_example:38: warning: [use curly braces to avoid double substitution][$i]