There was a question in the Wireshark Q&A site that prompted this post. A user wanted to pull out IP Addresses but only from the “Answer Records” section of DNS. All the information in Authority or Additional records section were to be ignored. The picture below describes what he was trying to accomplish with tshark.

Types of scripting
The problem is TShark does not actually expose an object model to a scripting language. The user gets the values of the fields “dns.qry.name” and “dns.resp.addr” which are tagged fields using the display filter format. Without doubt, this is a powerful capability of TShark but extending this to support adhoc scripting requirements is difficult. The solution is to dump the entire packet as text and parse if offline – a difficult ask.
How would you accomplish this with a scriptable object model ?
Unsniff Network Analyzer exposes an object model to scripting languages like Ruby and VBScript. So you can put together a quick script to walk down the protocol try which ever way you want. Lets do this example in Ruby.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | require 'win32ole' raise "Usage: pdns <pcap-file>"  unless ARGV.length == 1 UnsniffDB = WIN32OLE.new("Unsniff.Database") UnsniffDB.New("temp.usnf") UnsniffDB.Import("libpcap",ARGV[0]) UnsniffDB.PacketIndex.each do |pkt| next unless  pkt.Description =~ /QUERY Response/ dnslayer = pkt.FindLayer("DNS") answers = dnslayer.FindField("Answer Records") next if answers.nil? print "\n\nDNS Records in pkt #{pkt.ID} #{pkt.Description}\n" answers.SubFields.each do |rec| print  rec.FindField("Type").Value.ljust(30) print  rec.FindField("Name").Value.ljust(20) print  rec.FindField("RDATA").Value.ljust(20) print  "\n" end end UnsniffDB.Close() File.delete("temp.usnf") | 
Once you get hold of the packets you want, you use the same field names in the GUI to navigate the protocol tree. The key pieces in the above ruby code are :
- Import the pcap file
| 1 | UnsniffDB.Import("libpcap",ARGV[0]) | 
- Iterate over all packets and only work on QUERY Response. The same string is shown in the user interface, so it is easy to remember this string.
| 1 2 | UnsniffDB.PacketIndex.each do |pkt| next unless  pkt.Description =~ /QUERY Response/ | 
- Find the “Answer Records” section in the “DNS” layer and process each record
| 1 2 3 4 | dnslayer = pkt.FindLayer("DNS") answers = dnslayer.FindField("Answer Records") .. answers.SubFields.each do |rec| | 
Running this
If you run the above script
| 1 | ruby pdns.rb mycapture.pcap | 
You get something like this
| 1 2 3 4 5 6 7 8 9 10 11 | DNS Records in pkt 5 QUERY Response ad.doubleclick.net CNAME. Canonical name         ad.doubleclick.net  dart.l.doubleclick.net A.  IPv4 address              dart.l.doubleclick.net74.125.236.188 A.  IPv4 address              dart.l.doubleclick.net74.125.236.187 DNS Records in pkt 6 QUERY Response www.espncricinfo.com CNAME. Canonical name         www.espncricinfo.comwwwakamai.espncricinfo.com CNAME. Canonical name         wwwakamai.espncricinfo.comcontent.cricinfo.com.edgesuite.net CNAME. Canonical name         content.cricinfo.com.edgesuite.neta1850.g.akamai.net A.  IPv4 address              a1850.g.akamai.net  67.148.47.42 A.  IPv4 address              a1850.g.akamai.net  67.148.47.40 | 
Add Unsniff to your toolkit
The beauty of Unsniff is you can script higher layer objects the same way using the UserObjects model. For example you can save all Images matching a certain name or size or whatever. Check out the samples here
- Download Unsniff Network Analyzer for free here

 We just uploaded a new MIB package containing all public CISCO MIBs updated till date. You can import this package into
We just uploaded a new MIB package containing all public CISCO MIBs updated till date. You can import this package into