DNS Query Name Parsing iRule

Problem this snippet solves:

This iRule will extract the DNS Query Name in the absence of a DNS profile being applied to a Virtual Server.

How to use this snippet:

# This is a shameless rip from an old Devcentral post DNS Hostname Parsing iRule that, to the best of my knowledge, never made it to a Code Share.


To use this code, simply apply this to a UDP Virtual Server that processes DNS traffic. (No DNS Profile necessary).

Code :

when FLOW_INIT {
  #extract QNAME from QUESTION header
  #${i} is a sanity check so this logic won't spin on invalid QNAMEs
  set i 0
  #initialize our position in the QNAME parsing and the text QNAME
  set offset 12
  set length 1
  set endlength 1
  set name ""
  #/extract QNAME from QUESTION header
  while {${length} > 0 && ${i} < 10} {
    #length contains the first part length
    binary scan [string range [DATAGRAM::udp payload] ${offset} ${offset}]] c foo
    #make the length an unsigned integer
    set length [expr {${foo} & 0xff}]
    if {${length} > 0} {
      #grab a part and put it in our text QNAME section
      append name [string range [DATAGRAM::udp payload] [expr {${offset} + 1}] [expr {${offset} + ${length}}]]
      #Watch the DNS QNAME get built during the loop. Remove the following line for production use.
      log local0.info "BUILDING DNS NAME: [IP::client_addr] queried ${name} offset ${offset} length ${length}"
      #grab a part and put it in our text QNAME section
      set offset [expr {${offset} + ${length} +1}]
      #endlength contains the Last part length
      binary scan [string range [DATAGRAM::udp payload] ${offset} ${offset}]] c foo
      #make the length an unsigned integer
      set endlength [expr {${foo} & 0xff}]
      if { ${endlength} > 0} {
      #put a dot between parts like a normal DNS name
      append name "." }
      incr i
    }
  }
  #/extract QNAME from QUESTION header
  #Input the required action here, where "${name}" is the variable that is reviewed for decision making.
  #Sample action would be a pool statement. The below log statement should be removed for production use.
  log local0.info "FINAL DNS NAME: [IP::client_addr] queried ${name}"
}

Tested this on version:

12.1
Published Dec 02, 2019
Version 1.0